Tonemapping.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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/Tonemapping.h>
  6. #include <AnKi/Renderer/DownscaleBlur.h>
  7. #include <AnKi/Renderer/Renderer.h>
  8. namespace anki
  9. {
  10. Error Tonemapping::init(const ConfigSet& cfg)
  11. {
  12. const Error err = initInternal(cfg);
  13. if(err)
  14. {
  15. ANKI_R_LOGE("Failed to initialize tonemapping");
  16. }
  17. return err;
  18. }
  19. Error Tonemapping::initInternal(const ConfigSet& initializer)
  20. {
  21. m_inputTexMip = m_r->getDownscaleBlur().getMipmapCount() - 2;
  22. const U32 width = m_r->getDownscaleBlur().getPassWidth(m_inputTexMip);
  23. const U32 height = m_r->getDownscaleBlur().getPassHeight(m_inputTexMip);
  24. ANKI_R_LOGI("Initializing tonemapping (input %ux%u)", width, height);
  25. // Create program
  26. ANKI_CHECK(getResourceManager().loadResource("Shaders/TonemappingAverageLuminance.ankiprog", m_prog));
  27. ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
  28. variantInitInfo.addConstant("INPUT_TEX_SIZE", UVec2(width, height));
  29. const ShaderProgramResourceVariant* variant;
  30. m_prog->getOrCreateVariant(variantInitInfo, variant);
  31. m_grProg = variant->getProgram();
  32. // Create buffer
  33. m_luminanceBuff = getGrManager().newBuffer(BufferInitInfo(
  34. sizeof(Vec4), BufferUsageBit::ALL_STORAGE | BufferUsageBit::ALL_UNIFORM | BufferUsageBit::TRANSFER_DESTINATION,
  35. BufferMapAccessBit::NONE, "AvgLum"));
  36. CommandBufferInitInfo cmdbinit;
  37. cmdbinit.m_flags = CommandBufferFlag::SMALL_BATCH | CommandBufferFlag::GENERAL_WORK;
  38. CommandBufferPtr cmdb = getGrManager().newCommandBuffer(cmdbinit);
  39. TransferGpuAllocatorHandle handle;
  40. ANKI_CHECK(m_r->getResourceManager().getTransferGpuAllocator().allocate(sizeof(Vec4), handle));
  41. void* data = handle.getMappedMemory();
  42. *static_cast<Vec4*>(data) = Vec4(0.5);
  43. cmdb->copyBufferToBuffer(handle.getBuffer(), handle.getOffset(), m_luminanceBuff, 0, handle.getRange());
  44. FencePtr fence;
  45. cmdb->flush({}, &fence);
  46. m_r->getResourceManager().getTransferGpuAllocator().release(handle, fence);
  47. return Error::NONE;
  48. }
  49. void Tonemapping::importRenderTargets(RenderingContext& ctx)
  50. {
  51. // Computation of the AVG luminance will run first in the frame and it will use the m_luminanceBuff as storage
  52. // read/write. To skip the barrier import it as read/write as well.
  53. m_runCtx.m_buffHandle = ctx.m_renderGraphDescr.importBuffer(
  54. m_luminanceBuff, BufferUsageBit::STORAGE_COMPUTE_READ | BufferUsageBit::STORAGE_COMPUTE_WRITE);
  55. }
  56. void Tonemapping::populateRenderGraph(RenderingContext& ctx)
  57. {
  58. RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
  59. // Create the pass
  60. ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Avg lum");
  61. pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
  62. CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
  63. cmdb->bindShaderProgram(m_grProg);
  64. rgraphCtx.bindStorageBuffer(0, 1, m_runCtx.m_buffHandle);
  65. TextureSubresourceInfo inputTexSubresource;
  66. inputTexSubresource.m_firstMipmap = m_inputTexMip;
  67. rgraphCtx.bindTexture(0, 0, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
  68. cmdb->dispatchCompute(1, 1, 1);
  69. });
  70. pass.newDependency(
  71. {m_runCtx.m_buffHandle, BufferUsageBit::STORAGE_COMPUTE_READ | BufferUsageBit::STORAGE_COMPUTE_WRITE});
  72. TextureSubresourceInfo inputTexSubresource;
  73. inputTexSubresource.m_firstMipmap = m_inputTexMip;
  74. pass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE, inputTexSubresource});
  75. }
  76. } // end namespace anki