//
// 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.
//

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

#include "common/log_utils.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/wgpu/ContextWgpu.h"
#include "libANGLE/renderer/wgpu/DisplayWgpu.h"
#include "libANGLE/renderer/wgpu/wgpu_pipeline_state.h"
#include "webgpu/webgpu.h"

namespace rx
{

namespace webgpu
{
DisplayWgpu *GetDisplay(const gl::Context *context)
{
    ContextWgpu *contextWgpu = GetImpl(context);
    return contextWgpu->getDisplay();
}

const DawnProcTable *GetProcs(const gl::Context *context)
{
    DisplayWgpu *display = GetDisplay(context);
    return display->getProcs();
}

const DawnProcTable *GetProcs(const ContextWgpu *context)
{
    DisplayWgpu *display = context->getDisplay();
    return display->getProcs();
}

const angle::FeaturesWgpu &GetFeatures(const gl::Context *context)
{
    DisplayWgpu *display = GetDisplay(context);
    return display->getFeatures();
}

const angle::FeaturesWgpu &GetFeatures(const ContextWgpu *context)
{
    DisplayWgpu *display = context->getDisplay();
    return display->getFeatures();
}

webgpu::DeviceHandle GetDevice(const gl::Context *context)
{
    DisplayWgpu *display = GetDisplay(context);
    return display->getDevice();
}

webgpu::InstanceHandle GetInstance(const gl::Context *context)
{
    DisplayWgpu *display = GetDisplay(context);
    return display->getInstance();
}

PackedRenderPassColorAttachment CreateNewClearColorAttachment(const gl::ColorF &clearValue,
                                                              uint32_t depthSlice,
                                                              TextureViewHandle textureView)
{
    PackedRenderPassColorAttachment colorAttachment;
    colorAttachment.view       = textureView;
    colorAttachment.depthSlice = depthSlice;
    colorAttachment.loadOp     = WGPULoadOp_Clear;
    colorAttachment.storeOp    = WGPUStoreOp_Store;
    colorAttachment.clearValue = clearValue;

    return colorAttachment;
}

PackedRenderPassDepthStencilAttachment CreateNewClearDepthStencilAttachment(
    float depthClearValue,
    uint32_t stencilClearValue,
    TextureViewHandle textureView,
    bool hasDepthValue,
    bool hasStencilValue)
{
    PackedRenderPassDepthStencilAttachment depthStencilAttachment;
    depthStencilAttachment.view = textureView;
    // WebGPU requires that depth/stencil attachments have a load op if the correlated ReadOnly
    // value is set to false, so we make sure to set the value here to to support cases where only a
    // depth or stencil mask is set.
    depthStencilAttachment.depthReadOnly   = !hasDepthValue;
    depthStencilAttachment.stencilReadOnly = !hasStencilValue;
    if (hasDepthValue)
    {
        depthStencilAttachment.depthLoadOp     = WGPULoadOp_Clear;
        depthStencilAttachment.depthStoreOp    = WGPUStoreOp_Store;
        depthStencilAttachment.depthClearValue = depthClearValue;
    }
    if (hasStencilValue)
    {
        depthStencilAttachment.stencilLoadOp     = WGPULoadOp_Clear;
        depthStencilAttachment.stencilStoreOp    = WGPUStoreOp_Store;
        depthStencilAttachment.stencilClearValue = stencilClearValue;
    }

    return depthStencilAttachment;
}

PackedRenderPassDepthStencilAttachment
CreateNewDepthStencilAttachment(TextureViewHandle textureView, bool hasDepth, bool hasStencilValue)
{
    PackedRenderPassDepthStencilAttachment depthStencilAttachment;
    depthStencilAttachment.view = textureView;
    // WebGPU requires that depth/stencil attachments have a load op if the correlated ReadOnly
    // value is set to false, so we make sure to set the value here to to support cases where only a
    // depth or stencil mask is set.
    depthStencilAttachment.depthReadOnly   = !hasDepth;
    depthStencilAttachment.stencilReadOnly = !hasStencilValue;
    if (hasDepth)
    {
        depthStencilAttachment.depthLoadOp  = WGPULoadOp_Load;
        depthStencilAttachment.depthStoreOp = WGPUStoreOp_Store;
    }
    if (hasStencilValue)
    {
        depthStencilAttachment.stencilLoadOp  = WGPULoadOp_Load;
        depthStencilAttachment.stencilStoreOp = WGPUStoreOp_Store;
    }

    return depthStencilAttachment;
}

bool IsWgpuError(WGPUWaitStatus waitStatus)
{
    return waitStatus != WGPUWaitStatus_Success;
}

bool IsWgpuError(WGPUMapAsyncStatus mapAsyncStatus)
{
    return mapAsyncStatus != WGPUMapAsyncStatus_Success;
}

ClearValuesArray::ClearValuesArray() : mValues{}, mEnabled{} {}
ClearValuesArray::~ClearValuesArray() = default;

ClearValuesArray::ClearValuesArray(const ClearValuesArray &other)          = default;
ClearValuesArray &ClearValuesArray::operator=(const ClearValuesArray &rhs) = default;

void ClearValuesArray::store(uint32_t index, const ClearValues &clearValues)
{
    mValues[index] = clearValues;
    mEnabled.set(index);
}

gl::DrawBufferMask ClearValuesArray::getColorMask() const
{
    return gl::DrawBufferMask(mEnabled.bits() & kUnpackedColorBuffersMask);
}

bool operator==(const PackedRenderPassColorAttachment &a, const PackedRenderPassColorAttachment &b)
{
    return std::tie(a.view, a.depthSlice, a.loadOp, a.storeOp, a.clearValue) ==
           std::tie(b.view, b.depthSlice, b.loadOp, b.storeOp, b.clearValue);
}

bool operator==(const PackedRenderPassDepthStencilAttachment &a,
                const PackedRenderPassDepthStencilAttachment &b)
{
    return std::tie(a.view, a.depthLoadOp, a.depthStoreOp, a.depthReadOnly, a.depthClearValue,
                    a.stencilLoadOp, a.stencilStoreOp, a.stencilReadOnly, a.stencilClearValue) ==
           std::tie(b.view, b.depthLoadOp, b.depthStoreOp, b.depthReadOnly, b.depthClearValue,
                    b.stencilLoadOp, b.stencilStoreOp, b.stencilReadOnly, b.stencilClearValue);
}

bool operator==(const PackedRenderPassDescriptor &a, const PackedRenderPassDescriptor &b)
{
    return std::tie(a.colorAttachments, a.depthStencilAttachment) ==
           std::tie(b.colorAttachments, b.depthStencilAttachment);
}

bool operator!=(const PackedRenderPassDescriptor &a, const PackedRenderPassDescriptor &b)
{
    return !(a == b);
}

RenderPassEncoderHandle CreateRenderPass(const DawnProcTable *wgpu,
                                         webgpu::CommandEncoderHandle commandEncoder,
                                         const webgpu::PackedRenderPassDescriptor &packedDesc)
{
    WGPURenderPassDescriptor renderPassDesc = WGPU_RENDER_PASS_DESCRIPTOR_INIT;

    angle::FixedVector<WGPURenderPassColorAttachment, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>
        colorAttachments;
    for (size_t i = 0; i < packedDesc.colorAttachments.size(); i++)
    {
        const webgpu::PackedRenderPassColorAttachment &packedColorAttachment =
            packedDesc.colorAttachments[i];
        WGPURenderPassColorAttachment colorAttachment = WGPU_RENDER_PASS_COLOR_ATTACHMENT_INIT;

        colorAttachment.view          = packedColorAttachment.view.get();
        colorAttachment.depthSlice    = packedColorAttachment.depthSlice;
        colorAttachment.resolveTarget = nullptr;
        colorAttachment.loadOp        = packedColorAttachment.loadOp;
        colorAttachment.storeOp       = packedColorAttachment.storeOp;
        colorAttachment.clearValue    = {
            packedColorAttachment.clearValue.red, packedColorAttachment.clearValue.green,
            packedColorAttachment.clearValue.blue, packedColorAttachment.clearValue.alpha};

        colorAttachments.push_back(colorAttachment);
    }
    renderPassDesc.colorAttachments     = colorAttachments.data();
    renderPassDesc.colorAttachmentCount = colorAttachments.size();

    WGPURenderPassDepthStencilAttachment depthStencilAttachment =
        WGPU_RENDER_PASS_DEPTH_STENCIL_ATTACHMENT_INIT;
    if (packedDesc.depthStencilAttachment.has_value())
    {
        const webgpu::PackedRenderPassDepthStencilAttachment &packedDepthStencilAttachment =
            packedDesc.depthStencilAttachment.value();

        depthStencilAttachment.view              = packedDepthStencilAttachment.view.get();
        depthStencilAttachment.depthLoadOp       = packedDepthStencilAttachment.depthLoadOp;
        depthStencilAttachment.depthStoreOp      = packedDepthStencilAttachment.depthStoreOp;
        depthStencilAttachment.depthReadOnly     = packedDepthStencilAttachment.depthReadOnly;
        depthStencilAttachment.depthClearValue   = packedDepthStencilAttachment.depthClearValue;
        depthStencilAttachment.stencilLoadOp     = packedDepthStencilAttachment.stencilLoadOp;
        depthStencilAttachment.stencilStoreOp    = packedDepthStencilAttachment.stencilStoreOp;
        depthStencilAttachment.stencilReadOnly   = packedDepthStencilAttachment.stencilReadOnly;
        depthStencilAttachment.stencilClearValue = packedDepthStencilAttachment.stencilClearValue;

        renderPassDesc.depthStencilAttachment = &depthStencilAttachment;
    }

    return RenderPassEncoderHandle::Acquire(
        wgpu, wgpu->commandEncoderBeginRenderPass(commandEncoder.get(), &renderPassDesc));
}

void GenerateCaps(const WGPULimits &limitsWgpu,
                  gl::Caps *glCaps,
                  gl::TextureCapsMap *glTextureCapsMap,
                  gl::Extensions *glExtensions,
                  gl::Limitations *glLimitations,
                  egl::Caps *eglCaps,
                  egl::DisplayExtensions *eglExtensions,
                  gl::Version *maxSupportedESVersion)
{
    // WebGPU does not support separate front/back stencil masks.
    glLimitations->noSeparateStencilRefsAndMasks = true;

    // OpenGL ES extensions
    glExtensions->debugMarkerEXT              = true;
    glExtensions->textureUsageANGLE           = true;
    glExtensions->translatedShaderSourceANGLE = true;
    glExtensions->vertexArrayObjectOES        = true;
    glExtensions->elementIndexUintOES         = true;

    glExtensions->textureStorageEXT = true;
    glExtensions->rgb8Rgba8OES      = true;

    glExtensions->EGLImageOES                  = true;
    glExtensions->EGLImageExternalOES          = true;
    glExtensions->EGLImageExternalEssl3OES     = true;
    glExtensions->EGLImageExternalWrapModesEXT = true;
    glExtensions->requiredInternalformatOES    = true;
    glExtensions->copyTextureCHROMIUM          = true;

    // Depth/stencil extensions
    glExtensions->packedDepthStencilOES = true;

    // Blit extensions
    glExtensions->framebufferBlitANGLE = true;
    glExtensions->framebufferBlitNV    = true;

    // Explicit context entry points are supported.
    glExtensions->explicitContextANGLE = true;

    // OpenGL ES caps
    glCaps->maxElementIndex       = std::numeric_limits<GLuint>::max() - 1;
    glCaps->max3DTextureSize      = rx::LimitToInt(limitsWgpu.maxTextureDimension3D);
    glCaps->max2DTextureSize      = rx::LimitToInt(limitsWgpu.maxTextureDimension2D);
    glCaps->maxArrayTextureLayers = rx::LimitToInt(limitsWgpu.maxTextureArrayLayers);
    glCaps->maxLODBias            = 0.0f;
    glCaps->maxCubeMapTextureSize = rx::LimitToInt(limitsWgpu.maxTextureDimension2D);
    glCaps->maxRenderbufferSize   = rx::LimitToInt(limitsWgpu.maxTextureDimension2D);
    glCaps->minAliasedPointSize   = 1.0f;
    glCaps->maxAliasedPointSize   = 1.0f;
    glCaps->minAliasedLineWidth   = 1.0f;
    glCaps->maxAliasedLineWidth   = 1.0f;

    // "descriptor.sampleCount must be either 1 or 4."
    constexpr uint32_t kMaxSampleCount = 4;

    glCaps->maxDrawBuffers         = rx::LimitToInt(limitsWgpu.maxColorAttachments);
    glCaps->maxFramebufferWidth    = rx::LimitToInt(limitsWgpu.maxTextureDimension2D);
    glCaps->maxFramebufferHeight   = rx::LimitToInt(limitsWgpu.maxTextureDimension2D);
    glCaps->maxFramebufferSamples  = kMaxSampleCount;
    glCaps->maxColorAttachments    = rx::LimitToInt(limitsWgpu.maxColorAttachments);
    glCaps->maxViewportWidth       = rx::LimitToInt(limitsWgpu.maxTextureDimension2D);
    glCaps->maxViewportHeight      = glCaps->maxViewportWidth;
    glCaps->maxSampleMaskWords     = 1;
    glCaps->maxColorTextureSamples = kMaxSampleCount;
    glCaps->maxDepthTextureSamples = kMaxSampleCount;
    glCaps->maxIntegerSamples      = kMaxSampleCount;
    glCaps->maxServerWaitTimeout   = 0;

    glCaps->maxVertexAttribRelativeOffset = (1u << kAttributeOffsetMaxBits) - 1;
    glCaps->maxVertexAttribBindings =
        rx::LimitToInt(std::min(limitsWgpu.maxVertexBuffers, limitsWgpu.maxVertexAttributes));
    glCaps->maxVertexAttribStride =
        rx::LimitToInt(std::min(limitsWgpu.maxVertexBufferArrayStride,
                                static_cast<uint32_t>(std::numeric_limits<uint16_t>::max())));
    glCaps->maxElementsIndices  = std::numeric_limits<GLint>::max();
    glCaps->maxElementsVertices = std::numeric_limits<GLint>::max();
    glCaps->vertexHighpFloat.setIEEEFloat();
    glCaps->vertexMediumpFloat.setIEEEHalfFloat();
    glCaps->vertexLowpFloat.setIEEEHalfFloat();
    glCaps->fragmentHighpFloat.setIEEEFloat();
    glCaps->fragmentMediumpFloat.setIEEEHalfFloat();
    glCaps->fragmentLowpFloat.setIEEEHalfFloat();
    glCaps->vertexHighpInt.setTwosComplementInt(32);
    glCaps->vertexMediumpInt.setTwosComplementInt(16);
    glCaps->vertexLowpInt.setTwosComplementInt(16);
    glCaps->fragmentHighpInt.setTwosComplementInt(32);
    glCaps->fragmentMediumpInt.setTwosComplementInt(16);
    glCaps->fragmentLowpInt.setTwosComplementInt(16);

    const GLuint maxUniformBlockSize = static_cast<GLuint>(std::min<uint64_t>(
        gl::IMPLEMENTATION_MAX_UNIFORM_BLOCK_SIZE, limitsWgpu.maxUniformBufferBindingSize));

    const GLuint maxUniformVectors    = maxUniformBlockSize / (sizeof(GLfloat) * 4);
    const GLuint maxUniformComponents = maxUniformVectors * 4;

    const int32_t maxPerStageUniformBuffers = rx::LimitToInt(
        limitsWgpu.maxUniformBuffersPerShaderStage - kReservedPerStageDefaultUniformSlotCount);

    // There is no additional limit to the combined number of components.  We can have up to a
    // maximum number of uniform buffers, each having the maximum number of components.  Note that
    // this limit includes both components in and out of uniform buffers.
    //
    // This value is limited to INT_MAX to avoid overflow when queried from glGetIntegerv().
    const uint64_t maxCombinedUniformComponents =
        std::min<uint64_t>(static_cast<uint64_t>(maxPerStageUniformBuffers +
                                                 kReservedPerStageDefaultUniformSlotCount) *
                               maxUniformComponents,
                           std::numeric_limits<GLint>::max());

    for (gl::ShaderType shaderType : gl::AllShaderTypes())
    {
        glCaps->maxShaderUniformBlocks[shaderType] = maxPerStageUniformBuffers;
        glCaps->maxShaderTextureImageUnits[shaderType] =
            rx::LimitToInt(limitsWgpu.maxSamplersPerShaderStage);
        glCaps->maxShaderStorageBlocks[shaderType]             = 0;
        glCaps->maxShaderUniformComponents[shaderType]         = 0;
        glCaps->maxShaderAtomicCounterBuffers[shaderType]      = 0;
        glCaps->maxShaderAtomicCounters[shaderType]            = 0;
        glCaps->maxShaderImageUniforms[shaderType]             = 0;
        glCaps->maxCombinedShaderUniformComponents[shaderType] = maxCombinedUniformComponents;
    }

    const GLint maxVaryingComponents = rx::LimitToInt(limitsWgpu.maxInterStageShaderVariables * 4);

    glCaps->maxVertexAttributes = rx::LimitToInt(
        limitsWgpu.maxVertexBuffers);  // WebGPU has maxVertexBuffers and maxVertexAttributes but
                                       // since each vertex attribute can use a unique buffer, we
                                       // are limited by the total number of vertex buffers
    glCaps->maxVertexUniformVectors =
        maxUniformVectors;  // Uniforms are implemented using a uniform buffer, so the max number of
                            // uniforms we can support is the max buffer range divided by the size
                            // of a single uniform (4X float).
    glCaps->maxVertexOutputComponents = maxVaryingComponents;

    glCaps->maxFragmentUniformVectors     = maxUniformVectors;
    glCaps->maxFragmentInputComponents    = maxVaryingComponents;
    glCaps->minProgramTextureGatherOffset = 0;
    glCaps->maxProgramTextureGatherOffset = 0;
    glCaps->minProgramTexelOffset         = -8;
    glCaps->maxProgramTexelOffset         = 7;

    glCaps->maxComputeWorkGroupCount       = {0, 0, 0};
    glCaps->maxComputeWorkGroupSize        = {0, 0, 0};
    glCaps->maxComputeWorkGroupInvocations = 0;
    glCaps->maxComputeSharedMemorySize     = 0;

    // Only 2 stages (vertex+fragment) are supported.
    constexpr uint32_t kShaderStageCount = 2;

    glCaps->maxUniformBufferBindings = maxPerStageUniformBuffers * kShaderStageCount;
    glCaps->maxUniformBlockSize      = rx::LimitToInt(limitsWgpu.maxBufferSize);
    glCaps->uniformBufferOffsetAlignment =
        rx::LimitToInt(limitsWgpu.minUniformBufferOffsetAlignment);
    glCaps->maxCombinedUniformBlocks = glCaps->maxUniformBufferBindings;
    glCaps->maxVaryingComponents     = maxVaryingComponents;
    glCaps->maxVaryingVectors        = rx::LimitToInt(limitsWgpu.maxInterStageShaderVariables);
    glCaps->maxCombinedTextureImageUnits =
        rx::LimitToInt(limitsWgpu.maxSamplersPerShaderStage * kShaderStageCount);
    glCaps->maxCombinedShaderOutputResources = 0;

    glCaps->maxUniformLocations                = maxUniformVectors;
    glCaps->maxAtomicCounterBufferBindings     = 0;
    glCaps->maxAtomicCounterBufferSize         = 0;
    glCaps->maxCombinedAtomicCounterBuffers    = 0;
    glCaps->maxCombinedAtomicCounters          = 0;
    glCaps->maxImageUnits                      = 0;
    glCaps->maxCombinedImageUniforms           = 0;
    glCaps->maxShaderStorageBufferBindings     = 0;
    glCaps->maxShaderStorageBlockSize          = 0;
    glCaps->maxCombinedShaderStorageBlocks     = 0;
    glCaps->shaderStorageBufferOffsetAlignment = 0;

    glCaps->maxTransformFeedbackInterleavedComponents = 0;
    glCaps->maxTransformFeedbackSeparateAttributes    = 0;
    glCaps->maxTransformFeedbackSeparateComponents    = 0;

    glCaps->lineWidthGranularity    = 0.0f;
    glCaps->minMultisampleLineWidth = 0.0f;
    glCaps->maxMultisampleLineWidth = 0.0f;

    glCaps->maxTextureBufferSize         = 0;
    glCaps->textureBufferOffsetAlignment = 0;

    glCaps->maxSamples = kMaxSampleCount;

    // Max version
    *maxSupportedESVersion = gl::Version(3, 2);

    // OpenGL ES texture caps
    InitMinimumTextureCapsMap(*maxSupportedESVersion, *glExtensions, glTextureCapsMap);

    // EGL caps
    eglCaps->textureNPOT = true;

    // EGL extensions
    eglExtensions->createContextRobustness            = true;
    eglExtensions->postSubBuffer                      = true;
    eglExtensions->createContext                      = true;
    eglExtensions->image                              = true;
    eglExtensions->imageBase                          = true;
    eglExtensions->glTexture2DImage                   = true;
    eglExtensions->glRenderbufferImage                = true;
    eglExtensions->getAllProcAddresses                = true;
    eglExtensions->noConfigContext                    = true;
    eglExtensions->createContextNoError               = true;
    eglExtensions->createContextWebGLCompatibility    = true;
    eglExtensions->createContextBindGeneratesResource = true;
    eglExtensions->pixelFormatFloat                   = true;
    eglExtensions->surfacelessContext                 = true;
    eglExtensions->displayTextureShareGroup           = true;
    eglExtensions->displaySemaphoreShareGroup         = true;
    eglExtensions->createContextClientArrays          = true;
    eglExtensions->programCacheControlANGLE           = true;
    eglExtensions->robustResourceInitializationANGLE  = true;
    eglExtensions->webgpuTextureClientBuffer          = true;
}

bool IsStripPrimitiveTopology(WGPUPrimitiveTopology topology)
{
    switch (topology)
    {
        case WGPUPrimitiveTopology_LineStrip:
        case WGPUPrimitiveTopology_TriangleStrip:
            return true;

        default:
            return false;
    }
}

ErrorScope::ErrorScope(const DawnProcTable *procTable,
                       webgpu::InstanceHandle instance,
                       webgpu::DeviceHandle device,
                       WGPUErrorFilter errorType)
    : mProcTable(procTable), mInstance(instance), mDevice(device)
{
    mProcTable->devicePushErrorScope(mDevice.get(), errorType);
    mActive = true;
}

ErrorScope::~ErrorScope()
{
    ANGLE_UNUSED_VARIABLE(PopScope(nullptr, nullptr, nullptr, 0));
}

angle::Result ErrorScope::PopScope(ContextWgpu *context,
                                   const char *file,
                                   const char *function,
                                   unsigned int line)
{
    if (!mActive)
    {
        return angle::Result::Continue;
    }
    mActive = false;

    struct PopScopeContext
    {
        ContextWgpu *context = nullptr;
        const char *file     = nullptr;
        const char *function = nullptr;
        unsigned int line    = 0;
        bool hadError        = false;
    };

    WGPUPopErrorScopeCallbackInfo callbackInfo = WGPU_POP_ERROR_SCOPE_CALLBACK_INFO_INIT;
    callbackInfo.mode                          = WGPUCallbackMode_AllowSpontaneous;
    callbackInfo.callback = [](WGPUPopErrorScopeStatus status, WGPUErrorType type,
                               struct WGPUStringView message, void *userdata1, void *userdata2) {
        PopScopeContext *ctx = reinterpret_cast<PopScopeContext *>(userdata1);
        ASSERT(userdata2 == nullptr);

        if (type == WGPUErrorType_NoError)
        {
            return;
        }

        if (ctx)
        {
            ASSERT(ctx->file);
            ASSERT(ctx->function);
            std::string msgStr(message.data, message.length);
            ctx->context->handleError(GL_INVALID_OPERATION, msgStr.c_str(), ctx->file,
                                      ctx->function, ctx->line);
            ctx->hadError = true;
        }
        else
        {
            ERR() << "Unhandled WebGPU error: " << std::string(message.data, message.length);
        }
    };

    const angle::FeaturesWgpu &features = GetFeatures(context);
    if (features.avoidWaitAny.enabled)
    {
        // End the error scope but don't wait on it. The error messages will be printed later.
        mProcTable->devicePopErrorScope(mDevice.get(), callbackInfo);
        return angle::Result::Continue;
    }
    else
    {
        PopScopeContext popScopeContext{context, file, function, line, false};
        callbackInfo.userdata1 = &popScopeContext;

        WGPUFutureWaitInfo future = WGPU_FUTURE_WAIT_INFO_INIT;
        future.future             = mProcTable->devicePopErrorScope(mDevice.get(), callbackInfo);
        mProcTable->instanceWaitAny(mInstance.get(), 1, &future, -1);

        return popScopeContext.hadError ? angle::Result::Stop : angle::Result::Continue;
    }
}

}  // namespace webgpu

namespace wgpu_gl
{
gl::LevelIndex GetLevelIndex(webgpu::LevelIndex levelWgpu, gl::LevelIndex baseLevel)
{
    return gl::LevelIndex(levelWgpu.get() + baseLevel.get());
}

gl::Extents GetExtents(WGPUExtent3D wgpuExtent)
{
    gl::Extents glExtent;
    glExtent.width  = wgpuExtent.width;
    glExtent.height = wgpuExtent.height;
    glExtent.depth  = wgpuExtent.depthOrArrayLayers;
    return glExtent;
}
}  // namespace wgpu_gl

namespace gl_wgpu
{
webgpu::LevelIndex getLevelIndex(gl::LevelIndex levelGl, gl::LevelIndex baseLevel)
{
    ASSERT(baseLevel <= levelGl);
    return webgpu::LevelIndex(levelGl.get() - baseLevel.get());
}

WGPUExtent3D GetExtent3D(const gl::Extents &glExtent)
{
    WGPUExtent3D wgpuExtent       = WGPU_EXTENT_3D_INIT;
    wgpuExtent.width              = glExtent.width;
    wgpuExtent.height             = glExtent.height;
    wgpuExtent.depthOrArrayLayers = glExtent.depth;
    return wgpuExtent;
}

WGPUPrimitiveTopology GetPrimitiveTopology(gl::PrimitiveMode mode)
{
    switch (mode)
    {
        case gl::PrimitiveMode::Points:
            return WGPUPrimitiveTopology_PointList;
        case gl::PrimitiveMode::Lines:
            return WGPUPrimitiveTopology_LineList;
        case gl::PrimitiveMode::LineLoop:
            return WGPUPrimitiveTopology_LineStrip;  // Emulated
        case gl::PrimitiveMode::LineStrip:
            return WGPUPrimitiveTopology_LineStrip;
        case gl::PrimitiveMode::Triangles:
            return WGPUPrimitiveTopology_TriangleList;
        case gl::PrimitiveMode::TriangleStrip:
            return WGPUPrimitiveTopology_TriangleStrip;
        case gl::PrimitiveMode::TriangleFan:
            return WGPUPrimitiveTopology_TriangleList;  // Emulated
        default:
            UNREACHABLE();
            return WGPUPrimitiveTopology_Undefined;
    }
}

WGPUIndexFormat GetIndexFormat(gl::DrawElementsType drawElementsType)
{
    switch (drawElementsType)
    {
        case gl::DrawElementsType::UnsignedByte:
            return WGPUIndexFormat_Uint16;  // Emulated
        case gl::DrawElementsType::UnsignedShort:
            return WGPUIndexFormat_Uint16;
        case gl::DrawElementsType::UnsignedInt:
            return WGPUIndexFormat_Uint32;

        default:
            UNREACHABLE();
            return WGPUIndexFormat_Undefined;
    }
}

WGPUFrontFace GetFrontFace(GLenum frontFace)
{
    switch (frontFace)
    {
        case GL_CW:
            return WGPUFrontFace_CW;
        case GL_CCW:
            return WGPUFrontFace_CCW;

        default:
            UNREACHABLE();
            return WGPUFrontFace_Undefined;
    }
}

WGPUCullMode GetCullMode(gl::CullFaceMode mode, bool cullFaceEnabled)
{
    if (!cullFaceEnabled)
    {
        return WGPUCullMode_None;
    }

    switch (mode)
    {
        case gl::CullFaceMode::Front:
            return WGPUCullMode_Front;
        case gl::CullFaceMode::Back:
            return WGPUCullMode_Back;
        case gl::CullFaceMode::FrontAndBack:
            UNIMPLEMENTED();
            return WGPUCullMode_None;  // Emulated
        default:
            UNREACHABLE();
            return WGPUCullMode_None;
    }
}

WGPUColorWriteMask GetColorWriteMask(bool r, bool g, bool b, bool a)
{
    return (r ? WGPUColorWriteMask_Red : WGPUColorWriteMask_None) |
           (g ? WGPUColorWriteMask_Green : WGPUColorWriteMask_None) |
           (b ? WGPUColorWriteMask_Blue : WGPUColorWriteMask_None) |
           (a ? WGPUColorWriteMask_Alpha : WGPUColorWriteMask_None);
}

WGPUBlendFactor GetBlendFactor(gl::BlendFactorType blendFactor)
{
    switch (blendFactor)
    {
        case gl::BlendFactorType::Zero:
            return WGPUBlendFactor_Zero;

        case gl::BlendFactorType::One:
            return WGPUBlendFactor_One;

        case gl::BlendFactorType::SrcColor:
            return WGPUBlendFactor_Src;

        case gl::BlendFactorType::OneMinusSrcColor:
            return WGPUBlendFactor_OneMinusSrc;

        case gl::BlendFactorType::SrcAlpha:
            return WGPUBlendFactor_SrcAlpha;

        case gl::BlendFactorType::OneMinusSrcAlpha:
            return WGPUBlendFactor_OneMinusSrcAlpha;

        case gl::BlendFactorType::DstAlpha:
            return WGPUBlendFactor_DstAlpha;

        case gl::BlendFactorType::OneMinusDstAlpha:
            return WGPUBlendFactor_OneMinusDstAlpha;

        case gl::BlendFactorType::DstColor:
            return WGPUBlendFactor_Dst;

        case gl::BlendFactorType::OneMinusDstColor:
            return WGPUBlendFactor_OneMinusDst;

        case gl::BlendFactorType::SrcAlphaSaturate:
            return WGPUBlendFactor_SrcAlphaSaturated;

        case gl::BlendFactorType::ConstantColor:
            return WGPUBlendFactor_Constant;

        case gl::BlendFactorType::OneMinusConstantColor:
            return WGPUBlendFactor_OneMinusConstant;

        case gl::BlendFactorType::ConstantAlpha:
            UNIMPLEMENTED();
            return WGPUBlendFactor_Undefined;

        case gl::BlendFactorType::OneMinusConstantAlpha:
            UNIMPLEMENTED();
            return WGPUBlendFactor_Undefined;

        case gl::BlendFactorType::Src1Alpha:
            return WGPUBlendFactor_Src1Alpha;

        case gl::BlendFactorType::Src1Color:
            return WGPUBlendFactor_Src1;

        case gl::BlendFactorType::OneMinusSrc1Color:
            return WGPUBlendFactor_OneMinusSrc1;

        case gl::BlendFactorType::OneMinusSrc1Alpha:
            return WGPUBlendFactor_OneMinusSrc1Alpha;

        default:
            UNREACHABLE();
            return WGPUBlendFactor_Undefined;
    }
}

WGPUBlendOperation GetBlendEquation(gl::BlendEquationType blendEquation)
{
    switch (blendEquation)
    {
        case gl::BlendEquationType::Add:
            return WGPUBlendOperation_Add;

        case gl::BlendEquationType::Min:
            return WGPUBlendOperation_Min;

        case gl::BlendEquationType::Max:
            return WGPUBlendOperation_Max;

        case gl::BlendEquationType::Subtract:
            return WGPUBlendOperation_Subtract;

        case gl::BlendEquationType::ReverseSubtract:
            return WGPUBlendOperation_ReverseSubtract;

        case gl::BlendEquationType::Multiply:
        case gl::BlendEquationType::Screen:
        case gl::BlendEquationType::Overlay:
        case gl::BlendEquationType::Darken:
        case gl::BlendEquationType::Lighten:
        case gl::BlendEquationType::Colordodge:
        case gl::BlendEquationType::Colorburn:
        case gl::BlendEquationType::Hardlight:
        case gl::BlendEquationType::Softlight:
        case gl::BlendEquationType::Unused2:
        case gl::BlendEquationType::Difference:
        case gl::BlendEquationType::Unused3:
        case gl::BlendEquationType::Exclusion:
        case gl::BlendEquationType::HslHue:
        case gl::BlendEquationType::HslSaturation:
        case gl::BlendEquationType::HslColor:
        case gl::BlendEquationType::HslLuminosity:
            // EXT_blend_equation_advanced
            UNIMPLEMENTED();
            return WGPUBlendOperation_Undefined;

        default:
            UNREACHABLE();
            return WGPUBlendOperation_Undefined;
    }
}

WGPUTextureViewDimension GetWgpuTextureViewDimension(gl::TextureType textureType)
{
    switch (textureType)
    {
        case gl::TextureType::_2D:
        case gl::TextureType::_2DMultisample:
            return WGPUTextureViewDimension_2D;
        case gl::TextureType::_2DArray:
        case gl::TextureType::_2DMultisampleArray:
            return WGPUTextureViewDimension_2DArray;
        case gl::TextureType::_3D:
            return WGPUTextureViewDimension_3D;
        case gl::TextureType::CubeMap:
            return WGPUTextureViewDimension_Cube;
        case gl::TextureType::CubeMapArray:
            return WGPUTextureViewDimension_CubeArray;
        default:
            UNIMPLEMENTED();
            return WGPUTextureViewDimension_Undefined;
    }
}

WGPUTextureDimension GetWgpuTextureDimension(gl::TextureType glTextureType)
{
    switch (glTextureType)
    {
        // See https://www.w3.org/TR/webgpu/#dom-gputexture-createview.
        case gl::TextureType::_2D:
        case gl::TextureType::_2DArray:
        case gl::TextureType::_2DMultisample:
        case gl::TextureType::_2DMultisampleArray:
        case gl::TextureType::CubeMap:
        case gl::TextureType::CubeMapArray:
        case gl::TextureType::Rectangle:
        case gl::TextureType::External:
        case gl::TextureType::Buffer:
            return WGPUTextureDimension_2D;
        case gl::TextureType::_3D:
            return WGPUTextureDimension_3D;
        default:
            UNREACHABLE();
            return WGPUTextureDimension_Undefined;
    }
}

WGPUCompareFunction GetCompareFunc(const GLenum glCompareFunc, bool testEnabled)
{
    if (!testEnabled)
    {
        return WGPUCompareFunction_Always;
    }

    switch (glCompareFunc)
    {
        case GL_NEVER:
            return WGPUCompareFunction_Never;
        case GL_LESS:
            return WGPUCompareFunction_Less;
        case GL_EQUAL:
            return WGPUCompareFunction_Equal;
        case GL_LEQUAL:
            return WGPUCompareFunction_LessEqual;
        case GL_GREATER:
            return WGPUCompareFunction_Greater;
        case GL_NOTEQUAL:
            return WGPUCompareFunction_NotEqual;
        case GL_GEQUAL:
            return WGPUCompareFunction_GreaterEqual;
        case GL_ALWAYS:
            return WGPUCompareFunction_Always;
        default:
            UNREACHABLE();
            return WGPUCompareFunction_Always;
    }
}

WGPUTextureSampleType GetTextureSampleType(gl::SamplerFormat samplerFormat)
{
    switch (samplerFormat)
    {
        case gl::SamplerFormat::Float:
            return WGPUTextureSampleType_Float;
        case gl::SamplerFormat::Unsigned:
            return WGPUTextureSampleType_Uint;
        case gl::SamplerFormat::Signed:
            return WGPUTextureSampleType_Sint;
        case gl::SamplerFormat::Shadow:
            return WGPUTextureSampleType_Depth;
        default:
            UNIMPLEMENTED();
            return WGPUTextureSampleType_Undefined;
    }
}

WGPUStencilOperation GetStencilOp(const GLenum glStencilOp)
{
    switch (glStencilOp)
    {
        case GL_KEEP:
            return WGPUStencilOperation_Keep;
        case GL_ZERO:
            return WGPUStencilOperation_Zero;
        case GL_REPLACE:
            return WGPUStencilOperation_Replace;
        case GL_INCR:
            return WGPUStencilOperation_IncrementClamp;
        case GL_DECR:
            return WGPUStencilOperation_DecrementClamp;
        case GL_INCR_WRAP:
            return WGPUStencilOperation_IncrementWrap;
        case GL_DECR_WRAP:
            return WGPUStencilOperation_DecrementWrap;
        case GL_INVERT:
            return WGPUStencilOperation_Invert;
        default:
            UNREACHABLE();
            return WGPUStencilOperation_Keep;
    }
}

WGPUFilterMode GetFilter(const GLenum filter)
{
    switch (filter)
    {
        case GL_LINEAR_MIPMAP_LINEAR:
        case GL_LINEAR_MIPMAP_NEAREST:
        case GL_LINEAR:
            return WGPUFilterMode_Linear;
        case GL_NEAREST_MIPMAP_LINEAR:
        case GL_NEAREST_MIPMAP_NEAREST:
        case GL_NEAREST:
            return WGPUFilterMode_Nearest;
        default:
            UNREACHABLE();
            return WGPUFilterMode_Undefined;
    }
}

WGPUMipmapFilterMode GetSamplerMipmapMode(const GLenum filter)
{
    switch (filter)
    {
        case GL_LINEAR_MIPMAP_LINEAR:
        case GL_NEAREST_MIPMAP_LINEAR:
            return WGPUMipmapFilterMode_Linear;
        // GL_LINEAR and GL_NEAREST do not map directly to WebGPU but can be easily emulated,
        // see below.
        case GL_LINEAR:
        case GL_NEAREST:
        case GL_NEAREST_MIPMAP_NEAREST:
        case GL_LINEAR_MIPMAP_NEAREST:
            return WGPUMipmapFilterMode_Nearest;
        default:
            UNREACHABLE();
            return WGPUMipmapFilterMode_Undefined;
    }
}

WGPUAddressMode GetSamplerAddressMode(const GLenum wrap)
{
    switch (wrap)
    {
        case GL_REPEAT:
            return WGPUAddressMode_Repeat;
        case GL_MIRRORED_REPEAT:
            return WGPUAddressMode_MirrorRepeat;
        case GL_CLAMP_TO_BORDER:
            // Not in WebGPU and not available in ES 3.0 or before.
            UNIMPLEMENTED();
            return WGPUAddressMode_ClampToEdge;
        case GL_CLAMP_TO_EDGE:
            return WGPUAddressMode_ClampToEdge;
        case GL_MIRROR_CLAMP_TO_EDGE_EXT:
            // Not in WebGPU and not available in ES 3.0 or before.
            return WGPUAddressMode_ClampToEdge;
        default:
            UNREACHABLE();
            return WGPUAddressMode_Undefined;
    }
}

WGPUCompareFunction GetSamplerCompareFunc(const gl::SamplerState *samplerState)
{
    if (samplerState->getCompareMode() != GL_COMPARE_REF_TO_TEXTURE)
    {
        return WGPUCompareFunction_Undefined;
    }

    return GetCompareFunc(samplerState->getCompareFunc(), /*testEnabled=*/true);
}

WGPUSamplerDescriptor GetWgpuSamplerDesc(const gl::SamplerState *samplerState)
{
    WGPUMipmapFilterMode wgpuMipmapFilterMode = GetSamplerMipmapMode(samplerState->getMinFilter());
    // Negative values don't seem to make a difference to the behavior of GLES, a min lod of 0.0
    // functions the same.
    float wgpuLodMinClamp =
        gl::clamp(samplerState->getMinLod(), webgpu::kWGPUMinLod, webgpu::kWGPUMaxLod);
    float wgpuLodMaxClamp =
        gl::clamp(samplerState->getMaxLod(), webgpu::kWGPUMinLod, webgpu::kWGPUMaxLod);

    if (!gl::IsMipmapFiltered(samplerState->getMinFilter()))
    {
        // Similarly to Vulkan, GL_NEAREST and GL_LINEAR do not map directly to WGPU, so
        // they must be emulated (See "Mapping of OpenGL to Vulkan filter modes")
        wgpuMipmapFilterMode = WGPUMipmapFilterMode_Nearest;
        wgpuLodMinClamp      = 0.0f;
        wgpuLodMaxClamp      = 0.25f;
    }

    WGPUSamplerDescriptor samplerDesc = WGPU_SAMPLER_DESCRIPTOR_INIT;
    samplerDesc.addressModeU = GetSamplerAddressMode(samplerState->getWrapS());
    samplerDesc.addressModeV = GetSamplerAddressMode(samplerState->getWrapT());
    samplerDesc.addressModeW = GetSamplerAddressMode(samplerState->getWrapR());
    samplerDesc.magFilter    = GetFilter(samplerState->getMagFilter());
    samplerDesc.minFilter    = GetFilter(samplerState->getMinFilter());
    samplerDesc.mipmapFilter = wgpuMipmapFilterMode;
    samplerDesc.lodMinClamp  = wgpuLodMinClamp;
    samplerDesc.lodMaxClamp  = wgpuLodMaxClamp;
    samplerDesc.compare      = GetSamplerCompareFunc(samplerState);
    // TODO(anglebug.com/389145696): there's no way to get the supported maxAnisotropy value from
    // WGPU, so there's no way to communicate to the GL client whether anisotropy is even supported
    // as an extension, let alone what the max value is.
    samplerDesc.maxAnisotropy = static_cast<uint16_t>(std::floor(samplerState->getMaxAnisotropy()));

    return samplerDesc;
}

uint32_t GetFirstIndexForDrawCall(gl::DrawElementsType indexType, const void *indices)
{
    const size_t indexSize                = gl::GetDrawElementsTypeSize(indexType);
    const uintptr_t indexBufferByteOffset = reinterpret_cast<uintptr_t>(indices);
    if (indexBufferByteOffset % indexSize != 0)
    {
        // WebGPU only allows offsetting index buffers by multiples of the index size
        UNIMPLEMENTED();
    }

    return static_cast<uint32_t>(indexBufferByteOffset / indexSize);
}

}  // namespace gl_wgpu
}  // namespace rx
