//
// Copyright 2024 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ContextWgpu.cpp:
//    Implements the class methods for ContextWgpu.
//

#include "libANGLE/renderer/wgpu/ContextWgpu.h"

#include "common/PackedEnums.h"
#include "common/debug.h"

#include "compiler/translator/wgsl/OutputUniformBlocks.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/OverlayImpl.h"
#include "libANGLE/renderer/wgpu/BufferWgpu.h"
#include "libANGLE/renderer/wgpu/CompilerWgpu.h"
#include "libANGLE/renderer/wgpu/DisplayWgpu.h"
#include "libANGLE/renderer/wgpu/FenceNVWgpu.h"
#include "libANGLE/renderer/wgpu/FramebufferWgpu.h"
#include "libANGLE/renderer/wgpu/ImageWgpu.h"
#include "libANGLE/renderer/wgpu/ProgramExecutableWgpu.h"
#include "libANGLE/renderer/wgpu/ProgramPipelineWgpu.h"
#include "libANGLE/renderer/wgpu/ProgramWgpu.h"
#include "libANGLE/renderer/wgpu/QueryWgpu.h"
#include "libANGLE/renderer/wgpu/RenderbufferWgpu.h"
#include "libANGLE/renderer/wgpu/SamplerWgpu.h"
#include "libANGLE/renderer/wgpu/ShaderWgpu.h"
#include "libANGLE/renderer/wgpu/SyncWgpu.h"
#include "libANGLE/renderer/wgpu/TextureWgpu.h"
#include "libANGLE/renderer/wgpu/TransformFeedbackWgpu.h"
#include "libANGLE/renderer/wgpu/VertexArrayWgpu.h"
#include "libANGLE/renderer/wgpu/wgpu_pipeline_state.h"
#include "libANGLE/renderer/wgpu/wgpu_utils.h"

