Repository: google/filament
File: filament/backend/src/webgpu/WebGPUPipelineCache.cpp (C++)

Code before:
            .constants = nullptr,
            .bufferCount = request.vertexBufferSlots.size(),
            .buffers = request.vertexBufferLayouts,
        },
        .primitive = {
            .topology = toWebGPU(request.primitiveType),
            // TODO should we assume some constant format here or is there a way to get
            //      this from PipelineState somehow or elsewhere?
            //      Perhaps, cache/assert format from index buffers as they are requested?
            .stripIndexFormat = wgpu::IndexFormat::Undefined,
            .frontFace = request.rasterState.inverseFrontFaces ? wgpu::FrontFace::CW : wgpu::FrontFace::CCW,
            .cullMode = toWebGPU(request.rasterState.culling),
            // TODO no depth clamp in WebGPU supported directly. unclippedDepth is close, so we are
            //      starting there
            .unclippedDepth = !request.rasterState.depthClamp &&
                              mDevice.HasFeature(wgpu::FeatureName::DepthClipControl),
        },
        .depthStencil = depthOrStencilRequested ? &depthStencilState: nullptr,
        .multisample = {
            .count = request.multisampleCount,
            .mask = 0xFFFFFFFF,
            .alphaToCoverageEnabled = (request.multisampleCount > 1) && request.rasterState.alphaToCoverage
        },
        .fragment = nullptr // will add below if fragment module is included
    };
    if (pipelineDescriptor.primitive.topology == wgpu::PrimitiveTopology::LineStrip ||
            pipelineDescriptor.primitive.topology == wgpu::PrimitiveTopology::TriangleStrip) {
        pipelineDescriptor.primitive.stripIndexFormat = request.stripIndexFormat;
        FILAMENT_CHECK_POSTCONDITION(request.stripIndexFormat != wgpu::IndexFormat::Undefined)
                << "Invalid format";
    }

    wgpu::FragmentState fragmentState = {};
    const wgpu::BlendState blendState {
        .color = {
            .operation = toWebGPU(request.rasterState.blendEquationRGB),
            .srcFactor = toWebGPU(request.rasterState.blendFunctionSrcRGB),
            .dstFactor = toWebGPU(request.rasterState.blendFunctionDstRGB)
        },
        .alpha = {
            .operation = toWebGPU(request.rasterState.blendEquationAlpha),
            .srcFactor = toWebGPU(request.rasterState.blendFunctionSrcAlpha),
            .dstFactor = toWebGPU(request.rasterState.blendFunctionDstAlpha)
        }
    };
    // According to the WebGPU spec, a pipeline cannot have a fragment stage with zero color
    // targets. This situation can arise in Filament during depth-only passes (like shadow map
    // generation) if the material variant still includes a fragment shader.
    //
    // To handle this, we check if any color targets are configured for this pipeline. If not, we
    // create a pipeline *without* a fragment stage. This makes the pipeline valid for a

Review comment (refactor):
again, I would recommend a helper function, e.g.:
```cpp
[[nodiscard]] constexpr bool isStripTopology(const wgpu::PrimitiveTopology topology) {
    switch (topology) {
        case wgpu::PrimitiveTopology::Undefined:
        case wgpu::PrimitiveTopology::PointList:
        case wgpu::PrimitiveTopology::LineList:
        case wgpu::PrimitiveTopology::TriangleList:
            return false;
        case wgpu::PrimitiveTopology::LineStrip:
        case wgpu::PrimitiveTopology::TriangleStrip:
            return true;
    }
}
```
then this could be simplified to:
```cpp
FILAMENT_CHECK_POSTCONDITION(!isStripTopology(pipelineDescriptor.primitive.topology) ||
                             request.stripIndexFormat != wgpu::IndexFormat::Undefined)
        << "If the topology is a strip format, e.g. TriangleStrip, the stripIndexFormat cannot "
           "be Undefined.";
```
right?

Code after:
            // TODO This won't always be the case for the primitives bound.  But this particular field
            //  in the pipeline struct is only meant for restarting the strip, which we don't need so far.
            .stripIndexFormat =
                    isStripPrimitiveType(request.primitiveType)? wgpu::IndexFormat::Uint16 :
                                                                wgpu::IndexFormat::Undefined,
            .frontFace = request.rasterState.inverseFrontFaces ? wgpu::FrontFace::CW : wgpu::FrontFace::CCW,
            .cullMode = toWebGPU(request.rasterState.culling),
            // TODO no depth clamp in WebGPU supported directly. unclippedDepth is close, so we are
            //      starting there
            .unclippedDepth = !request.rasterState.depthClamp &&
                              mDevice.HasFeature(wgpu::FeatureName::DepthClipControl),
        },
        .depthStencil = depthOrStencilRequested ? &depthStencilState: nullptr,
        .multisample = {
            .count = request.multisampleCount,
            .mask = 0xFFFFFFFF,
            .alphaToCoverageEnabled = (request.multisampleCount > 1) && request.rasterState.alphaToCoverage
        },
        .fragment = nullptr // will add below if fragment module is included
    };
    FILAMENT_CHECK_POSTCONDITION(!isStripPrimitiveType(request.primitiveType) ||
            pipelineDescriptor.primitive.stripIndexFormat != wgpu::IndexFormat::Undefined)
            << "If the topology is a strip format, e.g. TriangleStrip, the stripIndexFormat cannot "
               "be Undefined.";

    wgpu::FragmentState fragmentState = {};
    const wgpu::BlendState blendState {
        .color = {
            .operation = toWebGPU(request.rasterState.blendEquationRGB),
            .srcFactor = toWebGPU(request.rasterState.blendFunctionSrcRGB),
            .dstFactor = toWebGPU(request.rasterState.blendFunctionDstRGB)
        },
        .alpha = {
            .operation = toWebGPU(request.rasterState.blendEquationAlpha),
            .srcFactor = toWebGPU(request.rasterState.blendFunctionSrcAlpha),
            .dstFactor = toWebGPU(request.rasterState.blendFunctionDstAlpha)
        }
    };
    // According to the WebGPU spec, a pipeline cannot have a fragment stage with zero color
    // targets. This situation can arise in Filament during depth-only passes (like shadow map
    // generation) if the material variant still includes a fragment shader.
    //
    // To handle this, we check if any color targets are configured for this pipeline. If not, we
    // create a pipeline *without* a fragment stage. This makes the pipeline valid for a
    // depth-only pass, allowing depth writes to proceed correctly.
    if (request.fragmentShaderModule != nullptr && request.colorFormatCount > 0) {
        fragmentState.module = request.fragmentShaderModule;
        fragmentState.entryPoint = "main";
        // see the comment about constants for the vertex state, as the same reasoning applies
        // here
        fragmentState.constantCount = 0;