2
0

Scale.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright (C) 2009-2021, 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/Scale.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/TemporalAA.h>
  8. #include <AnKi/Core/ConfigSet.h>
  9. #if ANKI_COMPILER_GCC_COMPATIBLE
  10. # pragma GCC diagnostic push
  11. # pragma GCC diagnostic ignored "-Wunused-function"
  12. # pragma GCC diagnostic ignored "-Wignored-qualifiers"
  13. #endif
  14. #define A_CPU
  15. #include <ThirdParty/FidelityFX/ffx_a.h>
  16. #include <ThirdParty/FidelityFX/ffx_fsr1.h>
  17. #if ANKI_COMPILER_GCC_COMPATIBLE
  18. # pragma GCC diagnostic pop
  19. #endif
  20. namespace anki {
  21. Scale::~Scale()
  22. {
  23. }
  24. Error Scale::init(const ConfigSet& cfg)
  25. {
  26. const Bool needsScaling = m_r->getPostProcessResolution() != m_r->getInternalResolution();
  27. const Bool needsSharpening = cfg.getBool("r_sharpen");
  28. if(!needsScaling && !needsSharpening)
  29. {
  30. return Error::NONE;
  31. }
  32. ANKI_R_LOGI("Initializing (up|down)scale pass");
  33. const U32 fsrQuality = cfg.getNumberU8("r_fsr");
  34. m_fsr = fsrQuality != 0;
  35. // Program
  36. if(needsScaling)
  37. {
  38. ANKI_CHECK(getResourceManager().loadResource((m_fsr) ? "Shaders/Fsr.ankiprog" : "Shaders/BlitCompute.ankiprog",
  39. m_scaleProg));
  40. const ShaderProgramResourceVariant* variant;
  41. if(m_fsr)
  42. {
  43. ShaderProgramResourceVariantInitInfo variantInitInfo(m_scaleProg);
  44. variantInitInfo.addMutation("SHARPEN", 0);
  45. variantInitInfo.addMutation("FSR_QUALITY", fsrQuality - 1);
  46. m_scaleProg->getOrCreateVariant(variantInitInfo, variant);
  47. }
  48. else
  49. {
  50. m_scaleProg->getOrCreateVariant(variant);
  51. }
  52. m_scaleGrProg = variant->getProgram();
  53. }
  54. if(needsSharpening)
  55. {
  56. ANKI_CHECK(getResourceManager().loadResource("Shaders/Fsr.ankiprog", m_sharpenProg));
  57. ShaderProgramResourceVariantInitInfo variantInitInfo(m_sharpenProg);
  58. variantInitInfo.addMutation("SHARPEN", 1);
  59. variantInitInfo.addMutation("FSR_QUALITY", 0);
  60. const ShaderProgramResourceVariant* variant;
  61. m_sharpenProg->getOrCreateVariant(variantInitInfo, variant);
  62. m_sharpenGrProg = variant->getProgram();
  63. }
  64. // The RT desc
  65. m_rtDesc =
  66. m_r->create2DRenderTargetDescription(m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(),
  67. LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "Scaled");
  68. m_rtDesc.bake();
  69. return Error::NONE;
  70. }
  71. void Scale::populateRenderGraph(RenderingContext& ctx)
  72. {
  73. if(!doScaling() && !doSharpening())
  74. {
  75. m_runCtx.m_scaledRt = m_r->getTemporalAA().getTonemappedRt();
  76. m_runCtx.m_sharpenedRt = m_r->getTemporalAA().getTonemappedRt();
  77. return;
  78. }
  79. if(doScaling())
  80. {
  81. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  82. m_runCtx.m_scaledRt = rgraph.newRenderTarget(m_rtDesc);
  83. ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Scale");
  84. pass.newDependency(
  85. RenderPassDependency(m_r->getTemporalAA().getTonemappedRt(), TextureUsageBit::SAMPLED_COMPUTE));
  86. pass.newDependency(RenderPassDependency(m_runCtx.m_scaledRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
  87. pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  88. runScaling(rgraphCtx);
  89. });
  90. }
  91. if(doSharpening())
  92. {
  93. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  94. m_runCtx.m_sharpenedRt = rgraph.newRenderTarget(m_rtDesc);
  95. ComputeRenderPassDescription& pass = ctx.m_renderGraphDescr.newComputeRenderPass("Sharpen");
  96. pass.newDependency(
  97. RenderPassDependency((!doScaling()) ? m_r->getTemporalAA().getTonemappedRt() : m_runCtx.m_scaledRt,
  98. TextureUsageBit::SAMPLED_COMPUTE));
  99. pass.newDependency(RenderPassDependency(m_runCtx.m_sharpenedRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
  100. pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  101. runSharpening(rgraphCtx);
  102. });
  103. }
  104. }
  105. void Scale::runScaling(RenderPassWorkContext& rgraphCtx)
  106. {
  107. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  108. cmdb->bindShaderProgram(m_scaleGrProg);
  109. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  110. rgraphCtx.bindColorTexture(0, 1, m_r->getTemporalAA().getTonemappedRt());
  111. rgraphCtx.bindImage(0, 2, m_runCtx.m_scaledRt);
  112. if(m_fsr)
  113. {
  114. class
  115. {
  116. public:
  117. UVec4 m_fsrConsts0;
  118. UVec4 m_fsrConsts1;
  119. UVec4 m_fsrConsts2;
  120. UVec4 m_fsrConsts3;
  121. UVec2 m_viewportSize;
  122. UVec2 m_padding;
  123. } pc;
  124. const Vec2 inRez(m_r->getInternalResolution());
  125. const Vec2 outRez(m_r->getPostProcessResolution());
  126. FsrEasuCon(&pc.m_fsrConsts0[0], &pc.m_fsrConsts1[0], &pc.m_fsrConsts2[0], &pc.m_fsrConsts3[0], inRez.x(),
  127. inRez.y(), inRez.x(), inRez.y(), outRez.x(), outRez.y());
  128. pc.m_viewportSize = m_r->getPostProcessResolution();
  129. cmdb->setPushConstants(&pc, sizeof(pc));
  130. }
  131. else
  132. {
  133. class
  134. {
  135. public:
  136. Vec2 m_viewportSize;
  137. UVec2 m_viewportSizeU;
  138. } pc;
  139. pc.m_viewportSize = Vec2(m_r->getPostProcessResolution());
  140. pc.m_viewportSizeU = m_r->getPostProcessResolution();
  141. cmdb->setPushConstants(&pc, sizeof(pc));
  142. }
  143. dispatchPPCompute(cmdb, 8, 8, m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y());
  144. }
  145. void Scale::runSharpening(RenderPassWorkContext& rgraphCtx)
  146. {
  147. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  148. cmdb->bindShaderProgram(m_sharpenGrProg);
  149. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  150. rgraphCtx.bindColorTexture(0, 1, (!doScaling()) ? m_r->getTemporalAA().getTonemappedRt() : m_runCtx.m_scaledRt);
  151. rgraphCtx.bindImage(0, 2, m_runCtx.m_sharpenedRt);
  152. class
  153. {
  154. public:
  155. UVec4 m_fsrConsts0;
  156. UVec4 m_fsrConsts1;
  157. UVec4 m_fsrConsts2;
  158. UVec4 m_fsrConsts3;
  159. UVec2 m_viewportSize;
  160. UVec2 m_padding;
  161. } pc;
  162. FsrRcasCon(&pc.m_fsrConsts0[0], 0.2f);
  163. pc.m_viewportSize = m_r->getPostProcessResolution();
  164. cmdb->setPushConstants(&pc, sizeof(pc));
  165. dispatchPPCompute(cmdb, 8, 8, m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y());
  166. }
  167. } // end namespace anki