RtShadows.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  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/GpuMemory/UnifiedGeometryBuffer.h>
  18. #include <AnKi/GpuMemory/GpuSceneBuffer.h>
  19. #include <AnKi/GpuMemory/GpuVisibleTransientMemoryPool.h>
  20. namespace anki {
  21. Error RtShadows::init()
  22. {
  23. m_useSvgf = g_cvarRenderRtShadowsSvgf;
  24. m_atrousPassCount = g_cvarRenderRtShadowsSvgfAtrousPassCount;
  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_cvarRenderRtShadowsRaysPerPixel);
  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_cvarRenderRtShadowsRaysPerPixel);
  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::kUavDispatchRays | 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::kUavDispatchRays | 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::kUavDispatchRays | 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. getDepthDownscale().getRt(), TextureUsageBit::kSrvDispatchRays | TextureUsageBit::kSrvCompute, DepthDownscale::kQuarterInternalResolution
  118. RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
  119. // Import RTs
  120. {
  121. const U32 prevRtIdx = getRenderer().getFrameCount() & 1;
  122. if(!m_rtsImportedOnce) [[unlikely]]
  123. {
  124. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_historyRt.get(), TextureUsageBit::kSrvPixel);
  125. m_runCtx.m_prevMomentsRt = rgraph.importRenderTarget(m_momentsRts[prevRtIdx].get(), TextureUsageBit::kSrvPixel);
  126. m_rtsImportedOnce = true;
  127. }
  128. else
  129. {
  130. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_historyRt.get());
  131. m_runCtx.m_prevMomentsRt = rgraph.importRenderTarget(m_momentsRts[prevRtIdx].get());
  132. }
  133. if((getPassCountWithoutUpscaling() % 2) == 1)
  134. {
  135. m_runCtx.m_intermediateShadowsRts[0] = rgraph.newRenderTarget(m_intermediateShadowsRtDescr);
  136. m_runCtx.m_intermediateShadowsRts[1] = rgraph.newRenderTarget(m_intermediateShadowsRtDescr);
  137. }
  138. else
  139. {
  140. // We can save a render target if we have even number of renderpasses
  141. m_runCtx.m_intermediateShadowsRts[0] = rgraph.newRenderTarget(m_intermediateShadowsRtDescr);
  142. m_runCtx.m_intermediateShadowsRts[1] = m_runCtx.m_historyRt;
  143. }
  144. m_runCtx.m_currentMomentsRt = rgraph.importRenderTarget(m_momentsRts[!prevRtIdx].get(), TextureUsageBit::kNone);
  145. if(m_useSvgf)
  146. {
  147. if(m_atrousPassCount > 1)
  148. {
  149. m_runCtx.m_varianceRts[0] = rgraph.newRenderTarget(m_varianceRtDescr);
  150. }
  151. m_runCtx.m_varianceRts[1] = rgraph.newRenderTarget(m_varianceRtDescr);
  152. }
  153. m_runCtx.m_upscaledRt = rgraph.newRenderTarget(m_upscaledRtDescr);
  154. }
  155. // Setup build SBT dispatch
  156. BufferHandle sbtBuildIndirectArgsHandle;
  157. BufferView sbtBuildIndirectArgsBuffer;
  158. {
  159. sbtBuildIndirectArgsBuffer = GpuVisibleTransientMemoryPool::getSingleton().allocateStructuredBuffer<DispatchIndirectArgs>(1);
  160. sbtBuildIndirectArgsHandle = rgraph.importBuffer(sbtBuildIndirectArgsBuffer, BufferUsageBit::kUavCompute);
  161. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows setup build SBT");
  162. rpass.newBufferDependency(sbtBuildIndirectArgsHandle, BufferUsageBit::kAccelerationStructureBuild);
  163. rpass.setWork([this, sbtBuildIndirectArgsBuffer](RenderPassWorkContext& rgraphCtx) {
  164. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  165. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  166. cmdb.bindShaderProgram(m_setupBuildSbtGrProg.get());
  167. cmdb.bindSrv(0, 0, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getBufferView());
  168. cmdb.bindUav(0, 0, sbtBuildIndirectArgsBuffer);
  169. cmdb.dispatchCompute(1, 1, 1);
  170. });
  171. }
  172. // Build the SBT
  173. BufferHandle sbtHandle;
  174. BufferView sbtBuffer;
  175. {
  176. // Allocate SBT
  177. WeakArray<U32> sbtMem;
  178. sbtBuffer = RebarTransientMemoryPool::getSingleton().allocateStructuredBuffer(
  179. (GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount() + 2) * m_sbtRecordSize / sizeof(U32), sbtMem);
  180. sbtHandle = rgraph.importBuffer(sbtBuffer, BufferUsageBit::kUavCompute);
  181. // Write the first 2 entries of the SBT
  182. ConstWeakArray<U8> shaderGroupHandles = m_rtLibraryGrProg->getShaderGroupHandles();
  183. const U32 shaderHandleSize = GrManager::getSingleton().getDeviceCapabilities().m_shaderGroupHandleSize;
  184. memcpy(&sbtMem[0], &shaderGroupHandles[m_rayGenShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  185. memcpy(&sbtMem[m_sbtRecordSize / sizeof(U32)], &shaderGroupHandles[m_missShaderGroupIdx * shaderHandleSize], shaderHandleSize);
  186. // Create the pass
  187. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows build SBT");
  188. AccelerationStructureVisibilityInfo asVis;
  189. GpuVisibilityLocalLightsOutput localLightsVis;
  190. getRenderer().getAccelerationStructureBuilder().getVisibilityInfo(asVis, localLightsVis);
  191. rpass.newBufferDependency(asVis.m_depedency, BufferUsageBit::kSrvCompute);
  192. rpass.newBufferDependency(sbtBuildIndirectArgsHandle, BufferUsageBit::kIndirectCompute);
  193. rpass.setWork([this, sbtBuildIndirectArgsBuffer, sbtBuffer,
  194. visibleRenderableIndicesBuff = asVis.m_visibleRenderablesBuffer](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::kSrvDispatchRays);
  217. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::kUavDispatchRays);
  218. rpass.newAccelerationStructureDependency(getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle(),
  219. AccelerationStructureUsageBit::kSrvDispatchRays);
  220. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  221. rpass.newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), TextureUsageBit::kSrvDispatchRays);
  222. rpass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvDispatchRays);
  223. rpass.newTextureDependency(m_runCtx.m_prevMomentsRt, TextureUsageBit::kSrvDispatchRays);
  224. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kUavDispatchRays);
  225. rpass.newBufferDependency(getClusterBinning().getDependency(), BufferUsageBit::kSrvDispatchRays);
  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. cmdb.bindSrv(ANKI_MATERIAL_REGISTER_UNIFIED_GEOMETRY, 0, UnifiedGeometryBuffer::getSingleton().getBufferView());
  241. #define ANKI_UNIFIED_GEOM_FORMAT(fmt, shaderType, reg) \
  242. cmdb.bindSrv( \
  243. reg, 0, \
  244. BufferView(&UnifiedGeometryBuffer::getSingleton().getBuffer(), 0, \
  245. getAlignedRoundDown(getFormatInfo(Format::k##fmt).m_texelSize, UnifiedGeometryBuffer::getSingleton().getBuffer().getSize())), \
  246. Format::k##fmt);
  247. #include <AnKi/Shaders/Include/UnifiedGeometryTypes.def.h>
  248. cmdb.bindConstantBuffer(0, 2, ctx.m_globalRenderingConstantsBuffer);
  249. cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearRepeat.get());
  250. rgraphCtx.bindUav(0, 2, m_runCtx.m_intermediateShadowsRts[0]);
  251. rgraphCtx.bindSrv(0, 2, m_runCtx.m_historyRt);
  252. cmdb.bindSampler(1, 2, getRenderer().getSamplers().m_trilinearClamp.get());
  253. rgraphCtx.bindSrv(1, 2, getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  254. rgraphCtx.bindSrv(2, 2, getRenderer().getMotionVectors().getMotionVectorsRt());
  255. cmdb.bindSrv(3, 2, TextureView(m_dummyHistoryLenTex.get(), TextureSubresourceDesc::all()));
  256. rgraphCtx.bindSrv(4, 2, getGBuffer().getColorRt(2));
  257. rgraphCtx.bindSrv(5, 2, getRenderer().getAccelerationStructureBuilder().getAccelerationStructureHandle());
  258. rgraphCtx.bindSrv(6, 2, m_runCtx.m_prevMomentsRt);
  259. rgraphCtx.bindUav(1, 2, m_runCtx.m_currentMomentsRt);
  260. cmdb.bindSrv(7, 2, TextureView(&m_blueNoiseImage->getTexture(), TextureSubresourceDesc::all()));
  261. cmdb.dispatchRays(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,
  262. getRenderer().getInternalResolution().x / 2, getRenderer().getInternalResolution().y / 2, 1);
  263. });
  264. }
  265. // Denoise pass horizontal
  266. if(!m_useSvgf)
  267. {
  268. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows Denoise Horizontal");
  269. rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
  270. runDenoise(ctx, rgraphCtx, true);
  271. });
  272. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::kSrvCompute);
  273. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  274. rpass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  275. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kSrvCompute);
  276. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[1], TextureUsageBit::kUavCompute);
  277. }
  278. // Denoise pass vertical
  279. if(!m_useSvgf)
  280. {
  281. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows Denoise Vertical");
  282. rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
  283. runDenoise(ctx, rgraphCtx, false);
  284. });
  285. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[1], TextureUsageBit::kSrvCompute);
  286. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  287. rpass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  288. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kSrvCompute);
  289. rpass.newTextureDependency(m_runCtx.m_historyRt, TextureUsageBit::kUavCompute);
  290. }
  291. // Variance calculation pass
  292. if(m_useSvgf)
  293. {
  294. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows SVGF Variance");
  295. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[0], TextureUsageBit::kSrvCompute);
  296. rpass.newTextureDependency(m_runCtx.m_currentMomentsRt, TextureUsageBit::kSrvCompute);
  297. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  298. rpass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  299. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[1], TextureUsageBit::kUavCompute);
  300. rpass.newTextureDependency(m_runCtx.m_varianceRts[1], TextureUsageBit::kUavCompute);
  301. rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
  302. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  303. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  304. cmdb.bindShaderProgram(m_svgfVarianceGrProg.get());
  305. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  306. rgraphCtx.bindSrv(0, 0, m_runCtx.m_intermediateShadowsRts[0]);
  307. rgraphCtx.bindSrv(1, 0, m_runCtx.m_currentMomentsRt);
  308. cmdb.bindSrv(2, 0, TextureView(m_dummyHistoryLenTex.get(), TextureSubresourceDesc::all()));
  309. rgraphCtx.bindSrv(3, 0, getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  310. rgraphCtx.bindUav(0, 0, m_runCtx.m_intermediateShadowsRts[1]);
  311. rgraphCtx.bindUav(1, 0, m_runCtx.m_varianceRts[1]);
  312. const Mat4& invProjMat = ctx.m_matrices.m_projectionJitter.invert();
  313. cmdb.setFastConstants(&invProjMat, sizeof(invProjMat));
  314. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x / 2, getRenderer().getInternalResolution().y / 2);
  315. });
  316. }
  317. // SVGF Atrous
  318. if(m_useSvgf)
  319. {
  320. for(U32 i = 0; i < m_atrousPassCount; ++i)
  321. {
  322. const Bool lastPass = i == U32(m_atrousPassCount - 1);
  323. const U32 readRtIdx = (i + 1) & 1;
  324. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows SVGF Atrous");
  325. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  326. rpass.newTextureDependency(getGBuffer().getColorRt(2), TextureUsageBit::kSrvCompute);
  327. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[readRtIdx], TextureUsageBit::kSrvCompute);
  328. rpass.newTextureDependency(m_runCtx.m_varianceRts[readRtIdx], TextureUsageBit::kSrvCompute);
  329. if(!lastPass)
  330. {
  331. rpass.newTextureDependency(m_runCtx.m_intermediateShadowsRts[!readRtIdx], TextureUsageBit::kUavCompute);
  332. rpass.newTextureDependency(m_runCtx.m_varianceRts[!readRtIdx], TextureUsageBit::kUavCompute);
  333. }
  334. else
  335. {
  336. rpass.newTextureDependency(m_runCtx.m_historyRt, TextureUsageBit::kUavCompute);
  337. }
  338. rpass.setWork([this, &ctx, passIdx = i](RenderPassWorkContext& rgraphCtx) {
  339. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  340. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  341. const Bool lastPass = passIdx == U32(m_atrousPassCount - 1);
  342. const U32 readRtIdx = (passIdx + 1) & 1;
  343. if(lastPass)
  344. {
  345. cmdb.bindShaderProgram(m_svgfAtrousLastPassGrProg.get());
  346. }
  347. else
  348. {
  349. cmdb.bindShaderProgram(m_svgfAtrousGrProg.get());
  350. }
  351. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  352. rgraphCtx.bindSrv(0, 0, getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  353. rgraphCtx.bindSrv(1, 0, m_runCtx.m_intermediateShadowsRts[readRtIdx]);
  354. rgraphCtx.bindSrv(2, 0, m_runCtx.m_varianceRts[readRtIdx]);
  355. if(!lastPass)
  356. {
  357. rgraphCtx.bindUav(0, 0, m_runCtx.m_intermediateShadowsRts[!readRtIdx]);
  358. rgraphCtx.bindUav(1, 0, m_runCtx.m_varianceRts[!readRtIdx]);
  359. }
  360. else
  361. {
  362. rgraphCtx.bindUav(0, 0, m_runCtx.m_historyRt);
  363. }
  364. const Mat4& invProjMat = ctx.m_matrices.m_projectionJitter.invert();
  365. cmdb.setFastConstants(&invProjMat, sizeof(invProjMat));
  366. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x / 2, getRenderer().getInternalResolution().y / 2);
  367. });
  368. }
  369. }
  370. // Upscale
  371. {
  372. NonGraphicsRenderPass& rpass = rgraph.newNonGraphicsRenderPass("RtShadows Upscale");
  373. rpass.newTextureDependency(m_runCtx.m_historyRt, TextureUsageBit::kSrvCompute);
  374. rpass.newTextureDependency(getGBuffer().getDepthRt(), TextureUsageBit::kSrvCompute);
  375. rpass.newTextureDependency(ANKI_DEPTH_DEP);
  376. rpass.newTextureDependency(m_runCtx.m_upscaledRt, TextureUsageBit::kUavCompute);
  377. rpass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  378. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  379. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  380. cmdb.bindShaderProgram(m_upscaleGrProg.get());
  381. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  382. rgraphCtx.bindSrv(0, 0, m_runCtx.m_historyRt);
  383. rgraphCtx.bindUav(0, 0, m_runCtx.m_upscaledRt);
  384. rgraphCtx.bindSrv(1, 0, getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  385. rgraphCtx.bindSrv(2, 0, getGBuffer().getDepthRt());
  386. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x, getRenderer().getInternalResolution().y);
  387. });
  388. }
  389. }
  390. void RtShadows::runDenoise(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx, Bool horizontal)
  391. {
  392. ANKI_TRACE_SCOPED_EVENT(RtShadows);
  393. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  394. cmdb.bindShaderProgram((horizontal) ? m_grDenoiseHorizontalProg.get() : m_grDenoiseVerticalProg.get());
  395. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  396. rgraphCtx.bindSrv(0, 0, m_runCtx.m_intermediateShadowsRts[(horizontal) ? 0 : 1]);
  397. rgraphCtx.bindSrv(1, 0, getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
  398. rgraphCtx.bindSrv(2, 0, getGBuffer().getColorRt(2));
  399. rgraphCtx.bindSrv(3, 0, m_runCtx.m_currentMomentsRt);
  400. cmdb.bindSrv(4, 0, TextureView(m_dummyHistoryLenTex.get(), TextureSubresourceDesc::all()));
  401. rgraphCtx.bindUav(0, 0, (horizontal) ? m_runCtx.m_intermediateShadowsRts[1] : m_runCtx.m_historyRt);
  402. RtShadowsDenoiseConstants consts;
  403. consts.m_invViewProjMat = ctx.m_matrices.m_invertedViewProjectionJitter;
  404. consts.m_time = F32(GlobalFrameIndex::getSingleton().m_value % 0xFFFFu);
  405. consts.m_minSampleCount = 8;
  406. consts.m_maxSampleCount = 32;
  407. cmdb.setFastConstants(&consts, sizeof(consts));
  408. dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x / 2, getRenderer().getInternalResolution().y / 2);
  409. }
  410. } // end namespace anki