TemporalAA.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright (C) 2009-2022, 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/TemporalAA.h>
  6. #include <AnKi/Renderer/Renderer.h>
  7. #include <AnKi/Renderer/GBuffer.h>
  8. #include <AnKi/Renderer/LightShading.h>
  9. #include <AnKi/Renderer/Tonemapping.h>
  10. #include <AnKi/Renderer/MotionVectors.h>
  11. #include <AnKi/Core/ConfigSet.h>
  12. namespace anki {
  13. TemporalAA::TemporalAA(Renderer* r)
  14. : RendererObject(r)
  15. {
  16. }
  17. TemporalAA::~TemporalAA()
  18. {
  19. }
  20. Error TemporalAA::init()
  21. {
  22. const Error err = initInternal();
  23. if(err)
  24. {
  25. ANKI_R_LOGE("Failed to init TAA");
  26. }
  27. return Error::NONE;
  28. }
  29. Error TemporalAA::initInternal()
  30. {
  31. ANKI_R_LOGV("Initializing TAA");
  32. ANKI_CHECK(m_r->getResourceManager().loadResource((getConfig().getRPreferCompute())
  33. ? "ShaderBinaries/TemporalAACompute.ankiprogbin"
  34. : "ShaderBinaries/TemporalAARaster.ankiprogbin",
  35. m_prog));
  36. {
  37. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  38. variantInitInfo.addConstant("VARIANCE_CLIPPING_GAMMA", 2.7f);
  39. variantInitInfo.addConstant("BLEND_FACTOR", 1.0f / 16.0f);
  40. variantInitInfo.addMutation("VARIANCE_CLIPPING", 1);
  41. variantInitInfo.addMutation("YCBCR", 0);
  42. if(getConfig().getRPreferCompute())
  43. {
  44. variantInitInfo.addConstant("FB_SIZE",
  45. UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()));
  46. }
  47. const ShaderProgramResourceVariant* variant;
  48. m_prog->getOrCreateVariant(variantInitInfo, variant);
  49. m_grProg = variant->getProgram();
  50. }
  51. for(U i = 0; i < 2; ++i)
  52. {
  53. TextureUsageBit usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_COMPUTE;
  54. usage |= (getConfig().getRPreferCompute()) ? TextureUsageBit::IMAGE_COMPUTE_WRITE
  55. : TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
  56. TextureInitInfo texinit =
  57. m_r->create2DRenderTargetInitInfo(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
  58. m_r->getHdrFormat(), usage, "TemporalAA");
  59. m_rtTextures[i] = m_r->createAndClearRenderTarget(texinit, TextureUsageBit::SAMPLED_FRAGMENT);
  60. }
  61. m_tonemappedRtDescr = m_r->create2DRenderTargetDescription(
  62. m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
  63. (getGrManager().getDeviceCapabilities().m_unalignedBbpTextureFormats) ? Format::R8G8B8_UNORM
  64. : Format::R8G8B8A8_UNORM,
  65. "TemporalAA Tonemapped");
  66. m_tonemappedRtDescr.bake();
  67. m_fbDescr.m_colorAttachmentCount = 2;
  68. m_fbDescr.bake();
  69. return Error::NONE;
  70. }
  71. void TemporalAA::populateRenderGraph(RenderingContext& ctx)
  72. {
  73. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  74. const U32 historyRtIdx = (m_r->getFrameCount() + 1) & 1;
  75. const U32 renderRtIdx = !historyRtIdx;
  76. const Bool preferCompute = getConfig().getRPreferCompute();
  77. // Import RTs
  78. if(ANKI_LIKELY(m_rtTexturesImportedOnce[historyRtIdx]))
  79. {
  80. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_rtTextures[historyRtIdx]);
  81. }
  82. else
  83. {
  84. m_runCtx.m_historyRt = rgraph.importRenderTarget(m_rtTextures[historyRtIdx], TextureUsageBit::SAMPLED_FRAGMENT);
  85. m_rtTexturesImportedOnce[historyRtIdx] = true;
  86. }
  87. m_runCtx.m_renderRt = rgraph.importRenderTarget(m_rtTextures[renderRtIdx], TextureUsageBit::NONE);
  88. m_runCtx.m_tonemappedRt = rgraph.newRenderTarget(m_tonemappedRtDescr);
  89. // Create pass
  90. TextureUsageBit readUsage;
  91. RenderPassDescriptionBase* prpass;
  92. if(preferCompute)
  93. {
  94. ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("TemporalAA");
  95. pass.newDependency(RenderPassDependency(m_runCtx.m_renderRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
  96. pass.newDependency(RenderPassDependency(m_runCtx.m_tonemappedRt, TextureUsageBit::IMAGE_COMPUTE_WRITE));
  97. readUsage = TextureUsageBit::SAMPLED_COMPUTE;
  98. prpass = &pass;
  99. }
  100. else
  101. {
  102. GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("TemporalAA");
  103. pass.setFramebufferInfo(m_fbDescr, {m_runCtx.m_renderRt, m_runCtx.m_tonemappedRt});
  104. pass.newDependency(RenderPassDependency(m_runCtx.m_renderRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
  105. pass.newDependency(
  106. RenderPassDependency(m_runCtx.m_tonemappedRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
  107. readUsage = TextureUsageBit::SAMPLED_FRAGMENT;
  108. prpass = &pass;
  109. }
  110. prpass->newDependency(RenderPassDependency(m_r->getGBuffer().getDepthRt(), readUsage,
  111. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)));
  112. prpass->newDependency(RenderPassDependency(m_r->getLightShading().getRt(), readUsage));
  113. prpass->newDependency(RenderPassDependency(m_runCtx.m_historyRt, readUsage));
  114. prpass->newDependency(RenderPassDependency(m_r->getMotionVectors().getMotionVectorsRt(), readUsage));
  115. prpass->setWork([this](RenderPassWorkContext& rgraphCtx) {
  116. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  117. cmdb->bindShaderProgram(m_grProg);
  118. cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
  119. rgraphCtx.bindTexture(0, 1, m_r->getGBuffer().getDepthRt(),
  120. TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
  121. rgraphCtx.bindColorTexture(0, 2, m_r->getLightShading().getRt());
  122. rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_historyRt);
  123. rgraphCtx.bindColorTexture(0, 4, m_r->getMotionVectors().getMotionVectorsRt());
  124. rgraphCtx.bindUniformBuffer(0, 5, m_r->getTonemapping().getAverageLuminanceBuffer());
  125. if(getConfig().getRPreferCompute())
  126. {
  127. rgraphCtx.bindImage(0, 6, m_runCtx.m_renderRt, TextureSubresourceInfo());
  128. rgraphCtx.bindImage(0, 7, m_runCtx.m_tonemappedRt, TextureSubresourceInfo());
  129. dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
  130. }
  131. else
  132. {
  133. cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
  134. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
  135. }
  136. });
  137. }
  138. } // end namespace anki