// Copyright 2017 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dawn/native/opengl/CommandBufferGL.h"

#include <algorithm>
#include <cstring>
#include <utility>
#include <vector>

#include "dawn/common/MatchVariant.h"
#include "dawn/common/Range.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/BindGroupTracker.h"
#include "dawn/native/CommandEncoder.h"
#include "dawn/native/Commands.h"
#include "dawn/native/ExternalTexture.h"
#include "dawn/native/RenderBundle.h"
#include "dawn/native/opengl/BufferGL.h"
#include "dawn/native/opengl/ComputePipelineGL.h"
#include "dawn/native/opengl/DeviceGL.h"
#include "dawn/native/opengl/Forward.h"
#include "dawn/native/opengl/PersistentPipelineStateGL.h"
#include "dawn/native/opengl/PhysicalDeviceGL.h"
#include "dawn/native/opengl/PipelineLayoutGL.h"
#include "dawn/native/opengl/QuerySetGL.h"
#include "dawn/native/opengl/RenderPipelineGL.h"
#include "dawn/native/opengl/SamplerGL.h"
#include "dawn/native/opengl/TextureGL.h"
#include "dawn/native/opengl/UtilsGL.h"
#include "partition_alloc/pointers/raw_ptr.h"

namespace dawn::native::opengl {

namespace {

GLenum ComponentSwizzle(wgpu::ComponentSwizzle swizzle) {
    switch (swizzle) {
        case wgpu::ComponentSwizzle::Zero:
            return GL_ZERO;
        case wgpu::ComponentSwizzle::One:
            return GL_ONE;
        case wgpu::ComponentSwizzle::R:
            return GL_RED;
        case wgpu::ComponentSwizzle::G:
            return GL_GREEN;
        case wgpu::ComponentSwizzle::B:
            return GL_BLUE;
        case wgpu::ComponentSwizzle::A:
            return GL_ALPHA;

        case wgpu::ComponentSwizzle::Undefined:
            DAWN_UNREACHABLE();
    }
}

GLenum IndexFormatType(wgpu::IndexFormat format) {
    switch (format) {
        case wgpu::IndexFormat::Uint16:
            return GL_UNSIGNED_SHORT;
        case wgpu::IndexFormat::Uint32:
            return GL_UNSIGNED_INT;
        case wgpu::IndexFormat::Undefined:
            break;
    }
    DAWN_UNREACHABLE();
}

GLenum VertexFormatType(wgpu::VertexFormat format) {
    switch (format) {
        case wgpu::VertexFormat::Uint8:
        case wgpu::VertexFormat::Uint8x2:
        case wgpu::VertexFormat::Uint8x4:
        case wgpu::VertexFormat::Unorm8:
        case wgpu::VertexFormat::Unorm8x2:
        case wgpu::VertexFormat::Unorm8x4:
        case wgpu::VertexFormat::Unorm8x4BGRA:
            return GL_UNSIGNED_BYTE;
        case wgpu::VertexFormat::Sint8:
        case wgpu::VertexFormat::Sint8x2:
        case wgpu::VertexFormat::Sint8x4:
        case wgpu::VertexFormat::Snorm8:
        case wgpu::VertexFormat::Snorm8x2:
        case wgpu::VertexFormat::Snorm8x4:
            return GL_BYTE;
        case wgpu::VertexFormat::Uint16:
        case wgpu::VertexFormat::Uint16x2:
        case wgpu::VertexFormat::Uint16x4:
        case wgpu::VertexFormat::Unorm16:
        case wgpu::VertexFormat::Unorm16x2:
        case wgpu::VertexFormat::Unorm16x4:
            return GL_UNSIGNED_SHORT;
        case wgpu::VertexFormat::Sint16:
        case wgpu::VertexFormat::Sint16x2:
        case wgpu::VertexFormat::Sint16x4:
        case wgpu::VertexFormat::Snorm16:
        case wgpu::VertexFormat::Snorm16x2:
        case wgpu::VertexFormat::Snorm16x4:
            return GL_SHORT;
        case wgpu::VertexFormat::Float16:
        case wgpu::VertexFormat::Float16x2:
        case wgpu::VertexFormat::Float16x4:
            return GL_HALF_FLOAT;
        case wgpu::VertexFormat::Float32:
        case wgpu::VertexFormat::Float32x2:
        case wgpu::VertexFormat::Float32x3:
        case wgpu::VertexFormat::Float32x4:
            return GL_FLOAT;
        case wgpu::VertexFormat::Uint32:
        case wgpu::VertexFormat::Uint32x2:
        case wgpu::VertexFormat::Uint32x3:
        case wgpu::VertexFormat::Uint32x4:
            return GL_UNSIGNED_INT;
        case wgpu::VertexFormat::Sint32:
        case wgpu::VertexFormat::Sint32x2:
        case wgpu::VertexFormat::Sint32x3:
        case wgpu::VertexFormat::Sint32x4:
            return GL_INT;
        case wgpu::VertexFormat::Unorm10_10_10_2:
            return GL_UNSIGNED_INT_2_10_10_10_REV;
        default:
            DAWN_UNREACHABLE();
    }
}

GLboolean VertexFormatIsNormalized(wgpu::VertexFormat format) {
    switch (format) {
        case wgpu::VertexFormat::Unorm8:
        case wgpu::VertexFormat::Unorm8x2:
        case wgpu::VertexFormat::Unorm8x4:
        case wgpu::VertexFormat::Unorm8x4BGRA:
        case wgpu::VertexFormat::Snorm8:
        case wgpu::VertexFormat::Snorm8x2:
        case wgpu::VertexFormat::Snorm8x4:
        case wgpu::VertexFormat::Unorm16:
        case wgpu::VertexFormat::Unorm16x2:
        case wgpu::VertexFormat::Unorm16x4:
        case wgpu::VertexFormat::Snorm16:
        case wgpu::VertexFormat::Snorm16x2:
        case wgpu::VertexFormat::Snorm16x4:
        case wgpu::VertexFormat::Unorm10_10_10_2:
            return GL_TRUE;
        default:
            return GL_FALSE;
    }
}

bool VertexFormatIsInt(wgpu::VertexFormat format) {
    switch (format) {
        case wgpu::VertexFormat::Uint8:
        case wgpu::VertexFormat::Uint8x2:
        case wgpu::VertexFormat::Uint8x4:
        case wgpu::VertexFormat::Sint8:
        case wgpu::VertexFormat::Sint8x2:
        case wgpu::VertexFormat::Sint8x4:
        case wgpu::VertexFormat::Uint16:
        case wgpu::VertexFormat::Uint16x2:
        case wgpu::VertexFormat::Uint16x4:
        case wgpu::VertexFormat::Sint16:
        case wgpu::VertexFormat::Sint16x2:
        case wgpu::VertexFormat::Sint16x4:
        case wgpu::VertexFormat::Uint32:
        case wgpu::VertexFormat::Uint32x2:
        case wgpu::VertexFormat::Uint32x3:
        case wgpu::VertexFormat::Uint32x4:
        case wgpu::VertexFormat::Sint32:
        case wgpu::VertexFormat::Sint32x2:
        case wgpu::VertexFormat::Sint32x3:
        case wgpu::VertexFormat::Sint32x4:
            return true;
        default:
            return false;
    }
}

// Vertex buffers and index buffers are implemented as part of an OpenGL VAO that
// corresponds to a VertexState. On the contrary in Dawn they are part of the global state.
// This means that we have to re-apply these buffers on a VertexState change.
class VertexStateBufferBindingTracker {
  public:
    void OnSetIndexBuffer(BufferBase* buffer) {
        mIndexBufferDirty = true;
        mIndexBuffer = ToBackend(buffer);
    }

    void OnSetVertexBuffer(VertexBufferSlot slot, BufferBase* buffer, uint64_t offset) {
        mVertexBuffers[slot] = ToBackend(buffer);
        mVertexBufferOffsets[slot] = offset;
        mDirtyVertexBuffers.set(slot);
    }

    void OnSetPipeline(RenderPipelineBase* pipeline) {
        if (mLastPipeline == pipeline) {
            return;
        }

        mIndexBufferDirty = true;
        mDirtyVertexBuffers |= pipeline->GetVertexBuffersUsed();

        mLastPipeline = pipeline;
    }

    MaybeError Apply(const OpenGLFunctions& gl, int32_t baseVertex, uint32_t firstInstance) {
        if (mBaseVertex != baseVertex) {
            mBaseVertex = baseVertex;
            mDirtyVertexBuffers |= mLastPipeline->GetVertexBuffersUsedAsVertexBuffer();
        }

        if (mFirstInstance != firstInstance) {
            mFirstInstance = firstInstance;
            mDirtyVertexBuffers |= mLastPipeline->GetVertexBuffersUsedAsInstanceBuffer();
        }

        if (mIndexBufferDirty && mIndexBuffer != nullptr) {
            DAWN_GL_TRY(gl, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->GetHandle()));
            mIndexBufferDirty = false;
        }

        for (VertexBufferSlot slot : mDirtyVertexBuffers & mLastPipeline->GetVertexBuffersUsed()) {
            for (VertexAttributeLocation location :
                 ToBackend(mLastPipeline)->GetAttributesUsingVertexBuffer(slot)) {
                const VertexAttributeInfo& attribute = mLastPipeline->GetAttribute(location);

                GLuint attribIndex = static_cast<GLuint>(static_cast<uint8_t>(location));
                GLuint buffer = mVertexBuffers[slot]->GetHandle();
                intptr_t offset = mVertexBufferOffsets[slot];

                const VertexBufferInfo& vertexBuffer = mLastPipeline->GetVertexBuffer(slot);

                if (vertexBuffer.stepMode == wgpu::VertexStepMode::Vertex) {
                    offset += mBaseVertex * vertexBuffer.arrayStride;
                } else if (vertexBuffer.stepMode == wgpu::VertexStepMode::Instance) {
                    offset += mFirstInstance * vertexBuffer.arrayStride;
                }
                uint32_t components = GetVertexFormatInfo(attribute.format).componentCount;
                GLenum formatType = VertexFormatType(attribute.format);

                GLboolean normalized = VertexFormatIsNormalized(attribute.format);
                DAWN_GL_TRY(gl, BindBuffer(GL_ARRAY_BUFFER, buffer));
                if (VertexFormatIsInt(attribute.format)) {
                    DAWN_GL_TRY(
                        gl, VertexAttribIPointer(
                                attribIndex, components, formatType, vertexBuffer.arrayStride,
                                reinterpret_cast<void*>(offset +
                                                        static_cast<intptr_t>(attribute.offset))));
                } else {
                    DAWN_GL_TRY(gl, VertexAttribPointer(
                                        attribIndex, components, formatType, normalized,
                                        vertexBuffer.arrayStride,
                                        reinterpret_cast<void*>(
                                            offset + static_cast<intptr_t>(attribute.offset))));
                }
            }
        }

