VrsSriGeneration.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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/VrsSriGeneration.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/LightShading.h>
  8. #include <AnKi/Util/CVarSet.h>
  9. #include <AnKi/Util/Tracer.h>
  10. namespace anki {
  11. Error VrsSriGeneration::init()
  12. {
  13. if(!GrManager::getSingleton().getDeviceCapabilities().m_vrs)
  14. {
  15. return Error::kNone;
  16. }
  17. m_sriTexelDimension = U8(GrManager::getSingleton().getDeviceCapabilities().m_minShadingRateImageTexelSize);
  18. ANKI_ASSERT(m_sriTexelDimension == 8 || m_sriTexelDimension == 16);
  19. const UVec2 rez = (getRenderer().getInternalResolution() + m_sriTexelDimension - 1) / m_sriTexelDimension;
  20. // Create textures
  21. const TextureUsageBit texUsage = TextureUsageBit::kShadingRate | TextureUsageBit::kUavCompute | TextureUsageBit::kAllSrv;
  22. TextureInitInfo sriInitInfo = getRenderer().create2DRenderTargetInitInfo(rez.x, rez.y, Format::kR8_Uint, texUsage, "VrsSri");
  23. m_sriTex = getRenderer().createAndClearRenderTarget(sriInitInfo, TextureUsageBit::kShadingRate);
  24. const UVec2 rezDownscaled = (getRenderer().getInternalResolution() / 2 + m_sriTexelDimension - 1) / m_sriTexelDimension;
  25. sriInitInfo = getRenderer().create2DRenderTargetInitInfo(rezDownscaled.x, rezDownscaled.y, Format::kR8_Uint, texUsage, "VrsSriDownscaled");
  26. m_downscaledSriTex = getRenderer().createAndClearRenderTarget(sriInitInfo, TextureUsageBit::kShadingRate);
  27. // Load programs
  28. ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/VrsSriGenerationCompute.ankiprogbin", m_prog));
  29. ShaderProgramResourceVariantInitInfo variantInit(m_prog);
  30. variantInit.addMutation("SRI_TEXEL_DIMENSION", m_sriTexelDimension);
  31. if(m_sriTexelDimension == 16 && GrManager::getSingleton().getDeviceCapabilities().m_minWaveSize >= 32)
  32. {
  33. // Algorithm's workgroup size is 32, GPU's subgroup size is min 32 -> each workgroup has 1 subgroup -> No need for shared mem
  34. variantInit.addMutation("SHARED_MEMORY", 0);
  35. }
  36. else if(m_sriTexelDimension == 8 && GrManager::getSingleton().getDeviceCapabilities().m_minWaveSize >= 16)
  37. {
  38. // Algorithm's workgroup size is 16, GPU's subgroup size is min 16 -> each workgroup has 1 subgroup -> No need for shared mem
  39. variantInit.addMutation("SHARED_MEMORY", 0);
  40. }
  41. else
  42. {
  43. variantInit.addMutation("SHARED_MEMORY", 1);
  44. }
  45. variantInit.addMutation("LIMIT_RATE_TO_2X2", g_cvarRenderVrsLimitTo2x2);
  46. const ShaderProgramResourceVariant* variant;
  47. m_prog->getOrCreateVariant(variantInit, variant);
  48. m_grProg.reset(&variant->getProgram());
  49. ANKI_CHECK(loadShaderProgram("ShaderBinaries/VrsSriVisualizeRenderTarget.ankiprogbin", m_visualizeProg, m_visualizeGrProg));
  50. ANKI_CHECK(loadShaderProgram("ShaderBinaries/VrsSriDownscale.ankiprogbin", m_downscaleProg, m_downscaleGrProg));
  51. return Error::kNone;
  52. }
  53. void VrsSriGeneration::importRenderTargets(RenderingContext& ctx)
  54. {
  55. const Bool enableVrs = GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_cvarGrVrs;
  56. if(!enableVrs)
  57. {
  58. return;
  59. }
  60. if(m_sriTexImportedOnce)
  61. {
  62. m_runCtx.m_rt = ctx.m_renderGraphDescr.importRenderTarget(m_sriTex.get());
  63. m_runCtx.m_downscaledRt = ctx.m_renderGraphDescr.importRenderTarget(m_downscaledSriTex.get());
  64. }
  65. else
  66. {
  67. m_runCtx.m_rt = ctx.m_renderGraphDescr.importRenderTarget(m_sriTex.get(), TextureUsageBit::kShadingRate);
  68. m_runCtx.m_downscaledRt = ctx.m_renderGraphDescr.importRenderTarget(m_downscaledSriTex.get(), TextureUsageBit::kShadingRate);
  69. m_sriTexImportedOnce = true;
  70. }
  71. }
  72. void VrsSriGeneration::populateRenderGraph(RenderingContext& ctx)
  73. {
  74. const Bool enableVrs = GrManager::getSingleton().getDeviceCapabilities().m_vrs && g_cvarGrVrs;
  75. if(!enableVrs)
  76. {
  77. return;
  78. }
  79. ANKI_TRACE_SCOPED_EVENT(VrsSriGeneration);
  80. RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
  81. // SRI generation
  82. {
  83. NonGraphicsRenderPass& pass = rgraph.newNonGraphicsRenderPass("VRS SRI generation");
  84. pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kUavCompute);
  85. pass.newTextureDependency(getRenderer().getLightShading().getRt(), TextureUsageBit::kSrvCompute);
  86. pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  87. ANKI_TRACE_SCOPED_EVENT(VrsSriGeneration);
  88. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  89. cmdb.bindShaderProgram(m_grProg.get());
  90. rgraphCtx.bindSrv(0, 0, getRenderer().getLightShading().getRt());
  91. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  92. rgraphCtx.bindUav(0, 0, m_runCtx.m_rt);
  93. const Vec4 pc(1.0f / Vec2(getRenderer().getInternalResolution()), g_cvarRenderVrsThreshold, 0.0f);
  94. cmdb.setFastConstants(&pc, sizeof(pc));
  95. const U32 fakeWorkgroupSizeXorY = m_sriTexelDimension;
  96. dispatchPPCompute(cmdb, fakeWorkgroupSizeXorY, fakeWorkgroupSizeXorY, getRenderer().getInternalResolution().x,
  97. getRenderer().getInternalResolution().y);
  98. });
  99. }
  100. // Downscale
  101. {
  102. NonGraphicsRenderPass& pass = rgraph.newNonGraphicsRenderPass("VRS SRI downscale");
  103. pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kSrvCompute);
  104. pass.newTextureDependency(m_runCtx.m_downscaledRt, TextureUsageBit::kUavCompute);
  105. pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  106. ANKI_TRACE_SCOPED_EVENT(VrsSriGeneration);
  107. const UVec2 rezDownscaled = (getRenderer().getInternalResolution() / 2 + m_sriTexelDimension - 1) / m_sriTexelDimension;
  108. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  109. cmdb.bindShaderProgram(m_downscaleGrProg.get());
  110. rgraphCtx.bindSrv(0, 0, m_runCtx.m_rt);
  111. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  112. rgraphCtx.bindUav(0, 0, m_runCtx.m_downscaledRt);
  113. const Vec4 pc(1.0f / Vec2(rezDownscaled), 0.0f, 0.0f);
  114. cmdb.setFastConstants(&pc, sizeof(pc));
  115. dispatchPPCompute(cmdb, 8, 8, rezDownscaled.x, rezDownscaled.y);
  116. });
  117. }
  118. }
  119. } // end namespace anki