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; };