// 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/BindingPoint.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/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 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, GLuint samplerIndex) {
        Sampler* sampler = ToBackend(s);

        for (PipelineGL::SamplerUnit unit : mPipeline->GetTextureUnitsForSampler(samplerIndex)) {
            // Only use filtering for certain texture units, because int
            // and uint texture are only complete without filtering
            if (unit.shouldUseFiltering) {
                DAWN_GL_TRY(gl, BindSampler(unit.unit, sampler->GetFilteringHandle()));
            } else {
                DAWN_GL_TRY(gl, BindSampler(unit.unit, sampler->GetNonFilteringHandle()));
            }
        }

        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();
                    GLuint 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;
                            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, 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();
                    GLuint viewIndex = indices[bindingIndex];

                    for (auto unit : mPipeline->GetTextureUnitsForTextureView(viewIndex)) {
                        DAWN_GL_TRY(gl, ActiveTexture(GL_TEXTURE0 + 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));
                    }

                    // Some texture builtin function data needs emulation to update into the
                    // internal uniform buffer.
                    UpdateTextureBuiltinsUniformData(gl, view, groupIndex, bindingIndex);
                    return {};
                },
                [&](const StorageTextureBindingInfo& layout) -> MaybeError {
                    TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                    Texture* texture = ToBackend(view->GetTexture());
                    GLuint handle = texture->GetHandle();
                    GLuint 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(imageIndex, handle, view->GetBaseMipLevel(),
                                                     isLayered, view->GetBaseArrayLayer(), access,
                                                     texture->GetGLFormat().internalFormat));
                    return {};
                },
                [](const InputAttachmentBindingInfo&) -> MaybeError { DAWN_UNREACHABLE(); }));
        }

        return {};
    }

    void UpdateTextureBuiltinsUniformData(const OpenGLFunctions& gl,
                                          const TextureView* view,
                                          BindGroupIndex groupIndex,
                                          BindingIndex bindingIndex) {
        const auto& bindingInfo = mPipeline->GetBindingPointBuiltinDataInfo();
        if (bindingInfo.empty()) {
            return;
        }

        auto iter = bindingInfo.find(tint::BindingPoint{static_cast<uint32_t>(groupIndex),
                                                        static_cast<uint32_t>(bindingIndex)});
        if (iter == bindingInfo.end()) {
            return;
        }

        // Update data by retrieving information from texture view object.
        const BindPointFunction field = iter->second.first;
        const size_t byteOffset = static_cast<size_t>(iter->second.second);

        uint32_t data;
        switch (field) {
            case BindPointFunction::kTextureNumLevels:
                data = view->GetLevelCount();
                break;
            case BindPointFunction::kTextureNumSamples:
                data = view->GetTexture()->GetSampleCount();
                break;
        }

        if (byteOffset >= mInternalUniformBufferData.size()) {
            mInternalUniformBufferData.resize(byteOffset + sizeof(uint32_t));
        }
        memcpy(mInternalUniformBufferData.data() + byteOffset, &data, sizeof(uint32_t));

        // Updating dirty range of the data vector
        mDirtyRange.begin = std::min(mDirtyRange.begin, byteOffset);
        mDirtyRange.end = std::max(mDirtyRange.end, byteOffset + 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,
                            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,
                               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();
        GLuint ssboIndex = bindingIndexInfo[groupIndex][bindingIndex];

        uint32_t data = static_cast<uint32_t>(size);
        const size_t index = static_cast<size_t>(ssboIndex);

        if (index >= mInternalArrayLengthBufferData.size()) {
            mInternalArrayLengthBufferData.resize(index + 4);
        }
        mInternalArrayLengthBufferData[index] = data;

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

    void ResetInternalUniformDataDirtyRangeArrayLength() {
        mDirtyRangeArrayLength = {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& bindingInfo = mPipeline->GetBindingPointBuiltinDataInfo();
        for (const auto& entry : bindingInfo) {
            mDirtyBindGroupsObjectChangedOrIsDynamic.set(BindGroupIndex(entry.first.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.
    std::vector<uint32_t> mInternalArrayLengthBufferData = std::vector<uint32_t>(4);
    // 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_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_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.
Extent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy, const Extent3D& copySize) {
    Extent3D validTextureCopyExtent = copySize;
    const TextureBase* texture = textureCopy.texture.Get();
    Extent3D 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 = ToBackend(GetDevice())->GetGL();

    auto LazyClearSyncScope = [](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(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());

                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));

                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.width == 0 || copy->copySize.height == 0 ||
                    copy->copySize.depthOrArrayLayers == 0) {
                    // 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);
                if (IsCompleteSubresourceCopiedTo(texture, copy->copySize, dst.mipLevel,
                                                  dst.aspect)) {
                    texture->SetIsSubresourceContentInitialized(true, range);
                } else {
                    DAWN_TRY(texture->EnsureSubresourceContentInitialized(range));
                }

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

                TexelCopyBufferLayout dataLayout;
                dataLayout.offset = 0;
                dataLayout.bytesPerRow = src.bytesPerRow;
                dataLayout.rowsPerImage = src.rowsPerImage;

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

                buffer->TrackUsage();
                break;
            }

            case Command::CopyTextureToBuffer: {
                CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
                if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
                    copy->copySize.depthOrArrayLayers == 0) {
                    // 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);
                DAWN_TRY(texture->EnsureSubresourceContentInitialized(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 TexelBlockInfo& blockInfo = formatInfo.GetAspectInfo(src.aspect).block;

                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, dst.bytesPerRow / blockInfo.byteSize));

                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(src.origin.x, src.origin.y, copySize.width,
                                                       copySize.height, glFormat, glType, offset));
                            break;
                        } else if (target == GL_TEXTURE_CUBE_MAP) {
                            DAWN_ASSERT(texture->GetArrayLayers() == 6);
                            const uint64_t bytesPerImage = dst.bytesPerRow * dst.rowsPerImage;
                            for (uint32_t z = 0; z < copySize.depthOrArrayLayers; ++z) {
                                GLenum cubeMapTarget =
                                    GL_TEXTURE_CUBE_MAP_POSITIVE_X + z + src.origin.z;
                                DAWN_GL_TRY(
                                    gl, FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment,
                                                             cubeMapTarget, texture->GetHandle(),
                                                             src.mipLevel));
                                DAWN_GL_TRY(gl,
                                            ReadPixels(src.origin.x, src.origin.y, copySize.width,
                                                       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 = dst.bytesPerRow * dst.rowsPerImage;
                        for (uint32_t z = 0; z < copySize.depthOrArrayLayers; ++z) {
                            DAWN_GL_TRY(gl,
                                        FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment,
                                                                texture->GetHandle(), src.mipLevel,
                                                                src.origin.z + z));
                            DAWN_GL_TRY(gl, ReadPixels(src.origin.x, src.origin.y, copySize.width,
                                                       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.width == 0 || copy->copySize.height == 0 ||
                    copy->copySize.depthOrArrayLayers == 0) {
                    // 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.
                Extent3D 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);
                SubresourceRange dstRange = GetSubresourcesAffectedByCopy(dst, copy->copySize);

                DAWN_TRY(srcTexture->EnsureSubresourceContentInitialized(srcRange));
                if (IsCompleteSubresourceCopiedTo(dstTexture, copySize, dst.mipLevel, dst.aspect)) {
                    dstTexture->SetIsSubresourceContentInitialized(true, dstRange);
                } else {
                    DAWN_TRY(dstTexture->EnsureSubresourceContentInitialized(dstRange));
                }
                DAWN_TRY(CopyImageSubData(gl, src.aspect, srcTexture->GetHandle(),
                                          srcTexture->GetGLTarget(), src.mipLevel, src.origin,
                                          dstTexture->GetHandle(), dstTexture->GetGLTarget(),
                                          dst.mipLevel, dst.origin, copySize));
                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 = ToBackend(GetDevice())->GetGL();
    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());

                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::SetImmediateData:
                return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");

            default:
                DAWN_UNREACHABLE();
        }
    }

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

MaybeError CommandBuffer::ExecuteRenderPass(BeginRenderPassCmd* renderPass) {
    const OpenGLFunctions& gl = ToBackend(GetDevice())->GetGL();
    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_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_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(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::SetImmediateData:
                return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData 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 Extent3D& 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 TexelBlockInfo& blockInfo = texture->GetFormat().GetAspectInfo(destination.aspect).block;

    uint32_t x = destination.origin.x;
    uint32_t y = destination.origin.y;
    uint32_t z = destination.origin.z;
    if (texture->GetFormat().isCompressed) {
        size_t rowSize = copySize.width / blockInfo.width * blockInfo.byteSize;
        Extent3D virtSize = texture->GetMipLevelSingleSubresourceVirtualSize(destination.mipLevel,
                                                                             destination.aspect);
        uint32_t 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 (dataLayout.bytesPerRow % blockInfo.byteSize == 0 && gl.GetVersion().IsDesktop()) {
            size_t imageSize =
                rowSize * (copySize.height / blockInfo.height) * copySize.depthOrArrayLayers;

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

            DAWN_GL_TRY(gl,
                        PixelStorei(GL_UNPACK_ROW_LENGTH,
                                    dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width));
            DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 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, x, y, width, 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);
                uint32_t baseLayer = destination.origin.z;
                for (uint32_t l = 0; l < copySize.depthOrArrayLayers; ++l) {
                    GLenum cubeMapTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + baseLayer + l;
                    DAWN_GL_TRY(gl, CompressedTexSubImage2D(cubeMapTarget, destination.mipLevel, x,
                                                            y, width, height, format.internalFormat,
                                                            imageSize, pointer));
                    pointer += dataLayout.rowsPerImage * dataLayout.bytesPerRow;
                }
            } else {
                DAWN_GL_TRY(gl, PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
                                            dataLayout.rowsPerImage * blockInfo.height));
                DAWN_GL_TRY(gl, CompressedTexSubImage3D(target, destination.mipLevel, x, y, z,
                                                        width, height, 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) {
                    uint32_t height = std::min(blockInfo.height, virtSize.height - y);
                    DAWN_GL_TRY(gl,
                                CompressedTexSubImage2D(target, destination.mipLevel, x, y, width,
                                                        height, format.internalFormat, rowSize, d));
                    d += dataLayout.bytesPerRow;
                }
            } else if (target == GL_TEXTURE_CUBE_MAP) {
                DAWN_ASSERT(texture->GetArrayLayers() == 6);
                const uint8_t* pointer = static_cast<const uint8_t*>(data);
                uint32_t baseLayer = destination.origin.z;
                for (uint32_t l = 0; l < copySize.depthOrArrayLayers; ++l) {
                    const uint8_t* d =
                        pointer + l * dataLayout.rowsPerImage * dataLayout.bytesPerRow;
                    GLenum cubeMapTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + baseLayer + l;
                    for (y = destination.origin.y; y < destination.origin.y + copySize.height;
                         y += blockInfo.height) {
                        uint32_t height = std::min(blockInfo.height, virtSize.height - y);
                        DAWN_GL_TRY(gl, CompressedTexSubImage2D(cubeMapTarget, destination.mipLevel,
                                                                x, y, width, height,
                                                                format.internalFormat, rowSize, d));
                        d += dataLayout.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) {
                        uint32_t height = std::min(blockInfo.height, virtSize.height - y);
                        DAWN_GL_TRY(gl, CompressedTexSubImage3D(target, destination.mipLevel, x, y,
                                                                z, width, height, 1,
                                                                format.internalFormat, rowSize, d));
                        d += dataLayout.bytesPerRow;
                    }

                    slice += dataLayout.rowsPerImage * dataLayout.bytesPerRow;
                }
            }
        }
    } else {
        uint32_t width = copySize.width;
        uint32_t 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 (dataLayout.bytesPerRow % blockInfo.byteSize == 0) {
            // 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,
                                    dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width));
            if (target == GL_TEXTURE_2D) {
                DAWN_GL_TRY(gl, TexSubImage2D(target, destination.mipLevel, x, y, width, 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);
                uint32_t baseLayer = destination.origin.z;
                for (uint32_t l = 0; l < copySize.depthOrArrayLayers; ++l) {
                    GLenum cubeMapTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + baseLayer + l;
                    DAWN_GL_TRY(gl, TexSubImage2D(cubeMapTarget, destination.mipLevel, x, y, width,
                                                  height, adjustedFormat, format.type, pointer));
                    pointer += dataLayout.rowsPerImage * dataLayout.bytesPerRow;
                }
            } 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,
                                            dataLayout.rowsPerImage * blockInfo.height));
                DAWN_GL_TRY(gl, TexSubImage3D(target, destination.mipLevel, x, y, z, width, height,
                                              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, x, y, width, 1,
                                                  adjustedFormat, format.type, d));
                    d += dataLayout.bytesPerRow;
                }
            } else if (target == GL_TEXTURE_CUBE_MAP) {
                DAWN_ASSERT(texture->GetArrayLayers() == 6);
                const uint8_t* pointer = static_cast<const uint8_t*>(data);
                uint32_t baseLayer = destination.origin.z;
                for (uint32_t l = 0; l < copySize.depthOrArrayLayers; ++l) {
                    const uint8_t* d = pointer;
                    GLenum cubeMapTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + baseLayer + l;
                    for (y = destination.origin.y; y < destination.origin.y + height; ++y) {
                        DAWN_GL_TRY(gl, TexSubImage2D(cubeMapTarget, destination.mipLevel, x, y,
                                                      width, 1, adjustedFormat, format.type, d));
                        d += dataLayout.bytesPerRow;
                    }
                    pointer += dataLayout.rowsPerImage * dataLayout.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 + height; ++y) {
                        DAWN_GL_TRY(gl, TexSubImage3D(target, destination.mipLevel, x, y, z, width,
                                                      1, 1, adjustedFormat, format.type, d));
                        d += dataLayout.bytesPerRow;
                    }
                    slice += dataLayout.rowsPerImage * dataLayout.bytesPerRow;
                }
            }
        }
    }

    return {};
}

}  // namespace dawn::native::opengl
