Repository: google/filament
File: filament/src/PostProcessManager.cpp (C++)

Code before:
        return upscaleSGSR1(fg, sourceHasLuminance, dsrOptions, input, vp, outDesc);
    }
    return upscaleFSR1(fg, dsrOptions, input, vp, outDesc);
}

FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleBilinear(FrameGraph& fg, bool translucent,
        DynamicResolutionOptions dsrOptions, FrameGraphId<FrameGraphTexture> const input,
        filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
        SamplerMagFilter filter) noexcept {

    struct QuadBlitData {
        FrameGraphId<FrameGraphTexture> input;
        FrameGraphId<FrameGraphTexture> output;
    };

    auto const& ppQuadBlit = fg.addPass<QuadBlitData>(dsrOptions.enabled ? "upscaling" : "compositing",
            [&](FrameGraph::Builder& builder, auto& data) {
                data.input = builder.sample(input);
                data.output = builder.createTexture("upscaled output", outDesc);
                data.output = builder.write(data.output, FrameGraphTexture::Usage::COLOR_ATTACHMENT);

                TargetBufferFlags clearFlags = TargetBufferFlags::DEPTH;
                if (translucent) {
                    clearFlags |= TargetBufferFlags::COLOR0;
                }

                builder.declareRenderPass(builder.getName(data.output), {
                        .attachments = { .color = { data.output } },
                        .clearFlags = clearFlags });
            },
            [this, vp, translucent, filter](FrameGraphResources const& resources,
                    auto const& data, DriverApi& driver) {
                bindPostProcessDescriptorSet(driver);

                // helper to enable blending
                auto enableTranslucentBlending = [](PipelineState& pipeline) {
                    pipeline.rasterState.blendFunctionSrcRGB = BlendFunction::ONE;
                    pipeline.rasterState.blendFunctionSrcAlpha = BlendFunction::ONE;
                    pipeline.rasterState.blendFunctionDstRGB = BlendFunction::ONE_MINUS_SRC_ALPHA;
                    pipeline.rasterState.blendFunctionDstAlpha = BlendFunction::ONE_MINUS_SRC_ALPHA;
                };

                auto color = resources.getTexture(data.input);
                auto const& inputDesc = resources.getDescriptor(data.input);

                // --------------------------------------------------------------------------------
                // set uniforms

                auto& material = getPostProcessMaterial("blitLow");
                FMaterialInstance* const mi =
                        PostProcessMaterial::getMaterialInstance(mEngine, material);

Review comment (suggestion):
I'm really not sure about this.  In theory we shouldn't need blending at all if the source has just been allocated.

I think this code tries to handle the case where the source "upscaled output" has been "forwarded" to an existing buffer, in this case you don't want to clear it.

I think that's why it's written this way; but I'm not entirely sure. Again, if we're going to blend into a cleared buffer, we don't need to actually blend.  So there must have been a reason the code was written this way.


Code after:
        return upscaleSGSR1(fg, sourceHasLuminance, dsrOptions, input, vp, outDesc);
    }
    return upscaleFSR1(fg, dsrOptions, input, vp, outDesc);
}

FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleBilinear(FrameGraph& fg,
        DynamicResolutionOptions dsrOptions, FrameGraphId<FrameGraphTexture> const input,
        filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
        SamplerMagFilter filter) noexcept {

    struct QuadBlitData {
        FrameGraphId<FrameGraphTexture> input;
        FrameGraphId<FrameGraphTexture> output;
    };

    auto const& ppQuadBlit = fg.addPass<QuadBlitData>(dsrOptions.enabled ? "upscaling" : "compositing",
            [&](FrameGraph::Builder& builder, auto& data) {
                data.input = builder.sample(input);
                data.output = builder.createTexture("upscaled output", outDesc);
                data.output = builder.write(data.output, FrameGraphTexture::Usage::COLOR_ATTACHMENT);
                builder.declareRenderPass(builder.getName(data.output), {
                        .attachments = { .color = { data.output } },
                        .clearFlags = TargetBufferFlags::DEPTH });
            },
            [this, vp, filter](FrameGraphResources const& resources,
                    auto const& data, DriverApi& driver) {
                bindPostProcessDescriptorSet(driver);

                auto color = resources.getTexture(data.input);
                auto const& inputDesc = resources.getDescriptor(data.input);

                // --------------------------------------------------------------------------------
                // set uniforms

                auto& material = getPostProcessMaterial("blitLow");
                FMaterialInstance* const mi =
                        PostProcessMaterial::getMaterialInstance(mEngine, material);
                mi->setParameter("color", color, {
                    .filterMag = filter
                });

                mi->setParameter("levelOfDetail", 0.0f);

                mi->setParameter("viewport", float4{
                        float(vp.left)   / inputDesc.width,
                        float(vp.bottom) / inputDesc.height,
                        float(vp.width)  / inputDesc.width,
                        float(vp.height) / inputDesc.height
                });
                mi->commit(driver);
                mi->use(driver);