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

Code before:
                // Assuming combined depth/stencil format if only stencil is present
                if (sfTexture) {
                    pipelineDepthFormat = sfTexture->getTexture().GetFormat();
                }
            }
        }
        pipelineSamples = mCurrentRenderTarget->getSamples();
    }

    // TODO: We expected this to be a sane check, however it complains when running shadowtest.
    //if (program->fragmentShaderModule != nullptr) {
    //    FILAMENT_CHECK_POSTCONDITION(!pipelineColorFormats.empty())
    //            << "Render pipeline with fragment shader must have at least one color target "
    //               "format.";
    //}
    wgpu::RenderPipeline pipeline = createWebGPURenderPipeline(mDevice, *program, *vertexBufferInfo,
            layout, pipelineState.rasterState, pipelineState.stencilState,
            pipelineState.polygonOffset, pipelineState.primitiveType, pipelineColorFormats,
            pipelineDepthFormat, pipelineSamples);
    assert_invariant(pipeline);
    mPipelineMap[hash] = pipeline;
    mRenderPassEncoder.SetPipeline(pipeline);
}

void WebGPUDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> renderPrimitiveHandle) {
    auto* renderPrimitive = handleCast<WGPURenderPrimitive>(renderPrimitiveHandle);
    auto vertexBufferInfo = handleCast<WGPUVertexBufferInfo>(renderPrimitive->vertexBuffer->vbih);
    for (size_t slotIndex = 0; slotIndex < vertexBufferInfo->getVertexBufferLayoutCount();
            slotIndex++) {
        WGPUVertexBufferInfo::WebGPUSlotBindingInfo const& bindingInfo =
                vertexBufferInfo->getWebGPUSlotBindingInfos()[slotIndex];
        mRenderPassEncoder.SetVertexBuffer(slotIndex,
                renderPrimitive->vertexBuffer->buffers[bindingInfo.sourceBufferIndex],
                bindingInfo.bufferOffset);
    }
    mRenderPassEncoder.SetIndexBuffer(renderPrimitive->indexBuffer->getBuffer(),
            renderPrimitive->indexBuffer->indexFormat);
}

void WebGPUDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
    // We defer actually binding until we actually draw
    for (size_t i = 0; i < MAX_DESCRIPTOR_SET_COUNT; i++) {
        auto& binding = mCurrentDescriptorSets[i];
        if (binding.bindGroup) {
            mRenderPassEncoder.SetBindGroup(i, binding.bindGroup, binding.offsetCount,
                    binding.offsets.data());
        }
    }

    mRenderPassEncoder.DrawIndexed(indexCount, instanceCount, indexOffset, 0, 0);
}

Review comment (suggestion):
Not a huge issue and it existed before, but a bit inconsistent to do auto* for one handleCast, and auto for the other.

Code after:
                // Assuming combined depth/stencil format if only stencil is present
                if (sfTexture) {
                    pipelineDepthFormat = sfTexture->getTexture().GetFormat();
                }
            }
        }
        pipelineSamples = mCurrentRenderTarget->getSamples();
    }

    // TODO: We expected this to be a sane check, however it complains when running shadowtest.
    //if (program->fragmentShaderModule != nullptr) {
    //    FILAMENT_CHECK_POSTCONDITION(!pipelineColorFormats.empty())
    //            << "Render pipeline with fragment shader must have at least one color target "
    //               "format.";
    //}
    wgpu::RenderPipeline pipeline = createWebGPURenderPipeline(mDevice, *program, *vertexBufferInfo,
            layout, pipelineState.rasterState, pipelineState.stencilState,
            pipelineState.polygonOffset, pipelineState.primitiveType, pipelineColorFormats,
            pipelineDepthFormat, pipelineSamples);
    assert_invariant(pipeline);
    mPipelineMap[hash] = pipeline;
    mRenderPassEncoder.SetPipeline(pipeline);
}

void WebGPUDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> renderPrimitiveHandle) {
    const auto renderPrimitive = handleCast<WGPURenderPrimitive>(renderPrimitiveHandle);
    const auto vertexBufferInfo =
            handleCast<WGPUVertexBufferInfo>(renderPrimitive->vertexBuffer->vbih);
    for (size_t slotIndex = 0; slotIndex < vertexBufferInfo->getVertexBufferLayoutCount();
            slotIndex++) {
        WGPUVertexBufferInfo::WebGPUSlotBindingInfo const& bindingInfo =
                vertexBufferInfo->getWebGPUSlotBindingInfos()[slotIndex];
        mRenderPassEncoder.SetVertexBuffer(slotIndex,
                renderPrimitive->vertexBuffer->buffers[bindingInfo.sourceBufferIndex],
                bindingInfo.bufferOffset);
    }
    mRenderPassEncoder.SetIndexBuffer(renderPrimitive->indexBuffer->getBuffer(),
            renderPrimitive->indexBuffer->indexFormat);
}

void WebGPUDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
    // We defer actually binding until we actually draw
    for (size_t i = 0; i < MAX_DESCRIPTOR_SET_COUNT; i++) {
        auto& binding = mCurrentDescriptorSets[i];
        if (binding.bindGroup) {
            mRenderPassEncoder.SetBindGroup(i, binding.bindGroup, binding.offsetCount,
                    binding.offsets.data());
        }
    }

    mRenderPassEncoder.DrawIndexed(indexCount, instanceCount, indexOffset, 0, 0);