        mDirtyVertexBuffers.reset();
        return {};
    }

  private:
    bool mIndexBufferDirty = false;
    raw_ptr<Buffer> mIndexBuffer = nullptr;

    VertexBufferMask mDirtyVertexBuffers;
    PerVertexBuffer<Buffer*> mVertexBuffers;
    PerVertexBuffer<uint64_t> mVertexBufferOffsets;

    int32_t mBaseVertex = 0;
    uint32_t mFirstInstance = 0;
    raw_ptr<RenderPipelineBase> mLastPipeline = nullptr;
};

// Tracking dirty byte range of a vector that needs to call bufferSubData
// to update to the internal uniform buffer of mPipeline. Range it represents: [begin, end)
struct VectorDirtyRangeInfo {
    size_t begin;
    size_t end;
};

class BindGroupTracker : public BindGroupTrackerBase<false, uint64_t> {
  public:
    void OnSetPipeline(RenderPipeline* pipeline) {
        BindGroupTrackerBase::OnSetPipeline(pipeline);
        mPipeline = pipeline;
        ResetInternalUniformDataBindgroupAndDirtyRange();
    }

    void OnSetPipeline(ComputePipeline* pipeline) {
        BindGroupTrackerBase::OnSetPipeline(pipeline);
        mPipeline = pipeline;
        ResetInternalUniformDataBindgroupAndDirtyRange();
    }

    MaybeError Apply(const OpenGLFunctions& gl) {
        BeforeApply();
        for (BindGroupIndex index : mDirtyBindGroupsObjectChangedOrIsDynamic) {
            DAWN_TRY(ApplyBindGroup(gl, index, mBindGroups[index], GetDynamicOffsets(index)));
        }
        DAWN_TRY(ApplyInternalUniforms(gl));
        DAWN_TRY(ApplyInternalArrayLengthUniforms(gl));
        AfterApply();
        return {};
    }

  private:
    MaybeError BindSamplerAtIndex(const OpenGLFunctions& gl,
                                  SamplerBase* s,
                                  FlatBindingIndex samplerIndex) {
        Sampler* sampler = ToBackend(s);

        for (TextureUnit unit : mPipeline->GetTextureUnitsForSampler(samplerIndex)) {
            DAWN_GL_TRY(gl, BindSampler(uint32_t(unit), sampler->GetHandle()));
        }

        return {};
    }

    MaybeError ApplyBindGroup(const OpenGLFunctions& gl,
                              BindGroupIndex groupIndex,
                              BindGroupBase* group,
                              const ityp::span<BindingIndex, uint64_t>& dynamicOffsets) {
        const auto& indices = ToBackend(mPipelineLayout)->GetBindingIndexInfo()[groupIndex];

        for (BindingIndex bindingIndex : Range(group->GetLayout()->GetBindingCount())) {
            const BindingInfo& bindingInfo = group->GetLayout()->GetBindingInfo(bindingIndex);
            DAWN_TRY(MatchVariant(
                bindingInfo.bindingLayout,
                [&](const BufferBindingInfo& layout) -> MaybeError {
                    BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
                    GLuint buffer = ToBackend(binding.buffer)->GetHandle();
                    FlatBindingIndex index = indices[bindingIndex];
                    GLuint offset = binding.offset;

                    if (layout.hasDynamicOffset) {
                        // Dynamic buffers are packed at the front of BindingIndices.
                        offset += dynamicOffsets[bindingIndex];
                    }

                    GLenum target;
                    switch (layout.type) {
                        case wgpu::BufferBindingType::Uniform:
                            target = GL_UNIFORM_BUFFER;

                            // Round uniform buffer binding sizes up to a multiple of 16 bytes since
                            // Tint will polyfill them as array<vec4u, ...>.
                            binding.size = Align(binding.size, 16u);
                            break;
                        case wgpu::BufferBindingType::Storage:
                        case kInternalStorageBufferBinding:
                        case wgpu::BufferBindingType::ReadOnlyStorage:
                        case kInternalReadOnlyStorageBufferBinding:
                            target = GL_SHADER_STORAGE_BUFFER;
                            UpdateSSBOLengthUniformData(gl, binding.size, groupIndex, bindingIndex);
                            break;
                        case wgpu::BufferBindingType::BindingNotUsed:
                        case wgpu::BufferBindingType::Undefined:
                            DAWN_UNREACHABLE();
                    }

                    DAWN_GL_TRY(
                        gl, BindBufferRange(target, GLuint(index), buffer, offset, binding.size));
                    return {};
                },
                [&](const StaticSamplerBindingInfo& layout) -> MaybeError {
                    DAWN_TRY(BindSamplerAtIndex(gl, layout.sampler.Get(), indices[bindingIndex]));
                    return {};
                },
                [&](const SamplerBindingInfo&) -> MaybeError {
                    DAWN_TRY(BindSamplerAtIndex(gl, group->GetBindingAsSampler(bindingIndex),
                                                indices[bindingIndex]));
                    return {};
                },
                [&](const TextureBindingInfo&) -> MaybeError {
                    TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                    GLuint handle = view->GetHandle();
                    GLenum target = view->GetGLTarget();
                    FlatBindingIndex viewIndex = indices[bindingIndex];

                    for (auto unit : mPipeline->GetTextureUnitsForTextureView(viewIndex)) {
                        DAWN_GL_TRY(gl, ActiveTexture(GL_TEXTURE0 + GLuint(unit)));
                        DAWN_GL_TRY(gl, BindTexture(target, handle));
                        if (ToBackend(view->GetTexture())->GetGLFormat().format ==
                            GL_DEPTH_STENCIL) {
                            Aspect aspect = view->GetAspects();
                            DAWN_ASSERT(HasOneBit(aspect));
                            switch (aspect) {
                                case Aspect::None:
                                case Aspect::Color:
                                case Aspect::CombinedDepthStencil:
                                case Aspect::Plane0:
                                case Aspect::Plane1:
                                case Aspect::Plane2:
                                    DAWN_UNREACHABLE();
                                case Aspect::Depth:
                                    DAWN_GL_TRY(gl,
                                                TexParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE,
                                                              GL_DEPTH_COMPONENT));
                                    break;
                                case Aspect::Stencil:
                                    DAWN_GL_TRY(gl,
                                                TexParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE,
                                                              GL_STENCIL_INDEX));
                                    break;
                            }
                        }
                        DAWN_GL_TRY(gl, TexParameteri(target, GL_TEXTURE_BASE_LEVEL,
                                                      view->GetBaseMipLevel()));
                        DAWN_GL_TRY(
                            gl, TexParameteri(target, GL_TEXTURE_MAX_LEVEL,
                                              view->GetBaseMipLevel() + view->GetLevelCount() - 1));
                        PhysicalDeviceBase* device =
                            ToBackend(mPipelineLayout->GetDevice())->GetPhysicalDevice();
                        if (ToBackend(device)->SupportTextureComponentSwizzle()) {
                            wgpu::TextureComponentSwizzle swizzle = view->GetSwizzle();
                            if (view->GetTexture()->GetFormat().HasDepthOrStencil()) {
                                swizzle = ComposeSwizzle(kR001Swizzle, swizzle);
                            }
                            DAWN_GL_TRY(gl, TexParameteri(target, GL_TEXTURE_SWIZZLE_R,
                                                          ComponentSwizzle(swizzle.r)));
                            DAWN_GL_TRY(gl, TexParameteri(target, GL_TEXTURE_SWIZZLE_G,
                                                          ComponentSwizzle(swizzle.g)));
                            DAWN_GL_TRY(gl, TexParameteri(target, GL_TEXTURE_SWIZZLE_B,
                                                          ComponentSwizzle(swizzle.b)));
                            DAWN_GL_TRY(gl, TexParameteri(target, GL_TEXTURE_SWIZZLE_A,
                                                          ComponentSwizzle(swizzle.a)));
                        }
                    }

                    // Some texture builtin function data needs emulation to update into the
                    // internal uniform buffer.
                    UpdateTextureBuiltinsUniformData(gl, view, viewIndex);
                    return {};
                },
                [&](const StorageTextureBindingInfo& layout) -> MaybeError {
                    TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                    Texture* texture = ToBackend(view->GetTexture());
                    GLuint handle = texture->GetHandle();
                    FlatBindingIndex imageIndex = indices[bindingIndex];

                    GLenum access;
                    switch (layout.access) {
                        case wgpu::StorageTextureAccess::WriteOnly:
                            access = GL_WRITE_ONLY;
                            break;
                        case wgpu::StorageTextureAccess::ReadWrite:
                            access = GL_READ_WRITE;
                            break;
                        case wgpu::StorageTextureAccess::ReadOnly:
                            access = GL_READ_ONLY;
                            break;
                        case wgpu::StorageTextureAccess::BindingNotUsed:
                        case wgpu::StorageTextureAccess::Undefined:
                            DAWN_UNREACHABLE();
                    }

                    // OpenGL ES only supports either binding a layer or the entire
                    // texture in glBindImageTexture().
                    GLboolean isLayered;
                    if (texture->GetArrayLayers() == view->GetLayerCount()) {
                        isLayered = GL_TRUE;
                    } else if (view->GetLayerCount() == 1) {
                        isLayered = GL_FALSE;
                    } else {
                        DAWN_UNREACHABLE();
                    }

                    DAWN_GL_TRY(
                        gl, BindImageTexture(GLuint(imageIndex), handle, view->GetBaseMipLevel(),
                                             isLayered, view->GetBaseArrayLayer(), access,
                                             texture->GetGLFormat().internalFormat));
                    return {};
                },
                [&](const TexelBufferBindingInfo&) -> MaybeError {
                    // OpenGL does not support texel buffers.
                    // TODO(crbug/382544164): Prototype texel buffer feature
                    DAWN_UNREACHABLE();
                    return {};
                },
                [](const InputAttachmentBindingInfo&) -> MaybeError { DAWN_UNREACHABLE(); },
                [](const ExternalTextureBindingInfo&) -> MaybeError { DAWN_UNREACHABLE(); }));
        }

