FinalComposite.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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/FinalComposite.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/Bloom.h>
  8. #include <AnKi/Renderer/Tonemapping.h>
  9. #include <AnKi/Renderer/LightShading.h>
  10. #include <AnKi/Renderer/GBuffer.h>
  11. #include <AnKi/Renderer/Dbg.h>
  12. #include <AnKi/Renderer/UiStage.h>
  13. #include <AnKi/Renderer/MotionBlur.h>
  14. #include <AnKi/Util/Logger.h>
  15. #include <AnKi/Util/Tracer.h>
  16. #include <AnKi/Util/CVarSet.h>
  17. #if ANKI_COMPILER_GCC_COMPATIBLE
  18. # pragma GCC diagnostic push
  19. # pragma GCC diagnostic ignored "-Wunused-function"
  20. # pragma GCC diagnostic ignored "-Wignored-qualifiers"
  21. #elif ANKI_COMPILER_MSVC
  22. # pragma warning(push)
  23. # pragma warning(disable : 4505)
  24. #endif
  25. #define A_CPU
  26. #include <ThirdParty/FidelityFX/ffx_a.h>
  27. #include <ThirdParty/FidelityFX/ffx_fsr1.h>
  28. #if ANKI_COMPILER_GCC_COMPATIBLE
  29. # pragma GCC diagnostic pop
  30. #elif ANKI_COMPILER_MSVC
  31. # pragma warning(pop)
  32. #endif
  33. namespace anki {
  34. Error FinalComposite::initInternal()
  35. {
  36. // Progs
  37. for(MutatorValue dbg = 0; dbg < 2; ++dbg)
  38. {
  39. ANKI_CHECK(loadShaderProgram(
  40. "ShaderBinaries/FinalComposite.ankiprogbin",
  41. {{"FILM_GRAIN", (g_filmGrainCVar > 0.0) ? 1 : 0}, {"BLOOM", 1}, {"DBG", dbg}, {"SHARPEN", MutatorValue(g_sharpnessCVar > 0.0)}}, m_prog,
  42. m_grProgs[dbg]));
  43. }
  44. ANKI_CHECK(loadShaderProgram("ShaderBinaries/VisualizeRenderTarget.ankiprogbin", m_defaultVisualizeRenderTargetProg,
  45. m_defaultVisualizeRenderTargetGrProg));
  46. if(getRenderer().getSwapchainResolution() != getRenderer().getPostProcessResolution())
  47. {
  48. m_rtDesc = getRenderer().create2DRenderTargetDescription(
  49. getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y(),
  50. (GrManager::getSingleton().getDeviceCapabilities().m_unalignedBbpTextureFormats) ? Format::kR8G8B8_Unorm : Format::kR8G8B8A8_Unorm,
  51. "Final Composite");
  52. m_rtDesc.bake();
  53. }
  54. return Error::kNone;
  55. }
  56. Error FinalComposite::init()
  57. {
  58. const Error err = initInternal();
  59. if(err)
  60. {
  61. ANKI_R_LOGE("Failed to init final composite");
  62. }
  63. return err;
  64. }
  65. void FinalComposite::populateRenderGraph(RenderingContext& ctx)
  66. {
  67. ANKI_TRACE_SCOPED_EVENT(RFinalComposite);
  68. RenderGraphBuilder& rgraph = ctx.m_renderGraphDescr;
  69. // Create the pass
  70. GraphicsRenderPass& pass = rgraph.newGraphicsRenderPass("Final Composite");
  71. const Bool bRendersToSwapchain = getRenderer().getSwapchainResolution() == getRenderer().getPostProcessResolution();
  72. const RenderTargetHandle outRt = (!bRendersToSwapchain) ? rgraph.newRenderTarget(m_rtDesc) : ctx.m_swapchainRenderTarget;
  73. if(!bRendersToSwapchain)
  74. {
  75. m_runCtx.m_rt = outRt;
  76. }
  77. pass.setRenderpassInfo({GraphicsRenderPassTargetDesc(outRt)});
  78. pass.newTextureDependency(outRt, TextureUsageBit::kRtvDsvWrite);
  79. if(g_dbgSceneCVar || g_dbgPhysicsCVar)
  80. {
  81. pass.newTextureDependency(getRenderer().getDbg().getRt(), TextureUsageBit::kSrvPixel);
  82. }
  83. pass.newTextureDependency((g_motionBlurSampleCountCVar != 0) ? getRenderer().getMotionBlur().getRt() : getRenderer().getTonemapping().getRt(),
  84. TextureUsageBit::kSrvPixel);
  85. pass.newTextureDependency(getRenderer().getBloom().getBloomRt(), TextureUsageBit::kSrvPixel);
  86. Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
  87. ShaderProgramPtr debugProgram;
  88. const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, debugProgram);
  89. if(hasDebugRt)
  90. {
  91. for(const RenderTargetHandle& handle : dbgRts)
  92. {
  93. if(handle.isValid())
  94. {
  95. pass.newTextureDependency(handle, TextureUsageBit::kSrvPixel);
  96. }
  97. }
  98. }
  99. pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  100. ANKI_TRACE_SCOPED_EVENT(FinalComposite);
  101. CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
  102. const Bool dbgEnabled = g_dbgSceneCVar || g_dbgPhysicsCVar;
  103. Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
  104. ShaderProgramPtr optionalDebugProgram;
  105. const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, optionalDebugProgram);
  106. // Bind program
  107. if(hasDebugRt && optionalDebugProgram.isCreated())
  108. {
  109. cmdb.bindShaderProgram(optionalDebugProgram.get());
  110. }
  111. else if(hasDebugRt)
  112. {
  113. cmdb.bindShaderProgram(m_defaultVisualizeRenderTargetGrProg.get());
  114. }
  115. else
  116. {
  117. cmdb.bindShaderProgram(m_grProgs[dbgEnabled].get());
  118. }
  119. // Bind stuff
  120. if(!hasDebugRt)
  121. {
  122. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
  123. rgraphCtx.bindSrv(0, 0,
  124. (g_motionBlurSampleCountCVar != 0) ? getRenderer().getMotionBlur().getRt() : getRenderer().getTonemapping().getRt());
  125. rgraphCtx.bindSrv(1, 0, getRenderer().getBloom().getBloomRt());
  126. if(dbgEnabled)
  127. {
  128. rgraphCtx.bindSrv(2, 0, getRenderer().getDbg().getRt());
  129. }
  130. struct Constants
  131. {
  132. UVec4 m_fsrConsts0;
  133. F32 m_filmGrainStrength;
  134. U32 m_frameCount;
  135. U32 m_padding1;
  136. U32 m_padding2;
  137. } consts;
  138. F32 sharpness = g_sharpnessCVar; // [0, 1]
  139. sharpness *= 3.0f; // [0, 3]
  140. sharpness = 3.0f - sharpness; // [3, 0], RCAS translates 0 to max sharpness
  141. FsrRcasCon(&consts.m_fsrConsts0[0], sharpness);
  142. consts.m_filmGrainStrength = g_filmGrainCVar;
  143. consts.m_frameCount = getRenderer().getFrameCount() & kMaxU32;
  144. cmdb.setFastConstants(&consts, sizeof(consts));
  145. }
  146. else
  147. {
  148. cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
  149. U32 count = 0;
  150. for(const RenderTargetHandle& handle : dbgRts)
  151. {
  152. if(handle.isValid())
  153. {
  154. rgraphCtx.bindSrv(count++, 0, handle);
  155. }
  156. }
  157. }
  158. cmdb.setViewport(0, 0, getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y());
  159. drawQuad(cmdb);
  160. // Draw UI
  161. const Bool bRendersToSwapchain = getRenderer().getSwapchainResolution() == getRenderer().getPostProcessResolution();
  162. if(bRendersToSwapchain)
  163. {
  164. getRenderer().getUiStage().draw(getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y(), cmdb);
  165. }
  166. });
  167. }
  168. } // end namespace anki