void InitializePrepass(HDRenderPipelineAsset hdAsset) { m_DepthResolveMaterial = CoreUtils.CreateEngineMaterial(asset.renderPipelineResources.shaders.depthValuesPS); m_GBufferOutput = new GBufferOutput(); m_GBufferOutput.mrt = new TextureHandle[RenderGraph.kMaxMRTCount]; m_DBufferOutput = new DBufferOutput(); m_DBufferOutput.mrt = new TextureHandle[(int)Decal.DBufferMaterial.Count]; m_DepthBufferMipChainInfo = new HDUtils.PackedMipChainInfo(); m_DepthBufferMipChainInfo.Allocate(); }
void InitializePrepass(HDRenderPipelineAsset hdAsset) { m_DepthResolveMaterial = CoreUtils.CreateEngineMaterial(asset.renderPipelineResources.shaders.depthValuesPS); m_GBufferOutput = new GBufferOutput(); m_GBufferOutput.mrt = new TextureHandle[RenderGraph.kMaxMRTCount]; m_DBufferOutput = new DBufferOutput(); m_DBufferOutput.mrt = new TextureHandle[(int)Decal.DBufferMaterial.Count]; m_DepthBufferMipChainInfo = new HDUtils.PackedMipChainInfo(); m_DepthBufferMipChainInfo.Allocate(); m_DepthPyramidDesc = new TextureDesc(ComputeDepthBufferMipChainSize, true, true) { colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "CameraDepthBufferMipChain" }; }
void BuildGPULightList(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthStencilBuffer, TextureHandle stencilBufferCopy, GBufferOutput gBuffer) { using (var builder = renderGraph.AddRenderPass <BuildGPULightListPassData>("Build Light List", out var passData, ProfilingSampler.Get(HDProfileId.BuildLightList))) { builder.EnableAsyncCompute(hdCamera.frameSettings.BuildLightListRunsAsync()); passData.shadowGlobalParameters = PrepareShadowGlobalParameters(hdCamera); passData.lightLoopGlobalParameters = PrepareLightLoopGlobalParameters(hdCamera); passData.buildGPULightListParameters = PrepareBuildGPULightListParameters(hdCamera, buildForProbeVolumes: false); // TODO: Move this inside the render function onces compute buffers are RenderGraph ready passData.buildGPULightListResources = PrepareBuildGPULightListResources(m_TileAndClusterData, null, null, isGBufferNeeded: true); passData.depthBuffer = builder.ReadTexture(depthStencilBuffer); passData.stencilTexture = builder.ReadTexture(stencilBufferCopy); if (passData.buildGPULightListParameters.computeMaterialVariants && passData.buildGPULightListParameters.enableFeatureVariants) { for (int i = 0; i < gBuffer.gBufferCount; ++i) { passData.gBuffer[i] = builder.ReadTexture(gBuffer.mrt[i]); } passData.gBufferCount = gBuffer.gBufferCount; } builder.SetRenderFunc( (BuildGPULightListPassData data, RenderGraphContext context) => { bool tileFlagsWritten = false; data.buildGPULightListResources.depthBuffer = context.resources.GetTexture(data.depthBuffer); data.buildGPULightListResources.stencilTexture = context.resources.GetTexture(data.stencilTexture); if (data.buildGPULightListParameters.computeMaterialVariants && data.buildGPULightListParameters.enableFeatureVariants) { data.buildGPULightListResources.gBuffer = context.renderGraphPool.GetTempArray <RTHandle>(data.gBufferCount); for (int i = 0; i < data.gBufferCount; ++i) { data.buildGPULightListResources.gBuffer[i] = context.resources.GetTexture(data.gBuffer[i]); } } ClearLightLists(data.buildGPULightListParameters, data.buildGPULightListResources, context.cmd); GenerateLightsScreenSpaceAABBs(data.buildGPULightListParameters, data.buildGPULightListResources, context.cmd); BigTilePrepass(data.buildGPULightListParameters, data.buildGPULightListResources, context.cmd); BuildPerTileLightList(data.buildGPULightListParameters, data.buildGPULightListResources, ref tileFlagsWritten, context.cmd); VoxelLightListGeneration(data.buildGPULightListParameters, data.buildGPULightListResources, context.cmd); BuildDispatchIndirectArguments(data.buildGPULightListParameters, data.buildGPULightListResources, tileFlagsWritten, context.cmd); // TODO RENDERGRAPH WARNING: Note that the three sets of variables are bound here, but it should be handled differently. PushShadowGlobalParams(data.shadowGlobalParameters, context.cmd); PushLightLoopGlobalParams(data.lightLoopGlobalParameters, context.cmd); }); } }
BuildGPULightListOutput BuildGPULightList(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthStencilBuffer, TextureHandle stencilBufferCopy, GBufferOutput gBuffer) { using (var builder = renderGraph.AddRenderPass <BuildGPULightListPassData>("Build Light List", out var passData, ProfilingSampler.Get(HDProfileId.BuildLightList))) { builder.EnableAsyncCompute(hdCamera.frameSettings.BuildLightListRunsAsync()); passData.lightLoopGlobalParameters = PrepareLightLoopGlobalParameters(hdCamera, m_TileAndClusterData); passData.buildGPULightListParameters = PrepareBuildGPULightListParameters(hdCamera, m_TileAndClusterData, ref m_ShaderVariablesLightListCB, m_TotalLightCount); passData.depthBuffer = builder.ReadTexture(depthStencilBuffer); passData.stencilTexture = builder.ReadTexture(stencilBufferCopy); if (passData.buildGPULightListParameters.computeMaterialVariants && passData.buildGPULightListParameters.enableFeatureVariants) { for (int i = 0; i < gBuffer.gBufferCount; ++i) { passData.gBuffer[i] = builder.ReadTexture(gBuffer.mrt[i]); } passData.gBufferCount = gBuffer.gBufferCount; } passData.lightVolumeDataBuffer = m_TileAndClusterData.lightVolumeDataBuffer; passData.convexBoundsBuffer = m_TileAndClusterData.convexBoundsBuffer; passData.AABBBoundsBuffer = m_TileAndClusterData.AABBBoundsBuffer; passData.globalLightListAtomic = m_TileAndClusterData.globalLightListAtomic; passData.output.tileFeatureFlags = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.tileFeatureFlags)); passData.output.dispatchIndirectBuffer = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.dispatchIndirectBuffer)); passData.output.perVoxelOffset = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.perVoxelOffset)); passData.output.perTileLogBaseTweak = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.perTileLogBaseTweak)); passData.output.tileList = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.tileList)); passData.output.bigTileLightList = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.bigTileLightList)); passData.output.perVoxelLightLists = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.perVoxelLightLists)); passData.output.lightList = builder.WriteComputeBuffer(renderGraph.ImportComputeBuffer(m_TileAndClusterData.lightList)); builder.SetRenderFunc( (BuildGPULightListPassData data, RenderGraphContext context) => { bool tileFlagsWritten = false; var buildLightListResources = PrepareBuildGPULightListResources(context, data); ClearLightLists(data.buildGPULightListParameters, buildLightListResources, context.cmd); GenerateLightsScreenSpaceAABBs(data.buildGPULightListParameters, buildLightListResources, context.cmd); BigTilePrepass(data.buildGPULightListParameters, buildLightListResources, context.cmd); BuildPerTileLightList(data.buildGPULightListParameters, buildLightListResources, ref tileFlagsWritten, context.cmd); VoxelLightListGeneration(data.buildGPULightListParameters, buildLightListResources, context.cmd); BuildDispatchIndirectArguments(data.buildGPULightListParameters, buildLightListResources, tileFlagsWritten, context.cmd); // TODO RENDERGRAPH WARNING: Note that the three sets of variables are bound here, but it should be handled differently. PushLightLoopGlobalParams(data.lightLoopGlobalParameters, context.cmd); }); return(passData.output); } }
BuildGPULightListOutput BuildGPULightList(RenderGraph renderGraph, HDCamera hdCamera, TileAndClusterData tileAndClusterData, int totalLightCount, int maxLightOnScreen, ref ShaderVariablesLightList constantBuffer, TextureHandle depthStencilBuffer, TextureHandle stencilBufferCopy, GBufferOutput gBuffer) { using (var builder = renderGraph.AddRenderPass <BuildGPULightListPassData>("Build Light List", out var passData, ProfilingSampler.Get(HDProfileId.BuildLightList))) { builder.EnableAsyncCompute(hdCamera.frameSettings.BuildLightListRunsAsync()); passData.buildGPULightListParameters = PrepareBuildGPULightListParameters(hdCamera, tileAndClusterData, ref constantBuffer, totalLightCount); passData.depthBuffer = builder.ReadTexture(depthStencilBuffer); passData.stencilTexture = builder.ReadTexture(stencilBufferCopy); if (passData.buildGPULightListParameters.computeMaterialVariants && passData.buildGPULightListParameters.enableFeatureVariants) { for (int i = 0; i < gBuffer.gBufferCount; ++i) { passData.gBuffer[i] = builder.ReadTexture(gBuffer.mrt[i]); } passData.gBufferCount = gBuffer.gBufferCount; } // Here we use m_MaxViewCount/m_MaxWidthHeight to avoid always allocating buffers of different sizes for each camera. // This way we'll be reusing them more often. // Those buffer are filled with the CPU outside of the render graph. passData.convexBoundsBuffer = builder.ReadComputeBuffer(renderGraph.ImportComputeBuffer(tileAndClusterData.convexBoundsBuffer)); passData.lightVolumeDataBuffer = builder.ReadComputeBuffer(renderGraph.ImportComputeBuffer(tileAndClusterData.lightVolumeDataBuffer)); passData.globalLightListAtomic = builder.CreateTransientComputeBuffer(new ComputeBufferDesc(1, sizeof(uint)) { name = "LightListAtomic" }); passData.AABBBoundsBuffer = builder.CreateTransientComputeBuffer(new ComputeBufferDesc(m_MaxViewCount * 2 * maxLightOnScreen, 4 * sizeof(float)) { name = "AABBBoundBuffer" }); var nrTilesX = (m_MaxCameraWidth + LightDefinitions.s_TileSizeFptl - 1) / LightDefinitions.s_TileSizeFptl; var nrTilesY = (m_MaxCameraHeight + LightDefinitions.s_TileSizeFptl - 1) / LightDefinitions.s_TileSizeFptl; var nrTiles = nrTilesX * nrTilesY * m_MaxViewCount; const int capacityUShortsPerTile = 32; const int dwordsPerTile = (capacityUShortsPerTile + 1) >> 1; // room for 31 lights and a nrLights value. if (tileAndClusterData.hasTileBuffers) { // note that nrTiles include the viewCount in allocation below // Tile buffers passData.output.lightList = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc((int)LightCategory.Count * dwordsPerTile * nrTiles, sizeof(uint)) { name = "LightList" })); passData.output.tileList = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc(LightDefinitions.s_NumFeatureVariants * nrTiles, sizeof(uint)) { name = "TileList" })); passData.output.tileFeatureFlags = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc(nrTiles, sizeof(uint)) { name = "TileFeatureFlags" })); // DispatchIndirect: Buffer with arguments has to have three integer numbers at given argsOffset offset: number of work groups in X dimension, number of work groups in Y dimension, number of work groups in Z dimension. // DrawProceduralIndirect: Buffer with arguments has to have four integer numbers at given argsOffset offset: vertex count per instance, instance count, start vertex location, and start instance location // Use use max size of 4 unit for allocation passData.output.dispatchIndirectBuffer = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc(m_MaxViewCount * LightDefinitions.s_NumFeatureVariants * 4, sizeof(uint), ComputeBufferType.IndirectArguments) { name = "DispatchIndirectBuffer" })); } // Big Tile buffer if (passData.buildGPULightListParameters.runBigTilePrepass) { var nrBigTilesX = (m_MaxCameraWidth + 63) / 64; var nrBigTilesY = (m_MaxCameraHeight + 63) / 64; var nrBigTiles = nrBigTilesX * nrBigTilesY * m_MaxViewCount; // TODO: (Nick) In the case of Probe Volumes, this buffer could be trimmed down / tuned more specifically to probe volumes if we added a s_MaxNrBigTileProbeVolumesPlusOne value. passData.output.bigTileLightList = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc(LightDefinitions.s_MaxNrBigTileLightsPlusOne * nrBigTiles, sizeof(uint)) { name = "BigTiles" })); } // Cluster buffers var nrClustersX = (m_MaxCameraWidth + LightDefinitions.s_TileSizeClustered - 1) / LightDefinitions.s_TileSizeClustered; var nrClustersY = (m_MaxCameraHeight + LightDefinitions.s_TileSizeClustered - 1) / LightDefinitions.s_TileSizeClustered; var nrClusterTiles = nrClustersX * nrClustersY * m_MaxViewCount; passData.output.perVoxelOffset = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc((int)LightCategory.Count * (1 << k_Log2NumClusters) * nrClusterTiles, sizeof(uint)) { name = "PerVoxelOffset" })); passData.output.perVoxelLightLists = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc(NumLightIndicesPerClusteredTile() * nrClusterTiles, sizeof(uint)) { name = "PerVoxelLightList" })); if (tileAndClusterData.clusterNeedsDepth) { passData.output.perTileLogBaseTweak = builder.WriteComputeBuffer( renderGraph.CreateComputeBuffer(new ComputeBufferDesc(nrClusterTiles, sizeof(float)) { name = "PerTileLogBaseTweak" })); } builder.SetRenderFunc( (BuildGPULightListPassData data, RenderGraphContext context) => { bool tileFlagsWritten = false; var buildLightListResources = PrepareBuildGPULightListResources(context, data); ClearLightLists(data.buildGPULightListParameters, buildLightListResources, context.cmd); GenerateLightsScreenSpaceAABBs(data.buildGPULightListParameters, buildLightListResources, context.cmd); BigTilePrepass(data.buildGPULightListParameters, buildLightListResources, context.cmd); BuildPerTileLightList(data.buildGPULightListParameters, buildLightListResources, ref tileFlagsWritten, context.cmd); VoxelLightListGeneration(data.buildGPULightListParameters, buildLightListResources, context.cmd); BuildDispatchIndirectArguments(data.buildGPULightListParameters, buildLightListResources, tileFlagsWritten, context.cmd); }); return(passData.output); } }
void BuildGPULightList(RenderGraph renderGraph, HDCamera hdCamera, RenderGraphResource depthStencilBuffer, RenderGraphResource stencilBufferCopy, GBufferOutput gBuffer) { using (var builder = renderGraph.AddRenderPass <BuildGPULightListPassData>("Build Light List", out var passData)) { builder.EnableAsyncCompute(hdCamera.frameSettings.BuildLightListRunsAsync()); passData.lightLoopGlobalParameters = PrepareLightLoopGlobalParameters(hdCamera); passData.buildGPULightListParameters = PrepareBuildGPULightListParameters(hdCamera); // TODO: Move this inside the render function onces compute buffers are RenderGraph ready passData.buildGPULightListResources = PrepareBuildGPULightListResources(m_TileAndClusterData, null, null); passData.depthBuffer = builder.ReadTexture(depthStencilBuffer); passData.stencilTexture = builder.ReadTexture(stencilBufferCopy); if (passData.buildGPULightListParameters.computeMaterialVariants && passData.buildGPULightListParameters.enableFeatureVariants) { for (int i = 0; i < gBuffer.gBufferCount; ++i) { passData.gBuffer[i] = builder.ReadTexture(gBuffer.mrt[i]); } passData.gBufferCount = gBuffer.gBufferCount; } builder.SetRenderFunc( (BuildGPULightListPassData data, RenderGraphContext context) => { bool tileFlagsWritten = false; data.buildGPULightListResources.depthBuffer = context.resources.GetTexture(data.depthBuffer); data.buildGPULightListResources.stencilTexture = context.resources.GetTexture(data.stencilTexture); if (passData.buildGPULightListParameters.computeMaterialVariants && passData.buildGPULightListParameters.enableFeatureVariants) { data.buildGPULightListResources.gBuffer = context.renderGraphPool.GetTempArray <RTHandle>(data.gBufferCount); for (int i = 0; i < data.gBufferCount; ++i) { data.buildGPULightListResources.gBuffer[i] = context.resources.GetTexture(data.gBuffer[i]); } } GenerateLightsScreenSpaceAABBs(data.buildGPULightListParameters, data.buildGPULightListResources, context.cmd); BigTilePrepass(data.buildGPULightListParameters, data.buildGPULightListResources, context.cmd); BuildPerTileLightList(data.buildGPULightListParameters, data.buildGPULightListResources, ref tileFlagsWritten, context.cmd); VoxelLightListGeneration(data.buildGPULightListParameters, data.buildGPULightListResources, context.cmd); BuildDispatchIndirectArguments(data.buildGPULightListParameters, data.buildGPULightListResources, tileFlagsWritten, context.cmd); PushLightLoopGlobalParams(data.lightLoopGlobalParameters, context.cmd); }); } }