        return {};
    }

    void UpdateTextureBuiltinsUniformData(const OpenGLFunctions& gl,
                                          const TextureView* view,
                                          FlatBindingIndex textureIndex) {
        const auto& builtinInfo = mPipeline->GetEmulatedTextureBuiltinInfo();
        auto iter = builtinInfo.find(textureIndex);
        if (iter == builtinInfo.end()) {
            return;
        }

        // Update data by retrieving information from texture view object.
        uint32_t data;
        switch (iter->second.query) {
            case TextureQuery::NumLevels:
                data = view->GetLevelCount();
                break;
            case TextureQuery::NumSamples:
                data = view->GetTexture()->GetSampleCount();
                break;
        }

        const size_t offset = iter->second.index * sizeof(uint32_t);
        if (offset >= mInternalUniformBufferData.size()) {
            mInternalUniformBufferData.resize(offset + sizeof(uint32_t));
        }
        memcpy(mInternalUniformBufferData.data() + offset, &data, sizeof(uint32_t));

        // Updating dirty range of the data vector
        mDirtyRange.begin = std::min(mDirtyRange.begin, offset);
        mDirtyRange.end = std::max(mDirtyRange.end, offset + sizeof(uint32_t));
    }

    void ResetInternalUniformDataDirtyRange() {
        mDirtyRange = {mInternalUniformBufferData.size(), 0};
    }

    MaybeError ApplyInternalUniforms(const OpenGLFunctions& gl) {
        if (!mPipeline->NeedsTextureBuiltinUniformBuffer()) {
            return {};
        }

        if (mDirtyRange.begin >= mDirtyRange.end) {
            // Early return if no dirty uniform range needs updating.
            return {};
        }

        const Buffer* internalUniformBuffer =
            ToBackend(mPipelineLayout->GetDevice())->GetInternalTextureBuiltinsUniformBuffer();
        DAWN_ASSERT(internalUniformBuffer);

        GLuint internalUniformBufferHandle = internalUniformBuffer->GetHandle();
        DAWN_GL_TRY(
            gl, BindBufferBase(
                    GL_UNIFORM_BUFFER,
                    GLuint(ToBackend(mPipelineLayout)->GetInternalTextureBuiltinsUniformBinding()),
                    internalUniformBufferHandle));

        DAWN_GL_TRY(gl, BindBuffer(GL_UNIFORM_BUFFER, internalUniformBufferHandle));
        DAWN_GL_TRY(gl, BufferSubData(GL_UNIFORM_BUFFER, mDirtyRange.begin,
                                      mDirtyRange.end - mDirtyRange.begin,
                                      mInternalUniformBufferData.data() + mDirtyRange.begin));
        DAWN_GL_TRY(gl, BindBuffer(GL_UNIFORM_BUFFER, 0));

        ResetInternalUniformDataDirtyRange();

        return {};
    }

    MaybeError ApplyInternalArrayLengthUniforms(const OpenGLFunctions& gl) {
        if (!mPipeline->NeedsSSBOLengthUniformBuffer()) {
            return {};
        }

        if (mDirtyRangeArrayLength.begin >= mDirtyRangeArrayLength.end) {
            // Early return if no dirty uniform range needs updating.
            return {};
        }

        const Buffer* internalUniformBuffer =
            ToBackend(mPipelineLayout->GetDevice())->GetInternalArrayLengthUniformBuffer();
        DAWN_ASSERT(internalUniformBuffer);

        GLuint internalUniformBufferHandle = internalUniformBuffer->GetHandle();
        DAWN_GL_TRY(gl,
                    BindBufferBase(
                        GL_UNIFORM_BUFFER,
                        GLuint(ToBackend(mPipelineLayout)->GetInternalArrayLengthUniformBinding()),
                        internalUniformBufferHandle));

        DAWN_GL_TRY(gl, BindBuffer(GL_UNIFORM_BUFFER, internalUniformBufferHandle));
        DAWN_GL_TRY(
            gl, BufferSubData(
                    GL_UNIFORM_BUFFER, sizeof(uint32_t) * mDirtyRangeArrayLength.begin,
                    sizeof(uint32_t) * (mDirtyRangeArrayLength.end - mDirtyRangeArrayLength.begin),
                    mInternalArrayLengthBufferData.data() + mDirtyRangeArrayLength.begin));
        DAWN_GL_TRY(gl, BindBuffer(GL_UNIFORM_BUFFER, 0));

        ResetInternalUniformDataDirtyRangeArrayLength();

        return {};
    }

    void UpdateSSBOLengthUniformData(const OpenGLFunctions& gl,
                                     uint64_t size,
                                     BindGroupIndex groupIndex,
                                     BindingIndex bindingIndex) {
        if (!mPipeline->NeedsSSBOLengthUniformBuffer()) {
            return;
        }

        const auto& bindingIndexInfo = ToBackend(mPipelineLayout)->GetBindingIndexInfo();
        FlatBindingIndex ssboIndex = bindingIndexInfo[groupIndex][bindingIndex];

        if (ssboIndex >= mInternalArrayLengthBufferData.size()) {
            mInternalArrayLengthBufferData.resize(ssboIndex + FlatBindingIndex(4));
        }
        mInternalArrayLengthBufferData[ssboIndex] = static_cast<uint32_t>(size);

        // Updating dirty range of the data vector
        mDirtyRangeArrayLength.begin = std::min(mDirtyRangeArrayLength.begin, size_t(ssboIndex));
        mDirtyRangeArrayLength.end = std::max(mDirtyRangeArrayLength.end, size_t(ssboIndex) + 1);
    }

    void ResetInternalUniformDataDirtyRangeArrayLength() {
        mDirtyRangeArrayLength = {size_t(mInternalArrayLengthBufferData.size()), 0};
    }

    void ResetInternalUniformDataBindgroupAndDirtyRange() {
        // Mark bind groups that need emulated builtin uniforms dirty so that they can be updated
        // properly, even if the bind group is not updated.
        // TODO(crbug.com/408065421): This forces bindgroups with metadata to be completely set
        // again each pipeline change. In the future we will want to optimize that to only recompute
        // the metadata as needed, not force a rebind of all resources.
        const auto& builtinInfo = mPipeline->GetEmulatedTextureBuiltinInfo();
        for (const auto& entry : builtinInfo) {
            mDirtyBindGroupsObjectChangedOrIsDynamic.set(BindGroupIndex(entry.second.group));
        }
        ResetInternalUniformDataDirtyRange();
        ResetInternalUniformDataDirtyRangeArrayLength();
    }

    raw_ptr<PipelineGL> mPipeline = nullptr;

    // The data used for mPipeline's internal uniform buffer from current bind group.
    // Expecting no more than 4 texture bindings called as textureNumLevels/textureNumSamples
    // argument in a pipeline. Initialize the vector to this size to avoid frequent resizing.
    std::vector<uint8_t> mInternalUniformBufferData = std::vector<uint8_t>(4 * sizeof(uint32_t));
    // Tracking dirty byte range of the mInternalUniformBufferData that needs to call bufferSubData
    // to update to the internal uniform buffer of mPipeline.
    VectorDirtyRangeInfo mDirtyRange;

    // The data used for mPipeline's internal uniform buffer to store ssbo buffer sizes.
    ityp::vector<FlatBindingIndex, uint32_t> mInternalArrayLengthBufferData;
    // Tracking dirty byte range of the mInternalArrayLengthBufferData that needs to call
    // bufferSubData to update to the internal uniform buffer of mPipeline.
    VectorDirtyRangeInfo mDirtyRangeArrayLength;
};

MaybeError ResolveMultisampledRenderTargets(const OpenGLFunctions& gl,
                                            const BeginRenderPassCmd* renderPass) {
    DAWN_ASSERT(renderPass != nullptr);

    // Reset state that may affect glBlitFramebuffer().
    DAWN_GL_TRY(gl, Disable(GL_SCISSOR_TEST));

    GLuint readFbo = 0;
    GLuint writeFbo = 0;

    for (auto i : renderPass->attachmentState->GetColorAttachmentsMask()) {
        if (renderPass->colorAttachments[i].resolveTarget != nullptr) {
            if (readFbo == 0) {
                DAWN_ASSERT(writeFbo == 0);
                DAWN_GL_TRY(gl, GenFramebuffers(1, &readFbo));
                DAWN_GL_TRY(gl, GenFramebuffers(1, &writeFbo));
            }

            TextureView* colorView = ToBackend(renderPass->colorAttachments[i].view.Get());

            DAWN_GL_TRY(gl, BindFramebuffer(GL_READ_FRAMEBUFFER, readFbo));
            DAWN_TRY(colorView->BindToFramebuffer(gl, GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0));

            TextureView* resolveView =
                ToBackend(renderPass->colorAttachments[i].resolveTarget.Get());
            DAWN_GL_TRY(gl, BindFramebuffer(GL_DRAW_FRAMEBUFFER, writeFbo));
            DAWN_TRY(resolveView->BindToFramebuffer(gl, GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0));
            DAWN_GL_TRY(gl, BlitFramebuffer(0, 0, renderPass->width, renderPass->height, 0, 0,
                                            renderPass->width, renderPass->height,
                                            GL_COLOR_BUFFER_BIT, GL_NEAREST));
        }
    }

    DAWN_GL_TRY(gl, Enable(GL_SCISSOR_TEST));
    DAWN_GL_TRY(gl, DeleteFramebuffers(1, &readFbo));
    DAWN_GL_TRY(gl, DeleteFramebuffers(1, &writeFbo));
    return {};
}

