| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669 |
- // 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/Renderer.h>
- #include <AnKi/Renderer/RenderQueue.h>
- #include <AnKi/Util/Tracer.h>
- #include <AnKi/Core/ConfigSet.h>
- #include <AnKi/Util/HighRezTimer.h>
- #include <AnKi/Collision/Aabb.h>
- #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
- #include <AnKi/Renderer/ProbeReflections.h>
- #include <AnKi/Renderer/GBuffer.h>
- #include <AnKi/Renderer/GBufferPost.h>
- #include <AnKi/Renderer/LightShading.h>
- #include <AnKi/Renderer/ShadowMapping.h>
- #include <AnKi/Renderer/FinalComposite.h>
- #include <AnKi/Renderer/Ssao.h>
- #include <AnKi/Renderer/Bloom.h>
- #include <AnKi/Renderer/Tonemapping.h>
- #include <AnKi/Renderer/ForwardShading.h>
- #include <AnKi/Renderer/LensFlare.h>
- #include <AnKi/Renderer/Dbg.h>
- #include <AnKi/Renderer/DownscaleBlur.h>
- #include <AnKi/Renderer/VolumetricFog.h>
- #include <AnKi/Renderer/DepthDownscale.h>
- #include <AnKi/Renderer/TemporalAA.h>
- #include <AnKi/Renderer/UiStage.h>
- #include <AnKi/Renderer/Ssr.h>
- #include <AnKi/Renderer/Ssgi.h>
- #include <AnKi/Renderer/VolumetricLightingAccumulation.h>
- #include <AnKi/Renderer/GlobalIllumination.h>
- #include <AnKi/Renderer/GenericCompute.h>
- #include <AnKi/Renderer/ShadowmapsResolve.h>
- #include <AnKi/Renderer/RtShadows.h>
- #include <AnKi/Renderer/AccelerationStructureBuilder.h>
- #include <AnKi/Renderer/MotionVectors.h>
- namespace anki
- {
- Renderer::Renderer()
- : m_sceneDrawer(this)
- {
- }
- Renderer::~Renderer()
- {
- for(DebugRtInfo& info : m_debugRts)
- {
- info.m_rtName.destroy(getAllocator());
- }
- m_debugRts.destroy(getAllocator());
- m_currentDebugRtName.destroy(getAllocator());
- }
- Error Renderer::init(ThreadHive* hive, ResourceManager* resources, GrManager* gl, StagingGpuMemoryManager* stagingMem,
- UiManager* ui, HeapAllocator<U8> alloc, const ConfigSet& config, Timestamp* globTimestamp)
- {
- ANKI_TRACE_SCOPED_EVENT(R_INIT);
- m_globTimestamp = globTimestamp;
- m_threadHive = hive;
- m_resources = resources;
- m_gr = gl;
- m_stagingMem = stagingMem;
- m_ui = ui;
- m_alloc = alloc;
- Error err = initInternal(config);
- if(err)
- {
- ANKI_R_LOGE("Failed to initialize the renderer");
- }
- return err;
- }
- Error Renderer::initInternal(const ConfigSet& config)
- {
- // Set from the config
- m_width = config.getNumberU32("width");
- m_height = config.getNumberU32("height");
- ANKI_R_LOGI("Initializing offscreen renderer. Size %ux%u", m_width, m_height);
- m_frameCount = 0;
- m_clusterCount[0] = config.getNumberU32("r_clusterSizeX");
- m_clusterCount[1] = config.getNumberU32("r_clusterSizeY");
- m_clusterCount[2] = config.getNumberU32("r_clusterSizeZ");
- m_clusterCount[3] = m_clusterCount[0] * m_clusterCount[1] * m_clusterCount[2];
- m_clusterBin.init(m_alloc, m_clusterCount[0], m_clusterCount[1], m_clusterCount[2], config);
- // A few sanity checks
- if(m_width < 10 || m_height < 10)
- {
- ANKI_R_LOGE("Incorrect sizes");
- return Error::USER_DATA;
- }
- {
- TextureInitInfo texinit;
- texinit.m_width = texinit.m_height = 4;
- texinit.m_usage = TextureUsageBit::ALL_SAMPLED;
- texinit.m_format = Format::R8G8B8A8_UNORM;
- texinit.m_initialUsage = TextureUsageBit::ALL_SAMPLED;
- TexturePtr tex = getGrManager().newTexture(texinit);
- TextureViewInitInfo viewinit(tex);
- m_dummyTexView2d = getGrManager().newTextureView(viewinit);
- texinit.m_depth = 4;
- texinit.m_type = TextureType::_3D;
- tex = getGrManager().newTexture(texinit);
- viewinit = TextureViewInitInfo(tex);
- m_dummyTexView3d = getGrManager().newTextureView(viewinit);
- }
- m_dummyBuff = getGrManager().newBuffer(BufferInitInfo(
- 1024, BufferUsageBit::ALL_UNIFORM | BufferUsageBit::ALL_STORAGE, BufferMapAccessBit::NONE, "Dummy"));
- ANKI_CHECK(m_resources->loadResource("Shaders/ClearTextureCompute.ankiprog", m_clearTexComputeProg));
- // Init the stages. Careful with the order!!!!!!!!!!
- m_genericCompute.reset(m_alloc.newInstance<GenericCompute>(this));
- ANKI_CHECK(m_genericCompute->init(config));
- m_volLighting.reset(m_alloc.newInstance<VolumetricLightingAccumulation>(this));
- ANKI_CHECK(m_volLighting->init(config));
- m_gi.reset(m_alloc.newInstance<GlobalIllumination>(this));
- ANKI_CHECK(m_gi->init(config));
- m_probeReflections.reset(m_alloc.newInstance<ProbeReflections>(this));
- ANKI_CHECK(m_probeReflections->init(config));
- m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
- ANKI_CHECK(m_gbuffer->init(config));
- m_gbufferPost.reset(m_alloc.newInstance<GBufferPost>(this));
- ANKI_CHECK(m_gbufferPost->init(config));
- m_shadowMapping.reset(m_alloc.newInstance<ShadowMapping>(this));
- ANKI_CHECK(m_shadowMapping->init(config));
- m_volFog.reset(m_alloc.newInstance<VolumetricFog>(this));
- ANKI_CHECK(m_volFog->init(config));
- m_lightShading.reset(m_alloc.newInstance<LightShading>(this));
- ANKI_CHECK(m_lightShading->init(config));
- m_depth.reset(m_alloc.newInstance<DepthDownscale>(this));
- ANKI_CHECK(m_depth->init(config));
- m_forwardShading.reset(m_alloc.newInstance<ForwardShading>(this));
- ANKI_CHECK(m_forwardShading->init(config));
- m_lensFlare.reset(m_alloc.newInstance<LensFlare>(this));
- ANKI_CHECK(m_lensFlare->init(config));
- m_ssao.reset(m_alloc.newInstance<Ssao>(this));
- ANKI_CHECK(m_ssao->init(config));
- m_downscale.reset(getAllocator().newInstance<DownscaleBlur>(this));
- ANKI_CHECK(m_downscale->init(config));
- m_ssr.reset(m_alloc.newInstance<Ssr>(this));
- ANKI_CHECK(m_ssr->init(config));
- m_ssgi.reset(m_alloc.newInstance<Ssgi>(this));
- ANKI_CHECK(m_ssgi->init(config));
- m_tonemapping.reset(getAllocator().newInstance<Tonemapping>(this));
- ANKI_CHECK(m_tonemapping->init(config));
- m_temporalAA.reset(getAllocator().newInstance<TemporalAA>(this));
- ANKI_CHECK(m_temporalAA->init(config));
- m_bloom.reset(m_alloc.newInstance<Bloom>(this));
- ANKI_CHECK(m_bloom->init(config));
- m_finalComposite.reset(m_alloc.newInstance<FinalComposite>(this));
- ANKI_CHECK(m_finalComposite->init(config));
- m_dbg.reset(m_alloc.newInstance<Dbg>(this));
- ANKI_CHECK(m_dbg->init(config));
- m_uiStage.reset(m_alloc.newInstance<UiStage>(this));
- ANKI_CHECK(m_uiStage->init(config));
- if(getGrManager().getDeviceCapabilities().m_rayTracingEnabled && config.getBool("scene_rayTracedShadows"))
- {
- m_accelerationStructureBuilder.reset(m_alloc.newInstance<AccelerationStructureBuilder>(this));
- ANKI_CHECK(m_accelerationStructureBuilder->init(config));
- m_rtShadows.reset(m_alloc.newInstance<RtShadows>(this));
- ANKI_CHECK(m_rtShadows->init(config));
- }
- else
- {
- m_smResolve.reset(m_alloc.newInstance<ShadowmapsResolve>(this));
- ANKI_CHECK(m_smResolve->init(config));
- }
- m_motionVectors.reset(m_alloc.newInstance<MotionVectors>(this));
- ANKI_CHECK(m_motionVectors->init(config));
- // Init samplers
- {
- SamplerInitInfo sinit("Renderer");
- sinit.m_addressing = SamplingAddressing::CLAMP;
- sinit.m_mipmapFilter = SamplingFilter::NEAREST;
- sinit.m_minMagFilter = SamplingFilter::NEAREST;
- m_samplers.m_nearestNearestClamp = m_gr->newSampler(sinit);
- sinit.m_minMagFilter = SamplingFilter::LINEAR;
- sinit.m_mipmapFilter = SamplingFilter::LINEAR;
- m_samplers.m_trilinearClamp = m_gr->newSampler(sinit);
- sinit.m_addressing = SamplingAddressing::REPEAT;
- m_samplers.m_trilinearRepeat = m_gr->newSampler(sinit);
- sinit.m_anisotropyLevel = U8(config.getNumberU32("r_textureAnisotropy"));
- m_samplers.m_trilinearRepeatAniso = m_gr->newSampler(sinit);
- }
- initJitteredMats();
- return Error::NONE;
- }
- void Renderer::initJitteredMats()
- {
- static const Array<Vec2, 16> SAMPLE_LOCS_16 = {
- {Vec2(-8.0, 0.0), Vec2(-6.0, -4.0), Vec2(-3.0, -2.0), Vec2(-2.0, -6.0), Vec2(1.0, -1.0), Vec2(2.0, -5.0),
- Vec2(6.0, -7.0), Vec2(5.0, -3.0), Vec2(4.0, 1.0), Vec2(7.0, 4.0), Vec2(3.0, 5.0), Vec2(0.0, 7.0),
- Vec2(-1.0, 3.0), Vec2(-4.0, 6.0), Vec2(-7.0, 8.0), Vec2(-5.0, 2.0)}};
- for(U i = 0; i < 16; ++i)
- {
- Vec2 texSize(1.0f / Vec2(F32(m_width), F32(m_height))); // Texel size
- texSize *= 2.0f; // Move it to NDC
- Vec2 S = SAMPLE_LOCS_16[i] / 8.0f; // In [-1, 1]
- Vec2 subSample = S * texSize; // In [-texSize, texSize]
- subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
- m_jitteredMats16x[i] = Mat4::getIdentity();
- m_jitteredMats16x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
- }
- static const Array<Vec2, 8> SAMPLE_LOCS_8 = {Vec2(-7.0, 1.0), Vec2(-5.0, -5.0), Vec2(-1.0, -3.0), Vec2(3.0, -7.0),
- Vec2(5.0, -1.0), Vec2(7.0, 7.0), Vec2(1.0, 3.0), Vec2(-3.0, 5.0)};
- for(U i = 0; i < 8; ++i)
- {
- Vec2 texSize(1.0f / Vec2(F32(m_width), F32(m_height))); // Texel size
- texSize *= 2.0f; // Move it to NDC
- Vec2 S = SAMPLE_LOCS_8[i] / 8.0f; // In [-1, 1]
- Vec2 subSample = S * texSize; // In [-texSize, texSize]
- subSample *= 0.5f; // In [-texSize / 2, texSize / 2]
- m_jitteredMats8x[i] = Mat4::getIdentity();
- m_jitteredMats8x[i].setTranslationPart(Vec4(subSample, 0.0, 1.0));
- }
- }
- Error Renderer::populateRenderGraph(RenderingContext& ctx)
- {
- ctx.m_matrices.m_cameraTransform = ctx.m_renderQueue->m_cameraTransform;
- ctx.m_matrices.m_view = ctx.m_renderQueue->m_viewMatrix;
- ctx.m_matrices.m_projection = ctx.m_renderQueue->m_projectionMatrix;
- ctx.m_matrices.m_viewProjection = ctx.m_renderQueue->m_viewProjectionMatrix;
- ctx.m_matrices.m_jitter = m_jitteredMats8x[m_frameCount & (m_jitteredMats8x.getSize() - 1)];
- ctx.m_matrices.m_projectionJitter = ctx.m_matrices.m_jitter * ctx.m_matrices.m_projection;
- ctx.m_matrices.m_viewProjectionJitter = ctx.m_matrices.m_projectionJitter * ctx.m_matrices.m_view;
- ctx.m_prevMatrices = m_prevMatrices;
- ctx.m_unprojParams = ctx.m_renderQueue->m_projectionMatrix.extractPerspectiveUnprojectionParams();
- // Check if resources got loaded
- if(m_prevLoadRequestCount != m_resources->getLoadingRequestCount()
- || m_prevAsyncTasksCompleted != m_resources->getAsyncTaskCompletedCount())
- {
- m_prevLoadRequestCount = m_resources->getLoadingRequestCount();
- m_prevAsyncTasksCompleted = m_resources->getAsyncTaskCompletedCount();
- m_resourcesDirty = true;
- }
- else
- {
- m_resourcesDirty = false;
- }
- // Import RTs first
- m_downscale->importRenderTargets(ctx);
- m_tonemapping->importRenderTargets(ctx);
- m_depth->importRenderTargets(ctx);
- // Populate render graph. WARNING Watch the order
- m_genericCompute->populateRenderGraph(ctx);
- if(m_accelerationStructureBuilder)
- {
- m_accelerationStructureBuilder->populateRenderGraph(ctx);
- }
- m_shadowMapping->populateRenderGraph(ctx);
- m_gi->populateRenderGraph(ctx);
- m_probeReflections->populateRenderGraph(ctx);
- m_volLighting->populateRenderGraph(ctx);
- m_gbuffer->populateRenderGraph(ctx);
- m_motionVectors->populateRenderGraph(ctx);
- m_gbufferPost->populateRenderGraph(ctx);
- m_depth->populateRenderGraph(ctx);
- if(m_rtShadows)
- {
- m_rtShadows->populateRenderGraph(ctx);
- }
- else
- {
- m_smResolve->populateRenderGraph(ctx);
- }
- m_volFog->populateRenderGraph(ctx);
- m_ssao->populateRenderGraph(ctx);
- m_lensFlare->populateRenderGraph(ctx);
- m_ssr->populateRenderGraph(ctx);
- m_ssgi->populateRenderGraph(ctx);
- m_lightShading->populateRenderGraph(ctx);
- m_temporalAA->populateRenderGraph(ctx);
- m_downscale->populateRenderGraph(ctx);
- m_tonemapping->populateRenderGraph(ctx);
- m_bloom->populateRenderGraph(ctx);
- if(m_dbg->getEnabled())
- {
- m_dbg->populateRenderGraph(ctx);
- }
- m_finalComposite->populateRenderGraph(ctx);
- // Bin lights and update uniforms
- m_stats.m_lightBinTime = (m_statsEnabled) ? HighRezTimer::getCurrentTime() : -1.0;
- ClusterBinIn cin;
- cin.m_renderQueue = ctx.m_renderQueue;
- cin.m_tempAlloc = ctx.m_tempAllocator;
- cin.m_shadowsEnabled = true; // TODO
- cin.m_stagingMem = m_stagingMem;
- cin.m_threadHive = m_threadHive;
- m_clusterBin.bin(cin, ctx.m_clusterBinOut);
- ctx.m_prevClustererMagicValues =
- (m_frameCount > 0) ? m_prevClustererMagicValues : ctx.m_clusterBinOut.m_shaderMagicValues;
- m_prevClustererMagicValues = ctx.m_clusterBinOut.m_shaderMagicValues;
- updateLightShadingUniforms(ctx);
- m_stats.m_lightBinTime = (m_statsEnabled) ? (HighRezTimer::getCurrentTime() - m_stats.m_lightBinTime) : -1.0;
- return Error::NONE;
- }
- void Renderer::finalize(const RenderingContext& ctx)
- {
- ++m_frameCount;
- m_prevMatrices = ctx.m_matrices;
- // Inform about the HiZ map. Do it as late as possible
- if(ctx.m_renderQueue->m_fillCoverageBufferCallback)
- {
- F32* depthValues;
- U32 width;
- U32 height;
- m_depth->getClientDepthMapInfo(depthValues, width, height);
- ctx.m_renderQueue->m_fillCoverageBufferCallback(ctx.m_renderQueue->m_fillCoverageBufferCallbackUserData,
- depthValues, width, height);
- }
- }
- TextureInitInfo Renderer::create2DRenderTargetInitInfo(U32 w, U32 h, Format format, TextureUsageBit usage, CString name)
- {
- ANKI_ASSERT(!!(usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE)
- || !!(usage & TextureUsageBit::IMAGE_COMPUTE_WRITE));
- TextureInitInfo init(name);
- init.m_width = w;
- init.m_height = h;
- init.m_depth = 1;
- init.m_layerCount = 1;
- init.m_type = TextureType::_2D;
- init.m_format = format;
- init.m_mipmapCount = 1;
- init.m_samples = 1;
- init.m_usage = usage;
- return init;
- }
- RenderTargetDescription Renderer::create2DRenderTargetDescription(U32 w, U32 h, Format format, CString name)
- {
- RenderTargetDescription init(name);
- init.m_width = w;
- init.m_height = h;
- init.m_depth = 1;
- init.m_layerCount = 1;
- init.m_type = TextureType::_2D;
- init.m_format = format;
- init.m_mipmapCount = 1;
- init.m_samples = 1;
- init.m_usage = TextureUsageBit::NONE;
- return init;
- }
- TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, const ClearValue& clearVal)
- {
- ANKI_ASSERT(!!(inf.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE)
- || !!(inf.m_usage & TextureUsageBit::IMAGE_COMPUTE_WRITE));
- const U faceCount = (inf.m_type == TextureType::CUBE || inf.m_type == TextureType::CUBE_ARRAY) ? 6 : 1;
- Bool useCompute = false;
- if(!!(inf.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE))
- {
- useCompute = false;
- }
- else if(!!(inf.m_usage & TextureUsageBit::IMAGE_COMPUTE_WRITE))
- {
- useCompute = true;
- }
- else
- {
- ANKI_ASSERT(!"Can't handle that");
- }
- // Create tex
- TexturePtr tex = m_gr->newTexture(inf);
- // Clear all surfaces
- CommandBufferInitInfo cmdbinit;
- cmdbinit.m_flags = (useCompute) ? CommandBufferFlag::COMPUTE_WORK : CommandBufferFlag::GRAPHICS_WORK;
- if((inf.m_mipmapCount * faceCount * inf.m_layerCount * 4) < COMMAND_BUFFER_SMALL_BATCH_MAX_COMMANDS)
- {
- cmdbinit.m_flags |= CommandBufferFlag::SMALL_BATCH;
- }
- CommandBufferPtr cmdb = m_gr->newCommandBuffer(cmdbinit);
- for(U32 mip = 0; mip < inf.m_mipmapCount; ++mip)
- {
- for(U32 face = 0; face < faceCount; ++face)
- {
- for(U32 layer = 0; layer < inf.m_layerCount; ++layer)
- {
- TextureSurfaceInfo surf(mip, 0, face, layer);
- if(!useCompute)
- {
- FramebufferInitInfo fbInit("RendererClearRT");
- Array<TextureUsageBit, MAX_COLOR_ATTACHMENTS> colUsage = {};
- TextureUsageBit dsUsage = TextureUsageBit::NONE;
- if(formatIsDepthStencil(inf.m_format))
- {
- DepthStencilAspectBit aspect = DepthStencilAspectBit::NONE;
- if(formatIsDepth(inf.m_format))
- {
- aspect |= DepthStencilAspectBit::DEPTH;
- }
- if(formatIsStencil(inf.m_format))
- {
- aspect |= DepthStencilAspectBit::STENCIL;
- }
- TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf, aspect));
- fbInit.m_depthStencilAttachment.m_textureView = view;
- fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::CLEAR;
- fbInit.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
- fbInit.m_depthStencilAttachment.m_clearValue = clearVal;
- dsUsage = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
- }
- else
- {
- TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
- fbInit.m_colorAttachmentCount = 1;
- fbInit.m_colorAttachments[0].m_textureView = view;
- fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
- fbInit.m_colorAttachments[0].m_clearValue = clearVal;
- colUsage[0] = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE;
- }
- FramebufferPtr fb = m_gr->newFramebuffer(fbInit);
- cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::NONE,
- TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, surf);
- cmdb->beginRenderPass(fb, colUsage, dsUsage);
- cmdb->endRenderPass();
- if(!!inf.m_initialUsage)
- {
- cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
- inf.m_initialUsage, surf);
- }
- }
- else
- {
- // Compute
- ShaderProgramResourceVariantInitInfo variantInitInfo(m_clearTexComputeProg);
- variantInitInfo.addMutation("IS_2D", I32((inf.m_type != TextureType::_3D) ? 1 : 0));
- const ShaderProgramResourceVariant* variant;
- m_clearTexComputeProg->getOrCreateVariant(variantInitInfo, variant);
- cmdb->bindShaderProgram(variant->getProgram());
- cmdb->setPushConstants(&clearVal.m_colorf[0], sizeof(clearVal.m_colorf));
- TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
- cmdb->bindImage(0, 0, view);
- cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::NONE, TextureUsageBit::IMAGE_COMPUTE_WRITE,
- surf);
- UVec3 wgSize;
- wgSize.x() = (8 - 1 + (tex->getWidth() >> mip)) / 8;
- wgSize.y() = (8 - 1 + (tex->getHeight() >> mip)) / 8;
- wgSize.z() = (inf.m_type == TextureType::_3D) ? ((8 - 1 + (tex->getDepth() >> mip)) / 8) : 1;
- cmdb->dispatchCompute(wgSize.x(), wgSize.y(), wgSize.z());
- if(!!inf.m_initialUsage)
- {
- cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::IMAGE_COMPUTE_WRITE, inf.m_initialUsage,
- surf);
- }
- }
- }
- }
- }
- cmdb->flush();
- return tex;
- }
- void Renderer::updateLightShadingUniforms(RenderingContext& ctx) const
- {
- LightingUniforms* blk = static_cast<LightingUniforms*>(m_stagingMem->allocateFrame(
- sizeof(LightingUniforms), StagingGpuMemoryType::UNIFORM, ctx.m_lightShadingUniformsToken));
- // Start writing
- blk->m_unprojectionParams = ctx.m_unprojParams;
- blk->m_rendererSize = Vec2(F32(m_width), F32(m_height));
- blk->m_time = F32(HighRezTimer::getCurrentTime());
- blk->m_near = ctx.m_renderQueue->m_cameraNear;
- blk->m_clusterCount = UVec4(m_clusterCount[0], m_clusterCount[1], m_clusterCount[2], m_clusterCount[3]);
- blk->m_cameraPos = ctx.m_renderQueue->m_cameraTransform.getTranslationPart().xyz();
- blk->m_far = ctx.m_renderQueue->m_cameraFar;
- blk->m_clustererMagicValues = ctx.m_clusterBinOut.m_shaderMagicValues;
- blk->m_prevClustererMagicValues = ctx.m_prevClustererMagicValues;
- blk->m_lightVolumeLastCluster = m_volLighting->getFinalClusterInZ();
- blk->m_frameCount = m_frameCount & MAX_U32;
- // Matrices
- blk->m_viewMat = ctx.m_renderQueue->m_viewMatrix;
- blk->m_invViewMat = ctx.m_renderQueue->m_viewMatrix.getInverse();
- blk->m_projMat = ctx.m_matrices.m_projectionJitter;
- blk->m_invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
- blk->m_viewProjMat = ctx.m_matrices.m_viewProjectionJitter;
- blk->m_invViewProjMat = ctx.m_matrices.m_viewProjectionJitter.getInverse();
- blk->m_prevViewProjMat = ctx.m_prevMatrices.m_viewProjectionJitter;
- blk->m_prevViewProjMatMulInvViewProjMat =
- ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_viewProjectionJitter.getInverse();
- // Directional light
- if(ctx.m_renderQueue->m_directionalLight.m_uuid != 0)
- {
- DirectionalLight& out = blk->m_dirLight;
- const DirectionalLightQueueElement& in = ctx.m_renderQueue->m_directionalLight;
- out.m_diffuseColor = in.m_diffuseColor;
- out.m_cascadeCount = in.m_shadowCascadeCount;
- out.m_dir = in.m_direction;
- out.m_active = 1;
- out.m_effectiveShadowDistance = in.m_effectiveShadowDistance;
- out.m_shadowCascadesDistancePower = in.m_shadowCascadesDistancePower;
- out.m_shadowLayer = in.m_shadowLayer;
- for(U cascade = 0; cascade < in.m_shadowCascadeCount; ++cascade)
- {
- out.m_textureMatrices[cascade] = in.m_textureMatrices[cascade];
- }
- }
- else
- {
- blk->m_dirLight.m_active = 0;
- }
- }
- void Renderer::registerDebugRenderTarget(RendererObject* obj, CString rtName)
- {
- #if ANKI_ENABLE_ASSERTS
- for(const DebugRtInfo& inf : m_debugRts)
- {
- ANKI_ASSERT(inf.m_rtName != rtName && "Choose different name");
- }
- #endif
- ANKI_ASSERT(obj);
- DebugRtInfo inf;
- inf.m_obj = obj;
- inf.m_rtName.create(getAllocator(), rtName);
- m_debugRts.emplaceBack(getAllocator(), std::move(inf));
- }
- void Renderer::getCurrentDebugRenderTarget(RenderTargetHandle& handle, Bool& handleValid,
- ShaderProgramPtr& optionalShaderProgram)
- {
- if(ANKI_LIKELY(m_currentDebugRtName.isEmpty()))
- {
- handleValid = false;
- return;
- }
- RendererObject* obj = nullptr;
- for(const DebugRtInfo& inf : m_debugRts)
- {
- if(inf.m_rtName == m_currentDebugRtName)
- {
- obj = inf.m_obj;
- }
- }
- ANKI_ASSERT(obj);
- obj->getDebugRenderTarget(m_currentDebugRtName, handle, optionalShaderProgram);
- handleValid = true;
- }
- void Renderer::setCurrentDebugRenderTarget(CString rtName)
- {
- m_currentDebugRtName.destroy(getAllocator());
- if(!rtName.isEmpty() && rtName.getLength() > 0)
- {
- m_currentDebugRtName.create(getAllocator(), rtName);
- }
- }
- } // end namespace anki
|