From ee8d0e6ebffcc7efd037cb2993be6b5815a8f3e3 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 31 Jul 2025 21:34:37 -0700 Subject: [PATCH] remove fake dependencies on the PER_VIEW UBO The PER_VIEW UBO was updated by different render passes at different times, which created synchronizations on the GPU, between unrelated passes and prevented the vertex shader to run on parallel with another pass for instance. In the PR, we fix this by moving ALL the UBO set-up outside of render passes. It's now done early, just before creating the framegraph. The PER_VIEW UBO is shared between several passes, themselves using different descriptor sets; so we need to make sure all the data necessary for these passes is computed and set in the UBO (e.g. SSR passes). The passes themselves (like the color pass) still set the textures and UBOs in their descriptor sets, but then no longer updated the content of the UBO itself. In this PR we also remove some "fake" dependencies between passes due to descriptor sets straddling between passes. This is done by unbinding all descriptor sets at the end of each pass. The PER_MATERIAL descriptor set is a bit special because it should be unbound between full screen quads draws. Additionally, there some places in the code attempting to update UBOs only when the content was dirty were missing a "clean" call, to reset the dirty bit to the unset state. The main change here is to move the code that set the UBO content out of the ColorPassDescriptorSet (and a few other) into View and instead of updating the content in the color pass (and a few other), do that at the beginning of Renderer::render(). --- filament/src/PostProcessManager.cpp | 80 +++++++----- filament/src/PostProcessManager.h | 3 +- filament/src/RendererUtils.cpp | 36 ++--- filament/src/RendererUtils.h | 4 - filament/src/ShadowMapManager.cpp | 1 + filament/src/details/MaterialInstance.cpp | 1 + filament/src/details/Renderer.cpp | 73 ++++++----- filament/src/details/View.cpp | 145 ++++++++++++++++----- filament/src/details/View.h | 16 ++- filament/src/ds/ColorPassDescriptorSet.cpp | 74 +---------- filament/src/ds/ColorPassDescriptorSet.h | 31 +---- filament/src/ds/SsrPassDescriptorSet.cpp | 22 +--- filament/src/ds/SsrPassDescriptorSet.h | 11 +- filament/src/ds/StructureDescriptorSet.cpp | 14 +- filament/src/ds/StructureDescriptorSet.h | 5 +- 15 files changed, 250 insertions(+), 266 deletions(-) diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index d930fc9569..76ab875a3e 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -421,6 +421,12 @@ void PostProcessManager::resetForRender() { mFixedMaterialInstanceIndex = {}; } +void PostProcessManager::unbindAllDescriptorSets(DriverApi& driver) noexcept { + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW); + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE); + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); +} + UTILS_NOINLINE PipelineState PostProcessManager::getPipelineState( FMaterial const* const ma, PostProcessVariant variant) const noexcept { @@ -484,6 +490,7 @@ void PostProcessManager::commitAndRenderFullScreenQuad(DriverApi& driver, driver.beginRenderPass(out.target, out.params); driver.draw(pipeline, mFullScreenQuadRph, 0, 3, 1); driver.endRenderPass(); + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); } // ------------------------------------------------------------------------------------------------ @@ -556,11 +563,7 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph driver.beginRenderPass(out.target, out.params); pass.getExecutor().execute(mEngine, driver); driver.endRenderPass(); - - // unbind all descriptor sets to avoid false dependencies with the next pass - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW); - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE); - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); + unbindAllDescriptorSets(driver); }); auto const depth = structurePass->depth; @@ -607,8 +610,10 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph mi->commit(driver); mi->use(driver); renderFullScreenQuad(out, pipeline, driver); + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); driver.destroyTexture(th); } + unbindAllDescriptorSets(driver); }); return { depth, structurePass->picking }; @@ -666,11 +671,7 @@ FrameGraphId PostProcessManager::transparentPicking(FrameGrap driver.beginRenderPass(target, params); pass.getExecutor().execute(mEngine, driver); driver.endRenderPass(); - - // unbind all descriptor sets to avoid false dependencies with the next pass - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW); - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE); - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); + unbindAllDescriptorSets(driver); }); return pickingRenderPass->picking; @@ -681,9 +682,7 @@ FrameGraphId PostProcessManager::transparentPicking(FrameGrap FrameGraphId PostProcessManager::ssr(FrameGraph& fg, RenderPassBuilder const& passBuilder, FrameHistory const& frameHistory, - CameraInfo const& cameraInfo, FrameGraphId const structure, - ScreenSpaceReflectionsOptions const& options, FrameGraphTexture::Descriptor const& desc) noexcept { struct SSRPassData { @@ -704,8 +703,6 @@ FrameGraphId PostProcessManager::ssr(FrameGraph& fg, FrameGraphId const history = fg.import("SSR history", previous.desc, FrameGraphTexture::Usage::SAMPLEABLE, previous.color); - mat4 const& historyProjection = previous.projection; - auto const& uvFromClipMatrix = mEngine.getUvFromClipMatrix(); auto const& ssrPass = fg.addPass("SSR Pass", [&](FrameGraph::Builder& builder, auto& data) { @@ -739,23 +736,16 @@ FrameGraphId PostProcessManager::ssr(FrameGraph& fg, data.history = builder.sample(history); } }, - [this, projection = cameraInfo.projection, - userViewMatrix = cameraInfo.getUserViewMatrix(), uvFromClipMatrix, historyProjection, - options, passBuilder = passBuilder] - (FrameGraphResources const& resources, auto const& data, DriverApi& driver) mutable { + [this, passBuilder = passBuilder](FrameGraphResources const& resources, + auto const& data, DriverApi& driver) mutable { // set structure sampler mSsrPassDescriptorSet.prepareStructure(mEngine, data.structure ? resources.getTexture(data.structure) : getOneTexture()); - // set screen-space reflections and screen-space refractions - mat4f const uvFromViewMatrix = uvFromClipMatrix * projection; - mat4f const reprojection = uvFromClipMatrix * - mat4f{ historyProjection * inverse(userViewMatrix) }; - // the history sampler is a regular texture2D TextureHandle const history = data.history ? resources.getTexture(data.history) : getZeroTexture(); - mSsrPassDescriptorSet.prepareHistorySSR(mEngine, history, reprojection, uvFromViewMatrix, options); + mSsrPassDescriptorSet.prepareHistorySSR(mEngine, history); mSsrPassDescriptorSet.commit(mEngine); @@ -777,11 +767,7 @@ FrameGraphId PostProcessManager::ssr(FrameGraph& fg, driver.beginRenderPass(out.target, out.params); pass.getExecutor().execute(mEngine, driver); driver.endRenderPass(); - - // unbind all descriptor sets to avoid false dependencies with the next pass - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW); - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE); - DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); + unbindAllDescriptorSets(driver); }); return ssrPass->reflections; @@ -1047,6 +1033,7 @@ FrameGraphId PostProcessManager::screenSpaceAmbientOcclusion( pipeline.rasterState.depthFunc = RasterState::DepthFunc::L; assert_invariant(ssao.params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH); renderFullScreenQuad(ssao, pipeline, driver); + unbindAllDescriptorSets(driver); }); FrameGraphId ssao = SSAOPass->ssao; @@ -1165,6 +1152,7 @@ FrameGraphId PostProcessManager::bilateralBlurPass(FrameGraph auto pipeline = getPipelineState(ma); pipeline.rasterState.depthFunc = RasterState::DepthFunc::L; renderFullScreenQuad(blurred, pipeline, driver); + unbindAllDescriptorSets(driver); }); return blurPass->blurred; @@ -1381,6 +1369,7 @@ FrameGraphId PostProcessManager::gaussianBlurPass(FrameGraph& commitAndRenderFullScreenQuad(driver, hwOutRT, mi); } + unbindAllDescriptorSets(driver); }); return blurPass->out; @@ -1783,6 +1772,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, 1.0f / float(colorDesc.width), 1.0f / float(colorDesc.height) }); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); /* @@ -1849,10 +1839,12 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, mi->use(driver); renderFullScreenQuad(out, pipeline, driver); + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); driver.destroyTexture(inColor); driver.destroyTexture(inCoc); } + unbindAllDescriptorSets(driver); }); /* @@ -1908,6 +1900,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, mi->setParameter("cocMinMax", inCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); mi->setParameter("texelSize", float2{ 1.0f / inputDesc.width, 1.0f / inputDesc.height }); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); inTilesCocMinMax = ppDoFTiling->outTilesCocMinMax; } @@ -1940,6 +1933,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, FMaterialInstance* const mi = getMaterialInstance(mEngine, material); mi->setParameter("tiles", inTilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); return ppDoFDilate->outTilesCocMinMax; }; @@ -2019,6 +2013,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, }); mi->setParameter("bokehAngle", bokehAngle); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); /* @@ -2062,6 +2057,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, mi->setParameter("alpha", inAlpha, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST }); mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); @@ -2111,6 +2107,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, mi->setParameter("alpha", alpha, { .filterMag = SamplerMagFilter::NEAREST }); mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST }); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); return ppDoFCombine->output; @@ -2145,7 +2142,7 @@ FrameGraphId PostProcessManager::downscalePass(FrameGraph& fg mi->setParameter("fireflies", fireflies ? 1.0f : 0.0f); mi->setParameter("invHighlight", std::isinf(highlight) ? 0.0f : 1.0f / highlight); commitAndRenderFullScreenQuad(driver, out, mi); - + unbindAllDescriptorSets(driver); }); return downsamplePass->output; } @@ -2301,6 +2298,7 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg, commitAndRenderFullScreenQuad(driver, hwDstRT, mi); driver.destroyTexture(hwOutView); } + unbindAllDescriptorSets(driver); }); // output of bloom downsample pass becomes input of next (flare) pass @@ -2348,8 +2346,10 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg, mi->commit(driver); mi->use(driver); renderFullScreenQuad(hwDstRT, pipeline, driver); + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); driver.destroyTexture(hwOutView); } + unbindAllDescriptorSets(driver); }); return { bloomUpsamplePass->out, flare }; @@ -2403,6 +2403,7 @@ FrameGraphId PostProcessManager::flarePass(FrameGraph& fg, mi->setParameter("haloThickness", bloomOptions.haloThickness); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); constexpr float kernelWidth = 9; @@ -2661,6 +2662,8 @@ FrameGraphId PostProcessManager::colorGrading(FrameGraph& fg, commitAndRenderFullScreenQuad(driver, out, mi, colorGradingConfig.translucent ? PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE); + + unbindAllDescriptorSets(driver); } ); @@ -2713,6 +2716,7 @@ FrameGraphId PostProcessManager::fxaa(FrameGraph& fg, mi->setParameter("texelSize", 1.0f / float2{ inDesc.width, inDesc.height }); commitAndRenderFullScreenQuad(driver, out, mi, variant); + unbindAllDescriptorSets(driver); }); return ppFXAA->output; @@ -2997,6 +3001,7 @@ FrameGraphId PostProcessManager::taa(FrameGraph& fg, colorGradingSubpass(driver, colorGradingConfig); } driver.endRenderPass(); + unbindAllDescriptorSets(driver); }); input = colorGradingConfig.asSubpass ? taaPass->tonemappedOutput : taaPass->output; @@ -3066,6 +3071,7 @@ FrameGraphId PostProcessManager::rcas( outputDesc.width, outputDesc.height, 1.0f / outputDesc.width, 1.0f / outputDesc.height }); commitAndRenderFullScreenQuad(driver, out, mi, variant); + unbindAllDescriptorSets(driver); }); return ppFsrRcas->output; @@ -3145,6 +3151,7 @@ FrameGraphId PostProcessManager::upscaleBilinear(FrameGraph& auto pipeline = getPipelineState(material.getMaterial(mEngine)); renderFullScreenQuad(out, pipeline, driver); + unbindAllDescriptorSets(driver); }); auto output = ppQuadBlit->output; @@ -3219,9 +3226,9 @@ FrameGraphId PostProcessManager::upscaleSGSR1(FrameGraph& fg, mi->commit(driver); mi->use(driver); - auto out = resources.getRenderPassInfo(); + auto const out = resources.getRenderPassInfo(); commitAndRenderFullScreenQuad(driver, out, mi, variant); - + unbindAllDescriptorSets(driver); }); auto output = ppQuadBlit->output; @@ -3358,6 +3365,7 @@ FrameGraphId PostProcessManager::upscaleFSR1(FrameGraph& fg, auto pipeline = getPipelineState(easuMaterial->getMaterial(mEngine)); renderFullScreenQuad(out, pipeline, driver); } + unbindAllDescriptorSets(driver); }); auto output = ppQuadBlit->output; @@ -3432,6 +3440,7 @@ FrameGraphId PostProcessManager::blit(FrameGraph& fg, bool co pipeline.rasterState.blendFunctionDstAlpha = BlendFunction::ONE_MINUS_SRC_ALPHA; } renderFullScreenQuad(out, pipeline, driver); + unbindAllDescriptorSets(driver); }); return ppQuadBlit->output; @@ -3515,6 +3524,7 @@ FrameGraphId PostProcessManager::blitDepth(FrameGraph& fg, float(vp.bottom) / inputDesc.height, float(vp.width) / inputDesc.width, float(vp.height) / inputDesc.height}); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); return ppQuadBlit->output; @@ -3619,6 +3629,7 @@ FrameGraphId PostProcessManager::resolveDepth(FrameGraph& fg, getMaterialInstance(mEngine, material); mi->setParameter("depth", input, {}); // NEAREST commitAndRenderFullScreenQuad(driver, resources.getRenderPassInfo(), mi); + unbindAllDescriptorSets(driver); }); return ppResolve->output; @@ -3678,6 +3689,7 @@ FrameGraphId PostProcessManager::vsmMipmapPass(FrameGraph& fg mi->use(driver); renderFullScreenQuadWithScissor(out, pipeline, scissor, driver); + unbindAllDescriptorSets(driver); driver.destroyTexture(in); // `in` is just a view on `data.in` }); @@ -3714,6 +3726,7 @@ FrameGraphId PostProcessManager::debugShadowCascades(FrameGra mi->setParameter("color", color, {}); // nearest mi->setParameter("depth", depth, {}); // nearest commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); return debugShadowCascadePass->output; @@ -3791,11 +3804,13 @@ FrameGraphId PostProcessManager::debugCombineArrayTexture(Fra mi->setParameter("layerIndex", i); mi->commit(driver); renderFullScreenQuad(out, pipeline, driver); + DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL); // From the second draw, don't clear the targetbuffer. out.params.flags.clear = TargetBufferFlags::NONE; out.params.flags.discardStart = TargetBufferFlags::NONE; out.params.viewport.left += out.params.viewport.width; } + unbindAllDescriptorSets(driver); }); return ppQuadBlit->output; @@ -3842,6 +3857,7 @@ FrameGraphId PostProcessManager::debugDisplayShadowTexture( mi->setParameter("channel", (uint32_t)channel); mi->setParameter("power", power); commitAndRenderFullScreenQuad(driver, out, mi); + unbindAllDescriptorSets(driver); }); input = shadomapDebugPass->color; } diff --git a/filament/src/PostProcessManager.h b/filament/src/PostProcessManager.h index a05cd8094e..ccfdb590fb 100644 --- a/filament/src/PostProcessManager.h +++ b/filament/src/PostProcessManager.h @@ -114,9 +114,7 @@ public: FrameGraphId ssr(FrameGraph& fg, RenderPassBuilder const& passBuilder, FrameHistory const& frameHistory, - CameraInfo const& cameraInfo, FrameGraphId structure, - ScreenSpaceReflectionsOptions const& options, FrameGraphTexture::Descriptor const& desc) noexcept; // SSAO @@ -395,6 +393,7 @@ public: void resetForRender(); private: + static void unbindAllDescriptorSets(backend::DriverApi& driver) noexcept; // Helper to get a MaterialInstance from a FMaterial // This currently just call FMaterial::getDefaultInstance(). diff --git a/filament/src/RendererUtils.cpp b/filament/src/RendererUtils.cpp index 0fa9c351fd..1530161590 100644 --- a/filament/src/RendererUtils.cpp +++ b/filament/src/RendererUtils.cpp @@ -208,37 +208,23 @@ RendererUtils::ColorPassOutput RendererUtils::colorPass( view.prepareSSAO(data.ssao ? resources.getTexture(data.ssao) : engine.getOneTextureArray()); - view.prepareShadowMapping(engine, view.getVsmShadowOptions().highPrecision); - - // set shadow sampler - view.prepareShadow(data.shadows ? - resources.getTexture(data.shadows) : - (view.getShadowType() != ShadowType::PCF ? - engine.getOneTextureArray() : engine.getOneTextureArrayDepth())); + // set screen-space reflections and screen-space refractions + view.prepareSSR(data.ssr ? + resources.getTexture(data.ssr) : engine.getOneTextureArray()); // set structure sampler view.prepareStructure(data.structure ? resources.getTexture(data.structure) : engine.getOneTexture()); - // set screen-space reflections and screen-space refractions - TextureHandle const ssr = data.ssr ? - resources.getTexture(data.ssr) : engine.getOneTextureArray(); + // set shadow sampler + view.prepareShadowMapping(engine, + data.shadows + ? resources.getTexture(data.shadows) + : (view.getShadowType() != ShadowType::PCF + ? engine.getOneTextureArray() + : engine.getOneTextureArrayDepth())); - view.prepareSSR(ssr, config.screenSpaceReflectionHistoryNotReady, - config.ssrLodOffset, view.getScreenSpaceReflectionsOptions()); - - // Note: here we can't use data.color's descriptor for the viewport because - // the actual viewport might be offset when the target is the swapchain. - // However, the width/height should be the same. - assert_invariant( - out.params.viewport.width == resources.getDescriptor(data.color).width); - assert_invariant( - out.params.viewport.height == resources.getDescriptor(data.color).height); - - view.prepareViewport(static_cast(out.params.viewport), - config.logicalViewport); - - view.commitUniformsAndSamplers(driver); + view.commitDescriptorSet(driver); // TODO: this should be a parameter of FrameGraphRenderPass::Descriptor out.params.clearStencil = config.clearStencil; diff --git a/filament/src/RendererUtils.h b/filament/src/RendererUtils.h index 661f12e854..5f067dc9b2 100644 --- a/filament/src/RendererUtils.h +++ b/filament/src/RendererUtils.h @@ -65,16 +65,12 @@ public: math::float4 clearColor = {}; // Clear stencil uint8_t clearStencil = 0u; - // Lod offset for the SSR passes - float ssrLodOffset; // Contact shadow enabled? bool hasContactShadows; // Screen space reflections enabled bool hasScreenSpaceReflectionsOrRefractions; // Use a depth format with a stencil component. bool enabledStencilBuffer; - // whether the screenspace reflections history buffer is initialized - bool screenSpaceReflectionHistoryNotReady; }; struct ColorPassInput { diff --git a/filament/src/ShadowMapManager.cpp b/filament/src/ShadowMapManager.cpp index ff15cd0b4a..160f1dc0e3 100644 --- a/filament/src/ShadowMapManager.cpp +++ b/filament/src/ShadowMapManager.cpp @@ -436,6 +436,7 @@ FrameGraphId ShadowMapManager::render(FEngine& engine, FrameG // Finally update our UBO in one batch if (mShadowUb.isDirty()) { + mShadowUb.clean(); driver.updateBufferObject(mShadowUbh, mShadowUb.toBufferDescriptor(driver), 0); } diff --git a/filament/src/details/MaterialInstance.cpp b/filament/src/details/MaterialInstance.cpp index cd02b714fa..81a13cc1f3 100644 --- a/filament/src/details/MaterialInstance.cpp +++ b/filament/src/details/MaterialInstance.cpp @@ -222,6 +222,7 @@ void FMaterialInstance::commit(FEngine& engine) const { void FMaterialInstance::commit(DriverApi& driver) const { // update uniforms if needed if (mUniforms.isDirty() || mHasStreamUniformAssociations) { + mUniforms.clean(); driver.updateBufferObject(mUbHandle, mUniforms.toBufferDescriptor(driver), 0); } if (!mTextureParameters.empty()) { diff --git a/filament/src/details/Renderer.cpp b/filament/src/details/Renderer.cpp index 59af570342..c16eff9b6f 100644 --- a/filament/src/details/Renderer.cpp +++ b/filament/src/details/Renderer.cpp @@ -830,29 +830,57 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) { xvp.bottom = int32_t(guardBand); } + /* + * Frame graph + */ + FrameGraph fg(*mResourceAllocator, + isProtectedContent ? FrameGraph::Mode::PROTECTED : FrameGraph::Mode::UNPROTECTED); + auto& blackboard = fg.getBlackboard(); + + PostProcessManager::ScreenSpaceRefConfig const ssrConfig = PostProcessManager::prepareMipmapSSR( + fg, svp.width, svp.height, + ssReflectionsOptions.enabled ? TextureFormat::RGBA16F : TextureFormat::R11F_G11F_B10F, + view.getCameraUser().getFieldOfView(Camera::Fov::VERTICAL), scale); + + /* + * Update the PER_VIEW UBO used for the color, ssr and postfx passes. This UBO is never + * updated again during the frame. + */ + auto [bias, derivativeScale] = prepareUpscaler(scale, taaOptions, dsrOptions); - view.prepare(engine, driver, rootArenaScope, svp, cameraInfo, getShaderUserTime(), needsAlphaChannel); - view.prepareLodBias(bias, derivativeScale); + view.prepareSSAO(aoOptions); + view.prepareSSR(engine, cameraInfo, ssrConfig.lodOffset, ssReflectionsOptions); + view.prepareShadowMapping(); + // There might be a bug here with svp's origin; normally the origin could offset when the + // target is the swapchain (width/height are the same though). This would mean that we'd have + // to wait for the color pass to execute to set the viewport. For now, I wasn't able to + // get into such a case though. + view.prepareViewport(svp, xvp); + view.commitUniforms(driver); + + /* + * Update the PER_VIEW UBO use for the structure pass. It never updated again after this point. + */ // Set the PER_VIEW UBO for the passes that use the user materials, but are not the color pass // (e.g. structure, ssao). The PER_VIEW UBO may be different because these passes don't run // at the same resolution. We set only the values that are relevant to both user-materials // and the concerned passes. The PER_VIEW UBO contains data that is needed by the user // materials public APIs. - StructureDescriptorSet& descriptorSet = ppm.getStructureDescriptorSet(); - descriptorSet.prepareCamera(engine, cameraInfo); - descriptorSet.prepareTime(engine, getShaderUserTime()); - descriptorSet.prepareViewport(svp, { + { // the scope helps to guarantee that we're not modifying the descriptor-set later + StructureDescriptorSet& ds = ppm.getStructureDescriptorSet(); + ds.prepareCamera(engine, cameraInfo); + ds.prepareTime(engine, getShaderUserTime()); + ds.prepareViewport(svp, { int32_t(float(xvp.left) * aoOptions.resolution), int32_t(float(xvp.bottom) * aoOptions.resolution), uint32_t(float(xvp.width) * aoOptions.resolution), uint32_t(float(xvp.height) * aoOptions.resolution) }); - descriptorSet.prepareLodBias(bias, derivativeScale); - descriptorSet.prepareMaterialGlobals(view.getMaterialGlobals()); - descriptorSet.commit(driver); - + ds.prepareLodBias(bias, derivativeScale); + ds.prepareMaterialGlobals(view.getMaterialGlobals()); + } /* * Allocate command buffer @@ -886,14 +914,6 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) { variant.setVsm(view.hasShadowing() && view.getShadowType() != ShadowType::PCF); variant.setStereo(view.hasStereo()); - /* - * Frame graph - */ - - FrameGraph fg(*mResourceAllocator, - isProtectedContent ? FrameGraph::Mode::PROTECTED : FrameGraph::Mode::UNPROTECTED); - auto& blackboard = fg.getBlackboard(); - /* * Shadow pass */ @@ -969,7 +989,7 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) { // the clearFlags and clearColor specified below will only apply when rendering into the // temporary color buffer. In particular, they won't apply when rendering into the main // swapchain (imported render target above) - RendererUtils::ColorPassConfig config{ + RendererUtils::ColorPassConfig const config{ .physicalViewport = svp, .logicalViewport = xvp, .scale = scale, @@ -978,7 +998,6 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) { .clearFlags = getClearFlags(), .clearColor = clearColor, .clearStencil = clearStencil, - .ssrLodOffset = 0.0f, .hasContactShadows = scene.hasContactShadows(), // at this point we don't know if we have refraction, but that's handled later .hasScreenSpaceReflectionsOrRefractions = ssReflectionsOptions.enabled, @@ -1064,23 +1083,12 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) { blackboard["ssao"] = ssao; } - // -------------------------------------------------------------------------------------------- - // prepare screen-space reflection/refraction passes - - PostProcessManager::ScreenSpaceRefConfig const ssrConfig = PostProcessManager::prepareMipmapSSR( - fg, svp.width, svp.height, - ssReflectionsOptions.enabled ? TextureFormat::RGBA16F : TextureFormat::R11F_G11F_B10F, - view.getCameraUser().getFieldOfView(Camera::Fov::VERTICAL), config.scale); - config.ssrLodOffset = ssrConfig.lodOffset; - // -------------------------------------------------------------------------------------------- // screen-space reflections pass if (ssReflectionsOptions.enabled) { auto reflections = ppm.ssr(fg, passBuilder, - view.getFrameHistory(), cameraInfo, - structure, - ssReflectionsOptions, + view.getFrameHistory(), structure, { .width = svp.width, .height = svp.height }); if (UTILS_LIKELY(reflections)) { @@ -1088,7 +1096,6 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) { PostProcessManager::generateMipmapSSR(ppm, fg, reflections, ssrConfig.reflection, false, ssrConfig); } - config.screenSpaceReflectionHistoryNotReady = !reflections; } // -------------------------------------------------------------------------------------------- diff --git a/filament/src/details/View.cpp b/filament/src/details/View.cpp index 078199b6cf..30bd7599f7 100644 --- a/filament/src/details/View.cpp +++ b/filament/src/details/View.cpp @@ -948,54 +948,137 @@ void FView::prepareSSAO(Handle ssao) const noexcept { getColorPassDescriptorSet().prepareSSAO(ssao, mAmbientOcclusionOptions); } -void FView::prepareSSR(Handle ssr, - bool const disableSSR, - float const refractionLodOffset, - ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept { - getColorPassDescriptorSet().prepareSSR(ssr, disableSSR, refractionLodOffset, ssrOptions); +void FView::prepareSSAO(AmbientOcclusionOptions const& options) const noexcept { + // High quality sampling is enabled only if AO itself is enabled and upsampling quality is at + // least set to high and of course only if upsampling is needed. + const bool highQualitySampling = options.upsampling >= QualityLevel::HIGH + && options.resolution < 1.0f; + + const float edgeDistance = 1.0f / options.bilateralThreshold; + auto& s = mUniforms.edit(); + s.aoSamplingQualityAndEdgeDistance = + options.enabled ? (highQualitySampling ? edgeDistance : 0.0f) : -1.0f; + s.aoBentNormals = options.enabled && options.bentNormals ? 1.0f : 0.0f; } +void FView::prepareSSR(Handle ssr) const noexcept { + getColorPassDescriptorSet().prepareScreenSpaceRefraction(ssr); +} + +void FView::prepareSSR(FEngine& engine, CameraInfo const& cameraInfo, + float const refractionLodOffset, + ScreenSpaceReflectionsOptions const& options) const noexcept { + + auto const& ssr = getFrameHistory().getPrevious().ssr; + + bool const disableSSR = !ssr.color.handle; + mat4 const& historyProjection = ssr.projection; + mat4f const& uvFromClipMatrix = engine.getUvFromClipMatrix(); + mat4f const projection = cameraInfo.projection; + mat4 const userViewMatrix = cameraInfo.getUserViewMatrix(); + + // set screen-space reflections and screen-space refractions + mat4f const uvFromViewMatrix = uvFromClipMatrix * projection; + mat4f const reprojection = uvFromClipMatrix * + mat4f{ historyProjection * inverse(userViewMatrix) }; + + auto& s = mUniforms.edit(); + s.ssrReprojection = reprojection; + s.ssrUvFromViewMatrix = uvFromViewMatrix; + s.ssrThickness = options.thickness; + s.ssrBias = options.bias; + s.ssrStride = options.stride; + s.refractionLodOffset = refractionLodOffset; + s.ssrDistance = (options.enabled && !disableSSR) ? options.maxDistance : 0.0f; +} + + void FView::prepareStructure(Handle structure) const noexcept { // sampler must be NEAREST getColorPassDescriptorSet().prepareStructure(structure); } -void FView::prepareShadow(Handle texture) const noexcept { +void FView::prepareShadowMapping(FEngine const& engine, Handle texture) const noexcept { // when needsShadowMap() is not set, this method only just sets a dummy texture // in the needed samplers (in that case `texture` is actually a dummy texture). - ShadowMapManager::ShadowMappingUniforms uniforms; - if (needsShadowMap()) { - uniforms = mShadowMapManager->getShadowMappingUniforms(); - } - switch (mShadowType) { - case ShadowType::PCF: - getColorPassDescriptorSet().prepareShadowPCF(texture, uniforms); - break; - case ShadowType::VSM: - getColorPassDescriptorSet().prepareShadowVSM(texture, uniforms, mVsmShadowOptions); - break; - case ShadowType::DPCF: - getColorPassDescriptorSet().prepareShadowDPCF(texture, uniforms, mSoftShadowOptions); - break; - case ShadowType::PCSS: - getColorPassDescriptorSet().prepareShadowPCSS(texture, uniforms, mSoftShadowOptions); - break; - case ShadowType::PCFd: - getColorPassDescriptorSet().prepareShadowPCFDebug(texture, uniforms); - break; - } -} -void FView::prepareShadowMapping(FEngine const& engine, bool const highPrecision) const noexcept { BufferObjectHandle ubo{ engine.getDummyUniformBuffer() }; if (mHasShadowing) { assert_invariant(mShadowMapManager); ubo = mShadowMapManager->getShadowUniformsHandle(); } - getColorPassDescriptorSet().prepareShadowMapping(ubo, highPrecision); + getColorPassDescriptorSet().prepareShadowMapping(ubo); + + switch (mShadowType) { + case ShadowType::PCF: + getColorPassDescriptorSet().prepareShadowPCF(texture); + break; + case ShadowType::VSM: + getColorPassDescriptorSet().prepareShadowVSM(texture, mVsmShadowOptions); + break; + case ShadowType::DPCF: + getColorPassDescriptorSet().prepareShadowDPCF(texture); + break; + case ShadowType::PCSS: + getColorPassDescriptorSet().prepareShadowPCSS(texture); + break; + case ShadowType::PCFd: + getColorPassDescriptorSet().prepareShadowPCFDebug(texture); + break; + } } -void FView::commitUniformsAndSamplers(DriverApi& driver) const noexcept { +void FView::prepareShadowMapping() const noexcept { + + ShadowMapManager::ShadowMappingUniforms uniforms{}; + if (needsShadowMap()) { + uniforms = mShadowMapManager->getShadowMappingUniforms(); + } + + constexpr float low = 5.54f; // ~ std::log(std::numeric_limits::max()) * 0.5f; + constexpr float high = 42.0f; // ~ std::log(std::numeric_limits::max()) * 0.5f; + constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCF = 0u; + constexpr uint32_t SHADOW_SAMPLING_RUNTIME_EVSM = 1u; + constexpr uint32_t SHADOW_SAMPLING_RUNTIME_DPCF = 2u; + constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCSS = 3u; + auto& s = mUniforms.edit(); + s.cascadeSplits = uniforms.cascadeSplits; + s.ssContactShadowDistance = uniforms.ssContactShadowDistance; + s.directionalShadows = int32_t(uniforms.directionalShadows); + s.cascades = int32_t(uniforms.cascades); + switch (mShadowType) { + case ShadowType::PCF: + s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF; + break; + case ShadowType::VSM: + s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_EVSM; + s.vsmExponent = mVsmShadowOptions.highPrecision ? high : low; + s.vsmDepthScale = mVsmShadowOptions.minVarianceScale * 0.01f * s.vsmExponent; + s.vsmLightBleedReduction = mVsmShadowOptions.lightBleedReduction; + break; + case ShadowType::DPCF: + s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_DPCF; + s.shadowPenumbraRatioScale = mSoftShadowOptions.penumbraRatioScale; + break; + case ShadowType::PCSS: + s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCSS; + s.shadowPenumbraRatioScale = mSoftShadowOptions.penumbraRatioScale; + break; + case ShadowType::PCFd: + s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF; + break; + } +} + +void FView::commitUniforms(DriverApi& driver) const noexcept { + if (mUniforms.isDirty()) { + mUniforms.clean(); + driver.updateBufferObject(mUniforms.getUboHandle(), + mUniforms.toBufferDescriptor(driver), 0); + } +} + +void FView::commitDescriptorSet(DriverApi& driver) const noexcept { getColorPassDescriptorSet().commit(driver); } diff --git a/filament/src/details/View.h b/filament/src/details/View.h index f6c0ed6b1f..656a83ee05 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -173,15 +173,19 @@ public: void prepareLighting(FEngine& engine, CameraInfo const& cameraInfo) noexcept; void prepareSSAO(backend::Handle ssao) const noexcept; - void prepareSSR(backend::Handle ssr, bool disableSSR, - float refractionLodOffset, - ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept; + void prepareSSAO(AmbientOcclusionOptions const& options) const noexcept; + + void prepareSSR(backend::Handle ssr) const noexcept; + void prepareSSR(FEngine& engine, CameraInfo const& cameraInfo, + float refractionLodOffset, ScreenSpaceReflectionsOptions const& options) const noexcept; + void prepareStructure(backend::Handle structure) const noexcept; - void prepareShadow(backend::Handle structure) const noexcept; - void prepareShadowMapping(FEngine const& engine, bool highPrecision) const noexcept; + void prepareShadowMapping(FEngine const& engine, backend::Handle structure) const noexcept; + void prepareShadowMapping() const noexcept; void commitFroxels(backend::DriverApi& driverApi) const noexcept; - void commitUniformsAndSamplers(backend::DriverApi& driver) const noexcept; + void commitUniforms(backend::DriverApi& driver) const noexcept; + void commitDescriptorSet(backend::DriverApi& driver) const noexcept; utils::JobSystem::Job* getFroxelizerSync() const noexcept { return mFroxelizerSync; } void setFroxelizerSync(utils::JobSystem::Job* sync) noexcept { mFroxelizerSync = sync; } diff --git a/filament/src/ds/ColorPassDescriptorSet.cpp b/filament/src/ds/ColorPassDescriptorSet.cpp index 735f3638f3..bbfd4ff609 100644 --- a/filament/src/ds/ColorPassDescriptorSet.cpp +++ b/filament/src/ds/ColorPassDescriptorSet.cpp @@ -257,7 +257,6 @@ void ColorPassDescriptorSet::prepareFog(FEngine& engine, const CameraInfo& camer void ColorPassDescriptorSet::prepareSSAO(Handle ssao, AmbientOcclusionOptions const& options) noexcept { - // High quality sampling is enabled only if AO itself is enabled and upsampling quality is at // least set to high and of course only if upsampling is needed. const bool highQualitySampling = options.upsampling >= QualityLevel::HIGH @@ -268,12 +267,6 @@ void ColorPassDescriptorSet::prepareSSAO(Handle ssao, .filterMag = options.enabled && !highQualitySampling ? SamplerMagFilter::LINEAR : SamplerMagFilter::NEAREST }); - - const float edgeDistance = 1.0f / options.bilateralThreshold; - auto& s = mUniforms.edit(); - s.aoSamplingQualityAndEdgeDistance = - options.enabled ? (highQualitySampling ? edgeDistance : 0.0f) : -1.0f; - s.aoBentNormals = options.enabled && options.bentNormals ? 1.0f : 0.0f; } void ColorPassDescriptorSet::prepareBlending(bool const needsAlphaChannel) noexcept { @@ -285,19 +278,11 @@ void ColorPassDescriptorSet::prepareMaterialGlobals( PerViewDescriptorSetUtils::prepareMaterialGlobals(mUniforms.edit(), materialGlobals); } -void ColorPassDescriptorSet::prepareSSR(Handle ssr, - bool const disableSSR, - float const refractionLodOffset, - ScreenSpaceReflectionsOptions const& ssrOptions) noexcept { - +void ColorPassDescriptorSet::prepareScreenSpaceRefraction(Handle ssr) noexcept { setSampler(+PerViewBindingPoints::SSR, ssr, { .filterMag = SamplerMagFilter::LINEAR, .filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR }); - - auto& s = mUniforms.edit(); - s.refractionLodOffset = refractionLodOffset; - s.ssrDistance = (ssrOptions.enabled && !disableSSR) ? ssrOptions.maxDistance : 0.0f; } void ColorPassDescriptorSet::prepareStructure(Handle structure) noexcept { @@ -379,27 +364,12 @@ void ColorPassDescriptorSet::prepareDynamicLights(Froxelizer& froxelizer) noexce s.lightFarAttenuationParams = 0.5f * float2{ 10.0f, 10.0f / (f * f) }; } -void ColorPassDescriptorSet::prepareShadowMapping(BufferObjectHandle shadowUniforms, bool const highPrecision) noexcept { - auto& s = mUniforms.edit(); - constexpr float low = 5.54f; // ~ std::log(std::numeric_limits::max()) * 0.5f; - constexpr float high = 42.0f; // ~ std::log(std::numeric_limits::max()) * 0.5f; - s.vsmExponent = highPrecision ? high : low; +void ColorPassDescriptorSet::prepareShadowMapping(BufferObjectHandle shadowUniforms) noexcept { setBuffer(+PerViewBindingPoints::SHADOWS, shadowUniforms, 0, sizeof(ShadowUib)); } -void ColorPassDescriptorSet::prepareShadowSampling(PerViewUib& uniforms, - ShadowMappingUniforms const& shadowMappingUniforms) noexcept { - uniforms.cascadeSplits = shadowMappingUniforms.cascadeSplits; - uniforms.ssContactShadowDistance = shadowMappingUniforms.ssContactShadowDistance; - uniforms.directionalShadows = int32_t(shadowMappingUniforms.directionalShadows); - uniforms.cascades = int32_t(shadowMappingUniforms.cascades); -} - void ColorPassDescriptorSet::prepareShadowVSM(Handle texture, - ShadowMappingUniforms const& shadowMappingUniforms, VsmShadowOptions const& options) noexcept { - constexpr float low = 5.54f; // ~ std::log(std::numeric_limits::max()) * 0.5f; - constexpr float high = 42.0f; // ~ std::log(std::numeric_limits::max()) * 0.5f; SamplerMinFilter filterMin = SamplerMinFilter::LINEAR; if (options.anisotropy > 0 || options.mipmapping) { filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR; @@ -410,16 +380,9 @@ void ColorPassDescriptorSet::prepareShadowVSM(Handle texture, .filterMin = filterMin, .anisotropyLog2 = options.anisotropy, }); - auto& s = mUniforms.edit(); - s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_EVSM; - s.vsmExponent = options.highPrecision ? high : low; - s.vsmDepthScale = options.minVarianceScale * 0.01f * s.vsmExponent; - s.vsmLightBleedReduction = options.lightBleedReduction; - prepareShadowSampling(s, shadowMappingUniforms); } -void ColorPassDescriptorSet::prepareShadowPCF(Handle texture, - ShadowMappingUniforms const& shadowMappingUniforms) noexcept { +void ColorPassDescriptorSet::prepareShadowPCF(Handle texture) noexcept { setSampler(+PerViewBindingPoints::SHADOW_MAP, texture, { .filterMag = SamplerMagFilter::LINEAR, @@ -427,49 +390,24 @@ void ColorPassDescriptorSet::prepareShadowPCF(Handle texture, .compareMode = SamplerCompareMode::COMPARE_TO_TEXTURE, .compareFunc = SamplerCompareFunc::GE }); - auto& s = mUniforms.edit(); - s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF; - prepareShadowSampling(s, shadowMappingUniforms); } -void ColorPassDescriptorSet::prepareShadowDPCF(Handle texture, - ShadowMappingUniforms const& shadowMappingUniforms, - SoftShadowOptions const& options) noexcept { +void ColorPassDescriptorSet::prepareShadowDPCF(Handle texture) noexcept { setSampler(+PerViewBindingPoints::SHADOW_MAP, texture, {}); - auto& s = mUniforms.edit(); - s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_DPCF; - s.shadowPenumbraRatioScale = options.penumbraRatioScale; - prepareShadowSampling(s, shadowMappingUniforms); } -void ColorPassDescriptorSet::prepareShadowPCSS(Handle texture, - ShadowMappingUniforms const& shadowMappingUniforms, - SoftShadowOptions const& options) noexcept { +void ColorPassDescriptorSet::prepareShadowPCSS(Handle texture) noexcept { setSampler(+PerViewBindingPoints::SHADOW_MAP, texture, {}); - auto& s = mUniforms.edit(); - s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCSS; - s.shadowPenumbraRatioScale = options.penumbraRatioScale; - prepareShadowSampling(s, shadowMappingUniforms); } -void ColorPassDescriptorSet::prepareShadowPCFDebug(Handle texture, - ShadowMappingUniforms const& shadowMappingUniforms) noexcept { +void ColorPassDescriptorSet::prepareShadowPCFDebug(Handle texture) noexcept { setSampler(+PerViewBindingPoints::SHADOW_MAP, texture, { .filterMag = SamplerMagFilter::NEAREST, .filterMin = SamplerMinFilter::NEAREST }); - auto& s = mUniforms.edit(); - s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF; - prepareShadowSampling(s, shadowMappingUniforms); } void ColorPassDescriptorSet::commit(DriverApi& driver) noexcept { - if (mUniforms.isDirty()) { - driver.updateBufferObject(mUniforms.getUboHandle(), - mUniforms.toBufferDescriptor(driver), 0); - } - - for (size_t i = 0; i < DESCRIPTOR_LAYOUT_COUNT; i++) { mDescriptorSet[i].commit(mDescriptorSetLayout[i], driver); } diff --git a/filament/src/ds/ColorPassDescriptorSet.h b/filament/src/ds/ColorPassDescriptorSet.h index 3b7f0c4300..198ca7271d 100644 --- a/filament/src/ds/ColorPassDescriptorSet.h +++ b/filament/src/ds/ColorPassDescriptorSet.h @@ -23,6 +23,7 @@ #include "TypedUniformBuffer.h" +#include #include #include @@ -66,11 +67,6 @@ class ColorPassDescriptorSet { using LightManagerInstance = utils::EntityInstance; using TextureHandle = backend::Handle; - static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCF = 0u; - static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_EVSM = 1u; - static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_DPCF = 2u; - static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCSS = 3u; - public: static uint8_t getIndex(bool lit, bool ssr, bool fog) noexcept; @@ -112,12 +108,9 @@ public: void prepareMaterialGlobals(std::array const& materialGlobals) noexcept; // screen-space reflection and/or refraction (SSR) - void prepareSSR(TextureHandle ssr, - bool disableSSR, - float refractionLodOffset, - ScreenSpaceReflectionsOptions const& ssrOptions) noexcept; + void prepareScreenSpaceRefraction(TextureHandle ssr) noexcept; - void prepareShadowMapping(backend::BufferObjectHandle shadowUniforms, bool highPrecision) noexcept; + void prepareShadowMapping(backend::BufferObjectHandle shadowUniforms) noexcept; void prepareDirectionalLight(FEngine& engine, float exposure, math::float3 const& sceneSpaceDirection, LightManagerInstance instance) noexcept; @@ -128,22 +121,15 @@ public: void prepareDynamicLights(Froxelizer& froxelizer) noexcept; void prepareShadowVSM(TextureHandle texture, - ShadowMappingUniforms const& shadowMappingUniforms, VsmShadowOptions const& options) noexcept; - void prepareShadowPCF(TextureHandle texture, - ShadowMappingUniforms const& shadowMappingUniforms) noexcept; + void prepareShadowPCF(TextureHandle texture) noexcept; - void prepareShadowDPCF(TextureHandle texture, - ShadowMappingUniforms const& shadowMappingUniforms, - SoftShadowOptions const& options) noexcept; + void prepareShadowDPCF(TextureHandle texture) noexcept; - void prepareShadowPCSS(TextureHandle texture, - ShadowMappingUniforms const& shadowMappingUniforms, - SoftShadowOptions const& options) noexcept; + void prepareShadowPCSS(TextureHandle texture) noexcept; - void prepareShadowPCFDebug(TextureHandle texture, - ShadowMappingUniforms const& shadowMappingUniforms) noexcept; + void prepareShadowPCFDebug(TextureHandle texture) noexcept; // update local data into GPU UBO void commit(backend::DriverApi& driver) noexcept; @@ -164,9 +150,6 @@ private: void setBuffer(backend::descriptor_binding_t binding, backend::BufferObjectHandle boh, uint32_t offset, uint32_t size) noexcept; - static void prepareShadowSampling(PerViewUib& uniforms, - ShadowMappingUniforms const& shadowMappingUniforms) noexcept; - TypedUniformBuffer& mUniforms; std::array mDescriptorSetLayout; std::array mDescriptorSet; diff --git a/filament/src/ds/SsrPassDescriptorSet.cpp b/filament/src/ds/SsrPassDescriptorSet.cpp index dbb2507e6e..22e4fdc3d6 100644 --- a/filament/src/ds/SsrPassDescriptorSet.cpp +++ b/filament/src/ds/SsrPassDescriptorSet.cpp @@ -66,29 +66,14 @@ void SsrPassDescriptorSet::setFrameUniforms(FEngine const& engine, // and GL would be okay without this, but Vulkan's validation layer would complain. mDescriptorSet.setBuffer(engine.getPerViewDescriptorSetLayoutSsrVariant(), +PerViewBindingPoints::SHADOWS, mShadowUbh, 0, sizeof(ShadowUib)); - - mUniforms = std::addressof(uniforms); } -void SsrPassDescriptorSet::prepareHistorySSR(FEngine const& engine, Handle ssr, - mat4f const& historyProjection, - mat4f const& uvFromViewMatrix, - ScreenSpaceReflectionsOptions const& ssrOptions) noexcept { - +void SsrPassDescriptorSet::prepareHistorySSR(FEngine const& engine, Handle ssr) noexcept { mDescriptorSet.setSampler(engine.getPerViewDescriptorSetLayoutSsrVariant(), +PerViewBindingPoints::SSR_HISTORY, ssr, { .filterMag = SamplerMagFilter::LINEAR, .filterMin = SamplerMinFilter::LINEAR }); - - assert_invariant(mUniforms); - auto& s = mUniforms->edit(); - s.ssrReprojection = historyProjection; - s.ssrUvFromViewMatrix = uvFromViewMatrix; - s.ssrThickness = ssrOptions.thickness; - s.ssrBias = ssrOptions.bias; - s.ssrDistance = ssrOptions.enabled ? ssrOptions.maxDistance : 0.0f; - s.ssrStride = ssrOptions.stride; } void SsrPassDescriptorSet::prepareStructure(FEngine const& engine, @@ -99,12 +84,7 @@ void SsrPassDescriptorSet::prepareStructure(FEngine const& engine, } void SsrPassDescriptorSet::commit(FEngine& engine) noexcept { - assert_invariant(mUniforms); DriverApi& driver = engine.getDriverApi(); - if (mUniforms->isDirty()) { - driver.updateBufferObject(mUniforms->getUboHandle(), - mUniforms->toBufferDescriptor(driver), 0); - } mDescriptorSet.commit(engine.getPerViewDescriptorSetLayoutSsrVariant(), driver); } diff --git a/filament/src/ds/SsrPassDescriptorSet.h b/filament/src/ds/SsrPassDescriptorSet.h index 2ad4cbbe47..4e13601717 100644 --- a/filament/src/ds/SsrPassDescriptorSet.h +++ b/filament/src/ds/SsrPassDescriptorSet.h @@ -19,8 +19,6 @@ #include "DescriptorSet.h" -#include "DescriptorSetLayout.h" - #include "TypedUniformBuffer.h" #include @@ -28,8 +26,6 @@ #include #include -#include - namespace filament { class FEngine; @@ -51,11 +47,7 @@ public: void prepareStructure(FEngine const& engine, TextureHandle structure) noexcept; - void prepareHistorySSR(FEngine const& engine, TextureHandle ssr, - math::mat4f const& historyProjection, - math::mat4f const& uvFromViewMatrix, - ScreenSpaceReflectionsOptions const& ssrOptions) noexcept; - + void prepareHistorySSR(FEngine const& engine, TextureHandle ssr) noexcept; // update local data into GPU UBO void commit(FEngine& engine) noexcept; @@ -64,7 +56,6 @@ public: void bind(backend::DriverApi& driver) noexcept; private: - TypedUniformBuffer* mUniforms = nullptr; DescriptorSet mDescriptorSet; backend::BufferObjectHandle mShadowUbh; }; diff --git a/filament/src/ds/StructureDescriptorSet.cpp b/filament/src/ds/StructureDescriptorSet.cpp index c8dbe121a9..5562f72784 100644 --- a/filament/src/ds/StructureDescriptorSet.cpp +++ b/filament/src/ds/StructureDescriptorSet.cpp @@ -63,14 +63,14 @@ void StructureDescriptorSet::terminate(DriverApi& driver) { mUniforms.terminate(driver); } -void StructureDescriptorSet::commit(DriverApi& driver) noexcept { - assert_invariant(mDescriptorSetLayout); - driver.updateBufferObject(mUniforms.getUboHandle(), - mUniforms.toBufferDescriptor(driver), 0); - mDescriptorSet.commit(*mDescriptorSetLayout, driver); -} - void StructureDescriptorSet::bind(DriverApi& driver) const noexcept { + assert_invariant(mDescriptorSetLayout); + if (mUniforms.isDirty()) { + mUniforms.clean(); + driver.updateBufferObject(mUniforms.getUboHandle(), + mUniforms.toBufferDescriptor(driver), 0); + mDescriptorSet.commit(*mDescriptorSetLayout, driver); + } mDescriptorSet.bind(driver, DescriptorSetBindingPoints::PER_VIEW); } diff --git a/filament/src/ds/StructureDescriptorSet.h b/filament/src/ds/StructureDescriptorSet.h index 9c47b392f5..14701ccc4a 100644 --- a/filament/src/ds/StructureDescriptorSet.h +++ b/filament/src/ds/StructureDescriptorSet.h @@ -45,8 +45,7 @@ public: void terminate(backend::DriverApi& driver); - void commit(backend::DriverApi& driver) noexcept; - + // this commits the UBO if needed and binds the descriptor set void bind(backend::DriverApi& driver) const noexcept; @@ -65,7 +64,7 @@ public: private: DescriptorSetLayout const* mDescriptorSetLayout = nullptr; - DescriptorSet mDescriptorSet; + mutable DescriptorSet mDescriptorSet; TypedUniformBuffer mUniforms; };