RtShadows.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Renderer/RtShadows.h>
  6. #include <AnKi/Renderer/GBuffer.h>
  7. #include <AnKi/Renderer/Renderer.h>
  8. #include <AnKi/Renderer/ShadowMapping.h>
  9. #include <AnKi/Renderer/AccelerationStructureBuilder.h>
  10. #include <AnKi/Renderer/MotionVectors.h>
  11. #include <AnKi/Renderer/DepthDownscale.h>
  12. #include <AnKi/Renderer/ClusterBinning.h>
  13. #include <AnKi/Util/Tracer.h>
  14. #include <AnKi/Util/CVarSet.h>
  15. #include <AnKi/Shaders/Include/MaterialTypes.h>
  16. #include <AnKi/Shaders/Include/GpuSceneTypes.h>
  17. #include <AnKi/Core/GpuMemory/UnifiedGeometryBuffer.h>
  18. #include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
  19. #include <AnKi/Core/GpuMemory/GpuVisibleTransientMemoryPool.h>
  20. namespace anki {
  21. Error RtShadows::init()
  22. {
  23. m_useSvgf = g_rtShadowsSvgfCVar;
  24. m_atrousPassCount = g_rtShadowsSvgfAtrousPassCountCVar;
  25. ANKI_CHECK(ResourceManager::getSingleton().loadResource("EngineAssets/BlueNoise_Rgba8_64x64.png", m_blueNoiseImage));
  26. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtShadowsSetupSbtBuild.ankiprogbin", m_setupBuildSbtProg, m_setupBuildSbtGrProg));
  27. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtShadowsSbtBuild.ankiprogbin", m_buildSbtProg, m_buildSbtGrProg));
  28. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/RtShadows.ankiprogbin", m_rayGenAndMissProg));
  29. // Ray gen and miss
  30. {
  31. ShaderProgramResourceVariantInitInfo variantInitInfo(m_rayGenAndMissProg);
  32. variantInitInfo.addMutation("RAYS_PER_PIXEL", g_rtShadowsRaysPerPixelCVar);
  33. variantInitInfo.requestTechniqueAndTypes(ShaderTypeBit::kRayGen, "RtShadows");
  34. const ShaderProgramResourceVariant* variant;
  35. m_rayGenAndMissProg->getOrCreateVariant(variantInitInfo, variant);
  36. m_rtLibraryGrProg.reset(&variant->getProgram());
  37. m_rayGenShaderGroupIdx = variant->getShaderGroupHandleIndex();
  38. ShaderProgramResourceVariantInitInfo variantInitInfo2(m_rayGenAndMissProg);
  39. variantInitInfo2.addMutation("RAYS_PER_PIXEL", g_rtShadowsRaysPerPixelCVar);
  40. variantInitInfo2.requestTechniqueAndTypes(ShaderTypeBit::kMiss, "RtShadows");
  41. m_rayGenAndMissProg->getOrCreateVariant(variantInitInfo2, variant);
  42. m_missShaderGroupIdx = variant->getShaderGroupHandleIndex();
  43. }
  44. // Denoise program
  45. if(!m_useSvgf)
  46. {
  47. ANKI_CHECK(
  48. loadShaderProgram("ShaderBinaries/RtShadowsDenoise.ankiprogbin", {{"BLUR_ORIENTATION", 0}}, m_denoiseProg, m_grDenoiseHorizontalProg));
  49. ANKI_CHECK(
  50. loadShaderProgram("ShaderBinaries/RtShadowsDenoise.ankiprogbin", {{"BLUR_ORIENTATION", 1}}, m_denoiseProg, m_grDenoiseVerticalProg));
  51. }
  52. // SVGF variance program
  53. if(m_useSvgf)
  54. {
  55. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtShadowsSvgfVariance.ankiprogbin", m_svgfVarianceProg, m_svgfVarianceGrProg));
  56. }
  57. // SVGF atrous program
  58. if(m_useSvgf)
  59. {
  60. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtShadowsSvgfAtrous.ankiprogbin", {{"LAST_PASS", 0}}, m_svgfAtrousProg, m_svgfAtrousGrProg));
  61. ANKI_CHECK(
  62. loadShaderProgram("ShaderBinaries/RtShadowsSvgfAtrous.ankiprogbin", {{"LAST_PASS", 1}}, m_svgfAtrousProg, m_svgfAtrousLastPassGrProg));
  63. }
  64. // Upscale program
  65. ANKI_CHECK(loadShaderProgram("ShaderBinaries/RtShadowsUpscale.ankiprogbin", m_upscaleProg, m_upscaleGrProg));
  66. // Quarter rez shadow RT
  67. {
  68. TextureInitInfo texinit = getRenderer().create2DRenderTargetInitInfo(
  69. getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2, Format::kR8_Unorm,
  70. TextureUsageBit::kAllSrv | TextureUsageBit::kUavTraceRays | TextureUsageBit::kUavCompute, "RtShadows History");
  71. m_historyRt = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSrvPixel);
  72. }
  73. // Temp shadow RT
  74. {
  75. m_intermediateShadowsRtDescr = getRenderer().create2DRenderTargetDescription(
  76. getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2, Format::kR8_Unorm, "RtShadows Tmp");
  77. m_intermediateShadowsRtDescr.bake();
  78. }
  79. // Moments RT
  80. {
  81. TextureInitInfo texinit = getRenderer().create2DRenderTargetInitInfo(
  82. getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2, Format::kR32G32_Sfloat,
  83. TextureUsageBit::kAllSrv | TextureUsageBit::kUavTraceRays | TextureUsageBit::kUavCompute, "RtShadows Moments #1");
  84. m_momentsRts[0] = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSrvPixel);
  85. texinit.setName("RtShadows Moments #2");
  86. m_momentsRts[1] = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSrvPixel);
  87. }
  88. // Variance RT
  89. if(m_useSvgf)
  90. {
  91. m_varianceRtDescr = getRenderer().create2DRenderTargetDescription(
  92. getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2, Format::kR32_Sfloat, "RtShadows Variance");
  93. m_varianceRtDescr.bake();
  94. }
  95. // Final RT
  96. {
  97. m_upscaledRtDescr = getRenderer().create2DRenderTargetDescription(
  98. getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y(), Format::kR8_Unorm, "RtShadows Upscaled");
  99. m_upscaledRtDescr.bake();
  100. }
  101. {
  102. TextureInitInfo texinit = getRenderer().create2DRenderTargetInitInfo(
  103. getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2, Format::kR32_Sfloat,
  104. TextureUsageBit::kAllSrv | TextureUsageBit::kUavTraceRays | TextureUsageBit::kUavCompute, "RtShadows history len");
  105. ClearValue clear;
  106. clear.m_colorf[0] = 1.0f;
  107. m_dummyHistoryLenTex = getRenderer().createAndClearRenderTarget(texinit, TextureUsageBit::kSrvPixel, clear);
  108. }
  109. // Misc
  110. m_sbtRecordSize = getAlignedRoundUp(GrManager::getSingleton().getDeviceCapabilities().m_sbtRecordAlignment, m_sbtRecordSize);
  111. return Error::kNone;
  112. }
  113. void RtShadows::populateRenderGraph(RenderingContext& ctx)
  114. {
  115. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  116. #define ANKI_DEPTH_DEP \
  117. getRenderer().getDepthDownscale().getRt(), TextureUsageBit::kSrvTraceRays | TextureUsageBit::kSrvCompute, \
  118. DepthDownscale::kQuarterInternalResolution
  119. RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
  120. // Import RTs
  121. {
  122. const U32 prevRtIdx = getRenderer().getFrameCount() & 1;
  123. if(!m_rtsImportedOnce) [[unlikely]]
  124. {
  125. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_historyRt.get(), TextureUsageBit::kSrvPixel);
  126. m_runCtx.m_prevMomentsRt = rgraph.importRenderTarget(m_momentsRts[prevRtIdx].get(), TextureUsageBit::kSrvPixel);
  127. m_rtsImportedOnce = true;
  128. }
  129. else
  130. {
  131. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_historyRt.get());
  132. m_runCtx.m_prevMomentsRt = rgraph.importRenderTarget(m_momentsRts[prevRtIdx].get());
  133. }
  134. if((getPassCountWithoutUpscaling() % 2) == 1)
  135. {
  136. m_runCtx.m_intermediateShadowsRts[0] = rgraph.newRenderTarget(m_intermediateShadowsRtDescr);
  137. m_runCtx.m_intermediateShadowsRts[1] = rgraph.newRenderTarget(m_intermediateShadowsRtDescr);
  138. }
  139. else
  140. {
  141. // We can save a render target if we have even number of renderpasses
  142. m_runCtx.m_intermediateShadowsRts[0] = rgraph.newRenderTarget(m_intermediateShadowsRtDescr);
  143. m_runCtx.m_intermediateShadowsRts[1] = m_runCtx.m_historyRt;
  144. }
  145. m_runCtx.m_currentMomentsRt = rgraph.importRenderTarget(m_momentsRts[!prevRtIdx].get(), TextureUsageBit::kNone);
  146. if(m_useSvgf)
  147. {
  148. if(m_atrousPassCount > 1)
  149. {
  150. m_runCtx.m_varianceRts[0] = rgraph.newRenderTarget(m_varianceRtDescr);
  151. }
  152. m_runCtx.m_varianceRts[1] = rgraph.newRenderTarget(m_varianceRtDescr);
  153. }
  154. m_runCtx.m_upscaledRt = rgraph.newRenderTarget(m_upscaledRtDescr);
  155. }
  156. // Setup build SBT dispatch
  157. BufferHandle sbtBuildIndirectArgsHandle;
  158. BufferView sbtBuildIndirectArgsBuffer;
  159. {
  160. sbtBuildIndirectArgsBuffer = GpuVisibleTransientMemoryPool::getSingleton().allocateStructuredBuffer<DispatchIndirectArgs>(1);
  161. sbtBuildIndirectArgsHandle = rgraph.importBuffer(sbtBuildIndirectArgsBuffer, BufferUsageBit::kUavCompute);
  162. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows setup build SBT");
  163. rpass.newBufferDependency(sbtBuildIndirectArgsHandle, BufferUsageBit::kAccelerationStructureBuild);
  164. rpass.setWork([this, sbtBuildIndirectArgsBuffer](RenderPassWorkContext& rgraphCtx) {
  165. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  166. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  167. cmdb.bindShaderProgram(m_setupBuildSbtGrProg.get());
  168. cmdb.bindSrv(0, 0, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getBufferView());
  169. cmdb.bindUav(0, 0, sbtBuildIndirectArgsBuffer);
  170. cmdb.dispatchCompute(1, 1, 1);
  171. });
  172. }
  173. // Build the SBT
  174. BufferHandle sbtHandle;
  175. BufferView sbtBuffer;
  176. {
  177. // Allocate SBT
  178. WeakArray<U32> sbtMem;
  179. sbtBuffer = RebarTransientMemoryPool::getSingleton().allocateStructuredBuffer(
  180. (GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount() + 2) * m_sbtRecordSize / sizeof(U32), sbtMem);
  181. sbtHandle = rgraph.importBuffer(sbtBuffer, BufferUsageBit::kUavCompute);
  182. // Write the first 2 entries of the SBT
  183. ConstWeakArray<U8> shaderGroupHandles = m_rtLibraryGrProg->getShaderGroupHandles();
  184. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  185. memcpy(&sbtMem[0], &shaderGroupHandles[m_rayGenShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  186. memcpy(&sbtMem[m_sbtRecordSize / sizeof(U32)], &shaderGroupHandles[m_missShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  187. // Create the pass
  188. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows build SBT");
  189. BufferHandle visibilityHandle;
  190. BufferView visibleRenderableIndicesBuff, sbtBuildIndirectArgsBuff;
  191. getRenderer().getAccelerationStructureBuilder().getVisibilityInfo(visibilityHandle, visibleRenderableIndicesBuff, sbtBuildIndirectArgsBuff);
  192. rpass.newBufferDependency(visibilityHandle, BufferUsageBit::kSrvCompute);
  193. rpass.newBufferDependency(sbtBuildIndirectArgsHandle, BufferUsageBit::kIndirectCompute);
  194. rpass.setWork([this, sbtBuildIndirectArgsBuffer, sbtBuffer, visibleRenderableIndicesBuff](RenderPassWorkContext& rgraphCtx) {
  195. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  196. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  197. cmdb.bindShaderProgram(m_buildSbtGrProg.get());
  198. cmdb.bindSrv(0, 0, GpuSceneArrays::Renderable::getSingleton().getBufferView());
  199. cmdb.bindSrv(1, 0, BufferView(&GpuSceneBuffer::getSingleton().getBuffer()));
  200. cmdb.bindSrv(2, 0, visibleRenderableIndicesBuff);
  201. cmdb.bindSrv(3, 0, BufferView(&m_rtLibraryGrProg->getShaderGroupHandlesGpuBuffer()));
  202. cmdb.bindUav(0, 0, sbtBuffer);
  203. RtShadowsSbtBuildConstants consts = {};
  204. ANKI_ASSERT(m_sbtRecordSize % 4 == 0);
  205. consts.m_sbtRecordDwordSize = m_sbtRecordSize / 4;
  206. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  207. ANKI_ASSERT(shaderHandleSize % 4 == 0);
  208. consts.m_shaderHandleDwordSize = shaderHandleSize / 4;
  209. cmdb.setFastConstants(&consts, sizeof(consts));
  210. cmdb.dispatchComputeIndirect(sbtBuildIndirectArgsBuffer);
  211. });
  212. }
  213. // Ray gen
  214. {
  215. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows");
  216. rpass.newTextureDependency(m_runCtx.m_historyRt, TextureUsageBit::kSrvTraceRays);
  217. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::kUavTraceRays);
  218. rpass.newAccelerationStructureDependency(getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle(),
  219. AccelerationStructureUsageBit::kTraceRaysSrv);
  220. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  221. rpass.newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), TextureUsageBit::kSrvTraceRays);
  222. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvTraceRays);
  223. rpass.newTextureDependency(m_runCtx.m_prevMomentsRt, TextureUsageBit::kSrvTraceRays);
  224. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kUavTraceRays);
  225. rpass.newBufferDependency(getRenderer().getClusterBinning().getDependency(), BufferUsageBit::kSrvTraceRays);
  226. rpass.setWork([this, sbtBuffer, &ctx](RenderPassWorkContext& rgraphCtx) {
  227. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  228. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  229. cmdb.bindShaderProgram(m_rtLibraryGrProg.get());
  230. // Allocate, set and bind global uniforms
  231. {
  232. MaterialGlobalConstants* globalConstants;
  233. const BufferView globalConstantsToken = RebarTransientMemoryPool::getSingleton().allocateConstantBuffer(globalConstants);
  234. memset(globalConstants, 0, sizeof(*globalConstants)); // Don't care for now
  235. cmdb.bindConstantBuffer(ANKI_MATERIAL_REGISTER_GLOBAL_CONSTANTS, 0, globalConstantsToken);
  236. }
  237. // More globals
  238. cmdb.bindSampler(ANKI_MATERIAL_REGISTER_TILINEAR_REPEAT_SAMPLER, 0, getRenderer().getSamplers().m_trilinearRepeat.get());
  239. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_GPU_SCENE, 0, GpuSceneBuffer::getSingleton().getBufferView());
  240. #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType, reg) \
  241. cmdb.bindSrv( \
  242. reg, 0, \
  243. BufferView(&UnifiedGeometryBuffer::getSingleton().getBuffer(), 0, \
  244. getAlignedRoundDown(getFormatInfo(Format::k##fmt).m_texelSize, UnifiedGeometryBuffer::getSingleton().getBuffer().getSize())), \
  245. Format::k##fmt);
  246. #include <AnKi/Shaders/Include/UnifiedGeometryTypes.def.h>
  247. cmdb.bindConstantBuffer(0, 2, ctx.m_globalRenderingConstantsBuffer);
  248. cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearRepeat.get());
  249. rgraphCtx.bindUav(0, 2, m_runCtx.m_intermediateShadowsRts[0]);
  250. rgraphCtx.bindSrv(0, 2, m_runCtx.m_historyRt);
  251. cmdb.bindSampler(1, 2, getRenderer().getSamplers().m_trilinearClamp.get());
  252. rgraphCtx.bindSrv(1, 2, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  253. rgraphCtx.bindSrv(2, 2, getRenderer().getMotionVectors().getMotionVectorsRt());
  254. cmdb.bindSrv(3, 2, TextureView(m_dummyHistoryLenTex.get(), TextureSubresourceDesc::all()));
  255. rgraphCtx.bindSrv(4, 2, getRenderer().getGBuffer().getColorRt(2));
  256. rgraphCtx.bindSrv(5, 2, getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle());
  257. rgraphCtx.bindSrv(6, 2, m_runCtx.m_prevMomentsRt);
  258. rgraphCtx.bindUav(1, 2, m_runCtx.m_currentMomentsRt);
  259. cmdb.bindSrv(7, 2, TextureView(&m_blueNoiseImage->getTexture(), TextureSubresourceDesc::all()));
  260. cmdb.traceRays(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
  261. getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2, 1);
  262. });
  263. }
  264. // Denoise pass horizontal
  265. if(!m_useSvgf)
  266. {
  267. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows Denoise Horizontal");
  268. rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
  269. runDenoise(ctx, rgraphCtx, true);
  270. });
  271. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::kSrvCompute);
  272. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  273. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  274. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kSrvCompute);
  275. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[1], TextureUsageBit::kUavCompute);
  276. }
  277. // Denoise pass vertical
  278. if(!m_useSvgf)
  279. {
  280. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows Denoise Vertical");
  281. rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
  282. runDenoise(ctx, rgraphCtx, false);
  283. });
  284. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[1], TextureUsageBit::kSrvCompute);
  285. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  286. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  287. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kSrvCompute);
  288. rpass.newTextureDependency(m_runCtx.m_historyRt, TextureUsageBit::kUavCompute);
  289. }
  290. // Variance calculation pass
  291. if(m_useSvgf)
  292. {
  293. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows SVGF Variance");
  294. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::kSrvCompute);
  295. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kSrvCompute);
  296. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  297. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  298. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[1], TextureUsageBit::kUavCompute);
  299. rpass.newTextureDependency(m_runCtx.m_varianceRts[1], TextureUsageBit::kUavCompute);
  300. rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
  301. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  302. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  303. cmdb.bindShaderProgram(m_svgfVarianceGrProg.get());
  304. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  305. rgraphCtx.bindSrv(0, 0, m_runCtx.m_intermediateShadowsRts[0]);
  306. rgraphCtx.bindSrv(1, 0, m_runCtx.m_currentMomentsRt);
  307. cmdb.bindSrv(2, 0, TextureView(m_dummyHistoryLenTex.get(), TextureSubresourceDesc::all()));
  308. rgraphCtx.bindSrv(3, 0, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  309. rgraphCtx.bindUav(0, 0, m_runCtx.m_intermediateShadowsRts[1]);
  310. rgraphCtx.bindUav(1, 0, m_runCtx.m_varianceRts[1]);
  311. const Mat4& invProjMat = ctx.m_matrices.m_projectionJitter.invert();
  312. cmdb.setFastConstants(&invProjMat, sizeof(invProjMat));
  313. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2);
  314. });
  315. }
  316. // SVGF Atrous
  317. if(m_useSvgf)
  318. {
  319. for(U32 i = 0; i < m_atrousPassCount; ++i)
  320. {
  321. const Bool lastPass = i == U32(m_atrousPassCount - 1);
  322. const U32 readRtIdx = (i + 1) & 1;
  323. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows SVGF Atrous");
  324. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  325. rpass.newTextureDependency(getRenderer().getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  326. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[readRtIdx], TextureUsageBit::kSrvCompute);
  327. rpass.newTextureDependency(m_runCtx.m_varianceRts[readRtIdx], TextureUsageBit::kSrvCompute);
  328. if(!lastPass)
  329. {
  330. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[!readRtIdx], TextureUsageBit::kUavCompute);
  331. rpass.newTextureDependency(m_runCtx.m_varianceRts[!readRtIdx], TextureUsageBit::kUavCompute);
  332. }
  333. else
  334. {
  335. rpass.newTextureDependency(m_runCtx.m_historyRt, TextureUsageBit::kUavCompute);
  336. }
  337. rpass.setWork([this, &ctx, passIdx = i](RenderPassWorkContext& rgraphCtx) {
  338. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  339. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  340. const Bool lastPass = passIdx == U32(m_atrousPassCount - 1);
  341. const U32 readRtIdx = (passIdx + 1) & 1;
  342. if(lastPass)
  343. {
  344. cmdb.bindShaderProgram(m_svgfAtrousLastPassGrProg.get());
  345. }
  346. else
  347. {
  348. cmdb.bindShaderProgram(m_svgfAtrousGrProg.get());
  349. }
  350. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  351. rgraphCtx.bindSrv(0, 0, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  352. rgraphCtx.bindSrv(1, 0, m_runCtx.m_intermediateShadowsRts[readRtIdx]);
  353. rgraphCtx.bindSrv(2, 0, m_runCtx.m_varianceRts[readRtIdx]);
  354. if(!lastPass)
  355. {
  356. rgraphCtx.bindUav(0, 0, m_runCtx.m_intermediateShadowsRts[!readRtIdx]);
  357. rgraphCtx.bindUav(1, 0, m_runCtx.m_varianceRts[!readRtIdx]);
  358. }
  359. else
  360. {
  361. rgraphCtx.bindUav(0, 0, m_runCtx.m_historyRt);
  362. }
  363. const Mat4& invProjMat = ctx.m_matrices.m_projectionJitter.invert();
  364. cmdb.setFastConstants(&invProjMat, sizeof(invProjMat));
  365. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2);
  366. });
  367. }
  368. }
  369. // Upscale
  370. {
  371. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows Upscale");
  372. rpass.newTextureDependency(m_runCtx.m_historyRt, TextureUsageBit::kSrvCompute);
  373. rpass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  374. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  375. rpass.newTextureDependency(m_runCtx.m_upscaledRt, TextureUsageBit::kUavCompute);
  376. rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  377. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  378. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  379. cmdb.bindShaderProgram(m_upscaleGrProg.get());
  380. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  381. rgraphCtx.bindSrv(0, 0, m_runCtx.m_historyRt);
  382. rgraphCtx.bindUav(0, 0, m_runCtx.m_upscaledRt);
  383. rgraphCtx.bindSrv(1, 0, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  384. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getDepthRt());
  385. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
  386. });
  387. }
  388. }
  389. void RtShadows::runDenoise(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx, Bool horizontal)
  390. {
  391. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  392. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  393. cmdb.bindShaderProgram((horizontal) ? m_grDenoiseHorizontalProg.get() : m_grDenoiseVerticalProg.get());
  394. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  395. rgraphCtx.bindSrv(0, 0, m_runCtx.m_intermediateShadowsRts[(horizontal) ? 0 : 1]);
  396. rgraphCtx.bindSrv(1, 0, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  397. rgraphCtx.bindSrv(2, 0, getRenderer().getGBuffer().getColorRt(2));
  398. rgraphCtx.bindSrv(3, 0, m_runCtx.m_currentMomentsRt);
  399. cmdb.bindSrv(4, 0, TextureView(m_dummyHistoryLenTex.get(), TextureSubresourceDesc::all()));
  400. rgraphCtx.bindUav(0, 0, (horizontal) ? m_runCtx.m_intermediateShadowsRts[1] : m_runCtx.m_historyRt);
  401. RtShadowsDenoiseConstants consts;
  402. consts.m_invViewProjMat = ctx.m_matrices.m_invertedViewProjectionJitter;
  403. consts.m_time = F32(GlobalFrameIndex::getSingleton().m_value % 0xFFFFu);
  404. consts.m_minSampleCount = 8;
  405. consts.m_maxSampleCount = 32;
  406. cmdb.setFastConstants(&consts, sizeof(consts));
  407. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x() / 2, getRenderer().getInternalResolution().y() / 2);
  408. }
  409. void RtShadows::getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
  410. [[maybe_unused]] ShaderProgramPtr& optionalShaderProgram) const
  411. {
  412. handles[0] = m_runCtx.m_upscaledRt;
  413. }
  414. } // end namespace anki