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

Code before:
    mSwapChain = swapChain;
    assert_invariant(mSwapChain);
    wgpu::Extent2D surfaceSize = mPlatform.getSurfaceExtent(mNativeWindow);
    mTextureView = mSwapChain->getCurrentSurfaceTextureView(surfaceSize);
    assert_invariant(mTextureView);

    assert_invariant(mDefaultRenderTarget);

    wgpu::TextureFormat depthFormat = mSwapChain->getDepthFormat();
    TargetBufferFlags newTargetFlags = filament::backend::TargetBufferFlags::NONE;

    newTargetFlags = filament::backend::TargetBufferFlags::NONE;

    //Assuming Color and Depth are always present.
    newTargetFlags |= filament::backend::TargetBufferFlags::COLOR;
    if (depthFormat != wgpu::TextureFormat::Undefined) {
        newTargetFlags |= filament::backend::TargetBufferFlags::DEPTH;

        if (depthFormat == wgpu::TextureFormat::Depth24PlusStencil8 ||
                depthFormat == wgpu::TextureFormat::Depth32FloatStencil8) {
            newTargetFlags |= filament::backend::TargetBufferFlags::STENCIL;
        }
    }
    mDefaultRenderTarget->setTargetFlags(newTargetFlags);

    wgpu::CommandEncoderDescriptor commandEncoderDescriptor = { .label = "command_encoder" };
    mCommandEncoder = mDevice.CreateCommandEncoder(&commandEncoderDescriptor);
    assert_invariant(mCommandEncoder);
}

void WebGPUDriver::commit(Handle<HwSwapChain> sch) {
    wgpu::CommandBufferDescriptor commandBufferDescriptor{
        .label = "command_buffer",
    };
    mCommandBuffer = mCommandEncoder.Finish(&commandBufferDescriptor);
    assert_invariant(mCommandBuffer);
    mCommandEncoder = nullptr;
    mQueue.Submit(1, &mCommandBuffer);

    static bool firstRender = true;
    // For the first frame rendered, we need to make sure the work is done before presenting or we
    // get a purple flash
    if (firstRender) {
        auto f = mQueue.OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly,
                [=](wgpu::QueueWorkDoneStatus) {});
        const wgpu::Instance instance = mAdapter.GetInstance();
        auto wStatus = instance.WaitAny(f,
                std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count());
        if (wStatus != wgpu::WaitStatus::Success) {
            FWGPU_LOGW << "Waiting for first frame work to finish resulted in an error"
                       << static_cast<uint32_t>(wStatus);

Review comment (bug):
nit: maybe label it `"frame_command_encoder""` to differentiate it from another encoder, e.g. for mipmap generation or something. Otherwise, the label "command_encoder" doesn't really help us in debugging in any way; we already know it is a command encoder of some kind.

Code after:
            static_cast<float>(params.viewport.bottom),
            static_cast<float>(params.viewport.width),
            static_cast<float>(params.viewport.height),
            params.depthRange.near,
            params.depthRange.far);
}

void WebGPUDriver::endRenderPass(int /* dummy */) {
    mRenderPassEncoder.End();
    mRenderPassEncoder = nullptr;
}

void WebGPUDriver::nextSubpass(int) {
    //todo
}

void WebGPUDriver::makeCurrent(Handle<HwSwapChain> drawSch, Handle<HwSwapChain> readSch) {
    ASSERT_PRECONDITION_NON_FATAL(drawSch == readSch,
            "WebGPU driver does not support distinct draw/read swap chains.");
    auto swapChain = handleCast<WebGPUSwapChain>(drawSch);
    mSwapChain = swapChain;
    assert_invariant(mSwapChain);
    wgpu::Extent2D surfaceSize = mPlatform.getSurfaceExtent(mNativeWindow);
    mTextureView = mSwapChain->getCurrentSurfaceTextureView(surfaceSize);
    assert_invariant(mTextureView);

    assert_invariant(mDefaultRenderTarget);

    wgpu::TextureFormat depthFormat = mSwapChain->getDepthFormat();
    TargetBufferFlags newTargetFlags = filament::backend::TargetBufferFlags::NONE;

    //Assuming Color and Depth are always present.
    newTargetFlags |= filament::backend::TargetBufferFlags::COLOR;
    if (depthFormat != wgpu::TextureFormat::Undefined) {
        newTargetFlags |= filament::backend::TargetBufferFlags::DEPTH;

        if (depthFormat == wgpu::TextureFormat::Depth24PlusStencil8 ||
                depthFormat == wgpu::TextureFormat::Depth32FloatStencil8) {
            newTargetFlags |= filament::backend::TargetBufferFlags::STENCIL;
        }
    }
    mDefaultRenderTarget->setTargetFlags(newTargetFlags);

    wgpu::CommandEncoderDescriptor commandEncoderDescriptor = { .label = "frame_command_encoder" };
    mCommandEncoder = mDevice.CreateCommandEncoder(&commandEncoderDescriptor);
    assert_invariant(mCommandEncoder);
}

void WebGPUDriver::commit(Handle<HwSwapChain> sch) {
    wgpu::CommandBufferDescriptor commandBufferDescriptor{
        .label = "command_buffer",