// OpenGL SPEC requires the source/destination region muPst be a region that is contained
// within srcImage/dstImage. Here the size of the image refers to the virtual size, while
// Dawn validates texture copy extent with the physical size, so we need to re-calculate the
// texture copy extent to ensure it should fit in the virtual size of the subresource.
TexelExtent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy,
                                       const TexelExtent3D& copySize) {
    TexelExtent3D validTextureCopyExtent = copySize;
    const TextureBase* texture = textureCopy.texture.Get();
    TexelExtent3D virtualSizeAtLevel =
        texture->GetMipLevelSingleSubresourceVirtualSize(textureCopy.mipLevel, textureCopy.aspect);
    DAWN_ASSERT(textureCopy.origin.x <= virtualSizeAtLevel.width);
    DAWN_ASSERT(textureCopy.origin.y <= virtualSizeAtLevel.height);
    if (copySize.width > virtualSizeAtLevel.width - textureCopy.origin.x) {
        DAWN_ASSERT(texture->GetFormat().isCompressed);
        validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
    }
    if (copySize.height > virtualSizeAtLevel.height - textureCopy.origin.y) {
        DAWN_ASSERT(texture->GetFormat().isCompressed);
        validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
    }

    return validTextureCopyExtent;
}

}  // namespace

CommandBuffer::CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor)
    : CommandBufferBase(encoder, descriptor) {}

MaybeError CommandBuffer::Execute(const OpenGLFunctions& gl) {
    auto LazyClearSyncScope = [gl](const SyncScopeResourceUsage& scope) -> MaybeError {
        for (size_t i = 0; i < scope.textures.size(); i++) {
            Texture* texture = ToBackend(scope.textures[i]);

            // Clear subresources that are not render attachments. Render attachments will be
            // cleared in RecordBeginRenderPass by setting the loadop to clear when the texture
            // subresource has not been initialized before the render pass.
            DAWN_TRY(scope.textureSyncInfos[i].Iterate(
                [&](const SubresourceRange& range, const TextureSyncInfo& syncInfo) -> MaybeError {
                    if (syncInfo.usage & ~wgpu::TextureUsage::RenderAttachment) {
                        DAWN_TRY(texture->EnsureSubresourceContentInitialized(gl, range));
                    }
                    return {};
                }));
        }

        for (BufferBase* bufferBase : scope.buffers) {
            DAWN_TRY(ToBackend(bufferBase)->EnsureDataInitialized());
        }
        return {};
    };

    size_t nextComputePassNumber = 0;
    size_t nextRenderPassNumber = 0;

    Command type;
    while (mCommands.NextCommandId(&type)) {
        switch (type) {
            case Command::BeginComputePass: {
                mCommands.NextCommand<BeginComputePassCmd>();
                for (TextureBase* texture :
                     GetResourceUsages().computePasses[nextComputePassNumber].referencedTextures) {
                    DAWN_TRY(ToBackend(texture)->SynchronizeTextureBeforeUse());
                }
                for (const SyncScopeResourceUsage& scope :
                     GetResourceUsages().computePasses[nextComputePassNumber].dispatchUsages) {
                    DAWN_TRY(LazyClearSyncScope(scope));
                }
                DAWN_TRY(ExecuteComputePass(gl));

                nextComputePassNumber++;
                break;
            }

            case Command::BeginRenderPass: {
                auto* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
                for (TextureBase* texture :
                     this->GetResourceUsages().renderPasses[nextRenderPassNumber].textures) {
                    DAWN_TRY(ToBackend(texture)->SynchronizeTextureBeforeUse());
                }
                DAWN_TRY(
                    LazyClearSyncScope(GetResourceUsages().renderPasses[nextRenderPassNumber]));
                LazyClearRenderPassAttachments(cmd);
                DAWN_TRY(ExecuteRenderPass(cmd, gl));

                nextRenderPassNumber++;
                break;
            }

            case Command::CopyBufferToBuffer: {
                CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
                if (copy->size == 0) {
                    // Skip no-op copies.
                    break;
                }

                DAWN_TRY(ToBackend(copy->source)->EnsureDataInitialized());
                DAWN_TRY(
                    ToBackend(copy->destination)
                        ->EnsureDataInitializedAsDestination(copy->destinationOffset, copy->size));

                DAWN_GL_TRY(gl,
                            BindBuffer(GL_PIXEL_PACK_BUFFER, ToBackend(copy->source)->GetHandle()));
                DAWN_GL_TRY(gl, BindBuffer(GL_PIXEL_UNPACK_BUFFER,
                                           ToBackend(copy->destination)->GetHandle()));
                DAWN_GL_TRY(
                    gl, CopyBufferSubData(GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER,
                                          copy->sourceOffset, copy->destinationOffset, copy->size));

                DAWN_GL_TRY(gl, BindBuffer(GL_PIXEL_PACK_BUFFER, 0));
                DAWN_GL_TRY(gl, BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

                ToBackend(copy->source)->TrackUsage();
                ToBackend(copy->destination)->TrackUsage();
                break;
            }

            case Command::CopyBufferToTexture: {
                CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
                if (copy->copySize.IsEmpty()) {
                    // Skip no-op copies.
                    continue;
                }
                auto& src = copy->source;
                auto& dst = copy->destination;
                Buffer* buffer = ToBackend(src.buffer.Get());
                Texture* texture = ToBackend(dst.texture.Get());

                DAWN_TRY(texture->SynchronizeTextureBeforeUse());

                DAWN_TRY(buffer->EnsureDataInitialized());
                SubresourceRange range =
                    GetSubresourcesAffectedByCopy(dst, copy->copySize.ToExtent3D());
                if (IsCompleteSubresourceCopiedTo(texture, copy->copySize.ToExtent3D(),
                                                  dst.mipLevel, dst.aspect)) {
                    texture->SetIsSubresourceContentInitialized(true, range);
                } else {
                    DAWN_TRY(texture->EnsureSubresourceContentInitialized(gl, range));
                }

                DAWN_GL_TRY(gl, BindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->GetHandle()));

                // TODO(crbug.com/424536624): Replace TexelCopyBufferLayout with BufferCopy
                const TypedTexelBlockInfo& blockInfo = GetBlockInfo(dst);
                TexelCopyBufferLayout dataLayout;
                dataLayout.offset = 0;
                dataLayout.bytesPerRow = blockInfo.ToBytes(src.blocksPerRow);
                dataLayout.rowsPerImage = static_cast<uint32_t>(src.rowsPerImage);

                DAWN_TRY(DoTexSubImage(gl, dst, reinterpret_cast<void*>(src.offset), dataLayout,
                                       copy->copySize.ToExtent3D()));
                DAWN_GL_TRY(gl, BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

                buffer->TrackUsage();
                break;
            }

            case Command::CopyTextureToBuffer: {
                CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
                if (copy->copySize.IsEmpty()) {
                    // Skip no-op copies.
                    continue;
                }
                auto& src = copy->source;
                auto& dst = copy->destination;
                auto& copySize = copy->copySize;
                Texture* texture = ToBackend(src.texture.Get());
                Buffer* buffer = ToBackend(dst.buffer.Get());
                const Format& formatInfo = texture->GetFormat();
                const GLFormat& format = texture->GetGLFormat();
                GLenum target = texture->GetGLTarget();

                if (formatInfo.isCompressed) {
                    DAWN_UNREACHABLE();
                }

                DAWN_TRY(buffer->EnsureDataInitializedAsDestination(copy));
                DAWN_TRY(texture->SynchronizeTextureBeforeUse());

                SubresourceRange subresources =
                    GetSubresourcesAffectedByCopy(src, copy->copySize.ToExtent3D());
                DAWN_TRY(texture->EnsureSubresourceContentInitialized(gl, subresources));
                // The only way to move data from a texture to a buffer in GL is via
                // glReadPixels with a pack buffer. Create a temporary FBO for the copy.
                DAWN_GL_TRY(gl, BindTexture(target, texture->GetHandle()));

                GLuint readFBO = 0;
                DAWN_GL_TRY(gl, GenFramebuffers(1, &readFBO));
                DAWN_GL_TRY(gl, BindFramebuffer(GL_READ_FRAMEBUFFER, readFBO));

                const TypedTexelBlockInfo& blockInfo = GetBlockInfo(src);

                DAWN_GL_TRY(gl, BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle()));
                DAWN_GL_TRY(gl, PixelStorei(GL_PACK_ALIGNMENT, std::min(8u, blockInfo.byteSize)));
                DAWN_GL_TRY(
                    gl, PixelStorei(GL_PACK_ROW_LENGTH, static_cast<uint32_t>(dst.blocksPerRow)));

                GLenum glAttachment;
                GLenum glFormat;
                GLenum glType;
                switch (src.aspect) {
                    case Aspect::Color:
                        glAttachment = GL_COLOR_ATTACHMENT0;
                        glFormat = format.format;
                        glType = format.type;
                        break;
                    case Aspect::Depth:
                        glAttachment = GL_DEPTH_ATTACHMENT;
                        glFormat = GL_DEPTH_COMPONENT;
                        glType = GL_FLOAT;
                        break;
                    case Aspect::Stencil:
                        glAttachment = GL_STENCIL_ATTACHMENT;
                        glFormat = GL_STENCIL_INDEX;
                        glType = GL_UNSIGNED_BYTE;
                        break;

                    case Aspect::CombinedDepthStencil:
                    case Aspect::None:
                    case Aspect::Plane0:
                    case Aspect::Plane1:
                    case Aspect::Plane2:
                        DAWN_UNREACHABLE();
                }

                uint8_t* offset = reinterpret_cast<uint8_t*>(static_cast<uintptr_t>(dst.offset));
                switch (texture->GetDimension()) {
                    case wgpu::TextureDimension::Undefined:
                        DAWN_UNREACHABLE();
                    case wgpu::TextureDimension::e1D:
                    case wgpu::TextureDimension::e2D: {
                        if (target == GL_TEXTURE_2D) {
                            DAWN_ASSERT(texture->GetArrayLayers() == 1);
                            DAWN_GL_TRY(
                                gl, FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, target,
                                                         texture->GetHandle(), src.mipLevel));
                            DAWN_GL_TRY(gl, ReadPixels(static_cast<uint32_t>(src.origin.x),
                                                       static_cast<uint32_t>(src.origin.y),
                                                       static_cast<uint32_t>(copySize.width),
                                                       static_cast<uint32_t>(copySize.height),
                                                       glFormat, glType, offset));
                            break;
                        } else if (target == GL_TEXTURE_CUBE_MAP) {
                            DAWN_ASSERT(texture->GetArrayLayers() == 6);
                            const uint64_t bytesPerImage =
                                blockInfo.ToBytes(dst.blocksPerRow * dst.rowsPerImage);
                            for (TexelCount z{0}; z < copySize.depthOrArrayLayers; ++z) {
                                GLenum cubeMapTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X +
                                                       static_cast<uint32_t>(z + src.origin.z);
                                DAWN_GL_TRY(
                                    gl, FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment,
                                                             cubeMapTarget, texture->GetHandle(),
                                                             src.mipLevel));
                                DAWN_GL_TRY(gl, ReadPixels(static_cast<uint32_t>(src.origin.x),
                                                           static_cast<uint32_t>(src.origin.y),
                                                           static_cast<uint32_t>(copySize.width),
                                                           static_cast<uint32_t>(copySize.height),
                                                           glFormat, glType, offset));
                                offset += bytesPerImage;
                            }
                            break;
                        }
                        // Implementation for 2D array is the same as 3D.
                        [[fallthrough]];
                    }

                    case wgpu::TextureDimension::e3D: {
                        const uint64_t bytesPerImage =
                            blockInfo.ToBytes(dst.blocksPerRow * dst.rowsPerImage);
                        for (TexelCount z{0}; z < copySize.depthOrArrayLayers; ++z) {
                            DAWN_GL_TRY(gl,
                                        FramebufferTextureLayer(
                                            GL_READ_FRAMEBUFFER, glAttachment, texture->GetHandle(),
                                            src.mipLevel, static_cast<uint32_t>(src.origin.z + z)));
                            DAWN_GL_TRY(gl, ReadPixels(static_cast<uint32_t>(src.origin.x),
                                                       static_cast<uint32_t>(src.origin.y),
                                                       static_cast<uint32_t>(copySize.width),
                                                       static_cast<uint32_t>(copySize.height),
                                                       glFormat, glType, offset));

                            offset += bytesPerImage;
                        }
                        break;
                    }
                }

                DAWN_GL_TRY(gl, PixelStorei(GL_PACK_ROW_LENGTH, 0));
                DAWN_GL_TRY(gl, PixelStorei(GL_PACK_ALIGNMENT, 4));  // Reset to default
                DAWN_GL_TRY(gl, BindBuffer(GL_PIXEL_PACK_BUFFER, 0));
                DAWN_GL_TRY(gl, DeleteFramebuffers(1, &readFBO));

                buffer->TrackUsage();
                break;
            }

            case Command::CopyTextureToTexture: {
                CopyTextureToTextureCmd* copy = mCommands.NextCommand<CopyTextureToTextureCmd>();
                if (copy->copySize.IsEmpty()) {
                    // Skip no-op copies.
                    continue;
                }
                auto& src = copy->source;
                auto& dst = copy->destination;

                // TODO(crbug.com/dawn/817): add workaround for the case that imageExtentSrc
                // is not equal to imageExtentDst. For example when copySize fits in the virtual
                // size of the source image but does not fit in the one of the destination
                // image.
                TexelExtent3D copySize = ComputeTextureCopyExtent(dst, copy->copySize);
                Texture* srcTexture = ToBackend(src.texture.Get());
                Texture* dstTexture = ToBackend(dst.texture.Get());

                DAWN_TRY(srcTexture->SynchronizeTextureBeforeUse());
                DAWN_TRY(dstTexture->SynchronizeTextureBeforeUse());

                SubresourceRange srcRange =
                    GetSubresourcesAffectedByCopy(src, copy->copySize.ToExtent3D());
                SubresourceRange dstRange =
                    GetSubresourcesAffectedByCopy(dst, copy->copySize.ToExtent3D());

                DAWN_TRY(srcTexture->EnsureSubresourceContentInitialized(gl, srcRange));
                if (IsCompleteSubresourceCopiedTo(dstTexture, copySize.ToExtent3D(), dst.mipLevel,
                                                  dst.aspect)) {
                    dstTexture->SetIsSubresourceContentInitialized(true, dstRange);
                } else {
                    DAWN_TRY(dstTexture->EnsureSubresourceContentInitialized(gl, dstRange));
                }
                DAWN_TRY(CopyImageSubData(gl, src.aspect, srcTexture->GetHandle(),
                                          srcTexture->GetGLTarget(), src.mipLevel,
                                          src.origin.ToOrigin3D(), dstTexture->GetHandle(),
                                          dstTexture->GetGLTarget(), dst.mipLevel,
                                          dst.origin.ToOrigin3D(), copySize.ToExtent3D()));
                break;
            }

            case Command::ClearBuffer: {
                ClearBufferCmd* cmd = mCommands.NextCommand<ClearBufferCmd>();
                if (cmd->size == 0) {
                    // Skip no-op fills.
                    break;
                }
                Buffer* dstBuffer = ToBackend(cmd->buffer.Get());

                bool clearedToZero = false;
                DAWN_TRY(dstBuffer->EnsureDataInitializedAsDestination(cmd->offset, cmd->size,
                                                                       &clearedToZero));

                if (!clearedToZero) {
                    const std::vector<uint8_t> clearValues(cmd->size, 0u);
                    DAWN_GL_TRY(gl, BindBuffer(GL_ARRAY_BUFFER, dstBuffer->GetHandle()));
                    DAWN_GL_TRY(gl, BufferSubData(GL_ARRAY_BUFFER, cmd->offset, cmd->size,
                                                  clearValues.data()));
                }

                dstBuffer->TrackUsage();
                break;
            }

            case Command::ResolveQuerySet: {
                ResolveQuerySetCmd* cmd = mCommands.NextCommand<ResolveQuerySetCmd>();
                QuerySet* querySet = ToBackend(cmd->querySet.Get());
                Buffer* destination = ToBackend(cmd->destination.Get());

                size_t size = cmd->queryCount * sizeof(uint64_t);
                DAWN_TRY(
                    destination->EnsureDataInitializedAsDestination(cmd->destinationOffset, size));

                std::vector<uint64_t> values(cmd->queryCount);
                auto availability = querySet->GetQueryAvailability();

                for (uint32_t i = 0; i < cmd->queryCount; ++i) {
                    if (!availability[cmd->firstQuery + i]) {
                        values[i] = 0;
                        continue;
                    }
                    uint32_t query = querySet->Get(cmd->firstQuery + i);
                    GLuint value;
                    DAWN_GL_TRY(gl, GetQueryObjectuiv(query, GL_QUERY_RESULT, &value));
                    values[i] = value;
                }

                DAWN_GL_TRY(gl, BindBuffer(GL_ARRAY_BUFFER, destination->GetHandle()));
                DAWN_GL_TRY(gl, BufferSubData(GL_ARRAY_BUFFER, cmd->destinationOffset, size,
                                              values.data()));

                break;
            }

            case Command::WriteTimestamp: {
                return DAWN_UNIMPLEMENTED_ERROR("WriteTimestamp unimplemented");
            }

            case Command::InsertDebugMarker:
            case Command::PopDebugGroup:
            case Command::PushDebugGroup: {
                // Due to lack of linux driver support for GL_EXT_debug_marker
                // extension these functions are skipped.
                SkipCommand(&mCommands, type);
                break;
            }

            case Command::WriteBuffer: {
                WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
                uint64_t offset = write->offset;
                uint64_t size = write->size;
                if (size == 0) {
                    continue;
                }

                Buffer* dstBuffer = ToBackend(write->buffer.Get());
                uint8_t* data = mCommands.NextData<uint8_t>(size);
                DAWN_TRY(dstBuffer->EnsureDataInitializedAsDestination(offset, size));

                DAWN_GL_TRY(gl, BindBuffer(GL_ARRAY_BUFFER, dstBuffer->GetHandle()));
                DAWN_GL_TRY(gl, BufferSubData(GL_ARRAY_BUFFER, offset, size, data));

                dstBuffer->TrackUsage();
                break;
            }

            default:
                DAWN_UNREACHABLE();
        }
    }

    return {};
}