namespace rx
{

namespace
{

constexpr angle::PackedEnumMap<webgpu::RenderPassClosureReason, const char *>
    kRenderPassClosureReason = {{
        {webgpu::RenderPassClosureReason::NewRenderPass,
         "Render pass closed due to starting a new render pass"},
        {webgpu::RenderPassClosureReason::FramebufferBindingChange,
         "Render pass closed due to framebuffer binding change"},
        {webgpu::RenderPassClosureReason::FramebufferInternalChange,
         "Render pass closed due to framebuffer internal change"},
        {webgpu::RenderPassClosureReason::GLFlush, "Render pass closed due to glFlush"},
        {webgpu::RenderPassClosureReason::GLFinish, "Render pass closed due to glFinish"},
        {webgpu::RenderPassClosureReason::EGLSwapBuffers,
         "Render pass closed due to eglSwapBuffers"},
        {webgpu::RenderPassClosureReason::GLReadPixels, "Render pass closed due to glReadPixels"},
        {webgpu::RenderPassClosureReason::IndexRangeReadback,
         "Render pass closed due to index buffer read back for streamed client data"},
        {webgpu::RenderPassClosureReason::VertexArrayStreaming,
         "Render pass closed for uploading streamed client data"},
        {webgpu::RenderPassClosureReason::VertexArrayLineLoop,
         "Render pass closed for line loop emulation"},
    }};

}  // namespace

ContextWgpu::ContextWgpu(const gl::State &state, gl::ErrorSet *errorSet, DisplayWgpu *display)
    : ContextImpl(state, errorSet), mDisplay(display)
{
    mNewRenderPassDirtyBits = DirtyBits{
        DIRTY_BIT_RENDER_PIPELINE_BINDING,  // The pipeline needs to be bound for each renderpass
        DIRTY_BIT_VIEWPORT,
        DIRTY_BIT_SCISSOR,
        DIRTY_BIT_BLEND_CONSTANT,
        DIRTY_BIT_VERTEX_BUFFERS,
        DIRTY_BIT_INDEX_BUFFER,
        DIRTY_BIT_BIND_GROUPS,
    };
}

ContextWgpu::~ContextWgpu() {}

void ContextWgpu::onDestroy(const gl::Context *context)
{
    mImageLoadContext = {};
}

angle::Result ContextWgpu::initialize(const angle::ImageLoadContext &imageLoadContext)
{
    mImageLoadContext = imageLoadContext;

    return angle::Result::Continue;
}

angle::Result ContextWgpu::onFramebufferChange(FramebufferWgpu *framebufferWgpu,
                                               gl::Command command)
{
    // If internal framebuffer state changes, always end the render pass
    ANGLE_TRY(endRenderPass(webgpu::RenderPassClosureReason::FramebufferInternalChange));

    return angle::Result::Continue;
}

angle::Result ContextWgpu::flush(const gl::Context *context)
{
    return flush(webgpu::RenderPassClosureReason::GLFlush);
}

angle::Result ContextWgpu::flush(webgpu::RenderPassClosureReason closureReason)
{
    ANGLE_TRY(endRenderPass(closureReason));

    if (mCurrentCommandEncoder)
    {
        wgpu::CommandBuffer commandBuffer = mCurrentCommandEncoder.Finish();
        mCurrentCommandEncoder            = nullptr;

        getQueue().Submit(1, &commandBuffer);
    }

    return angle::Result::Continue;
}

void ContextWgpu::setColorAttachmentFormat(size_t colorIndex, wgpu::TextureFormat format)
{
    if (mRenderPipelineDesc.setColorAttachmentFormat(colorIndex, format))
    {
        invalidateCurrentRenderPipeline();
    }
}

void ContextWgpu::setColorAttachmentFormats(
    const gl::DrawBuffersArray<wgpu::TextureFormat> &formats)
{
    for (size_t i = 0; i < formats.size(); i++)
    {
        setColorAttachmentFormat(i, formats[i]);
    }
}

void ContextWgpu::setDepthStencilFormat(wgpu::TextureFormat format)
{
    if (mRenderPipelineDesc.setDepthStencilAttachmentFormat(format))
    {
        invalidateCurrentRenderPipeline();
    }
}

void ContextWgpu::setVertexAttribute(size_t attribIndex, webgpu::PackedVertexAttribute newAttrib)
{
    if (mRenderPipelineDesc.setVertexAttribute(attribIndex, newAttrib))
    {
        invalidateCurrentRenderPipeline();
    }
}

void ContextWgpu::invalidateVertexBuffer(size_t slot)
{
    if (mCurrentRenderPipelineAllAttributes[slot])
    {
        mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
        mDirtyVertexBuffers.set(slot);
    }
}

void ContextWgpu::invalidateVertexBuffers()
{
    mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
    mDirtyVertexBuffers = mCurrentRenderPipelineAllAttributes;
}

void ContextWgpu::invalidateIndexBuffer()
{
    mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
}

void ContextWgpu::ensureCommandEncoderCreated()
{
    if (!mCurrentCommandEncoder)
    {
        mCurrentCommandEncoder = getDevice().CreateCommandEncoder(nullptr);
    }
}

wgpu::CommandEncoder &ContextWgpu::getCurrentCommandEncoder()
{
    return mCurrentCommandEncoder;
}

angle::Result ContextWgpu::finish(const gl::Context *context)
{
    ANGLE_TRY(flush(webgpu::RenderPassClosureReason::GLFinish));

    wgpu::Future onWorkSubmittedFuture = getQueue().OnSubmittedWorkDone(
        wgpu::CallbackMode::WaitAnyOnly, [](wgpu::QueueWorkDoneStatus status) {});
    wgpu::WaitStatus status = getInstance().WaitAny(onWorkSubmittedFuture, -1);
    ASSERT(!webgpu::IsWgpuError(status));

    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawArrays(const gl::Context *context,
                                      gl::PrimitiveMode mode,
                                      GLint first,
                                      GLsizei count)
{
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    uint32_t firstIndex = 0;
    uint32_t indexCount = static_cast<uint32_t>(count);
    ANGLE_TRY(setupDraw(context, mode, first, count, 1, gl::DrawElementsType::InvalidEnum, nullptr,
                        0, &firstIndex, &indexCount));
    if (mode == gl::PrimitiveMode::LineLoop)
    {
        mCommandBuffer.drawIndexed(indexCount, 1, firstIndex, 0, 0);
    }
    else
    {
        mCommandBuffer.draw(static_cast<uint32_t>(count), 1, static_cast<uint32_t>(first), 0);
    }
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawArraysInstanced(const gl::Context *context,
                                               gl::PrimitiveMode mode,
                                               GLint first,
                                               GLsizei count,
                                               GLsizei instanceCount)
{
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    uint32_t firstIndex = 0;
    uint32_t indexCount = static_cast<uint32_t>(count);
    ANGLE_TRY(setupDraw(context, mode, first, count, instanceCount,
                        gl::DrawElementsType::InvalidEnum, nullptr, 0, &firstIndex, &indexCount));
    if (mode == gl::PrimitiveMode::LineLoop)
    {
        mCommandBuffer.drawIndexed(indexCount, static_cast<uint32_t>(instanceCount), firstIndex, 0,
                                   0);
    }
    else
    {
        mCommandBuffer.draw(indexCount, static_cast<uint32_t>(instanceCount),
                            static_cast<uint32_t>(first), 0);
    }
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawArraysInstancedBaseInstance(const gl::Context *context,
                                                           gl::PrimitiveMode mode,
                                                           GLint first,
                                                           GLsizei count,
                                                           GLsizei instanceCount,
                                                           GLuint baseInstance)
{
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    uint32_t firstIndex = 0;
    uint32_t indexCount = static_cast<uint32_t>(count);
    ANGLE_TRY(setupDraw(context, mode, first, count, instanceCount,
                        gl::DrawElementsType::InvalidEnum, nullptr, 0, &firstIndex, &indexCount));
    if (mode == gl::PrimitiveMode::LineLoop)
    {
        mCommandBuffer.drawIndexed(indexCount, static_cast<uint32_t>(instanceCount), firstIndex, 0,
                                   baseInstance);
    }
    else
    {
        mCommandBuffer.draw(static_cast<uint32_t>(count), static_cast<uint32_t>(instanceCount),
                            static_cast<uint32_t>(first), baseInstance);
    }
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawElements(const gl::Context *context,
                                        gl::PrimitiveMode mode,
                                        GLsizei count,
                                        gl::DrawElementsType type,
                                        const void *indices)
{
    uint32_t firstVertex = 0;
    uint32_t indexCount  = static_cast<uint32_t>(count);
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    ANGLE_TRY(setupDraw(context, mode, 0, count, 1, type, indices, 0, &firstVertex, &indexCount));
    mCommandBuffer.drawIndexed(indexCount, 1, firstVertex, 0, 0);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawElementsBaseVertex(const gl::Context *context,
                                                  gl::PrimitiveMode mode,
                                                  GLsizei count,
                                                  gl::DrawElementsType type,
                                                  const void *indices,
                                                  GLint baseVertex)
{
    uint32_t firstVertex = 0;
    uint32_t indexCount  = static_cast<uint32_t>(count);
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    ANGLE_TRY(setupDraw(context, mode, 0, count, 1, type, indices, baseVertex, &firstVertex,
                        &indexCount));
    mCommandBuffer.drawIndexed(indexCount, 1, firstVertex, static_cast<uint32_t>(baseVertex), 0);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawElementsInstanced(const gl::Context *context,
                                                 gl::PrimitiveMode mode,
                                                 GLsizei count,
                                                 gl::DrawElementsType type,
                                                 const void *indices,
                                                 GLsizei instances)
{
    uint32_t firstVertex = 0;
    uint32_t indexCount  = static_cast<uint32_t>(count);
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    ANGLE_TRY(
        setupDraw(context, mode, 0, count, instances, type, indices, 0, &firstVertex, &indexCount));
    mCommandBuffer.drawIndexed(indexCount, static_cast<uint32_t>(instances), firstVertex, 0, 0);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawElementsInstancedBaseVertex(const gl::Context *context,
                                                           gl::PrimitiveMode mode,
                                                           GLsizei count,
                                                           gl::DrawElementsType type,
                                                           const void *indices,
                                                           GLsizei instances,
                                                           GLint baseVertex)
{
    uint32_t firstVertex = 0;
    uint32_t indexCount  = static_cast<uint32_t>(count);
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    ANGLE_TRY(setupDraw(context, mode, 0, count, instances, type, indices, baseVertex, &firstVertex,
                        &indexCount));
    mCommandBuffer.drawIndexed(indexCount, static_cast<uint32_t>(instances), firstVertex,
                               static_cast<uint32_t>(baseVertex), 0);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
                                                                       gl::PrimitiveMode mode,
                                                                       GLsizei count,
                                                                       gl::DrawElementsType type,
                                                                       const void *indices,
                                                                       GLsizei instances,
                                                                       GLint baseVertex,
                                                                       GLuint baseInstance)
{
    uint32_t firstVertex = 0;
    uint32_t indexCount  = static_cast<uint32_t>(count);
    if (mode == gl::PrimitiveMode::TriangleFan)
    {
        UNIMPLEMENTED();
        return angle::Result::Continue;
    }

    ANGLE_TRY(setupDraw(context, mode, 0, count, instances, type, indices, baseVertex, &firstVertex,
                        &indexCount));
    mCommandBuffer.drawIndexed(indexCount, static_cast<uint32_t>(instances), firstVertex,
                               static_cast<uint32_t>(baseVertex),
                               static_cast<uint32_t>(baseInstance));
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawRangeElements(const gl::Context *context,
                                             gl::PrimitiveMode mode,
                                             GLuint start,
                                             GLuint end,
                                             GLsizei count,
                                             gl::DrawElementsType type,
                                             const void *indices)
{
    return drawElements(context, mode, count, type, indices);
}

angle::Result ContextWgpu::drawRangeElementsBaseVertex(const gl::Context *context,
                                                       gl::PrimitiveMode mode,
                                                       GLuint start,
                                                       GLuint end,
                                                       GLsizei count,
                                                       gl::DrawElementsType type,
                                                       const void *indices,
                                                       GLint baseVertex)
{
    return drawElementsBaseVertex(context, mode, count, type, indices, baseVertex);
}

angle::Result ContextWgpu::drawArraysIndirect(const gl::Context *context,
                                              gl::PrimitiveMode mode,
                                              const void *indirect)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::drawElementsIndirect(const gl::Context *context,
                                                gl::PrimitiveMode mode,
                                                gl::DrawElementsType type,
                                                const void *indirect)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawArrays(const gl::Context *context,
                                           gl::PrimitiveMode mode,
                                           const GLint *firsts,
                                           const GLsizei *counts,
                                           GLsizei drawcount)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawArraysInstanced(const gl::Context *context,
                                                    gl::PrimitiveMode mode,
                                                    const GLint *firsts,
                                                    const GLsizei *counts,
                                                    const GLsizei *instanceCounts,
                                                    GLsizei drawcount)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawArraysIndirect(const gl::Context *context,
                                                   gl::PrimitiveMode mode,
                                                   const void *indirect,
                                                   GLsizei drawcount,
                                                   GLsizei stride)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawElements(const gl::Context *context,
                                             gl::PrimitiveMode mode,
                                             const GLsizei *counts,
                                             gl::DrawElementsType type,
                                             const GLvoid *const *indices,
                                             GLsizei drawcount)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawElementsInstanced(const gl::Context *context,
                                                      gl::PrimitiveMode mode,
                                                      const GLsizei *counts,
                                                      gl::DrawElementsType type,
                                                      const GLvoid *const *indices,
                                                      const GLsizei *instanceCounts,
                                                      GLsizei drawcount)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawElementsIndirect(const gl::Context *context,
                                                     gl::PrimitiveMode mode,
                                                     gl::DrawElementsType type,
                                                     const void *indirect,
                                                     GLsizei drawcount,
                                                     GLsizei stride)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
                                                                gl::PrimitiveMode mode,
                                                                const GLint *firsts,
                                                                const GLsizei *counts,
                                                                const GLsizei *instanceCounts,
                                                                const GLuint *baseInstances,
                                                                GLsizei drawcount)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

angle::Result ContextWgpu::multiDrawElementsInstancedBaseVertexBaseInstance(
    const gl::Context *context,
    gl::PrimitiveMode mode,
    const GLsizei *counts,
    gl::DrawElementsType type,
    const GLvoid *const *indices,
    const GLsizei *instanceCounts,
    const GLint *baseVertices,
    const GLuint *baseInstances,
    GLsizei drawcount)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

gl::GraphicsResetStatus ContextWgpu::getResetStatus()
{
    return gl::GraphicsResetStatus::NoError;
}

angle::Result ContextWgpu::insertEventMarker(GLsizei length, const char *marker)
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::pushGroupMarker(GLsizei length, const char *marker)
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::popGroupMarker()
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::pushDebugGroup(const gl::Context *context,
                                          GLenum source,
                                          GLuint id,
                                          const std::string &message)
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::popDebugGroup(const gl::Context *context)
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::syncState(const gl::Context *context,
                                     const gl::state::DirtyBits dirtyBits,
                                     const gl::state::DirtyBits bitMask,
                                     const gl::state::ExtendedDirtyBits extendedDirtyBits,
                                     const gl::state::ExtendedDirtyBits extendedBitMask,
                                     gl::Command command)
{
    const gl::State &glState = context->getState();

    for (auto iter = dirtyBits.begin(), endIter = dirtyBits.end(); iter != endIter; ++iter)
    {
        size_t dirtyBit = *iter;
        switch (dirtyBit)
        {
            case gl::state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
            {
                const FramebufferWgpu *framebufferWgpu =
                    webgpu::GetImpl(context->getState().getDrawFramebuffer());
                setColorAttachmentFormats(framebufferWgpu->getCurrentColorAttachmentFormats());
                setDepthStencilFormat(framebufferWgpu->getCurrentDepthStencilAttachmentFormat());

                ANGLE_TRY(endRenderPass(webgpu::RenderPassClosureReason::FramebufferBindingChange));
            }
            break;
            case gl::state::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_SCISSOR_TEST_ENABLED:
                mDirtyBits.set(DIRTY_BIT_SCISSOR);
                break;
            case gl::state::DIRTY_BIT_SCISSOR:
                mDirtyBits.set(DIRTY_BIT_SCISSOR);
                break;
            case gl::state::DIRTY_BIT_VIEWPORT:
                mDirtyBits.set(DIRTY_BIT_VIEWPORT);
                break;
            case gl::state::DIRTY_BIT_DEPTH_RANGE:
                mDirtyBits.set(DIRTY_BIT_VIEWPORT);
                break;
            case gl::state::DIRTY_BIT_BLEND_ENABLED:
            {
                const gl::BlendStateExt &blendStateExt = mState.getBlendStateExt();
                gl::DrawBufferMask enabledMask         = blendStateExt.getEnabledMask();
                for (size_t i = 0; i < blendStateExt.getDrawBufferCount(); i++)
                {
                    if (mRenderPipelineDesc.setBlendEnabled(i, enabledMask.test(i)))
                    {
                        invalidateCurrentRenderPipeline();
                    }
                }
            }
                break;
            case gl::state::DIRTY_BIT_BLEND_COLOR:
                mDirtyBits.set(DIRTY_BIT_BLEND_CONSTANT);
                break;
            case gl::state::DIRTY_BIT_BLEND_FUNCS:
            {
                const gl::BlendStateExt &blendState = mState.getBlendStateExt();
                for (size_t i = 0; i < blendState.getDrawBufferCount(); i++)
                {
                    if (mRenderPipelineDesc.setBlendFuncs(
                            i, gl_wgpu::GetBlendFactor(blendState.getSrcColorIndexed(i)),
                            gl_wgpu::GetBlendFactor(blendState.getDstColorIndexed(i)),
                            gl_wgpu::GetBlendFactor(blendState.getSrcAlphaIndexed(i)),
                            gl_wgpu::GetBlendFactor(blendState.getDstAlphaIndexed(i))))
                    {
                        invalidateCurrentRenderPipeline();
                    }
                }
            }
                break;
            case gl::state::DIRTY_BIT_BLEND_EQUATIONS:
            {
                const gl::BlendStateExt &blendState = mState.getBlendStateExt();
                for (size_t i = 0; i < blendState.getDrawBufferCount(); i++)
                {
                    if (mRenderPipelineDesc.setBlendEquations(
                            i, gl_wgpu::GetBlendEquation(blendState.getEquationColorIndexed(i)),
                            gl_wgpu::GetBlendEquation(blendState.getEquationAlphaIndexed(i))))
                    {
                        invalidateCurrentRenderPipeline();
                    }
                }
            }
                break;
            case gl::state::DIRTY_BIT_COLOR_MASK:
            {
                const gl::BlendStateExt &blendStateExt = mState.getBlendStateExt();
                for (size_t i = 0; i < blendStateExt.getDrawBufferCount(); i++)
                {
                    bool r, g, b, a;
                    blendStateExt.getColorMaskIndexed(i, &r, &g, &b, &a);
                    mRenderPipelineDesc.setColorWriteMask(i, r, g, b, a);
                }
                invalidateCurrentRenderPipeline();
            }
            break;
            case gl::state::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
                break;
            case gl::state::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
                break;
            case gl::state::DIRTY_BIT_SAMPLE_COVERAGE:
                break;
            case gl::state::DIRTY_BIT_SAMPLE_MASK_ENABLED:
                break;
            case gl::state::DIRTY_BIT_SAMPLE_MASK:
                break;
            case gl::state::DIRTY_BIT_DEPTH_TEST_ENABLED:
                // Enabled and func get combined into one state in WebGPU. Only sync it once.
                iter.setLaterBit(gl::state::DIRTY_BIT_DEPTH_FUNC);
                break;
            case gl::state::DIRTY_BIT_DEPTH_FUNC:
                if (mRenderPipelineDesc.setDepthFunc(
                        gl_wgpu::GetCompareFunc(glState.getDepthStencilState().depthFunc,
                                                glState.getDepthStencilState().depthTest)))
                {
                    invalidateCurrentRenderPipeline();
                }
                break;
            case gl::state::DIRTY_BIT_DEPTH_MASK:
                break;
            case gl::state::DIRTY_BIT_STENCIL_TEST_ENABLED:
                // Changing the state of stencil test affects both the front and back funcs.
                iter.setLaterBit(gl::state::DIRTY_BIT_STENCIL_FUNCS_FRONT);
                iter.setLaterBit(gl::state::DIRTY_BIT_STENCIL_FUNCS_BACK);
                break;
            case gl::state::DIRTY_BIT_STENCIL_FUNCS_FRONT:
                if (mRenderPipelineDesc.setStencilFrontFunc(
                        gl_wgpu::GetCompareFunc(glState.getDepthStencilState().stencilFunc,
                                                glState.getDepthStencilState().stencilTest)))
                {
                    invalidateCurrentRenderPipeline();
                }
                break;
            case gl::state::DIRTY_BIT_STENCIL_FUNCS_BACK:
                if (mRenderPipelineDesc.setStencilBackFunc(
                        gl_wgpu::GetCompareFunc(glState.getDepthStencilState().stencilBackFunc,
                                                glState.getDepthStencilState().stencilTest)))
                {
                    invalidateCurrentRenderPipeline();
                }
                break;
            case gl::state::DIRTY_BIT_STENCIL_OPS_FRONT:
            {
                wgpu::StencilOperation failOp =
                    gl_wgpu::getStencilOp(glState.getDepthStencilState().stencilFail);
                wgpu::StencilOperation depthFailOp =
                    gl_wgpu::getStencilOp(glState.getDepthStencilState().stencilPassDepthFail);
                wgpu::StencilOperation passOp =
                    gl_wgpu::getStencilOp(glState.getDepthStencilState().stencilPassDepthPass);
                if (mRenderPipelineDesc.setStencilFrontOps(failOp, depthFailOp, passOp))
                {
                    invalidateCurrentRenderPipeline();
                }
            }
            break;
            case gl::state::DIRTY_BIT_STENCIL_OPS_BACK:
            {
                wgpu::StencilOperation failOp =
                    gl_wgpu::getStencilOp(glState.getDepthStencilState().stencilBackFail);
                wgpu::StencilOperation depthFailOp =
                    gl_wgpu::getStencilOp(glState.getDepthStencilState().stencilBackPassDepthFail);
                wgpu::StencilOperation passOp =
                    gl_wgpu::getStencilOp(glState.getDepthStencilState().stencilBackPassDepthPass);
                if (mRenderPipelineDesc.setStencilBackOps(failOp, depthFailOp, passOp))
                {
                    invalidateCurrentRenderPipeline();
                }
            }
            break;
            case gl::state::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
                if (mRenderPipelineDesc.setStencilWriteMask(
                        glState.getDepthStencilState().stencilWritemask))
                {
                    invalidateCurrentRenderPipeline();
                }
                break;
            case gl::state::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
                break;
            case gl::state::DIRTY_BIT_CULL_FACE_ENABLED:
            case gl::state::DIRTY_BIT_CULL_FACE:
                mRenderPipelineDesc.setCullMode(glState.getRasterizerState().cullMode,
                                                glState.getRasterizerState().cullFace);
                invalidateCurrentRenderPipeline();
                break;
            case gl::state::DIRTY_BIT_FRONT_FACE:
                mRenderPipelineDesc.setFrontFace(glState.getRasterizerState().frontFace);
                invalidateCurrentRenderPipeline();
                break;
            case gl::state::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
                break;
            case gl::state::DIRTY_BIT_POLYGON_OFFSET:
                break;
            case gl::state::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
                break;
            case gl::state::DIRTY_BIT_LINE_WIDTH:
                break;
            case gl::state::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
                break;
            case gl::state::DIRTY_BIT_CLEAR_COLOR:
                break;
            case gl::state::DIRTY_BIT_CLEAR_DEPTH:
                break;
            case gl::state::DIRTY_BIT_CLEAR_STENCIL:
                break;
            case gl::state::DIRTY_BIT_UNPACK_STATE:
                break;
            case gl::state::DIRTY_BIT_UNPACK_BUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_PACK_STATE:
                break;
            case gl::state::DIRTY_BIT_PACK_BUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_DITHER_ENABLED:
                break;
            case gl::state::DIRTY_BIT_RENDERBUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING:
                invalidateCurrentRenderPipeline();
                break;
            case gl::state::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_PROGRAM_BINDING:
            case gl::state::DIRTY_BIT_PROGRAM_EXECUTABLE:
                invalidateCurrentRenderPipeline();
                break;
            case gl::state::DIRTY_BIT_SAMPLER_BINDINGS:
                break;
            case gl::state::DIRTY_BIT_TEXTURE_BINDINGS:
                break;
            case gl::state::DIRTY_BIT_IMAGE_BINDINGS:
                break;
            case gl::state::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
                break;
            case gl::state::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
                break;
            case gl::state::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
                break;
            case gl::state::DIRTY_BIT_MULTISAMPLING:
                break;
            case gl::state::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
                break;
            case gl::state::DIRTY_BIT_COVERAGE_MODULATION:
                break;
            case gl::state::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE:
                break;
            case gl::state::DIRTY_BIT_CURRENT_VALUES:
                break;
            case gl::state::DIRTY_BIT_PROVOKING_VERTEX:
                break;
            case gl::state::DIRTY_BIT_SAMPLE_SHADING:
                break;
            case gl::state::DIRTY_BIT_PATCH_VERTICES:
                break;
            case gl::state::DIRTY_BIT_EXTENDED:
            {
                for (auto extendedIter    = extendedDirtyBits.begin(),
                          extendedEndIter = extendedDirtyBits.end();
                     extendedIter != extendedEndIter; ++extendedIter)
                {
                    const size_t extendedDirtyBit = *extendedIter;
                    switch (extendedDirtyBit)
                    {
                        case gl::state::EXTENDED_DIRTY_BIT_CLIP_CONTROL:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_CLIP_DISTANCES:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_POLYGON_MODE:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_POINT_ENABLED:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_LINE_ENABLED:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_SHADING_RATE:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_LOGIC_OP:
                            break;
                        case gl::state::EXTENDED_DIRTY_BIT_BLEND_ADVANCED_COHERENT:
                            break;
                        default:
                            UNREACHABLE();
                    }
                }
            }
            break;

            default:
                UNREACHABLE();
                break;
        }
    }

    return angle::Result::Continue;
}

GLint ContextWgpu::getGPUDisjoint()
{
    return 0;
}

GLint64 ContextWgpu::getTimestamp()
{
    return 0;
}

angle::Result ContextWgpu::onMakeCurrent(const gl::Context *context)
{
    return angle::Result::Continue;
}

gl::Caps ContextWgpu::getNativeCaps() const
{
    return mDisplay->getGLCaps();
}

const gl::TextureCapsMap &ContextWgpu::getNativeTextureCaps() const
{
    return mDisplay->getGLTextureCaps();
}

const gl::Extensions &ContextWgpu::getNativeExtensions() const
{
    return mDisplay->getGLExtensions();
}

const gl::Limitations &ContextWgpu::getNativeLimitations() const
{
    return mDisplay->getGLLimitations();
}

const ShPixelLocalStorageOptions &ContextWgpu::getNativePixelLocalStorageOptions() const
{
    return mDisplay->getPLSOptions();
}

CompilerImpl *ContextWgpu::createCompiler()
{
    return new CompilerWgpu();
}

ShaderImpl *ContextWgpu::createShader(const gl::ShaderState &data)
{
    return new ShaderWgpu(data);
}

ProgramImpl *ContextWgpu::createProgram(const gl::ProgramState &data)
{
    return new ProgramWgpu(data);
}

ProgramExecutableImpl *ContextWgpu::createProgramExecutable(const gl::ProgramExecutable *executable)
{
    return new ProgramExecutableWgpu(executable);
}

FramebufferImpl *ContextWgpu::createFramebuffer(const gl::FramebufferState &data)
{
    return new FramebufferWgpu(data);
}

TextureImpl *ContextWgpu::createTexture(const gl::TextureState &state)
{
    return new TextureWgpu(state);
}

RenderbufferImpl *ContextWgpu::createRenderbuffer(const gl::RenderbufferState &state)
{
    return new RenderbufferWgpu(state);
}

BufferImpl *ContextWgpu::createBuffer(const gl::BufferState &state)
{
    return new BufferWgpu(state);
}

VertexArrayImpl *ContextWgpu::createVertexArray(const gl::VertexArrayState &data)
{
    return new VertexArrayWgpu(data);
}

QueryImpl *ContextWgpu::createQuery(gl::QueryType type)
{
    return new QueryWgpu(type);
}

FenceNVImpl *ContextWgpu::createFenceNV()
{
    return new FenceNVWgpu();
}

SyncImpl *ContextWgpu::createSync()
{
    return new SyncWgpu();
}

TransformFeedbackImpl *ContextWgpu::createTransformFeedback(const gl::TransformFeedbackState &state)
{
    return new TransformFeedbackWgpu(state);
}

SamplerImpl *ContextWgpu::createSampler(const gl::SamplerState &state)
{
    return new SamplerWgpu(state);
}

ProgramPipelineImpl *ContextWgpu::createProgramPipeline(const gl::ProgramPipelineState &state)
{
    return new ProgramPipelineWgpu(state);
}

MemoryObjectImpl *ContextWgpu::createMemoryObject()
{
    UNREACHABLE();
    return nullptr;
}

SemaphoreImpl *ContextWgpu::createSemaphore()
{
    UNREACHABLE();
    return nullptr;
}

OverlayImpl *ContextWgpu::createOverlay(const gl::OverlayState &state)
{
    return new OverlayImpl(state);
}

angle::Result ContextWgpu::dispatchCompute(const gl::Context *context,
                                           GLuint numGroupsX,
                                           GLuint numGroupsY,
                                           GLuint numGroupsZ)
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::memoryBarrier(const gl::Context *context, GLbitfield barriers)
{
    return angle::Result::Continue;
}

angle::Result ContextWgpu::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
{
    return angle::Result::Continue;
}

void ContextWgpu::handleError(GLenum errorCode,
                              const char *message,
                              const char *file,
                              const char *function,
                              unsigned int line)
{
    std::stringstream errorStream;
    errorStream << "Internal Wgpu back-end error: " << message << ".";
    mErrors->handleError(errorCode, errorStream.str().c_str(), file, function, line);
}

angle::Result ContextWgpu::startRenderPass(const wgpu::RenderPassDescriptor &desc)
{
    ensureCommandEncoderCreated();

    mCurrentRenderPass = mCurrentCommandEncoder.BeginRenderPass(&desc);
    mDirtyBits |= mNewRenderPassDirtyBits;

    return angle::Result::Continue;
}

angle::Result ContextWgpu::endRenderPass(webgpu::RenderPassClosureReason closureReason)
{
    if (mCurrentRenderPass)
    {
        const char *reasonText = kRenderPassClosureReason[closureReason];
        ASSERT(reasonText);

        if (mCommandBuffer.hasCommands())
        {
            ANGLE_WGPU_SCOPED_DEBUG_TRY(this, mCommandBuffer.recordCommands(mCurrentRenderPass));
            mCommandBuffer.clear();
        }

        mCurrentRenderPass.End();
        mCurrentRenderPass = nullptr;
    }

    mDirtyBits.set(DIRTY_BIT_RENDER_PASS);

    return angle::Result::Continue;
}

angle::Result ContextWgpu::setupDraw(const gl::Context *context,
                                     gl::PrimitiveMode mode,
                                     GLint firstVertexOrInvalid,
                                     GLsizei vertexOrIndexCount,
                                     GLsizei instanceCount,
                                     gl::DrawElementsType indexTypeOrInvalid,
                                     const void *indices,
                                     GLint baseVertex,
                                     uint32_t *outFirstIndex,
                                     uint32_t *indexCountOut)
{
    gl::DrawElementsType dstDndexTypeOrInvalid = indexTypeOrInvalid;
    if (mode == gl::PrimitiveMode::LineLoop &&
        dstDndexTypeOrInvalid == gl::DrawElementsType::InvalidEnum)
    {
        if (vertexOrIndexCount >= std::numeric_limits<unsigned short>::max())
        {
            dstDndexTypeOrInvalid = gl::DrawElementsType::UnsignedInt;
        }
        else
        {
            dstDndexTypeOrInvalid = gl::DrawElementsType::UnsignedShort;
        }
    }

    if (mRenderPipelineDesc.setPrimitiveMode(mode, dstDndexTypeOrInvalid))
    {
        invalidateCurrentRenderPipeline();
    }

    ProgramExecutableWgpu *executableWgpu = webgpu::GetImpl(mState.getProgramExecutable());
    if (executableWgpu->checkDirtyUniforms())
    {
        mDirtyBits.set(DIRTY_BIT_BIND_GROUPS);
    }

    const void *adjustedIndicesPtr = indices;
    if (mState.areClientArraysEnabled())
    {
        VertexArrayWgpu *vertexArrayWgpu = GetImplAs<VertexArrayWgpu>(mState.getVertexArray());
        // Pass in original indexTypeOrInvalid into syncClientArrays because the method will need to
        // determine if the original draw call was a DrawElements or DrawArrays call.
        ANGLE_TRY(vertexArrayWgpu->syncClientArrays(
            context, mState.getProgramExecutable()->getActiveAttribLocationsMask(), mode,
            firstVertexOrInvalid, vertexOrIndexCount, instanceCount, indexTypeOrInvalid, indices,
            baseVertex, mState.isPrimitiveRestartEnabled(), &adjustedIndicesPtr, indexCountOut));
    }

    bool reAddDirtyIndexBufferBit = false;
    if (dstDndexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
    {
        *outFirstIndex =
            gl_wgpu::GetFirstIndexForDrawCall(dstDndexTypeOrInvalid, adjustedIndicesPtr);
        if (mCurrentIndexBufferType != dstDndexTypeOrInvalid)
        {
            invalidateIndexBuffer();
        }
    }

    if (mDirtyBits.any())
    {
        for (DirtyBits::Iterator dirtyBitIter = mDirtyBits.begin();
             dirtyBitIter != mDirtyBits.end(); ++dirtyBitIter)
        {
            size_t dirtyBit = *dirtyBitIter;
            switch (dirtyBit)
            {
                case DIRTY_BIT_RENDER_PIPELINE_DESC:
                    ANGLE_TRY(handleDirtyRenderPipelineDesc(&dirtyBitIter));
                    break;

                case DIRTY_BIT_RENDER_PASS:
                    ANGLE_TRY(handleDirtyRenderPass(&dirtyBitIter));
                    break;

                case DIRTY_BIT_RENDER_PIPELINE_BINDING:
                    ANGLE_TRY(handleDirtyRenderPipelineBinding(&dirtyBitIter));
                    break;

                case DIRTY_BIT_VIEWPORT:
                    ANGLE_TRY(handleDirtyViewport(&dirtyBitIter));
                    break;

                case DIRTY_BIT_SCISSOR:
                    ANGLE_TRY(handleDirtyScissor(&dirtyBitIter));
                    break;

                case DIRTY_BIT_BLEND_CONSTANT:
                    ANGLE_TRY(handleDirtyBlendConstant(&dirtyBitIter));
                    break;

                case DIRTY_BIT_VERTEX_BUFFERS:
                    ANGLE_TRY(handleDirtyVertexBuffers(mDirtyVertexBuffers, &dirtyBitIter));
                    mDirtyVertexBuffers.reset();
                    break;

                case DIRTY_BIT_INDEX_BUFFER:
                    if (dstDndexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
                    {
                        ANGLE_TRY(handleDirtyIndexBuffer(dstDndexTypeOrInvalid, &dirtyBitIter));
                    }
                    else
                    {
                        // If this is not an indexed draw call, don't sync the index buffer. Save it
                        // for a future indexed draw call when we know what index type to use
                        reAddDirtyIndexBufferBit = true;
                    }
                    break;
                case DIRTY_BIT_BIND_GROUPS:
                    ANGLE_TRY(handleDirtyBindGroups(&dirtyBitIter));
                    break;
                default:
                    UNREACHABLE();
                    break;
            }
        }

        if (reAddDirtyIndexBufferBit)
        {
            // Re-add the index buffer dirty bit for a future indexed draw call.
            mDirtyBits.reset(DIRTY_BIT_INDEX_BUFFER);
        }

        mDirtyBits.reset();
    }

    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyRenderPipelineDesc(DirtyBits::Iterator *dirtyBitsIterator)
{
    ASSERT(mState.getProgramExecutable() != nullptr);
    ProgramExecutableWgpu *executable = webgpu::GetImpl(mState.getProgramExecutable());
    ASSERT(executable);

    wgpu::RenderPipeline previousPipeline = std::move(mCurrentGraphicsPipeline);
    ANGLE_TRY(executable->getRenderPipeline(this, mRenderPipelineDesc, &mCurrentGraphicsPipeline));
    if (mCurrentGraphicsPipeline != previousPipeline)
    {
        dirtyBitsIterator->setLaterBit(DIRTY_BIT_RENDER_PIPELINE_BINDING);
    }
    mCurrentRenderPipelineAllAttributes =
        executable->getExecutable()->getActiveAttribLocationsMask();

    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyRenderPipelineBinding(DirtyBits::Iterator *dirtyBitsIterator)
{
    ASSERT(mCurrentGraphicsPipeline);
    mCommandBuffer.setPipeline(mCurrentGraphicsPipeline);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyViewport(DirtyBits::Iterator *dirtyBitsIterator)
{
    const gl::Framebuffer *framebuffer = mState.getDrawFramebuffer();
    const gl::Extents &framebufferSize = framebuffer->getExtents();
    const gl::Rectangle framebufferRect(0, 0, framebufferSize.width, framebufferSize.height);

    gl::Rectangle clampedViewport;
    if (!ClipRectangle(mState.getViewport(), framebufferRect, &clampedViewport))
    {
        clampedViewport = gl::Rectangle(0, 0, 1, 1);
    }

    float depthMin = mState.getNearPlane();
    float depthMax = mState.getFarPlane();

    // This clamping should be done by the front end. WebGPU requires values in this range.
    ASSERT(depthMin >= 0 && depthMin <= 1);
    ASSERT(depthMin >= 0 && depthMin <= 1);

    // WebGPU requires that the maxDepth is at least minDepth. WebGL requires the same but core GL
    // ES does not.
    if (depthMin > depthMax)
    {
        UNIMPLEMENTED();
    }

    bool isDefaultViewport = (clampedViewport == framebufferRect) && depthMin == 0 && depthMax == 1;
    if (isDefaultViewport && !mCommandBuffer.hasSetViewportCommand())
    {
        // Each render pass has a default viewport set equal to the size of the render targets. We
        // can skip setting the viewport.
        return angle::Result::Continue;
    }

    ASSERT(mCurrentGraphicsPipeline);
    mCommandBuffer.setViewport(clampedViewport.x, clampedViewport.y, clampedViewport.width,
                               clampedViewport.height, depthMin, depthMax);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyScissor(DirtyBits::Iterator *dirtyBitsIterator)
{
    const gl::Framebuffer *framebuffer = mState.getDrawFramebuffer();
    const gl::Extents &framebufferSize = framebuffer->getExtents();
    const gl::Rectangle framebufferRect(0, 0, framebufferSize.width, framebufferSize.height);

    gl::Rectangle clampedScissor = framebufferRect;

    // When the GL scissor test is disabled, set the scissor to the entire size of the framebuffer
    if (mState.isScissorTestEnabled())
    {
        if (!ClipRectangle(mState.getScissor(), framebufferRect, &clampedScissor))
        {
            clampedScissor = gl::Rectangle(0, 0, 0, 0);
        }
    }

    bool isDefaultScissor = clampedScissor == framebufferRect;
    if (isDefaultScissor && !mCommandBuffer.hasSetScissorCommand())
    {
        // Each render pass has a default scissor set equal to the size of the render targets. We
        // can skip setting the scissor.
        return angle::Result::Continue;
    }

    ASSERT(mCurrentGraphicsPipeline);
    mCommandBuffer.setScissorRect(clampedScissor.x, clampedScissor.y, clampedScissor.width,
                                  clampedScissor.height);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyBlendConstant(DirtyBits::Iterator *dirtyBitsIterator)
{
    const gl::ColorF &blendColor = mState.getBlendColor();

    bool isDefaultBlendConstant = blendColor.red == 0 && blendColor.green == 0 &&
                                  blendColor.blue == 0 && blendColor.alpha == 0;
    if (isDefaultBlendConstant && !mCommandBuffer.hasSetBlendConstantCommand())
    {
        // Each render pass has a default blend constant set to all zeroes. We can skip setting it.
        return angle::Result::Continue;
    }

    ASSERT(mCurrentGraphicsPipeline);
    mCommandBuffer.setBlendConstant(blendColor.red, blendColor.green, blendColor.blue,
                                    blendColor.alpha);
    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyRenderPass(DirtyBits::Iterator *dirtyBitsIterator)
{
    FramebufferWgpu *drawFramebufferWgpu = webgpu::GetImpl(mState.getDrawFramebuffer());
    ANGLE_TRY(drawFramebufferWgpu->startNewRenderPass(this));
    dirtyBitsIterator->setLaterBits(mNewRenderPassDirtyBits);
    mDirtyVertexBuffers = mCurrentRenderPipelineAllAttributes;
    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyVertexBuffers(const gl::AttributesMask &slots,
                                                    DirtyBits::Iterator *dirtyBitsIterator)
{
    VertexArrayWgpu *vertexArrayWgpu = GetImplAs<VertexArrayWgpu>(mState.getVertexArray());
    for (size_t slot : slots)
    {
        const VertexBufferWithOffset &buffer = vertexArrayWgpu->getVertexBuffer(slot);
        if (!buffer.buffer)
        {
            // Missing default attribute support
            ASSERT(!mState.getVertexArray()->getVertexAttribute(slot).enabled);
            UNIMPLEMENTED();
            continue;
        }
        if (buffer.buffer->getMappedState())
        {
            ANGLE_TRY(buffer.buffer->unmap());
        }
        mCommandBuffer.setVertexBuffer(static_cast<uint32_t>(slot), buffer.buffer->getBuffer(),
                                       buffer.offset, WGPU_WHOLE_SIZE);
    }
    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyIndexBuffer(gl::DrawElementsType indexType,
                                                  DirtyBits::Iterator *dirtyBitsIterator)
{
    VertexArrayWgpu *vertexArrayWgpu = GetImplAs<VertexArrayWgpu>(mState.getVertexArray());
    webgpu::BufferHelper *buffer     = vertexArrayWgpu->getIndexBuffer();
    ASSERT(buffer);
    if (buffer->getMappedState())
    {
        ANGLE_TRY(buffer->unmap());
    }
    mCommandBuffer.setIndexBuffer(buffer->getBuffer(), gl_wgpu::GetIndexFormat(indexType), 0, -1);
    mCurrentIndexBufferType = indexType;
    return angle::Result::Continue;
}

angle::Result ContextWgpu::handleDirtyBindGroups(DirtyBits::Iterator *dirtyBitsIterator)
{
    ProgramExecutableWgpu *executableWgpu = webgpu::GetImpl(mState.getProgramExecutable());
    wgpu::BindGroup bindGroup;
    ANGLE_TRY(executableWgpu->updateUniformsAndGetBindGroup(this, &bindGroup));
    // TODO(anglebug.com/376553328): need to set up every bind group here.
    mCommandBuffer.setBindGroup(sh::kDefaultUniformBlockBindGroup, bindGroup);

    return angle::Result::Continue;
}

}  // namespace rx
