Scale.cpp 5.7 KB

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