MaybeError CommandBuffer::ExecuteComputePass(const OpenGLFunctions& gl) {
    ComputePipeline* lastPipeline = nullptr;
    BindGroupTracker bindGroupTracker = {};

    Command type;
    while (mCommands.NextCommandId(&type)) {
        switch (type) {
            case Command::EndComputePass: {
                mCommands.NextCommand<EndComputePassCmd>();
                return {};
            }

            case Command::Dispatch: {
                DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();
                DAWN_TRY(bindGroupTracker.Apply(gl));

                DAWN_GL_TRY(gl, DispatchCompute(dispatch->x, dispatch->y, dispatch->z));
                DAWN_GL_TRY(gl, MemoryBarrier(GL_ALL_BARRIER_BITS));
                break;
            }

            case Command::DispatchIndirect: {
                DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>();
                DAWN_TRY(bindGroupTracker.Apply(gl));

                uint64_t indirectBufferOffset = dispatch->indirectOffset;
                Buffer* indirectBuffer = ToBackend(dispatch->indirectBuffer.Get());

                DAWN_GL_TRY(gl,
                            BindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirectBuffer->GetHandle()));
                DAWN_GL_TRY(gl,
                            DispatchComputeIndirect(static_cast<GLintptr>(indirectBufferOffset)));
                DAWN_GL_TRY(gl, MemoryBarrier(GL_ALL_BARRIER_BITS));

                indirectBuffer->TrackUsage();
                break;
            }

            case Command::SetComputePipeline: {
                SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>();
                lastPipeline = ToBackend(cmd->pipeline).Get();
                DAWN_TRY(lastPipeline->ApplyNow(gl));

                bindGroupTracker.OnSetPipeline(lastPipeline);
                break;
            }

            case Command::SetBindGroup: {
                SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
                uint32_t* dynamicOffsets = nullptr;
                if (cmd->dynamicOffsetCount > 0) {
                    dynamicOffsets = mCommands.NextData<uint32_t>(cmd->dynamicOffsetCount);
                }
                bindGroupTracker.OnSetBindGroup(cmd->index, cmd->group.Get(),
                                                cmd->dynamicOffsetCount, dynamicOffsets);
                break;
            }

            case Command::InsertDebugMarker:
            case Command::PopDebugGroup:
            case Command::PushDebugGroup: {
                // Due to lack of linux driver support for GL_EXT_debug_marker
                // extension these functions are skipped.
                SkipCommand(&mCommands, type);
                break;
            }

            case Command::WriteTimestamp: {
                return DAWN_UNIMPLEMENTED_ERROR("WriteTimestamp unimplemented");
            }

            case Command::SetImmediates:
                return DAWN_UNIMPLEMENTED_ERROR("SetImmediates unimplemented");

            default:
                DAWN_UNREACHABLE();
        }
    }

    // EndComputePass should have been called
    DAWN_UNREACHABLE();
}

MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass,
                                            const OpenGLFunctions& gl) {
    GLuint fbo = 0;

    // Create the framebuffer used for this render pass and calls the correct glDrawBuffers
    {
        // TODO(kainino@chromium.org): This is added to possibly work around an issue seen on
        // Windows/Intel. It should break any feedback loop before the clears, even if there
        // shouldn't be any negative effects from this. Investigate whether it's actually
        // needed.
        DAWN_GL_TRY(gl, BindFramebuffer(GL_READ_FRAMEBUFFER, 0));
        // TODO(kainino@chromium.org): possible future optimization: create these framebuffers
        // at Framebuffer build time (or maybe CommandBuffer build time) so they don't have to
        // be created and destroyed at draw time.
        DAWN_GL_TRY(gl, GenFramebuffers(1, &fbo));
        DAWN_GL_TRY(gl, BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo));

        // Mapping from attachmentSlot to GL framebuffer attachment points. Defaults to zero
        // (GL_NONE).
        PerColorAttachment<GLenum> drawBuffers = {};

        // Construct GL framebuffer

        ColorAttachmentIndex attachmentCount{};
        for (auto i : renderPass->attachmentState->GetColorAttachmentsMask()) {
            TextureView* textureView = ToBackend(renderPass->colorAttachments[i].view.Get());
            GLenum glAttachment = GL_COLOR_ATTACHMENT0 + static_cast<uint8_t>(i);

            // Attach color buffers.
            DAWN_TRY(textureView->BindToFramebuffer(gl, GL_DRAW_FRAMEBUFFER, glAttachment,
                                                    renderPass->colorAttachments[i].depthSlice));
            drawBuffers[i] = glAttachment;
            attachmentCount = ityp::PlusOne(i);
        }
        DAWN_GL_TRY(gl, DrawBuffers(static_cast<uint8_t>(attachmentCount), drawBuffers.data()));

        if (renderPass->attachmentState->HasDepthStencilAttachment()) {
            TextureView* textureView = ToBackend(renderPass->depthStencilAttachment.view.Get());
            const Format& format = textureView->GetTexture()->GetFormat();

            // Attach depth/stencil buffer.
            GLenum glAttachment = 0;
            if (format.aspects == (Aspect::Depth | Aspect::Stencil)) {
                glAttachment = GL_DEPTH_STENCIL_ATTACHMENT;
            } else if (format.aspects == Aspect::Depth) {
                glAttachment = GL_DEPTH_ATTACHMENT;
            } else if (format.aspects == Aspect::Stencil) {
                glAttachment = GL_STENCIL_ATTACHMENT;
            } else {
                DAWN_UNREACHABLE();
            }

            DAWN_TRY(textureView->BindToFramebuffer(gl, GL_DRAW_FRAMEBUFFER, glAttachment));
        }
    }

    DAWN_ASSERT(gl.CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);

    // Set defaults for dynamic state before executing clears and commands.
    PersistentPipelineState persistentPipelineState;
    DAWN_TRY(persistentPipelineState.SetDefaultState(gl));
    DAWN_GL_TRY(gl, BlendColor(0, 0, 0, 0));
    DAWN_GL_TRY(gl, Viewport(0, 0, renderPass->width, renderPass->height));
    float minDepth = 0.0f;
    float maxDepth = 1.0f;
    DAWN_GL_TRY(gl, DepthRangef(minDepth, maxDepth));

    DAWN_GL_TRY(gl, Scissor(0, 0, renderPass->width, renderPass->height));

    // Clear framebuffer attachments as needed
    {
        for (auto index : renderPass->attachmentState->GetColorAttachmentsMask()) {
            uint8_t i = static_cast<uint8_t>(index);
            auto* attachmentInfo = &renderPass->colorAttachments[index];

            // Load op - color
            if (attachmentInfo->loadOp == wgpu::LoadOp::Clear) {
                DAWN_GL_TRY(gl, ColorMask(true, true, true, true));

                TextureComponentType baseType =
                    attachmentInfo->view->GetFormat().GetAspectInfo(Aspect::Color).baseType;
                switch (baseType) {
                    case TextureComponentType::Float: {
                        const std::array<float, 4> appliedClearColor =
                            ConvertToFloatColor(attachmentInfo->clearColor);
                        DAWN_GL_TRY(gl, ClearBufferfv(GL_COLOR, i, appliedClearColor.data()));
                        break;
                    }
                    case TextureComponentType::Uint: {
                        const std::array<uint32_t, 4> appliedClearColor =
                            ConvertToUnsignedIntegerColor(attachmentInfo->clearColor);
                        DAWN_GL_TRY(gl, ClearBufferuiv(GL_COLOR, i, appliedClearColor.data()));
                        break;
                    }
                    case TextureComponentType::Sint: {
                        const std::array<int32_t, 4> appliedClearColor =
                            ConvertToSignedIntegerColor(attachmentInfo->clearColor);
                        DAWN_GL_TRY(gl, ClearBufferiv(GL_COLOR, i, appliedClearColor.data()));
                        break;
                    }
                }
            }

            if (attachmentInfo->storeOp == wgpu::StoreOp::Discard) {
                // TODO(natlee@microsoft.com): call glDiscard to do optimization
            }
        }

        if (renderPass->attachmentState->HasDepthStencilAttachment()) {
            auto* attachmentInfo = &renderPass->depthStencilAttachment;
            const Format& attachmentFormat = attachmentInfo->view->GetTexture()->GetFormat();

            // Load op - depth/stencil
            bool doDepthClear =
                attachmentFormat.HasDepth() && (attachmentInfo->depthLoadOp == wgpu::LoadOp::Clear);
            bool doStencilClear = attachmentFormat.HasStencil() &&
                                  (attachmentInfo->stencilLoadOp == wgpu::LoadOp::Clear);

            if (doDepthClear) {
                DAWN_GL_TRY(gl, DepthMask(GL_TRUE));
            }
            if (doStencilClear) {
                DAWN_GL_TRY(gl,
                            StencilMask(GetStencilMaskFromStencilFormat(attachmentFormat.format)));
            }

            if (doDepthClear && doStencilClear) {
                DAWN_GL_TRY(gl, ClearBufferfi(GL_DEPTH_STENCIL, 0, attachmentInfo->clearDepth,
                                              attachmentInfo->clearStencil));
            } else if (doDepthClear) {
                DAWN_GL_TRY(gl, ClearBufferfv(GL_DEPTH, 0, &attachmentInfo->clearDepth));
            } else if (doStencilClear) {
                const GLint clearStencil = attachmentInfo->clearStencil;
                DAWN_GL_TRY(gl, ClearBufferiv(GL_STENCIL, 0, &clearStencil));
            }
        }
    }

    RenderPipeline* lastPipeline = nullptr;
    uint64_t indexBufferBaseOffset = 0;
    GLenum indexBufferFormat;
    uint32_t indexFormatSize;

    VertexStateBufferBindingTracker vertexStateBufferBindingTracker;
    BindGroupTracker bindGroupTracker = {};

    auto DoRenderBundleCommand = [&](CommandIterator* iter, Command type) -> MaybeError {
        switch (type) {
            case Command::Draw: {
                DrawCmd* draw = iter->NextCommand<DrawCmd>();
                DAWN_TRY(vertexStateBufferBindingTracker.Apply(gl, 0, draw->firstInstance));
                DAWN_TRY(bindGroupTracker.Apply(gl));

                if (lastPipeline->UsesInstanceIndex()) {
                    DAWN_GL_TRY(gl, Uniform1ui(PipelineLayout::ImmediateLocation::FirstInstance,
                                               draw->firstInstance));
                }
                DAWN_GL_TRY(gl, DrawArraysInstanced(lastPipeline->GetGLPrimitiveTopology(),
                                                    draw->firstVertex, draw->vertexCount,
                                                    draw->instanceCount));
                break;
            }

            case Command::DrawIndexed: {
                DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
                DAWN_TRY(vertexStateBufferBindingTracker.Apply(gl, draw->baseVertex,
                                                               draw->firstInstance));
                DAWN_TRY(bindGroupTracker.Apply(gl));

                const auto topology = lastPipeline->GetGLPrimitiveTopology();
                if (topology == GL_LINE_STRIP || topology == GL_TRIANGLE_STRIP) {
                    DAWN_GL_TRY(gl, Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX));
                } else {
                    DAWN_GL_TRY(gl, Disable(GL_PRIMITIVE_RESTART_FIXED_INDEX));
                }

                if (lastPipeline->UsesVertexIndex()) {
                    DAWN_GL_TRY(gl, Uniform1ui(PipelineLayout::ImmediateLocation::FirstVertex,
                                               draw->baseVertex));
                }
                if (lastPipeline->UsesInstanceIndex()) {
                    DAWN_GL_TRY(gl, Uniform1ui(PipelineLayout::ImmediateLocation::FirstInstance,
                                               draw->firstInstance));
                }
                DAWN_GL_TRY(gl, DrawElementsInstanced(
                                    topology, draw->indexCount, indexBufferFormat,
                                    reinterpret_cast<void*>(draw->firstIndex * indexFormatSize +
                                                            indexBufferBaseOffset),
                                    draw->instanceCount));
                break;
            }

            case Command::DrawIndirect: {
                DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
                if (lastPipeline->UsesInstanceIndex()) {
                    DAWN_GL_TRY(gl,
                                Uniform1ui(PipelineLayout::ImmediateLocation::FirstInstance, 0));
                }
                DAWN_TRY(vertexStateBufferBindingTracker.Apply(gl, 0, 0));
                DAWN_TRY(bindGroupTracker.Apply(gl));

                uint64_t indirectBufferOffset = draw->indirectOffset;
                Buffer* indirectBuffer = ToBackend(draw->indirectBuffer.Get());

                DAWN_GL_TRY(gl, BindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer->GetHandle()));
                DAWN_GL_TRY(
                    gl, DrawArraysIndirect(
                            lastPipeline->GetGLPrimitiveTopology(),
                            reinterpret_cast<void*>(static_cast<intptr_t>(indirectBufferOffset))));
                indirectBuffer->TrackUsage();
                break;
            }

            case Command::DrawIndexedIndirect: {
                DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();

                if (lastPipeline->UsesInstanceIndex()) {
                    DAWN_GL_TRY(gl,
                                Uniform1ui(PipelineLayout::ImmediateLocation::FirstInstance, 0));
                }
                DAWN_TRY(vertexStateBufferBindingTracker.Apply(gl, 0, 0));
                DAWN_TRY(bindGroupTracker.Apply(gl));

                Buffer* indirectBuffer = ToBackend(draw->indirectBuffer.Get());
                DAWN_ASSERT(indirectBuffer != nullptr);

                const auto topology = lastPipeline->GetGLPrimitiveTopology();
                if (topology == GL_LINE_STRIP || topology == GL_TRIANGLE_STRIP) {
                    DAWN_GL_TRY(gl, Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX));
                } else {
                    DAWN_GL_TRY(gl, Disable(GL_PRIMITIVE_RESTART_FIXED_INDEX));
                }

                DAWN_GL_TRY(gl, BindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer->GetHandle()));
                DAWN_GL_TRY(
                    gl, DrawElementsIndirect(
                            topology, indexBufferFormat,
                            reinterpret_cast<void*>(static_cast<intptr_t>(draw->indirectOffset))));
                indirectBuffer->TrackUsage();
                break;
            }

            case Command::InsertDebugMarker:
            case Command::PopDebugGroup:
            case Command::PushDebugGroup: {
                // Due to lack of linux driver support for GL_EXT_debug_marker
                // extension these functions are skipped.
                SkipCommand(iter, type);
                break;
            }

            case Command::SetRenderPipeline: {
                SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
                lastPipeline = ToBackend(cmd->pipeline).Get();
                DAWN_TRY(lastPipeline->ApplyNow(gl, persistentPipelineState));

                vertexStateBufferBindingTracker.OnSetPipeline(lastPipeline);
                bindGroupTracker.OnSetPipeline(lastPipeline);
                if (lastPipeline->UsesFragDepth()) {
                    DAWN_GL_TRY(gl,
                                Uniform1f(PipelineLayout::ImmediateLocation::MinDepth, minDepth));
                    DAWN_GL_TRY(gl,
                                Uniform1f(PipelineLayout::ImmediateLocation::MaxDepth, maxDepth));
                }
                break;
            }

            case Command::SetBindGroup: {
                SetBindGroupCmd* cmd = iter->NextCommand<SetBindGroupCmd>();
                uint32_t* dynamicOffsets = nullptr;
                if (cmd->dynamicOffsetCount > 0) {
                    dynamicOffsets = iter->NextData<uint32_t>(cmd->dynamicOffsetCount);
                }
                bindGroupTracker.OnSetBindGroup(cmd->index, cmd->group.Get(),
                                                cmd->dynamicOffsetCount, dynamicOffsets);
                break;
            }

            case Command::SetIndexBuffer: {
                SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();

                indexBufferBaseOffset = cmd->offset;
                indexBufferFormat = IndexFormatType(cmd->format);
                indexFormatSize = IndexFormatSize(cmd->format);
                vertexStateBufferBindingTracker.OnSetIndexBuffer(cmd->buffer.Get());
                ToBackend(cmd->buffer)->TrackUsage();
                break;
            }

            case Command::SetVertexBuffer: {
                SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
                vertexStateBufferBindingTracker.OnSetVertexBuffer(cmd->slot, cmd->buffer.Get(),
                                                                  cmd->offset);
                ToBackend(cmd->buffer)->TrackUsage();
                break;
            }

            default:
                DAWN_UNREACHABLE();
                break;
        }

        return {};
    };

    Command type;
    while (mCommands.NextCommandId(&type)) {
        switch (type) {
            case Command::EndRenderPass: {
                mCommands.NextCommand<EndRenderPassCmd>();

                if (renderPass->attachmentState->GetSampleCount() > 1) {
                    DAWN_TRY(ResolveMultisampledRenderTargets(gl, renderPass));
                }
                DAWN_GL_TRY(gl, DeleteFramebuffers(1, &fbo));
                return {};
            }

            case Command::SetStencilReference: {
                SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
                DAWN_TRY(persistentPipelineState.SetStencilReference(gl, cmd->reference));
                break;
            }

            case Command::SetViewport: {
                SetViewportCmd* cmd = mCommands.NextCommand<SetViewportCmd>();
                if (gl.IsAtLeastGL(4, 1)) {
                    DAWN_GL_TRY(gl, ViewportIndexedf(0, cmd->x, cmd->y, cmd->width, cmd->height));
                } else {
                    // Floating-point viewport coords are unsupported on OpenGL ES, but
                    // truncation is ok because other APIs do not guarantee subpixel precision
                    // either.
                    DAWN_GL_TRY(
                        gl, Viewport(static_cast<int>(cmd->x), static_cast<int>(cmd->y),
                                     static_cast<int>(cmd->width), static_cast<int>(cmd->height)));
                }
                minDepth = cmd->minDepth;
                maxDepth = cmd->maxDepth;
                DAWN_GL_TRY(gl, DepthRangef(minDepth, maxDepth));
                if (lastPipeline && lastPipeline->UsesFragDepth()) {
                    DAWN_GL_TRY(gl,
                                Uniform1f(PipelineLayout::ImmediateLocation::MinDepth, minDepth));
                    DAWN_GL_TRY(gl,
                                Uniform1f(PipelineLayout::ImmediateLocation::MaxDepth, maxDepth));
                }
                break;
            }

            case Command::SetScissorRect: {
                SetScissorRectCmd* cmd = mCommands.NextCommand<SetScissorRectCmd>();
                DAWN_GL_TRY(gl, Scissor(cmd->x, cmd->y, cmd->width, cmd->height));
                break;
            }

            case Command::SetBlendConstant: {
                SetBlendConstantCmd* cmd = mCommands.NextCommand<SetBlendConstantCmd>();
                const std::array<float, 4> blendColor = ConvertToFloatColor(cmd->color);
                DAWN_GL_TRY(gl,
                            BlendColor(blendColor[0], blendColor[1], blendColor[2], blendColor[3]));
                break;
            }

            case Command::ExecuteBundles: {
                ExecuteBundlesCmd* cmd = mCommands.NextCommand<ExecuteBundlesCmd>();
                auto bundles = mCommands.NextData<Ref<RenderBundleBase>>(cmd->count);

                for (uint32_t i = 0; i < cmd->count; ++i) {
                    CommandIterator* iter = bundles[i]->GetCommands();
                    iter->Reset();
                    while (iter->NextCommandId(&type)) {
                        DAWN_TRY(DoRenderBundleCommand(iter, type));
                    }
                }
                break;
            }

            case Command::BeginOcclusionQuery: {
                BeginOcclusionQueryCmd* cmd = mCommands.NextCommand<BeginOcclusionQueryCmd>();
                QuerySet* querySet = ToBackend(renderPass->occlusionQuerySet.Get());
                DAWN_GL_TRY(gl, BeginQuery(GL_ANY_SAMPLES_PASSED, querySet->Get(cmd->queryIndex)));
                break;
            }

            case Command::EndOcclusionQuery: {
                mCommands.NextCommand<EndOcclusionQueryCmd>();
                DAWN_GL_TRY(gl, EndQuery(GL_ANY_SAMPLES_PASSED));
                break;
            }

            case Command::WriteTimestamp:
                return DAWN_UNIMPLEMENTED_ERROR("WriteTimestamp unimplemented");

            case Command::SetImmediates:
                return DAWN_UNIMPLEMENTED_ERROR("SetImmediates unimplemented");

            default: {
                DAWN_TRY(DoRenderBundleCommand(&mCommands, type));
                break;
            }
        }
    }

    // EndRenderPass should have been called
    DAWN_UNREACHABLE();
}

