| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #include <AnKi/Renderer/DownscaleBlur.h>
- #include <AnKi/Renderer/Renderer.h>
- #include <AnKi/Renderer/TemporalAA.h>
- namespace anki {
- DownscaleBlur::~DownscaleBlur()
- {
- m_fbDescrs.destroy(getAllocator());
- }
- Error DownscaleBlur::init()
- {
- const Error err = initInternal();
- if(err)
- {
- ANKI_R_LOGE("Failed to initialize downscale blur");
- }
- return err;
- }
- Error DownscaleBlur::initInternal()
- {
- m_passCount = computeMaxMipmapCount2d(m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(),
- DOWNSCALE_BLUR_DOWN_TO)
- - 1;
- ANKI_R_LOGI("Initializing dowscale blur (passCount: %u)", m_passCount);
- // Create the miped texture
- TextureInitInfo texinit = m_r->create2DRenderTargetDescription(
- m_r->getPostProcessResolution().x() / 2, m_r->getPostProcessResolution().y() / 2,
- LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "DownscaleBlur");
- texinit.m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_COMPUTE;
- if(m_useCompute)
- {
- texinit.m_usage |= TextureUsageBit::SAMPLED_COMPUTE | TextureUsageBit::IMAGE_COMPUTE_WRITE;
- }
- else
- {
- texinit.m_usage |= TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
- }
- texinit.m_mipmapCount = U8(m_passCount);
- texinit.m_initialUsage = TextureUsageBit::SAMPLED_COMPUTE;
- m_rtTex = m_r->createAndClearRenderTarget(texinit);
- // FB descr
- if(!m_useCompute)
- {
- m_fbDescrs.create(getAllocator(), m_passCount);
- for(U32 pass = 0; pass < m_passCount; ++pass)
- {
- m_fbDescrs[pass].m_colorAttachmentCount = 1;
- m_fbDescrs[pass].m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
- m_fbDescrs[pass].m_colorAttachments[0].m_surface.m_level = pass;
- m_fbDescrs[pass].bake();
- }
- }
- // Shader programs
- const ShaderProgramResourceVariant* variant = nullptr;
- if(m_useCompute)
- {
- ANKI_CHECK(getResourceManager().loadResource("Shaders/DownscaleBlurCompute.ankiprog", m_prog));
- m_prog->getOrCreateVariant(variant);
- m_workgroupSize[0] = variant->getWorkgroupSizes()[0];
- m_workgroupSize[1] = variant->getWorkgroupSizes()[1];
- ANKI_ASSERT(variant->getWorkgroupSizes()[2] == 1);
- }
- else
- {
- ANKI_CHECK(getResourceManager().loadResource("Shaders/DownscaleBlur.ankiprog", m_prog));
- m_prog->getOrCreateVariant(variant);
- }
- m_grProg = variant->getProgram();
- return Error::NONE;
- }
- void DownscaleBlur::importRenderTargets(RenderingContext& ctx)
- {
- RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
- m_runCtx.m_rt = rgraph.importRenderTarget(m_rtTex, TextureUsageBit::SAMPLED_COMPUTE);
- }
- void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
- {
- RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
- // Create passes
- static const Array<CString, 8> passNames = {"DownBlur #0", "Down/Blur #1", "Down/Blur #2", "Down/Blur #3",
- "Down/Blur #4", "Down/Blur #5", "Down/Blur #6", "Down/Blur #7"};
- if(m_useCompute)
- {
- for(U32 i = 0; i < m_passCount; ++i)
- {
- ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass(passNames[i]);
- pass.setWork([this, i](RenderPassWorkContext& rgraphCtx) {
- run(i, rgraphCtx);
- });
- if(i > 0)
- {
- TextureSubresourceInfo sampleSubresource;
- TextureSubresourceInfo renderSubresource;
- sampleSubresource.m_firstMipmap = i - 1;
- renderSubresource.m_firstMipmap = i;
- pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
- pass.newDependency({m_runCtx.m_rt, TextureUsageBit::SAMPLED_COMPUTE, sampleSubresource});
- }
- else
- {
- TextureSubresourceInfo renderSubresource;
- pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
- pass.newDependency({m_r->getTemporalAA().getHdrRt(), TextureUsageBit::SAMPLED_COMPUTE});
- }
- }
- }
- else
- {
- for(U32 i = 0; i < m_passCount; ++i)
- {
- GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[i]);
- pass.setWork([this, i](RenderPassWorkContext& rgraphCtx) {
- run(i, rgraphCtx);
- });
- pass.setFramebufferInfo(m_fbDescrs[i], {m_runCtx.m_rt}, {});
- if(i > 0)
- {
- TextureSubresourceInfo sampleSubresource;
- TextureSubresourceInfo renderSubresource;
- sampleSubresource.m_firstMipmap = i - 1;
- renderSubresource.m_firstMipmap = i;
- pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
- pass.newDependency({m_runCtx.m_rt, TextureUsageBit::SAMPLED_FRAGMENT, sampleSubresource});
- }
- else
- {
- TextureSubresourceInfo renderSubresource;
- pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
- pass.newDependency({m_r->getTemporalAA().getHdrRt(), TextureUsageBit::SAMPLED_FRAGMENT});
- }
- }
- }
- }
- void DownscaleBlur::run(U32 passIdx, RenderPassWorkContext& rgraphCtx)
- {
- CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
- cmdb->bindShaderProgram(m_grProg);
- const U32 vpWidth = m_rtTex->getWidth() >> passIdx;
- const U32 vpHeight = m_rtTex->getHeight() >> passIdx;
- cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
- if(passIdx > 0)
- {
- TextureSubresourceInfo sampleSubresource;
- sampleSubresource.m_firstMipmap = passIdx - 1;
- rgraphCtx.bindTexture(0, 1, m_runCtx.m_rt, sampleSubresource);
- }
- else
- {
- rgraphCtx.bindColorTexture(0, 1, m_r->getTemporalAA().getHdrRt());
- }
- if(m_useCompute)
- {
- TextureSubresourceInfo sampleSubresource;
- sampleSubresource.m_firstMipmap = passIdx;
- rgraphCtx.bindImage(0, 2, m_runCtx.m_rt, sampleSubresource);
- UVec4 fbSize(vpWidth, vpHeight, 0, 0);
- cmdb->setPushConstants(&fbSize, sizeof(fbSize));
- }
- if(m_useCompute)
- {
- dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], vpWidth, vpHeight);
- }
- else
- {
- cmdb->setViewport(0, 0, vpWidth, vpHeight);
- drawQuad(cmdb);
- }
- }
- } // end namespace anki
|