MaybeError DoTexSubImage(const OpenGLFunctions& gl,
                         const TextureCopy& destination,
                         const void* data,
                         const TexelCopyBufferLayout& dataLayout,
                         const TexelExtent3D& copySize) {
    Texture* texture = ToBackend(destination.texture.Get());

    const GLFormat& format = texture->GetGLFormat();
    GLenum target = texture->GetGLTarget();
    data = static_cast<const uint8_t*>(data) + dataLayout.offset;
    DAWN_GL_TRY(gl, ActiveTexture(GL_TEXTURE0));
    DAWN_GL_TRY(gl, BindTexture(target, texture->GetHandle()));
    const TypedTexelBlockInfo& blockInfo = GetBlockInfo(destination);
    const BlockExtent3D blockCopySize = blockInfo.ToBlock(copySize);
    const uint64_t bytesPerImage = dataLayout.rowsPerImage * dataLayout.bytesPerRow;
    const BlockCount rowsPerImage{dataLayout.rowsPerImage};
    // Note: bytesPerRow is not necessarily a multiple of block size because WriteTexture is
    // directly implemented by the GL backend and doesn't have alignment constraints for
    // bytesPerRow.
    const uint64_t bytesPerRow = dataLayout.bytesPerRow;

    TexelCount x = destination.origin.x;
    TexelCount y = destination.origin.y;
    TexelCount z = destination.origin.z;

    if (texture->GetFormat().isCompressed) {
        size_t rowSize = blockInfo.ToBytes(blockCopySize.width);
        TexelExtent3D virtSize = texture->GetMipLevelSingleSubresourceVirtualSize(
            destination.mipLevel, destination.aspect);
        const TexelCount width = std::min(copySize.width, virtSize.width - x);

        // In GLES glPixelStorei() doesn't affect CompressedTexSubImage*D() and
        // GL_UNPACK_COMPRESSED_BLOCK_* isn't defined, so we have to workaround
        // this limitation by copying the compressed texture data once per row.
        // See OpenGL ES 3.2 SPEC Chapter 8.4.1, "Pixel Storage Modes and Pixel
        // Buffer Objects" for more details. For Desktop GL, we use row-by-row
        // copies only for uploads where bytesPerRow is not a multiple of byteSize.
        if (bytesPerRow % blockInfo.byteSize == 0 && gl.GetVersion().IsDesktop()) {
            const BlockCount blocksPerRow = blockInfo.BytesToBlocks(bytesPerRow);

            size_t imageSize = rowSize * blockInfo.ToBytes(blockCopySize.height *
                                                           blockCopySize.depthOrArrayLayers);

            const TexelCount height = std::min(copySize.height, virtSize.height - y);

            DAWN_GL_TRY(gl,
                        PixelStorei(GL_UNPACK_ROW_LENGTH,
                                    static_cast<uint32_t>(blockInfo.ToTexelWidth(blocksPerRow))));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH,
                                        static_cast<uint32_t>(blockInfo.width)));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT,
                                        static_cast<uint32_t>(blockInfo.height)));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1));

            if (target == GL_TEXTURE_2D) {
                DAWN_GL_TRY(
                    gl, CompressedTexSubImage2D(
                            target, destination.mipLevel, static_cast<uint32_t>(x),
                            static_cast<uint32_t>(y), static_cast<uint32_t>(width),
                            static_cast<uint32_t>(height), format.internalFormat, imageSize, data));
            } else if (target == GL_TEXTURE_CUBE_MAP) {
                DAWN_ASSERT(texture->GetArrayLayers() == 6);
                const uint8_t* pointer = static_cast<const uint8_t*>(data);
                TexelCount baseLayer = destination.origin.z;
                for (TexelCount l{0}; l < copySize.depthOrArrayLayers; ++l) {
                    GLenum cubeMapTarget =
                        GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<uint32_t>(baseLayer + l);
                    DAWN_GL_TRY(gl, CompressedTexSubImage2D(
                                        cubeMapTarget, destination.mipLevel,
                                        static_cast<uint32_t>(x), static_cast<uint32_t>(y),
                                        static_cast<uint32_t>(width), static_cast<uint32_t>(height),
                                        format.internalFormat, imageSize, pointer));
                    pointer += bytesPerImage;
                }
            } else {
                DAWN_GL_TRY(
                    gl, PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
                                    static_cast<uint32_t>(blockInfo.ToTexelHeight(rowsPerImage))));
                DAWN_GL_TRY(gl, CompressedTexSubImage3D(
                                    target, destination.mipLevel, static_cast<uint32_t>(x),
                                    static_cast<uint32_t>(y), static_cast<uint32_t>(z),
                                    static_cast<uint32_t>(width), static_cast<uint32_t>(height),
                                    static_cast<uint32_t>(copySize.depthOrArrayLayers),
                                    format.internalFormat, imageSize, data));
                DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0));
            }

            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_ROW_LENGTH, 0));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, 0));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0));
        } else {
            if (target == GL_TEXTURE_2D) {
                const uint8_t* d = static_cast<const uint8_t*>(data);

                for (; y < destination.origin.y + copySize.height; y += blockInfo.height) {
                    TexelCount height = std::min(blockInfo.height, virtSize.height - y);
                    DAWN_GL_TRY(
                        gl, CompressedTexSubImage2D(
                                target, destination.mipLevel, static_cast<uint32_t>(x),
                                static_cast<uint32_t>(y), static_cast<uint32_t>(width),
                                static_cast<uint32_t>(height), format.internalFormat, rowSize, d));
                    d += bytesPerRow;
                }
            } else if (target == GL_TEXTURE_CUBE_MAP) {
                DAWN_ASSERT(texture->GetArrayLayers() == 6);
                const uint8_t* pointer = static_cast<const uint8_t*>(data);
                TexelCount baseLayer = destination.origin.z;
                for (TexelCount l{0}; l < copySize.depthOrArrayLayers; ++l) {
                    const uint8_t* d = pointer + static_cast<uint32_t>(l) * bytesPerImage;
                    GLenum cubeMapTarget =
                        GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<uint32_t>(baseLayer + l);
                    for (y = destination.origin.y; y < destination.origin.y + copySize.height;
                         y += blockInfo.height) {
                        TexelCount height = std::min(blockInfo.height, virtSize.height - y);
                        DAWN_GL_TRY(gl, CompressedTexSubImage2D(cubeMapTarget, destination.mipLevel,
                                                                static_cast<uint32_t>(x),
                                                                static_cast<uint32_t>(y),
                                                                static_cast<uint32_t>(width),
                                                                static_cast<uint32_t>(height),
                                                                format.internalFormat, rowSize, d));
                        d += bytesPerRow;
                    }
                }
            } else {
                DAWN_ASSERT(target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY ||
                            target == GL_TEXTURE_CUBE_MAP_ARRAY);
                const uint8_t* slice = static_cast<const uint8_t*>(data);

                for (; z < destination.origin.z + copySize.depthOrArrayLayers; ++z) {
                    const uint8_t* d = slice;

                    for (y = destination.origin.y; y < destination.origin.y + copySize.height;
                         y += blockInfo.height) {
                        TexelCount height = std::min(blockInfo.height, virtSize.height - y);
                        DAWN_GL_TRY(
                            gl, CompressedTexSubImage3D(
                                    target, destination.mipLevel, static_cast<uint32_t>(x),
                                    static_cast<uint32_t>(y), static_cast<uint32_t>(z),
                                    static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1,
                                    format.internalFormat, rowSize, d));
                        d += bytesPerRow;
                    }

                    slice += bytesPerImage;
                }
            }
        }
    } else {
        TexelCount width = copySize.width;
        TexelCount height = copySize.height;
        GLenum adjustedFormat = format.format;
        if (format.format == GL_STENCIL) {
            DAWN_ASSERT(gl.GetVersion().IsDesktop() ||
                        gl.IsGLExtensionSupported("GL_OES_texture_stencil8"));
            adjustedFormat = GL_STENCIL_INDEX;
        }
        if (bytesPerRow % blockInfo.byteSize == 0) {
            const BlockCount blocksPerRow = blockInfo.BytesToBlocks(bytesPerRow);

            // Valid values for GL_UNPACK_ALIGNMENT are 1, 2, 4, 8
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_ALIGNMENT, std::min(8u, blockInfo.byteSize)));
            DAWN_GL_TRY(gl,
                        PixelStorei(GL_UNPACK_ROW_LENGTH,
                                    static_cast<uint32_t>(blockInfo.ToTexelWidth(blocksPerRow))));
            if (target == GL_TEXTURE_2D) {
                DAWN_GL_TRY(
                    gl, TexSubImage2D(target, destination.mipLevel, static_cast<uint32_t>(x),
                                      static_cast<uint32_t>(y), static_cast<uint32_t>(width),
                                      static_cast<uint32_t>(height), adjustedFormat, format.type,
                                      data));
            } else if (target == GL_TEXTURE_CUBE_MAP) {
                DAWN_ASSERT(texture->GetArrayLayers() == 6);
                const uint8_t* pointer = static_cast<const uint8_t*>(data);
                TexelCount baseLayer = destination.origin.z;
                for (TexelCount l{0}; l < copySize.depthOrArrayLayers; ++l) {
                    GLenum cubeMapTarget =
                        GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<uint32_t>(baseLayer + l);
                    DAWN_GL_TRY(gl, TexSubImage2D(
                                        cubeMapTarget, destination.mipLevel,
                                        static_cast<uint32_t>(x), static_cast<uint32_t>(y),
                                        static_cast<uint32_t>(width), static_cast<uint32_t>(height),
                                        adjustedFormat, format.type, pointer));
                    pointer += bytesPerImage;
                }
            } else {
                DAWN_ASSERT(target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY ||
                            target == GL_TEXTURE_CUBE_MAP_ARRAY);
                DAWN_GL_TRY(
                    gl, PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
                                    static_cast<uint32_t>(blockInfo.ToTexelHeight(rowsPerImage))));
                DAWN_GL_TRY(
                    gl, TexSubImage3D(target, destination.mipLevel, static_cast<uint32_t>(x),
                                      static_cast<uint32_t>(y), static_cast<uint32_t>(z),
                                      static_cast<uint32_t>(width), static_cast<uint32_t>(height),
                                      static_cast<uint32_t>(copySize.depthOrArrayLayers),
                                      adjustedFormat, format.type, data));
                DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0));
            }
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_ROW_LENGTH, 0));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_ALIGNMENT, 4));  // Reset to default
        } else {
            if (target == GL_TEXTURE_2D) {
                const uint8_t* d = static_cast<const uint8_t*>(data);
                for (; y < destination.origin.y + height; ++y) {
                    DAWN_GL_TRY(
                        gl, TexSubImage2D(target, destination.mipLevel, static_cast<uint32_t>(x),
                                          static_cast<uint32_t>(y), static_cast<uint32_t>(width), 1,
                                          adjustedFormat, format.type, d));
                    d += bytesPerRow;
                }
            } else if (target == GL_TEXTURE_CUBE_MAP) {
                DAWN_ASSERT(texture->GetArrayLayers() == 6);
                const uint8_t* pointer = static_cast<const uint8_t*>(data);
                TexelCount baseLayer = destination.origin.z;
                for (TexelCount l{0}; l < copySize.depthOrArrayLayers; ++l) {
                    const uint8_t* d = pointer;
                    GLenum cubeMapTarget =
                        GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<uint32_t>(baseLayer + l);
                    for (y = destination.origin.y; y < destination.origin.y + height; ++y) {
                        DAWN_GL_TRY(
                            gl, TexSubImage2D(cubeMapTarget, destination.mipLevel,
                                              static_cast<uint32_t>(x), static_cast<uint32_t>(y),
                                              static_cast<uint32_t>(width), 1, adjustedFormat,
                                              format.type, d));
                        d += bytesPerRow;
                    }
                    pointer += bytesPerImage;
                }
            } else {
                DAWN_ASSERT(target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY ||
                            target == GL_TEXTURE_CUBE_MAP_ARRAY);
                const uint8_t* slice = static_cast<const uint8_t*>(data);
                for (; z < destination.origin.z + copySize.depthOrArrayLayers; ++z) {
                    const uint8_t* d = slice;
                    for (y = destination.origin.y; y < destination.origin.y + height; ++y) {
                        DAWN_GL_TRY(gl, TexSubImage3D(
                                            target, destination.mipLevel, static_cast<uint32_t>(x),
                                            static_cast<uint32_t>(y), static_cast<uint32_t>(z),
                                            static_cast<uint32_t>(width), 1, 1, adjustedFormat,
                                            format.type, d));
                        d += bytesPerRow;
                    }
                    slice += bytesPerImage;
                }
            }
        }
    }

    return {};
}

}  // namespace dawn::native::opengl
