// Copyright 2019 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 "src/dawn/native/CommandEncoder.h"

#include <string_view>
#include <utility>
#include <vector>

#include "absl/container/inlined_vector.h"
#include "dawn/native/ObjectType_autogen.h"
#include "dawn/native/ValidationUtils_autogen.h"
#include "dawn/platform/DawnPlatform.h"
#include "partition_alloc/pointers/raw_ptr.h"
#include "src/dawn/common/Enumerator.h"
#include "src/dawn/common/Math.h"
#include "src/dawn/native/Adapter.h"
#include "src/dawn/native/ApplyClearColorValueWithDrawHelper.h"
#include "src/dawn/native/BindGroup.h"
#include "src/dawn/native/BlitBufferToDepthStencil.h"
#include "src/dawn/native/BlitBufferToTexture.h"
#include "src/dawn/native/BlitDepthToDepth.h"
#include "src/dawn/native/BlitTextureToBuffer.h"
#include "src/dawn/native/Buffer.h"
#include "src/dawn/native/ChainUtils.h"
#include "src/dawn/native/CommandBuffer.h"
#include "src/dawn/native/CommandBufferStateTracker.h"
#include "src/dawn/native/CommandValidation.h"
#include "src/dawn/native/Commands.h"
#include "src/dawn/native/ComputePassEncoder.h"
#include "src/dawn/native/Device.h"
#include "src/dawn/native/ErrorData.h"
#include "src/dawn/native/QueryHelper.h"
#include "src/dawn/native/QuerySet.h"
#include "src/dawn/native/Queue.h"
#include "src/dawn/native/RenderPassEncoder.h"
#include "src/dawn/native/RenderPassWorkaroundsHelper.h"
#include "src/dawn/native/RenderPipeline.h"
#include "src/dawn/native/ValidationUtils.h"
#include "src/dawn/native/dawn_platform.h"
#include "src/dawn/native/utils/WGPUHelpers.h"
#include "src/dawn/platform/tracing/TraceEvent.h"
#include "src/utils/compiler.h"
#include "src/utils/non_movable.h"

namespace dawn::native {

namespace {

// Record the subresource range of a attachment used in render pass for checking overlaps.
struct RecordedAttachment {
    raw_ptr<const TextureBase> texture = nullptr;
    uint32_t mipLevel = 0;
    // For 3d color attachment, it's the attachment's depthSlice.
    uint32_t depthOrArrayLayer = 0;

    bool operator==(const RecordedAttachment& other) const = default;
};

enum class AttachmentType : uint8_t {
    ColorAttachment,
    ResolveTarget,
    DepthStencilAttachment,
    StorageAttachment
};

std::string_view GetAttachmentTypeStr(AttachmentType type) {
    switch (type) {
        case AttachmentType::ColorAttachment:
            return "color attachment";
        case AttachmentType::ResolveTarget:
            return "resolve target";
        case AttachmentType::DepthStencilAttachment:
            return "depth stencil attachment";
        case AttachmentType::StorageAttachment:
            return "storage attachment";
    }
    DAWN_UNREACHABLE();
}

// The width, height, sample count and subresource range need to be validated between all
// attachments in the render pass. This class records all the states and validate them for each
// attachment.
class RenderPassValidationState final : public NonMovable {
  public:
    // Record the attachment in the render pass if it passes all validations:
    // - the attachment has same with, height and sample count with other attachments
    // - no overlaps with other attachments
    // TODO(dawn:1020): Improve the error messages to include the index information of the
    // attachment in the render pass descriptor.
    MaybeError AddAttachment(const TextureViewBase* attachment,
                             AttachmentType attachmentType,
                             uint32_t depthSlice = wgpu::kDepthSliceUndefined) {
        if (attachment == nullptr) {
            return {};
        }

        DAWN_CHECK(attachment->GetLevelCount() == 1);

        const std::string_view attachmentTypeStr = GetAttachmentTypeStr(attachmentType);

        // Validate attachment sample count.
        if (mMsrtssAllowed) {
            switch (attachmentType) {
                case AttachmentType::ColorAttachment:
                    // Color attachments must match either the implicit sample count or 1
                    DAWN_INVALID_IF(
                        attachment->GetTexture()->GetSampleCount() != 1 &&
                            attachment->GetTexture()->GetSampleCount() != mSampleCount,
                        "The %s %s sample count (%u) is not 1 or %u when the render pass "
                        "has an explicit sample count (%u).",
                        attachmentTypeStr, attachment, attachment->GetTexture()->GetSampleCount(),
                        mSampleCount, mSampleCount);
                    break;
                case AttachmentType::DepthStencilAttachment:
                    // Depth/stencil attachments must match the implicit sample count
                    DAWN_INVALID_IF(attachment->GetTexture()->GetSampleCount() != mSampleCount,
                                    "The %s %s sample count (%u) does not match the render pass "
                                    "explicit sample count (%u).",
                                    attachmentTypeStr, attachment,
                                    attachment->GetTexture()->GetSampleCount(), mSampleCount);
                    break;
                case AttachmentType::ResolveTarget:
                    // Resolve target sample counts are already validated to be 1 elsewhere.
                    break;
                case AttachmentType::StorageAttachment:
                    // PLS is not currently compatible with MSRTSS.
                    DAWN_UNREACHABLE();
            }
        } else if (HasAttachment()) {
            // If no explicit sample count is set, all attachment sample counts must match.
            DAWN_INVALID_IF(attachmentType != AttachmentType::ResolveTarget &&
                                attachment->GetTexture()->GetSampleCount() != mSampleCount,
                            "The %s %s sample count (%u) does not match the sample count of the "
                            "other attachments (%u).",
                            attachmentTypeStr, attachment,
                            attachment->GetTexture()->GetSampleCount(), mSampleCount);
        }

        Extent3D renderSize = attachment->GetSingleSubresourceVirtualSize();
        Extent3D attachmentValidationSize = renderSize;
        if (attachment->GetTexture()->GetFormat().IsMultiPlanar()) {
            // For multi-planar texture, D3D requires depth stencil buffer size must be equal to the
            // size of the plane 0 for the color attachment texture (`attachmentValidationSize`).
            // Vulkan, Metal and GL requires buffer size equal or bigger than render size. To make
            // all dawn backends work, dawn requires depth attachment's size equal to the
            // `attachmentValidationSize`.
            // Vulkan:
            // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkFramebufferCreateInfo.html#VUID-VkFramebufferCreateInfo-flags-04533
            // OpenGLES3.0 (https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf
            // section 4.4.4.2) allows attachments have unequal size.
            attachmentValidationSize =
                attachment->GetTexture()->GetMipLevelSingleSubresourceVirtualSize(
                    attachment->GetBaseMipLevel(), Aspect::Plane0);
        }

        if (mExpandResolveRect) {
            if (attachmentType == AttachmentType::ColorAttachment) {
                DAWN_INVALID_IF(
                    static_cast<uint64_t>(mExpandResolveRect->colorOffsetX) +
                            static_cast<uint64_t>(mExpandResolveRect->width) >
                        renderSize.width,
                    "The color's x (%u) and width (%u) of ExpandResolveRect is out of the render "
                    "area width(%u).",
                    mExpandResolveRect->colorOffsetX, mExpandResolveRect->width, renderSize.width);
                DAWN_INVALID_IF(static_cast<uint64_t>(mExpandResolveRect->colorOffsetY) +
                                        static_cast<uint64_t>(mExpandResolveRect->height) >
                                    renderSize.height,
                                "The color's y (%u) and height (%u) of ExpandResolveRect is out of "
                                "the render area "
                                "height(%u).",
                                mExpandResolveRect->colorOffsetY, mExpandResolveRect->height,
                                renderSize.height);
            } else if (attachmentType == AttachmentType::ResolveTarget) {
                DAWN_INVALID_IF(static_cast<uint64_t>(mExpandResolveRect->resolveOffsetX) +
                                        static_cast<uint64_t>(mExpandResolveRect->width) >
                                    renderSize.width,
                                "The resolve's x (%u) and width (%u) of ExpandResolveRect is out "
                                "of the resolve "
                                "area width(%u).",
                                mExpandResolveRect->resolveOffsetX, mExpandResolveRect->width,
                                renderSize.width);
                DAWN_INVALID_IF(static_cast<uint64_t>(mExpandResolveRect->resolveOffsetY) +
                                        static_cast<uint64_t>(mExpandResolveRect->height) >
                                    renderSize.height,
                                "The resolve's y (%u) and height (%u) of ExpandResolveRect is out "
                                "of the resolve area "
                                "height(%u).",
                                mExpandResolveRect->resolveOffsetY, mExpandResolveRect->height,
                                renderSize.height);
            }
        }
        if (HasAttachment()) {
            switch (attachmentType) {
                case AttachmentType::ColorAttachment:
                case AttachmentType::StorageAttachment: {
                    DAWN_INVALID_IF(
                        renderSize.width != mRenderWidth || renderSize.height != mRenderHeight,
                        "The %s %s size (width: %u, height: %u) does not match the size of the "
                        "other attachments (width: %u, height: %u).",
                        attachmentTypeStr, attachment, renderSize.width, renderSize.height,
                        mRenderWidth, mRenderHeight);
                    break;
                }
                case AttachmentType::ResolveTarget: {
                    // TODO(chromium:324422644): support using multi-planar texture as resolve
                    // target.
                    DAWN_INVALID_IF(attachment->GetTexture()->GetFormat().IsMultiPlanar(),
                                    "The resolve target %s used as resolve target is from a "
                                    "multi-planar texture. It is not supported by dawn yet.",
                                    attachment);
                    // RenderPassDescriptorResolveRect relaxes the requirement for the color
                    // attachment texture size to match the resolve texture size.
                    if (!mExpandResolveRect) {
                        DAWN_INVALID_IF(
                            renderSize.width != mRenderWidth || renderSize.height != mRenderHeight,
                            "The resolve target %s size (width: %u, height: %u) does not match the "
                            "size of the other attachments (width: %u, height: %u).",
                            attachment, renderSize.width, renderSize.height, mRenderWidth,
                            mRenderHeight);
                    }
                    break;
                }
                case AttachmentType::DepthStencilAttachment: {
                    DAWN_INVALID_IF(
                        attachmentValidationSize.width != mAttachmentValidationWidth ||
                            attachmentValidationSize.height != mAttachmentValidationHeight,
                        "The depth stencil attachment %s size (width: %u, height: %u) does not "
                        "match the size of the other attachments' base plane (width: %u, height: "
                        "%u).",
                        attachment, attachmentValidationSize.width, attachmentValidationSize.height,
                        mAttachmentValidationWidth, mAttachmentValidationHeight);
                    break;
                }
            }
        } else {
            DAWN_CHECK(attachmentType != AttachmentType::ResolveTarget);
            mRenderWidth = renderSize.width;
            mRenderHeight = renderSize.height;
            mAttachmentValidationWidth = attachmentValidationSize.width;
            mAttachmentValidationHeight = attachmentValidationSize.height;
            if (!mMsrtssAllowed) {
                mSampleCount = attachment->GetTexture()->GetSampleCount();
            }
            DAWN_CHECK(mRenderWidth != 0);
            DAWN_CHECK(mRenderHeight != 0);
            DAWN_CHECK(mAttachmentValidationWidth != 0);
            DAWN_CHECK(mAttachmentValidationHeight != 0);
            DAWN_CHECK(mSampleCount != 0);
        }

        RecordedAttachment record;
        record.texture = attachment->GetTexture();
        record.mipLevel = attachment->GetBaseMipLevel();
        if (attachment->GetDimension() == wgpu::TextureViewDimension::e3D) {
            DAWN_CHECK(attachment->GetBaseArrayLayer() == 0);
            record.depthOrArrayLayer = depthSlice;
        } else {
            DAWN_CHECK(depthSlice == wgpu::kDepthSliceUndefined);
            record.depthOrArrayLayer = attachment->GetBaseArrayLayer();
        }

        for (size_t i = 0; i < mRecords.size(); i++) {
            DAWN_INVALID_IF(
                mRecords[i] == record,
                "The %s %s has read-write or write-write conflict with another attachment.",
                attachmentTypeStr, attachment);
        }

        mRecords.push_back(record);

        return {};
    }

    // Only sets the values needed for executing the render pass, used when validation is disabled.
    void SetUnvalidatedAttachment(const TextureViewBase* attachment) {
        // Should only be called once.
        DAWN_CHECK(!HasAttachment());

        DAWN_CHECK(attachment);
        DAWN_CHECK(attachment->GetLevelCount() == 1);

        Extent3D renderSize = attachment->GetSingleSubresourceVirtualSize();
        mRenderWidth = renderSize.width;
        mRenderHeight = renderSize.height;
        mAttachmentValidationWidth = mRenderWidth;
        mAttachmentValidationHeight = mRenderHeight;
        if (!mMsrtssAllowed) {
            mSampleCount = attachment->GetTexture()->GetSampleCount();
        }

        DAWN_CHECK(mRenderWidth != 0);
        DAWN_CHECK(mRenderHeight != 0);
        DAWN_CHECK(mSampleCount != 0);

        RecordedAttachment record;
        record.texture = attachment->GetTexture();
        record.mipLevel = attachment->GetBaseMipLevel();
        mRecords.push_back(record);
    }

    bool HasAttachment() const { return !mRecords.empty(); }

    bool IsValidState() const {
        return ((mRenderWidth > 0) && (mRenderHeight > 0) && (mSampleCount > 0));
    }

    uint32_t GetRenderWidth() const { return mRenderWidth; }

    uint32_t GetRenderHeight() const { return mRenderHeight; }

    uint32_t GetSampleCount() const { return mSampleCount; }

    uint32_t IsMsrtssAllowed() const { return mMsrtssAllowed; }

    void SetExplicitSampleCount(uint32_t sampleCount) {
        mSampleCount = sampleCount;
        mMsrtssAllowed = true;
    }

    bool WillExpandResolveTexture() const { return mWillExpandResolveTexture; }
    void SetWillExpandResolveTexture(bool enabled) { mWillExpandResolveTexture = enabled; }
    void SetExpandResolveRect(
        const std::optional<RenderPassDescriptorResolveRect>& expandResolveRect) {
        mExpandResolveRect = expandResolveRect;
    }

  private:
    // The attachment's width, height and sample count.
    uint32_t mRenderWidth = 0;
    uint32_t mRenderHeight = 0;
    uint32_t mSampleCount = 0;
    bool mMsrtssAllowed = false;

    uint32_t mAttachmentValidationWidth = 0;
    uint32_t mAttachmentValidationHeight = 0;

    // The records of the attachments that were validated in render pass.
    absl::InlinedVector<RecordedAttachment, kMaxColorAttachments> mRecords;

    bool mWillExpandResolveTexture = false;
    std::optional<RenderPassDescriptorResolveRect> mExpandResolveRect;
};

MaybeError ValidateB2BCopyAlignment(uint64_t dataSize, uint64_t srcOffset, uint64_t dstOffset) {
    // Copy size must be a multiple of 4 bytes on macOS.
    DAWN_INVALID_IF(dataSize % 4 != 0, "Copy size (%u) is not a multiple of 4.", dataSize);

    // SourceOffset and destinationOffset must be multiples of 4 bytes on macOS.
    DAWN_INVALID_IF(srcOffset % 4 != 0 || dstOffset % 4 != 0,
                    "Source offset (%u) or destination offset (%u) is not a multiple of 4 bytes,",
                    srcOffset, dstOffset);

    return {};
}

MaybeError ValidateTextureSampleCountInBufferCopyCommands(const TextureBase* texture) {
    DAWN_INVALID_IF(texture->GetSampleCount() > 1,
                    "%s sample count (%u) is not 1 when copying to or from a buffer.", texture,
                    texture->GetSampleCount());

    return {};
}

MaybeError ValidateLinearTextureCopyOffset(const TexelCopyBufferLayout& layout,
                                           const TexelBlockInfo& blockInfo,
                                           const bool hasDepthOrStencil) {
    if (hasDepthOrStencil) {
        // For depth-stencil texture, buffer offset must be a multiple of 4.
        DAWN_INVALID_IF(layout.offset % 4 != 0,
                        "Offset (%u) is not a multiple of 4 for depth/stencil texture.",
                        layout.offset);
    } else {
        DAWN_INVALID_IF(layout.offset % blockInfo.byteSize != 0,
                        "Offset (%u) is not a multiple of the texel block byte size (%u).",
                        layout.offset, blockInfo.byteSize);
    }
    return {};
}

MaybeError ValidateTextureFormatForTextureToBufferCopyInCompatibilityMode(
    const TextureBase* texture) {
    DAWN_INVALID_IF(texture->GetFormat().isCompressed,
                    "%s with format %s cannot be used as the source in a texture to buffer copy in "
                    "compatibility mode.",
                    texture, texture->GetFormat().format);
    return {};
}

MaybeError ValidateSourceTextureFormatForTextureToTextureCopyInCompatibilityMode(
    const TextureBase* texture) {
    DAWN_INVALID_IF(
        texture->GetFormat().isCompressed,
        "%s with format %s cannot be used as the source in a texture to texture copy in "
        "compatibility mode.",
        texture, texture->GetFormat().format);
    return {};
}

MaybeError ValidateTextureDepthStencilToBufferCopyRestrictions(const DeviceBase* device,
                                                               const TexelCopyTextureInfo& src) {
    Aspect aspectUsed;
    DAWN_TRY_ASSIGN(aspectUsed, SingleAspectUsedByTexelCopyTextureInfo(src));
    if (aspectUsed == Aspect::Depth) {
        switch (src.texture->GetFormat().format) {
            case wgpu::TextureFormat::Depth24Plus:
            case wgpu::TextureFormat::Depth24PlusStencil8:
                if (!device->IsToggleEnabled(Toggle::UseBlitForDepth24PlusTextureToBufferCopy)) {
                    return DAWN_VALIDATION_ERROR(
                        "The depth aspect of %s format %s cannot be selected in a texture to "
                        "buffer copy.",
                        src.texture, src.texture->GetFormat().format);
                }
                break;
            case wgpu::TextureFormat::Depth32Float:
            case wgpu::TextureFormat::Depth16Unorm:
            case wgpu::TextureFormat::Depth32FloatStencil8:
                break;

            default:
                DAWN_UNREACHABLE();
        }
    }

    return {};
}

MaybeError ValidateAttachmentArrayLayersAndLevelCount(const TextureViewBase* attachment) {
    // Currently we do not support layered rendering.
    DAWN_INVALID_IF(attachment->GetLayerCount() > 1,
                    "The layer count (%u) of %s used as attachment is greater than 1.",
                    attachment->GetLayerCount(), attachment);

    DAWN_INVALID_IF(attachment->GetLevelCount() > 1,
                    "The mip level count (%u) of %s used as attachment is greater than 1.",
                    attachment->GetLevelCount(), attachment);

    return {};
}

MaybeError ValidateResolveTarget(const DeviceBase* device,
                                 const RenderPassColorAttachment& colorAttachment,
                                 UsageValidationMode usageValidationMode) {
    if (colorAttachment.resolveTarget == nullptr) {
        return {};
    }

    const TextureViewBase* resolveTarget = colorAttachment.resolveTarget;
    const TextureViewBase* attachment = colorAttachment.view;
    DAWN_TRY(device->ValidateObject(resolveTarget));
    DAWN_TRY(
        ValidateCanUseAs(resolveTarget, wgpu::TextureUsage::RenderAttachment, usageValidationMode));
    DAWN_INVALID_IF(resolveTarget->GetUsage() & wgpu::TextureUsage::TransientAttachment,
                    "Cannot use transient attachment %s as a resolve target.", resolveTarget);

    DAWN_INVALID_IF(!attachment->GetTexture()->IsMultisampledTexture(),
                    "Cannot set %s as a resolve target when the color attachment %s has a sample "
                    "count of 1.",
                    resolveTarget, attachment);

    DAWN_INVALID_IF(resolveTarget->GetTexture()->IsMultisampledTexture(),
                    "Cannot use %s as resolve target. Sample count (%u) is greater than 1.",
                    resolveTarget, resolveTarget->GetTexture()->GetSampleCount());

    DAWN_INVALID_IF(resolveTarget->GetDimension() != wgpu::TextureViewDimension::e2D &&
                        resolveTarget->GetDimension() != wgpu::TextureViewDimension::e2DArray,
                    "The dimension (%s) of resolve target %s is not 2D or 2DArray.",
                    resolveTarget->GetDimension(), resolveTarget);

    DAWN_INVALID_IF(resolveTarget->GetLayerCount() > 1,
                    "The resolve target %s array layer count (%u) is not 1.", resolveTarget,
                    resolveTarget->GetLayerCount());

    DAWN_INVALID_IF(resolveTarget->GetLevelCount() > 1,
                    "The resolve target %s mip level count (%u) is not 1.", resolveTarget,
                    resolveTarget->GetLevelCount());

    wgpu::TextureFormat resolveTargetFormat = resolveTarget->GetFormat().format;
    DAWN_INVALID_IF(
        resolveTargetFormat != attachment->GetFormat().format,
        "The resolve target %s format (%s) does not match the color attachment %s format "
        "(%s).",
        resolveTarget, resolveTargetFormat, attachment, attachment->GetFormat().format);
    DAWN_INVALID_IF(
        !resolveTarget->GetFormat().SupportsResolveTarget(),
        "The resolve target %s format (%s) does not support being used as resolve target.",
        resolveTarget, resolveTargetFormat);

    // TODO(450506641): Precompute allowed usages of texture views (including swizzle identity
    // check) instead of recomputing.
    DAWN_INVALID_IF(!resolveTarget->IsSwizzleIdentity(),
                    "The resolve target swizzle must be identity.");

    return {};
}

MaybeError ValidateColorAttachmentDepthSlice(const TextureViewBase* attachment,
                                             uint32_t depthSlice) {
    if (attachment->GetDimension() != wgpu::TextureViewDimension::e3D) {
        DAWN_INVALID_IF(depthSlice != wgpu::kDepthSliceUndefined,
                        "depthSlice (%u) is defined for a non-3D attachment (%s).", depthSlice,
                        attachment);
        return {};
    }

    DAWN_INVALID_IF(depthSlice == wgpu::kDepthSliceUndefined,
                    "depthSlice is required for a 3D attachment (%s), but it is undefined.",
                    attachment);

    const Extent3D& attachmentSize = attachment->GetSingleSubresourceVirtualSize();
    DAWN_INVALID_IF(depthSlice >= attachmentSize.depthOrArrayLayers,
                    "depthSlice (%u) of the attachment (%s) is >= the "
                    "depthOrArrayLayers (%u) of the attachment's subresource at mip level (%u).",
                    depthSlice, attachment, attachmentSize.depthOrArrayLayers,
                    attachment->GetBaseMipLevel());

    return {};
}

MaybeError ValidateDawnRenderPassSampleCount(
    const DeviceBase* device,
    const DawnRenderPassSampleCount* renderPassSampleCount) {
    DAWN_ASSERT(renderPassSampleCount != nullptr);

    DAWN_INVALID_IF(
        !device->HasFeature(Feature::MSAARenderToSingleSampled),
        "The render pass has an explicit sample count while the %s feature is not enabled.",
        ToAPI(Feature::MSAARenderToSingleSampled));

    DAWN_INVALID_IF(!IsValidSampleCount(renderPassSampleCount->sampleCount) ||
                        renderPassSampleCount->sampleCount <= 1,
                    "The render pass sample count (%u) is not supported.",
                    renderPassSampleCount->sampleCount);

    return {};
}

MaybeError ValidateColorAttachmentRenderToSingleSampled(
    const DeviceBase* device,
    const RenderPassColorAttachment& colorAttachment,
    const DawnRenderPassSampleCount* renderPassSampleCount) {
    TextureViewBase* attachment = colorAttachment.view;
    DAWN_CHECK(attachment);

    DAWN_ASSERT(renderPassSampleCount != nullptr);
    DAWN_CHECK(device->HasFeature(Feature::MSAARenderToSingleSampled));

    uint32_t passSampleCount = renderPassSampleCount->sampleCount;
    uint32_t attachmentSampleCount = attachment->GetTexture()->GetSampleCount();
    DAWN_INVALID_IF(attachmentSampleCount != 1 && attachmentSampleCount != passSampleCount,
                    "The color attachment %s sample count (%u) must be either 1 or %u when the "
                    "render pass is using MSAARenderToSingleSampled with a sample count of %u.",
                    attachment, attachmentSampleCount, passSampleCount, passSampleCount);

    if (attachmentSampleCount != 1) {
        // The following rules only apply to attachments that will actually be resolved.
        return {};
    }

    DAWN_INVALID_IF(!attachment->GetFormat().SupportsResolveTarget(),
                    "The color attachment %s format (%s) does not support being used with a render "
                    "pass using MSAARenderToSingleSampled with a sample count of %u. The format "
                    "does not support resolve.",
                    attachment, attachment->GetFormat().format, passSampleCount);

    DAWN_INVALID_IF(colorAttachment.resolveTarget != nullptr,
                    "Cannot set %s as a resolve target. No resolve target should be specified "
                    "for the color attachment %s when the render pass is using "
                    "MSAARenderToSingleSampled with a sample count of %u.",
                    colorAttachment.resolveTarget, attachment, passSampleCount);

    return {};
}

MaybeError ValidateExpandResolveTextureLoadOp(const DeviceBase* device,
                                              const RenderPassColorAttachment& colorAttachment,
                                              RenderPassValidationState* validationState) {
    DAWN_INVALID_IF(!device->HasFeature(Feature::DawnLoadResolveTexture),
                    "%s is used while the %s is not enabled.", wgpu::LoadOp::ExpandResolveTexture,
                    ToAPI(Feature::DawnLoadResolveTexture));

    uint32_t textureSampleCount = colorAttachment.view->GetTexture()->GetSampleCount();

    DAWN_INVALID_IF(!IsValidSampleCount(textureSampleCount) || textureSampleCount <= 1,
                    "The color attachment %s's sample count (%u) is not supported by %s.",
                    colorAttachment.view, textureSampleCount, wgpu::LoadOp::ExpandResolveTexture);

    // These should already be validated before entering this function.
    DAWN_CHECK(colorAttachment.resolveTarget != nullptr &&
               !colorAttachment.resolveTarget->IsError());
    DAWN_CHECK(colorAttachment.view->GetFormat().SupportsResolveTarget());

    DAWN_INVALID_IF(
        (colorAttachment.resolveTarget->GetUsage() & wgpu::TextureUsage::TextureBinding) == 0,
        "Resolve target %s was not created with %s usage, which is required for "
        "%s.",
        colorAttachment.resolveTarget, wgpu::TextureUsage::TextureBinding,
        wgpu::LoadOp::ExpandResolveTexture);

    // TODO(42240662): multiplanar textures are not supported as resolve target.
    // The RenderPassValidationState currently rejects such usage.
    DAWN_CHECK(!colorAttachment.resolveTarget->GetTexture()->GetFormat().IsMultiPlanar());

    validationState->SetWillExpandResolveTexture(true);

    return {};
}

MaybeError ValidateRenderPassColorAttachment(DeviceBase* device,
                                             const RenderPassColorAttachment& colorAttachment,
                                             UsageValidationMode usageValidationMode,
                                             RenderPassValidationState* validationState) {
    TextureViewBase* attachment = colorAttachment.view;
    if (attachment == nullptr) {
        return {};
    }

    DAWN_TRY(device->ValidateObject(attachment));
    DAWN_TRY(
        ValidateCanUseAs(attachment, wgpu::TextureUsage::RenderAttachment, usageValidationMode));

    UnpackedPtr<RenderPassColorAttachment> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(&colorAttachment));

    // Plane0, Plane1, and Plane2 aspects for multiplanar texture views should be allowed as color
    // attachments.
    Aspect kRenderableAspects = Aspect::Color | Aspect::Plane0 | Aspect::Plane1 | Aspect::Plane2;
    DAWN_INVALID_IF(
        !(attachment->GetAspects() & kRenderableAspects) || !attachment->GetFormat().IsRenderable(),
        "The color attachment %s format (%s) is not color renderable.", attachment,
        attachment->GetFormat().format);

    DAWN_TRY(ValidateLoadOp(colorAttachment.loadOp));
    DAWN_TRY(ValidateStoreOp(colorAttachment.storeOp));
    DAWN_INVALID_IF(colorAttachment.loadOp == wgpu::LoadOp::Undefined, "loadOp must be set.");
    DAWN_INVALID_IF(colorAttachment.storeOp == wgpu::StoreOp::Undefined, "storeOp must be set.");

    // TODO(450506641): Precompute allowed usages of texture views (including swizzle identity
    // check) instead of recomputing.
    DAWN_INVALID_IF(!attachment->IsSwizzleIdentity(),
                    "The color attachment swizzle must be identity.");

    if (attachment->GetUsage() & wgpu::TextureUsage::TransientAttachment) {
        DAWN_INVALID_IF(colorAttachment.loadOp != wgpu::LoadOp::Clear &&
                            colorAttachment.loadOp != wgpu::LoadOp::ExpandResolveTexture,
                        "The color attachment %s has the load op set to %s while its usage (%s) "
                        "has the transient attachment bit set.",
                        attachment, colorAttachment.loadOp, attachment->GetUsage());
        DAWN_INVALID_IF(colorAttachment.storeOp != wgpu::StoreOp::Discard,
                        "The color attachment %s has the store op set to %s while its usage (%s) "
                        "has the transient attachment bit set.",
                        attachment, wgpu::StoreOp::Store, attachment->GetUsage());
    }

    const dawn::native::Color& clearValue = colorAttachment.clearValue;
    if (colorAttachment.loadOp == wgpu::LoadOp::Clear) {
        DAWN_TRY(ValidateColor("clearValue", clearValue));
    } else if (colorAttachment.loadOp == wgpu::LoadOp::ExpandResolveTexture) {
        DAWN_INVALID_IF(colorAttachment.resolveTarget == nullptr,
                        "%s is used without resolve target.", wgpu::LoadOp::ExpandResolveTexture);
    }

    DAWN_TRY(ValidateColorAttachmentDepthSlice(attachment, colorAttachment.depthSlice));
    DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment));

    DAWN_TRY(validationState->AddAttachment(attachment, AttachmentType::ColorAttachment,
                                            colorAttachment.depthSlice));

    DAWN_TRY(ValidateResolveTarget(device, colorAttachment, usageValidationMode));

    if (colorAttachment.loadOp == wgpu::LoadOp::ExpandResolveTexture) {
        DAWN_TRY(ValidateExpandResolveTextureLoadOp(device, colorAttachment, validationState));
    }
    // Add resolve target after adding color attachment to make sure there is already a color
    // attachment for the comparison of width and height.
    DAWN_TRY(validationState->AddAttachment(colorAttachment.resolveTarget,
                                            AttachmentType::ResolveTarget));

    return {};
}

MaybeError ValidateRenderPassDepthStencilAttachment(
    DeviceBase* device,
    const RenderPassDepthStencilAttachment* depthStencilAttachment,
    UsageValidationMode usageValidationMode,
    RenderPassValidationState* validationState) {
    DAWN_CHECK(depthStencilAttachment != nullptr);
    UnpackedPtr<RenderPassDepthStencilAttachment> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(depthStencilAttachment));

    TextureViewBase* attachment = unpacked->view;
    DAWN_TRY(device->ValidateObject(attachment));
    DAWN_TRY(
        ValidateCanUseAs(attachment, wgpu::TextureUsage::RenderAttachment, usageValidationMode));

    // DS attachments must encompass all aspects of the texture, so we first check that this is
    // true, which means that in the rest of the function we can assume that the view's format is
    // the same as the texture's format.
    const Format& format = attachment->GetTexture()->GetFormat();
    DAWN_INVALID_IF(
        attachment->GetAspects() != format.aspects,
        "The depth stencil attachment %s must encompass all aspects of it's texture's format (%s).",
        attachment, format.format);
    DAWN_CHECK(attachment->GetFormat().format == format.format);

    DAWN_INVALID_IF(!format.HasDepthOrStencil(),
                    "The depth stencil attachment %s format (%s) is not a depth stencil format.",
                    attachment, format.format);

    DAWN_INVALID_IF(!format.IsRenderable(),
                    "The depth stencil attachment %s format (%s) is not renderable.", attachment,
                    format.format);

    // Read only, or depth doesn't exist.
    bool hasDepthAspect = IsSubset(Aspect::Depth, attachment->GetAspects());
    if (unpacked->depthReadOnly || !hasDepthAspect) {
        DAWN_INVALID_IF(unpacked->depthLoadOp != wgpu::LoadOp::Undefined ||
                            unpacked->depthStoreOp != wgpu::StoreOp::Undefined,
                        "Both depthLoadOp (%s) and depthStoreOp (%s) must not be set if the "
                        "attachment (%s) has no depth aspect or depthReadOnly (%u) is true.",
                        unpacked->depthLoadOp, unpacked->depthStoreOp, attachment,
                        unpacked->depthReadOnly);
    } else {
        DAWN_TRY(ValidateLoadOp(unpacked->depthLoadOp));
        DAWN_TRY(ValidateStoreOp(unpacked->depthStoreOp));
        DAWN_INVALID_IF(unpacked->depthLoadOp == wgpu::LoadOp::Undefined ||
                            unpacked->depthStoreOp == wgpu::StoreOp::Undefined,
                        "Both depthLoadOp (%s) and depthStoreOp (%s) must be set if the attachment "
                        "(%s) has a depth aspect or depthReadOnly (%u) is false.",
                        unpacked->depthLoadOp, unpacked->depthStoreOp, attachment,
                        unpacked->depthReadOnly);
    }

    DAWN_INVALID_IF(unpacked->depthLoadOp == wgpu::LoadOp::ExpandResolveTexture ||
                        unpacked->stencilLoadOp == wgpu::LoadOp::ExpandResolveTexture,
                    "%s is not supported on depth/stencil attachment",
                    wgpu::LoadOp::ExpandResolveTexture);

    // Read only, or stencil doesn't exist.
    bool hasStencilAspect = IsSubset(Aspect::Stencil, attachment->GetAspects());
    if (unpacked->stencilReadOnly || !hasStencilAspect) {
        DAWN_INVALID_IF(unpacked->stencilLoadOp != wgpu::LoadOp::Undefined ||
                            unpacked->stencilStoreOp != wgpu::StoreOp::Undefined,
                        "Both stencilLoadOp (%s) and stencilStoreOp (%s) must not be set if the "
                        "attachment (%s) has no stencil aspect or stencilReadOnly (%u) is true.",
                        unpacked->stencilLoadOp, unpacked->stencilStoreOp, attachment,
                        unpacked->stencilReadOnly);
    } else {
        DAWN_TRY(ValidateLoadOp(unpacked->stencilLoadOp));
        DAWN_TRY(ValidateStoreOp(unpacked->stencilStoreOp));
        DAWN_INVALID_IF(unpacked->stencilLoadOp == wgpu::LoadOp::Undefined ||
                            unpacked->stencilStoreOp == wgpu::StoreOp::Undefined,
                        "Both stencilLoadOp (%s) and stencilStoreOp (%s) must be set if the "
                        "attachment (%s) has a stencil aspect or stencilReadOnly (%u) is false.",
                        unpacked->stencilLoadOp, unpacked->stencilStoreOp, attachment,
                        unpacked->stencilReadOnly);
    }
    if (attachment->GetUsage() & wgpu::TextureUsage::TransientAttachment) {
        DAWN_INVALID_IF(hasDepthAspect && unpacked->depthLoadOp != wgpu::LoadOp::Clear,
                        "depthLoadOp (%s) is not %s when the attachment (%s) has a depth aspect "
                        "and its usage (%s) contains %s.",
                        unpacked->depthLoadOp, wgpu::LoadOp::Clear, attachment,
                        attachment->GetUsage(), wgpu::TextureUsage::TransientAttachment);
        DAWN_INVALID_IF(hasStencilAspect && unpacked->stencilLoadOp != wgpu::LoadOp::Clear,
                        "stencilLoadOp (%s) is not %s when the attachment (%s) has a stencil "
                        "aspect and its usage (%s) contains %s.",
                        unpacked->stencilLoadOp, wgpu::LoadOp::Clear, attachment,
                        attachment->GetUsage(), wgpu::TextureUsage::TransientAttachment);
        DAWN_INVALID_IF(hasDepthAspect && unpacked->depthStoreOp != wgpu::StoreOp::Discard,
                        "depthStoreOp (%s) is not %s when the attachment (%s) has a depth aspect "
                        "and its usage (%s) contains %s.",
                        unpacked->depthStoreOp, wgpu::StoreOp::Discard, attachment,
                        attachment->GetUsage(), wgpu::TextureUsage::TransientAttachment);
        DAWN_INVALID_IF(hasStencilAspect && unpacked->stencilStoreOp != wgpu::StoreOp::Discard,
                        "stencilStoreOp (%s) is not %s when the attachment (%s) has a stencil "
                        "aspect and its usage (%s) contains %s.",
                        unpacked->stencilStoreOp, wgpu::StoreOp::Discard, attachment,
                        attachment->GetUsage(), wgpu::TextureUsage::TransientAttachment);
    }

    if (unpacked->depthLoadOp == wgpu::LoadOp::Clear &&
        IsSubset(Aspect::Depth, attachment->GetAspects())) {
        DAWN_INVALID_IF(
            std::isnan(unpacked->depthClearValue),
            "depthClearValue (%f) must be set and must not be a NaN value if the attachment "
            "(%s) has a depth aspect and depthLoadOp is clear.",
            unpacked->depthClearValue, attachment);
        DAWN_INVALID_IF(unpacked->depthClearValue < 0.0f || unpacked->depthClearValue > 1.0f,
                        "depthClearValue (%f) must be between 0.0 and 1.0 if the attachment (%s) "
                        "has a depth aspect and depthLoadOp is clear.",
                        unpacked->depthClearValue, attachment);
    }

    DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment));

    // TODO(450506641): Precompute allowed usages of texture views (including swizzle identity
    // check) instead of recomputing.
    DAWN_INVALID_IF(!attachment->IsSwizzleIdentity(),
                    "The depth stencil attachment swizzle must be identity.");

    DAWN_TRY(validationState->AddAttachment(attachment, AttachmentType::DepthStencilAttachment));

    return {};
}

MaybeError ValidateRenderPassPLS(DeviceBase* device,
                                 const RenderPassPixelLocalStorage* pls,
                                 UsageValidationMode usageValidationMode,
                                 RenderPassValidationState* validationState) {
    absl::InlinedVector<StorageAttachmentInfoForValidation, 4> attachments;

    for (size_t i = 0; i < pls->storageAttachmentCount; i++) {
        const RenderPassStorageAttachment& attachment =
            DAWN_UNSAFE_TODO(pls->storageAttachments[i]);

        // Validate the attachment can be used as a storage attachment.
        DAWN_TRY(device->ValidateObject(attachment.storage));
        DAWN_TRY(ValidateCanUseAs(attachment.storage, wgpu::TextureUsage::StorageAttachment,
                                  usageValidationMode));
        DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment.storage));

        // Validate the load/storeOp and the clearValue.
        DAWN_TRY(ValidateLoadOp(attachment.loadOp));
        DAWN_TRY(ValidateStoreOp(attachment.storeOp));
        DAWN_INVALID_IF(attachment.loadOp == wgpu::LoadOp::Undefined,
                        "storageAttachments[%i].loadOp must be set.", i);
        DAWN_INVALID_IF(attachment.storeOp == wgpu::StoreOp::Undefined,
                        "storageAttachments[%i].storeOp must be set.", i);

        const dawn::native::Color& clearValue = attachment.clearValue;
        if (attachment.loadOp == wgpu::LoadOp::Clear) {
            DAWN_TRY(ValidateColor("clearValue", clearValue));
        }

        DAWN_TRY(
            validationState->AddAttachment(attachment.storage, AttachmentType::StorageAttachment));

        attachments.push_back({attachment.offset, attachment.storage->GetFormat().format});
    }

    return ValidatePLSInfo(device, pls->totalPixelLocalStorageSize,
                           {attachments.data(), attachments.size()});
}

MaybeError ValidateRenderPassDescriptor(DeviceBase* device,
                                        UnpackedPtr<RenderPassDescriptor> descriptor,
                                        UsageValidationMode usageValidationMode,
                                        RenderPassValidationState* validationState) {
    uint32_t maxColorAttachments = device->GetLimits().v1.maxColorAttachments;
    DAWN_INVALID_IF(
        descriptor->colorAttachmentCount > maxColorAttachments,
        "Color attachment count (%u) exceeds the maximum number of color attachments (%u).%s",
        descriptor->colorAttachmentCount, maxColorAttachments,
        DAWN_INCREASE_LIMIT_MESSAGE(device->GetAdapter()->GetLimits().v1, maxColorAttachments,
                                    descriptor->colorAttachmentCount));

    auto colorAttachments = ityp::SpanFromUntyped<ColorAttachmentIndex>(
        descriptor->colorAttachments, descriptor->colorAttachmentCount);
    ColorAttachmentFormats colorAttachmentFormats;
    if (const auto* expandResolveRect = descriptor.Get<RenderPassDescriptorResolveRect>()) {
        DAWN_INVALID_IF(!device->HasFeature(Feature::DawnPartialLoadResolveTexture),
                        "RenderPassDescriptorResolveRect can't be used without %s.",
                        ToAPI(Feature::DawnPartialLoadResolveTexture));
        validationState->SetExpandResolveRect(*expandResolveRect);
    }

    const auto* renderPassSampleCount = descriptor.Get<DawnRenderPassSampleCount>();
    if (renderPassSampleCount) {
        DAWN_TRY(ValidateDawnRenderPassSampleCount(device, renderPassSampleCount));
        validationState->SetExplicitSampleCount(renderPassSampleCount->sampleCount);
    }

    for (auto [i, attachment] : Enumerate(colorAttachments)) {
        DAWN_TRY_CONTEXT(ValidateRenderPassColorAttachment(device, attachment, usageValidationMode,
                                                           validationState),
                         "validating colorAttachments[%u].", i);
        if (attachment.view) {
            if (renderPassSampleCount) {
                DAWN_TRY(ValidateColorAttachmentRenderToSingleSampled(device, attachment,
                                                                      renderPassSampleCount));
            }
            colorAttachmentFormats.push_back(&attachment.view->GetFormat());
        }
    }
    DAWN_TRY_CONTEXT(ValidateColorAttachmentBytesPerSample(device, colorAttachmentFormats),
                     "validating color attachment bytes per sample.");

    if (descriptor->depthStencilAttachment != nullptr) {
        DAWN_TRY_CONTEXT(
            ValidateRenderPassDepthStencilAttachment(device, descriptor->depthStencilAttachment,
                                                     usageValidationMode, validationState),
            "validating depthStencilAttachment.");
    }

    if (descriptor->occlusionQuerySet != nullptr) {
        DAWN_TRY(device->ValidateObject(descriptor->occlusionQuerySet));

        DAWN_INVALID_IF(descriptor->occlusionQuerySet->GetQueryType() != wgpu::QueryType::Occlusion,
                        "The occlusionQuerySet %s type (%s) is not %s.",
                        descriptor->occlusionQuerySet,
                        descriptor->occlusionQuerySet->GetQueryType(), wgpu::QueryType::Occlusion);
    }

    if (descriptor->timestampWrites != nullptr) {
        DAWN_TRY_CONTEXT(ValidatePassTimestampWrites(device, descriptor->timestampWrites),
                         "validating timestampWrites.");
    }

    // Validation for any pixel local storage.
    auto pls = descriptor.Get<RenderPassPixelLocalStorage>();
    if (pls != nullptr) {
        DAWN_TRY(ValidateRenderPassPLS(device, pls, usageValidationMode, validationState));
    }

    DAWN_INVALID_IF(!validationState->HasAttachment(), "Render pass has no attachments.");

    if (validationState->IsMsrtssAllowed()) {
        // TODO(dawn:1704): Consider supporting MSAARenderToSingleSampled + PLS
        DAWN_INVALID_IF(
            pls != nullptr,
            "For now pixel local storage is invalid to use with MSAARenderToSingleSampled.");
    }

    if (validationState->WillExpandResolveTexture()) {
        // TODO(dawn:1704): Consider supporting ExpandResolveTexture + PLS
        DAWN_INVALID_IF(pls != nullptr, "For now pixel local storage is invalid to use with %s.",
                        wgpu::LoadOp::ExpandResolveTexture);
    }

    if (auto area = descriptor.Get<RenderPassRenderAreaRect>()) {
        DAWN_INVALID_IF(!device->HasFeature(Feature::RenderPassRenderArea),
                        "RenderPassRenderAreaRect can't be used without %s.",
                        ToAPI(Feature::RenderPassRenderArea));
        DAWN_INVALID_IF(area->size.width == 0 || area->size.height == 0,
                        "RenderPassRenderAreaRect %s must not be empty", area);
        DAWN_INVALID_IF(
            static_cast<uint64_t>(area->origin.x) + static_cast<uint64_t>(area->size.width) >
                    validationState->GetRenderWidth() ||
                static_cast<uint64_t>(area->origin.y) + static_cast<uint64_t>(area->size.height) >
                    validationState->GetRenderHeight(),
            "RenderPassRenderAreaRect %s is not contained in the render pass (%u x %u)", area,
            validationState->GetRenderWidth(), validationState->GetRenderHeight());
    }

    return {};
}

// Adds a single attachment to the validation state to ensure that it is valid and can report a
// render width and height.
MaybeError InitializeValidationStateAttachment(DeviceBase* device,
                                               UnpackedPtr<RenderPassDescriptor> descriptor,
                                               RenderPassValidationState* validationState) {
    TextureViewBase* representativeView = nullptr;

    // Check every attachment to guard against invalid objects caused by OOM errors.
    auto CheckAttachment = [&](TextureViewBase* view) -> MaybeError {
        DAWN_CHECK(view);
        DAWN_TRY(device->IsNotErrorObject(view));
        representativeView = view;
        return {};
    };

    auto pls = descriptor.Get<RenderPassPixelLocalStorage>();
    if (pls != nullptr && pls->storageAttachmentCount > 0) {
        for (size_t i = 0; i < pls->storageAttachmentCount; i++) {
            const RenderPassStorageAttachment& attachment =
                DAWN_UNSAFE_TODO(pls->storageAttachments[i]);
            DAWN_TRY(CheckAttachment(attachment.storage));
        }
    }

    if (descriptor->depthStencilAttachment != nullptr) {
        DAWN_TRY(CheckAttachment(descriptor->depthStencilAttachment->view));
    }

    for (size_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
        const RenderPassColorAttachment& colorAttachment =
            DAWN_UNSAFE_TODO(descriptor->colorAttachments[i]);
        if (colorAttachment.view != nullptr) {
            DAWN_TRY(CheckAttachment(colorAttachment.view));
            if (colorAttachment.resolveTarget != nullptr) {
                DAWN_TRY(device->IsNotErrorObject(colorAttachment.resolveTarget));
            }
        }
    }

    // Only one attachment needs to be added to the validation state.
    DAWN_CHECK(representativeView);
    validationState->SetUnvalidatedAttachment(representativeView);

    return {};
}

MaybeError ValidateComputePassDescriptor(const DeviceBase* device,
                                         const ComputePassDescriptor* descriptor) {
    if (descriptor == nullptr) {
        return {};
    }

    if (descriptor->timestampWrites != nullptr) {
        DAWN_TRY_CONTEXT(ValidatePassTimestampWrites(device, descriptor->timestampWrites),
                         "validating timestampWrites.");
    }

    return {};
}

MaybeError ValidateQuerySetResolve(const QuerySetBase* querySet,
                                   QueryIndex firstQuery,
                                   QueryIndex queryCount,
                                   const BufferBase* destination,
                                   uint64_t destinationOffset) {
    DAWN_INVALID_IF(firstQuery >= querySet->GetQueryCount(),
                    "First query (%u) exceeds the number of queries (%u) in %s.", firstQuery,
                    querySet->GetQueryCount(), querySet);

    DAWN_INVALID_IF(
        queryCount > querySet->GetQueryCount() - firstQuery,
        "The query range (firstQuery: %u, queryCount: %u) exceeds the number of queries "
        "(%u) in %s.",
        firstQuery, queryCount, querySet->GetQueryCount(), querySet);

    DAWN_INVALID_IF(destinationOffset % kQueryResolveAlignment != 0,
                    "The destination buffer %s offset (%u) is not a multiple of %u.", destination,
                    destinationOffset, kQueryResolveAlignment);

    uint64_t bufferSize = destination->GetSize();
    // The destination buffer must have enough storage, from destination offset, to contain
    // the result of resolved queries
    bool fitsInBuffer =
        destinationOffset <= bufferSize &&
        (static_cast<uint64_t>(queryCount) * sizeof(uint64_t) <= (bufferSize - destinationOffset));
    DAWN_INVALID_IF(
        !fitsInBuffer,
        "The resolved %s data size (%u) would not fit in %s with size %u at the offset %u.",
        querySet, static_cast<uint64_t>(queryCount) * sizeof(uint64_t), destination, bufferSize,
        destinationOffset);

    return {};
}

MaybeError EncodeTimestampsToNanosecondsConversion(CommandEncoder* encoder,
                                                   QuerySetBase* querySet,
                                                   QueryIndex firstQuery,
                                                   QueryIndex queryCount,
                                                   BufferBase* destination,
                                                   uint64_t destinationOffset) {
    DeviceBase* device = encoder->GetDevice();

    const uint32_t quantizationMask = device->IsToggleEnabled(Toggle::TimestampQuantization)
                                          ? kTimestampQuantizationMask
                                          : 0xFFFFFFFF;

    // Timestamp params uniform buffer
    TimestampParams params(uint32_t{queryCount}, static_cast<uint32_t>(destinationOffset),
                           quantizationMask, device->GetTimestampPeriodInNS());

    BufferDescriptor parmsDesc = {};
    parmsDesc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
    parmsDesc.size = sizeof(params);
    Ref<BufferBase> paramsBuffer;
    DAWN_TRY_ASSIGN(paramsBuffer, device->CreateBuffer(&parmsDesc));

    DAWN_TRY(device->GetQueue()->WriteBuffer(paramsBuffer.Get(), 0, &params, sizeof(params)));

    return EncodeConvertTimestampsToNanoseconds(encoder, uint32_t{queryCount}, destination,
                                                paramsBuffer.Get());
}

bool ShouldUseTextureToBufferBlit(const DeviceBase* device,
                                  const Format& format,
                                  const Aspect& aspect,
                                  const Extent3D& copySize) {
    // Noop copy, do not use blit.
    if (copySize.width == 0 || copySize.height == 0 || copySize.depthOrArrayLayers == 0) {
        return false;
    }

    // Snorm
    if (format.IsSnorm() && device->IsToggleEnabled(Toggle::UseBlitForSnormTextureToBufferCopy)) {
        return true;
    }
    // BGRA8Unorm
    if (format.format == wgpu::TextureFormat::BGRA8Unorm &&
        device->IsToggleEnabled(Toggle::UseBlitForBGRA8UnormTextureToBufferCopy)) {
        return true;
    }
    // RGB9E5Ufloat
    if (format.format == wgpu::TextureFormat::RGB9E5Ufloat &&
        device->IsToggleEnabled(Toggle::UseBlitForRGB9E5UfloatTextureCopy)) {
        return true;
    }
    // RG11B10Ufloat
    if (format.format == wgpu::TextureFormat::RG11B10Ufloat &&
        device->IsToggleEnabled(Toggle::UseBlitForRG11B10UfloatTextureCopy)) {
        return true;
    }
    // float16
    if ((format.format == wgpu::TextureFormat::R16Float ||
         format.format == wgpu::TextureFormat::RG16Float ||
         format.format == wgpu::TextureFormat::RGBA16Float) &&
        device->IsToggleEnabled(Toggle::UseBlitForFloat16TextureCopy)) {
        return true;
    }
    // float32
    if ((format.format == wgpu::TextureFormat::R32Float ||
         format.format == wgpu::TextureFormat::RG32Float ||
         format.format == wgpu::TextureFormat::RGBA32Float) &&
        device->IsToggleEnabled(Toggle::UseBlitForFloat32TextureCopy)) {
        return true;
    }
    // Depth
    if (aspect == Aspect::Depth &&
        ((format.format == wgpu::TextureFormat::Depth16Unorm &&
          device->IsToggleEnabled(Toggle::UseBlitForDepth16UnormTextureToBufferCopy)) ||
         (format.format == wgpu::TextureFormat::Depth24Plus &&
          device->IsToggleEnabled(Toggle::UseBlitForDepth24PlusTextureToBufferCopy)) ||
         (format.format == wgpu::TextureFormat::Depth24PlusStencil8 &&
          device->IsToggleEnabled(Toggle::UseBlitForDepth24PlusTextureToBufferCopy)) ||
         (format.format == wgpu::TextureFormat::Depth32Float &&
          device->IsToggleEnabled(Toggle::UseBlitForDepth32FloatTextureToBufferCopy)))) {
        return true;
    }
    // Stencil
    if (aspect == Aspect::Stencil &&
        device->IsToggleEnabled(Toggle::UseBlitForStencilTextureToBufferCopy)) {
        return true;
    }

    if (device->IsToggleEnabled(Toggle::UseBlitForT2B) &&
        IsFormatSupportedByTextureToBufferBlit(format.format)) {
        return true;
    }

    return false;
}

bool ShouldUseT2B2TForT2T(const DeviceBase* device,
                          const Format& srcFormat,
                          const Format& dstFormat) {
    // RGB9E5Ufloat
    if (srcFormat.baseFormat == wgpu::TextureFormat::RGB9E5Ufloat &&
        device->IsToggleEnabled(Toggle::UseBlitForRGB9E5UfloatTextureCopy)) {
        return true;
    }
    // sRGB <-> non-sRGB
    if (srcFormat.format != dstFormat.format && srcFormat.baseFormat == dstFormat.baseFormat &&
        device->IsToggleEnabled(Toggle::UseT2B2TForSRGBTextureCopy)) {
        return true;
    }
    // Snorm
    if (srcFormat.IsSnorm() &&
        device->IsToggleEnabled(Toggle::UseBlitForSnormTextureToBufferCopy)) {
        return true;
    }
    return false;
}

}  // namespace

Color ClampClearColorValueToLegalRange(const Color& originalColor, const Format& format) {
    const AspectInfo& aspectInfo = format.GetAspectInfo(Aspect::Color);
    double minValue = 0;
    double maxValue = 0;
    switch (aspectInfo.baseType) {
        case TextureComponentType::Float: {
            return originalColor;
        }
        case TextureComponentType::Sint: {
            const uint32_t bitsPerComponent =
                (aspectInfo.block.byteSize * 8 / format.componentCount);
            maxValue =
                static_cast<double>((static_cast<uint64_t>(1) << (bitsPerComponent - 1)) - 1);
            minValue = -static_cast<double>(static_cast<uint64_t>(1) << (bitsPerComponent - 1));
            break;
        }
        case TextureComponentType::Uint: {
            const uint32_t bitsPerComponent =
                (aspectInfo.block.byteSize * 8 / format.componentCount);
            maxValue = static_cast<double>((static_cast<uint64_t>(1) << bitsPerComponent) - 1);
            break;
        }
    }

    return {std::clamp(originalColor.r, minValue, maxValue),
            std::clamp(originalColor.g, minValue, maxValue),
            std::clamp(originalColor.b, minValue, maxValue),
            std::clamp(originalColor.a, minValue, maxValue)};
}

ResultOrError<UnpackedPtr<CommandEncoderDescriptor>> ValidateCommandEncoderDescriptor(
    const DeviceBase* device,
    const CommandEncoderDescriptor* descriptor) {
    UnpackedPtr<CommandEncoderDescriptor> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(descriptor));

    const auto* internalUsageDesc = unpacked.Get<DawnEncoderInternalUsageDescriptor>();
    DAWN_INVALID_IF(internalUsageDesc != nullptr &&
                        !device->APIHasFeature(wgpu::FeatureName::DawnInternalUsages),
                    "%s is not available.", wgpu::FeatureName::DawnInternalUsages);
    return unpacked;
}

// static
Ref<CommandEncoder> CommandEncoder::Create(
    DeviceBase* device,
    const UnpackedPtr<CommandEncoderDescriptor>& descriptor) {
    return AcquireRef(new CommandEncoder(device, descriptor));
}

// static
Ref<CommandEncoder> CommandEncoder::MakeError(DeviceBase* device, StringView label) {
    return AcquireRef(new CommandEncoder(device, ObjectBase::kError, label));
}

CommandEncoder::CommandEncoder(DeviceBase* device,
                               const UnpackedPtr<CommandEncoderDescriptor>& descriptor)
    : ApiObjectBase(device, descriptor->label), mEncodingContext(device, this) {
    GetObjectTrackingList()->Track(this);

    auto* internalUsageDesc = descriptor.Get<DawnEncoderInternalUsageDescriptor>();
    if (internalUsageDesc != nullptr && internalUsageDesc->useInternalUsages) {
        mUsageValidationMode = UsageValidationMode::Internal;
    } else {
        mUsageValidationMode = UsageValidationMode::Default;
    }
}

CommandEncoder::CommandEncoder(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
    : ApiObjectBase(device, tag, label),
      mEncodingContext(device, tag),
      mUsageValidationMode(UsageValidationMode::Default) {}

ObjectType CommandEncoder::GetType() const {
    return ObjectType::CommandEncoder;
}

void CommandEncoder::DestroyImpl(DestroyReason reason) {
    mEncodingContext.Destroy();
}

CommandBufferResourceUsage CommandEncoder::AcquireResourceUsages() {
    return CommandBufferResourceUsage{
        mEncodingContext.AcquireRenderPassUsages(),
        mEncodingContext.AcquireComputePassUsages(),
        std::move(mTopLevelBuffers),
        std::move(mTopLevelTextures),
        std::move(mUsedQuerySets),
    };
}

CommandIterator CommandEncoder::AcquireCommands() {
    return mEncodingContext.AcquireCommands();
}

void CommandEncoder::TrackUsedQuerySet(QuerySetBase* querySet) {
    mUsedQuerySets.insert(querySet);
}

ityp::vector<PassIndex, IndirectDrawMetadata> CommandEncoder::AcquireIndirectDrawMetadata() {
    return mEncodingContext.AcquireIndirectDrawMetadata();
}

// Implementation of the API's command recording methods

ComputePassEncoder* CommandEncoder::APIBeginComputePass(const ComputePassDescriptor* descriptor) {
    // This function will create new object, need to lock the Device.
    auto deviceGuard = GetDevice()->GetGuard();

    return ReturnToAPI(BeginComputePass(descriptor));
}

Ref<ComputePassEncoder> CommandEncoder::BeginComputePass(const ComputePassDescriptor* descriptor) {
    DeviceBase* device = GetDevice();
    DAWN_ASSERT(device->IsLockedByCurrentThreadIfNeeded());

    bool success = mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateComputePassDescriptor(device, descriptor));
            }

            BeginComputePassCmd* cmd =
                allocator->Allocate<BeginComputePassCmd>(Command::BeginComputePass);

            if (descriptor == nullptr) {
                return {};
            }

            if (!descriptor->label.IsUndefined()) {
                cmd->label = std::string(descriptor->label);
            }

            if (descriptor->timestampWrites != nullptr) {
                QuerySetBase* querySet = descriptor->timestampWrites->querySet;
                QueryIndex beginningOfPassWriteIndex{
                    descriptor->timestampWrites->beginningOfPassWriteIndex};
                QueryIndex endOfPassWriteIndex{descriptor->timestampWrites->endOfPassWriteIndex};

                TrackUsedQuerySet(querySet);
                cmd->timestampWrites.querySet = querySet;
                cmd->timestampWrites.beginningOfPassWriteIndex = beginningOfPassWriteIndex;
                cmd->timestampWrites.endOfPassWriteIndex = endOfPassWriteIndex;
            }
            return {};
        },
        "encoding %s.BeginComputePass(%s).", this, descriptor);

    if (success) {
        const ComputePassDescriptor defaultDescriptor = {};
        if (descriptor == nullptr) {
            descriptor = &defaultDescriptor;
        }

        Ref<ComputePassEncoder> passEncoder =
            ComputePassEncoder::Create(device, descriptor, this, &mEncodingContext);
        mEncodingContext.EnterPass(passEncoder.Get());
        return passEncoder;
    }

    return ComputePassEncoder::MakeError(device, this, &mEncodingContext,
                                         descriptor ? descriptor->label : nullptr);
}

RenderPassEncoder* CommandEncoder::APIBeginRenderPass(const RenderPassDescriptor* descriptor) {
    // This function will create new object, need to lock the Device.
    auto deviceGuard = GetDevice()->GetGuard();

    return ReturnToAPI(BeginRenderPass(descriptor));
}

Ref<RenderPassEncoder> CommandEncoder::BeginRenderPass(const RenderPassDescriptor* rawDescriptor) {
    DeviceBase* device = GetDevice();
    DAWN_ASSERT(device->IsLockedByCurrentThreadIfNeeded());

    RenderPassResourceUsageTracker usageTracker;

    bool depthReadOnly = false;
    bool stencilReadOnly = false;
    Ref<AttachmentState> attachmentState;

    RenderPassValidationState validationState;

    // Lazy make error function to be called if we error and need to return an error encoder.
    auto MakeError = [&]() {
        return RenderPassEncoder::MakeError(device, this, &mEncodingContext,
                                            rawDescriptor ? rawDescriptor->label : nullptr);
    };

    UnpackedPtr<RenderPassDescriptor> descriptor;
    ClearWithDrawHelper clearWithDrawHelper;
    RenderPassWorkaroundsHelper renderpassWorkaroundsHelper;

    RenderPassEncoder::EndCallback passEndCallback = nullptr;

    RenderAreaRect renderArea;

    bool success = mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            DAWN_TRY_ASSIGN_CONTEXT(descriptor, ValidateAndUnpack(rawDescriptor),
                                    "validating and unpacking chained structs.");

            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateRenderPassDescriptor(device, descriptor, mUsageValidationMode,
                                                      &validationState));
            } else {
                // If validation is skipped at least one attachment still needs to be added to the
                // validation state to compute the render width and height from.
                DAWN_TRY(InitializeValidationStateAttachment(device, descriptor, &validationState));
            }

            DAWN_CHECK(validationState.IsValidState());

            DAWN_TRY(clearWithDrawHelper.Initialize(this, descriptor));
            DAWN_TRY(renderpassWorkaroundsHelper.Initialize(this, descriptor));

            mEncodingContext.WillBeginRenderPass();
            BeginRenderPassCmd* cmd =
                allocator->Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);

            if (!descriptor->label.IsUndefined()) {
                cmd->label = std::string(descriptor->label);
            }

            cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
            attachmentState = cmd->attachmentState;

            auto descColorAttachments = ityp::SpanFromUntyped<ColorAttachmentIndex>(
                descriptor->colorAttachments, descriptor->colorAttachmentCount);
            for (auto i : cmd->attachmentState->GetColorAttachmentsMask()) {
                auto& descColorAttachment = descColorAttachments[i];
                auto& cmdColorAttachment = cmd->colorAttachments[i];

                TextureViewBase* colorTarget;
                TextureViewBase* resolveTarget;

                colorTarget = descColorAttachment.view;
                resolveTarget = descColorAttachment.resolveTarget;

                cmdColorAttachment.view = colorTarget;
                // Explicitly set depthSlice to 0 if it's undefined. The
                // wgpu::kDepthSliceUndefined is defined to differentiate between `undefined`
                // and 0 for depthSlice, but we use it as 0 for 2d attachments in backends.
                cmdColorAttachment.depthSlice =
                    descColorAttachment.depthSlice == wgpu::kDepthSliceUndefined
                        ? 0
                        : descColorAttachment.depthSlice;
                cmdColorAttachment.loadOp = descColorAttachment.loadOp;
                cmdColorAttachment.storeOp = descColorAttachment.storeOp;

                cmdColorAttachment.resolveTarget = resolveTarget;
                cmdColorAttachment.clearColor = ClampClearColorValueToLegalRange(
                    descColorAttachment.clearValue, colorTarget->GetFormat());

                usageTracker.TextureViewUsedAs(colorTarget, wgpu::TextureUsage::RenderAttachment);

                if (resolveTarget != nullptr) {
                    usageTracker.TextureViewUsedAs(resolveTarget,
                                                   wgpu::TextureUsage::RenderAttachment);
                } else if (colorTarget->GetTexture()->GetSampleCount() == 1 &&
                           attachmentState->GetSampleCount() > 1) {
                    // Detect if multisample render to single-sampled is in use
                    cmd->msaaRenderToSingleSampled = true;
                }
            }

            if (cmd->attachmentState->HasDepthStencilAttachment()) {
                TextureViewBase* view = descriptor->depthStencilAttachment->view;
                TextureBase* attachment = view->GetTexture();
                cmd->depthStencilAttachment.view = view;
                // Range that will be modified per aspect to track the usage.
                SubresourceRange usageRange = view->GetSubresourceRange();

                switch (descriptor->depthStencilAttachment->depthLoadOp) {
                    case wgpu::LoadOp::Clear:
                        cmd->depthStencilAttachment.clearDepth =
                            descriptor->depthStencilAttachment->depthClearValue;
                        break;
                    case wgpu::LoadOp::Load:
                    case wgpu::LoadOp::Undefined:
                        // Set depthClearValue to 0 if it is the load op is not clear.
                        // The default value NaN may be invalid in the backend.
                        cmd->depthStencilAttachment.clearDepth = 0.f;
                        break;
                    case wgpu::LoadOp::ExpandResolveTexture:
                        DAWN_UNREACHABLE();
                        break;
                }

                // GPURenderPassDepthStencilAttachment.stencilClearValue will be converted to
                // the type of the stencil aspect of view by taking the same number of LSBs as
                // the number of bits in the stencil aspect of one texel block of view.
                DAWN_CHECK(!(view->GetFormat().aspects & Aspect::Stencil) ||
                           view->GetFormat().GetAspectInfo(Aspect::Stencil).block.byteSize == 1u);
                cmd->depthStencilAttachment.clearStencil =
                    descriptor->depthStencilAttachment->stencilClearValue & 0xFF;

                // Depth aspect:
                //  - Copy parameters for the aspect, reyifing the values when it is not present or
                //  readonly.
                //  - Export depthReadOnly to the outside of the depth-stencil attachment handling.
                //  - Track the usage of this aspect.
                depthReadOnly = descriptor->depthStencilAttachment->depthReadOnly;

                cmd->depthStencilAttachment.depthReadOnly = false;
                cmd->depthStencilAttachment.depthLoadOp = wgpu::LoadOp::Load;
                cmd->depthStencilAttachment.depthStoreOp = wgpu::StoreOp::Store;
                if (attachment->GetFormat().HasDepth()) {
                    cmd->depthStencilAttachment.depthReadOnly = depthReadOnly;
                    if (!depthReadOnly) {
                        cmd->depthStencilAttachment.depthLoadOp =
                            descriptor->depthStencilAttachment->depthLoadOp;
                        cmd->depthStencilAttachment.depthStoreOp =
                            descriptor->depthStencilAttachment->depthStoreOp;
                    }

                    usageRange.aspects = Aspect::Depth;
                    usageTracker.TextureRangeUsedAs(attachment, usageRange,
                                                    depthReadOnly
                                                        ? kReadOnlyRenderAttachment
                                                        : wgpu::TextureUsage::RenderAttachment);
                }

                // Stencil aspect:
                //  - Copy parameters for the aspect, reyifing the values when it is not present or
                //  readonly.
                //  - Export stencilReadOnly to the outside of the depth-stencil attachment
                //  handling.
                //  - Track the usage of this aspect.
                stencilReadOnly = descriptor->depthStencilAttachment->stencilReadOnly;

                cmd->depthStencilAttachment.stencilReadOnly = false;
                cmd->depthStencilAttachment.stencilLoadOp = wgpu::LoadOp::Load;
                cmd->depthStencilAttachment.stencilStoreOp = wgpu::StoreOp::Store;
                if (attachment->GetFormat().HasStencil()) {
                    cmd->depthStencilAttachment.stencilReadOnly = stencilReadOnly;
                    if (!stencilReadOnly) {
                        cmd->depthStencilAttachment.stencilLoadOp =
                            descriptor->depthStencilAttachment->stencilLoadOp;
                        cmd->depthStencilAttachment.stencilStoreOp =
                            descriptor->depthStencilAttachment->stencilStoreOp;
                    }

                    usageRange.aspects = Aspect::Stencil;
                    usageTracker.TextureRangeUsedAs(attachment, usageRange,
                                                    stencilReadOnly
                                                        ? kReadOnlyRenderAttachment
                                                        : wgpu::TextureUsage::RenderAttachment);
                }
            }

            cmd->width = validationState.GetRenderWidth();
            cmd->height = validationState.GetRenderHeight();

            if (auto* area = descriptor.Get<RenderPassRenderAreaRect>()) {
                renderArea.x = area->origin.x;
                renderArea.y = area->origin.y;
                renderArea.width = area->size.width;
                renderArea.height = area->size.height;
            } else {
                renderArea.x = 0;
                renderArea.y = 0;
                renderArea.width = validationState.GetRenderWidth();
                renderArea.height = validationState.GetRenderHeight();
            }

            cmd->renderArea = renderArea;

            if (descriptor->occlusionQuerySet) {
                TrackUsedQuerySet(descriptor->occlusionQuerySet);
                cmd->occlusionQuerySet = descriptor->occlusionQuerySet;
            }

            if (descriptor->timestampWrites != nullptr) {
                QuerySetBase* querySet = descriptor->timestampWrites->querySet;
                QueryIndex beginningOfPassWriteIndex{
                    descriptor->timestampWrites->beginningOfPassWriteIndex};
                QueryIndex endOfPassWriteIndex{descriptor->timestampWrites->endOfPassWriteIndex};

                TrackUsedQuerySet(querySet);
                cmd->timestampWrites.querySet = querySet;
                cmd->timestampWrites.beginningOfPassWriteIndex = beginningOfPassWriteIndex;
                cmd->timestampWrites.endOfPassWriteIndex = endOfPassWriteIndex;

                // The render pass usage tracker contains data about written queries. This is
                // necessary on Vulkan to be able to reset queries before the start of render passes
                // (it can only be done outside of a render pass).
                if (beginningOfPassWriteIndex != kQuerySetIndexUndefinedTyped) {
                    usageTracker.TrackQueryAvailability(querySet, beginningOfPassWriteIndex);
                }
                if (endOfPassWriteIndex != kQuerySetIndexUndefinedTyped) {
                    usageTracker.TrackQueryAvailability(querySet, endOfPassWriteIndex);
                }
            }

            if (auto* pls = descriptor.Get<RenderPassPixelLocalStorage>()) {
                for (size_t i = 0; i < pls->storageAttachmentCount; i++) {
                    const RenderPassStorageAttachment& apiAttachment =
                        DAWN_UNSAFE_TODO(pls->storageAttachments[i]);
                    RenderPassStorageAttachmentInfo* attachmentInfo =
                        &cmd->storageAttachments[apiAttachment.offset / kPLSSlotByteSize];

                    attachmentInfo->storage = apiAttachment.storage;
                    attachmentInfo->loadOp = apiAttachment.loadOp;
                    attachmentInfo->storeOp = apiAttachment.storeOp;
                    attachmentInfo->clearColor = ClampClearColorValueToLegalRange(
                        apiAttachment.clearValue, apiAttachment.storage->GetFormat());

                    usageTracker.TextureViewUsedAs(apiAttachment.storage,
                                                   wgpu::TextureUsage::StorageAttachment);
                }
            }

            DAWN_TRY(renderpassWorkaroundsHelper.ApplyOnPostEncoding(
                this, descriptor, &usageTracker, cmd, &passEndCallback));

            return {};
        },
        "encoding %s.BeginRenderPass(%s).", this, descriptor);

    if (success) {
        Ref<RenderPassEncoder> passEncoder =
            RenderPassEncoder::Create(device, descriptor, this, &mEncodingContext,
                                      std::move(usageTracker), std::move(attachmentState),
                                      renderArea, depthReadOnly, stencilReadOnly, passEndCallback);

        mEncodingContext.EnterPass(passEncoder.Get());

        auto error = [&]() -> MaybeError {
            // clearWithDrawHelper.Apply() applies clear with draw if clear_color_with_draw or
            // apply_clear_big_integer_color_value_with_draw toggle is enabled, and the render pass
            // attachments need to be cleared.
            // TODO(341129591): move inside RenderPassWorkaroundsHelper.
            DAWN_TRY(clearWithDrawHelper.Apply(passEncoder.Get()));

            DAWN_TRY(
                renderpassWorkaroundsHelper.ApplyOnRenderPassStart(passEncoder.Get(), descriptor));

            return {};
        }();

        if (device->ConsumedError(std::move(error))) {
            return MakeError();
        }

        return passEncoder;
    }

    return MakeError();
}

void CommandEncoder::APICopyBufferToBuffer(BufferBase* source,
                                           uint64_t sourceOffset,
                                           BufferBase* destination,
                                           uint64_t destinationOffset,
                                           uint64_t size) {
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(source));
                DAWN_TRY(GetDevice()->ValidateObject(destination));

                DAWN_INVALID_IF(source == destination,
                                "Source and destination are the same buffer (%s).", source);

                DAWN_TRY_CONTEXT(ValidateCopySizeFitsInBuffer(source, sourceOffset, size),
                                 "validating source %s copy size.", source);
                DAWN_TRY_CONTEXT(ValidateCopySizeFitsInBuffer(destination, destinationOffset, size),
                                 "validating destination %s copy size.", destination);
                DAWN_TRY(ValidateB2BCopyAlignment(size, sourceOffset, destinationOffset));

                DAWN_TRY_CONTEXT(ValidateCanUseAs(source, wgpu::BufferUsage::CopySrc),
                                 "validating source %s usage.", source);
                DAWN_TRY_CONTEXT(ValidateCanUseAs(destination, wgpu::BufferUsage::CopyDst),
                                 "validating destination %s usage.", destination);
            }

            mTopLevelBuffers.insert(source);
            mTopLevelBuffers.insert(destination);

            CopyBufferToBufferCmd* copy =
                allocator->Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
            copy->source = source;
            copy->sourceOffset = sourceOffset;
            copy->destination = destination;
            copy->destinationOffset = destinationOffset;
            copy->size = size;

            return {};
        },
        "encoding %s.CopyBufferToBuffer(%s, %u, %s, %u, %u).", this, source, sourceOffset,
        destination, destinationOffset, size);
}

// The internal version of APICopyBufferToBuffer which validates against mAllocatedSize instead of
// mSize of buffers.
void CommandEncoder::InternalCopyBufferToBufferWithAllocatedSize(BufferBase* source,
                                                                 uint64_t sourceOffset,
                                                                 BufferBase* destination,
                                                                 uint64_t destinationOffset,
                                                                 uint64_t size) {
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(source));
                DAWN_TRY(GetDevice()->ValidateObject(destination));

                DAWN_INVALID_IF(source == destination,
                                "Source and destination are the same buffer (%s).", source);

                DAWN_TRY_CONTEXT(ValidateCopySizeFitsInBuffer(source, sourceOffset, size,
                                                              BufferSizeType::AllocatedSize),
                                 "validating source %s copy size against allocated size.", source);
                DAWN_TRY_CONTEXT(ValidateCopySizeFitsInBuffer(destination, destinationOffset, size,
                                                              BufferSizeType::AllocatedSize),
                                 "validating destination %s copy size against allocated size.",
                                 destination);
                DAWN_TRY(ValidateB2BCopyAlignment(size, sourceOffset, destinationOffset));

                DAWN_TRY_CONTEXT(ValidateCanUseAsInternal(
                                     source, wgpu::BufferUsage::CopySrc | kInternalCopySrcBuffer),
                                 "validating source %s usage.", source);
                DAWN_TRY_CONTEXT(ValidateCanUseAs(destination, wgpu::BufferUsage::CopyDst),
                                 "validating destination %s usage.", destination);
            }

            mTopLevelBuffers.insert(source);
            mTopLevelBuffers.insert(destination);

            CopyBufferToBufferCmd* copy =
                allocator->Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
            copy->source = source;
            copy->sourceOffset = sourceOffset;
            copy->destination = destination;
            copy->destinationOffset = destinationOffset;
            copy->size = size;

            return {};
        },
        "encoding internal %s.CopyBufferToBuffer(%s, %u, %s, %u, %u).", this, source, sourceOffset,
        destination, destinationOffset, size);
}

void CommandEncoder::APICopyBufferToTexture(const TexelCopyBufferInfo* source,
                                            const TexelCopyTextureInfo* destinationOrig,
                                            const Extent3D* copySize) {
    TexelCopyTextureInfo destination = destinationOrig->WithTrivialFrontendDefaults();

    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateTexelCopyBufferInfo(GetDevice(), *source));
                DAWN_TRY_CONTEXT(ValidateCanUseAs(source->buffer, wgpu::BufferUsage::CopySrc),
                                 "validating source %s usage.", source->buffer);

                DAWN_TRY(ValidateTexelCopyTextureInfo(GetDevice(), destination, *copySize));
                DAWN_TRY_CONTEXT(ValidateCanUseAs(destination.texture, wgpu::TextureUsage::CopyDst,
                                                  mUsageValidationMode),
                                 "validating destination %s usage.", destination.texture);
                DAWN_TRY(ValidateTextureSampleCountInBufferCopyCommands(destination.texture));

                DAWN_TRY(ValidateLinearToDepthStencilCopyRestrictions(destination));
                // We validate texture copy range before validating linear texture data,
                // because in the latter we divide copyExtent.width by blockWidth and
                // copyExtent.height by blockHeight while the divisibility conditions are
                // checked in validating texture copy range.
                DAWN_TRY(ValidateTextureCopyRange(GetDevice(), destination, *copySize));
            }
            const TypedTexelBlockInfo& blockInfo = GetBlockInfo(destination);
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateLinearTextureCopyOffset(
                    source->layout, blockInfo.ToTexelBlockInfo(),
                    destination.texture->GetFormat().HasDepthOrStencil()));
                DAWN_TRY(ValidateLinearTextureData(source->layout, source->buffer->GetSize(),
                                                   blockInfo.ToTexelBlockInfo(), *copySize));
            }

            mTopLevelBuffers.insert(source->buffer);
            mTopLevelTextures.insert(destination.texture);

            TexelCopyBufferLayout srcLayout = source->layout;
            ApplyDefaultTexelCopyBufferLayoutOptions(&srcLayout, blockInfo.ToTexelBlockInfo(),
                                                     *copySize);

            TextureCopy dst;
            dst.texture = destination.texture;
            dst.origin = destination.origin;
            dst.mipLevel = destination.mipLevel;
            dst.aspect = ConvertAspect(destination.texture->GetFormat(), destination.aspect);

            if (dst.aspect == Aspect::Depth &&
                GetDevice()->IsToggleEnabled(Toggle::UseBlitForBufferToDepthTextureCopy)) {
                // The below function might create new resources. Need to lock the Device.
                // TODO(crbug.com/dawn/1618): In future, all temp resources should be created at
                // Command Submit time, so the locking would be removed from here at that point.
                auto deviceGuard = GetDevice()->GetGuard();

                DAWN_TRY_CONTEXT(
                    BlitBufferToDepth(GetDevice(), this, source->buffer, srcLayout, dst, *copySize),
                    "copying from %s to depth aspect of %s using blit workaround.", source->buffer,
                    dst.texture.Get());
                return {};
            } else if (dst.aspect == Aspect::Stencil &&
                       GetDevice()->IsToggleEnabled(Toggle::UseBlitForBufferToStencilTextureCopy)) {
                // The below function might create new resources. Need to lock the Device.
                // TODO(crbug.com/dawn/1618): In future, all temp resources should be created at
                // Command Submit time, so the locking would be removed from here at that point.
                auto deviceGuard = GetDevice()->GetGuard();

                DAWN_TRY_CONTEXT(BlitBufferToStencil(GetDevice(), this, source->buffer, srcLayout,
                                                     dst, *copySize),
                                 "copying from %s to stencil aspect of %s using blit workaround.",
                                 source->buffer, dst.texture.Get());
                return {};
            } else if (GetDevice()->IsToggleEnabled(Toggle::UseBlitForB2T) &&
                       IsBufferToTextureBlitSupported(source->buffer, dst, *copySize)) {
                // This function might create new resources. Need to lock the Device.
                // TODO(crbug.com/dawn/1618): In future, all temp resources should be created at
                // Command Submit time, so the locking would be removed from here at that point.
                auto deviceGuard = GetDevice()->GetGuard();
                DAWN_TRY_CONTEXT(BlitBufferToTexture(GetDevice(), this, source->buffer, srcLayout,
                                                     dst, *copySize),
                                 "copying buffer %s to %s using blit workaround.", source->buffer,
                                 dst.texture.Get());

                return {};
            }

            CopyBufferToTextureCmd* copy =
                allocator->Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
            copy->source.buffer = source->buffer;
            copy->source.offset = srcLayout.offset;
            copy->source.blocksPerRow = blockInfo.BytesToBlocks(srcLayout.bytesPerRow);
            copy->source.rowsPerImage = BlockCount{srcLayout.rowsPerImage};
            copy->destination = dst;
            copy->copySize = *copySize;

            return {};
        },
        "encoding %s.CopyBufferToTexture(%s, %s, %s).", this, source->buffer, destination.texture,
        copySize);
}

void CommandEncoder::APICopyTextureToBuffer(const TexelCopyTextureInfo* sourceOrig,
                                            const TexelCopyBufferInfo* destination,
                                            const Extent3D* copySize) {
    TexelCopyTextureInfo source = sourceOrig->WithTrivialFrontendDefaults();

    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateTexelCopyTextureInfo(GetDevice(), source, *copySize));
                DAWN_TRY_CONTEXT(ValidateCanUseAs(source.texture, wgpu::TextureUsage::CopySrc,
                                                  mUsageValidationMode),
                                 "validating source %s usage.", source.texture);
                DAWN_TRY(ValidateTextureSampleCountInBufferCopyCommands(source.texture));
                DAWN_TRY(ValidateTextureDepthStencilToBufferCopyRestrictions(GetDevice(), source));

                DAWN_TRY(ValidateTexelCopyBufferInfo(GetDevice(), *destination));
                DAWN_TRY_CONTEXT(ValidateCanUseAs(destination->buffer, wgpu::BufferUsage::CopyDst),
                                 "validating destination %s usage.", destination->buffer);

                // We validate texture copy range before validating linear texture data,
                // because in the latter we divide copyExtent.width by blockWidth and
                // copyExtent.height by blockHeight while the divisibility conditions are
                // checked in validating texture copy range.
                DAWN_TRY(ValidateTextureCopyRange(GetDevice(), source, *copySize));

                if (GetDevice()->IsCompatibilityMode()) {
                    DAWN_TRY(ValidateTextureFormatForTextureToBufferCopyInCompatibilityMode(
                        source.texture));
                }
            }
            const TypedTexelBlockInfo& blockInfo = GetBlockInfo(source);
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateLinearTextureCopyOffset(
                    destination->layout, blockInfo.ToTexelBlockInfo(),
                    source.texture->GetFormat().HasDepthOrStencil()));
                DAWN_TRY(ValidateLinearTextureData(destination->layout,
                                                   destination->buffer->GetSize(),
                                                   blockInfo.ToTexelBlockInfo(), *copySize));
            }

            mTopLevelTextures.insert(source.texture);
            mTopLevelBuffers.insert(destination->buffer);

            TexelCopyBufferLayout dstLayout = destination->layout;
            ApplyDefaultTexelCopyBufferLayoutOptions(&dstLayout, blockInfo.ToTexelBlockInfo(),
                                                     *copySize);

            auto format = source.texture->GetFormat();
            auto aspect = ConvertAspect(format, source.aspect);

            // Workaround to use compute pass to emulate texture to buffer copy
            if (ShouldUseTextureToBufferBlit(GetDevice(), format, aspect, *copySize)) {
                // This function might create new resources. Need to lock the Device.
                // TODO(crbug.com/dawn/1618): In future, all temp resources should be created at
                // Command Submit time, so the locking would be removed from here at that point.
                auto deviceGuard = GetDevice()->GetGuard();

                TextureCopy src;
                src.texture = source.texture;
                src.origin = source.origin;
                src.mipLevel = source.mipLevel;
                src.aspect = aspect;

                BufferCopy dst;
                dst.buffer = destination->buffer;
                dst.blocksPerRow = blockInfo.BytesToBlocks(dstLayout.bytesPerRow);
                dst.rowsPerImage = BlockCount{dstLayout.rowsPerImage};
                dst.offset = dstLayout.offset;
                DAWN_TRY_CONTEXT(
                    BlitTextureToBuffer(GetDevice(), this, src, dst, blockInfo.ToBlock(*copySize)),
                    "copying texture %s to %s using blit workaround.", src.texture.Get(),
                    destination->buffer);

                return {};
            }

            CopyTextureToBufferCmd* t2b =
                allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
            t2b->source.texture = source.texture;
            t2b->source.origin = source.origin;
            t2b->source.mipLevel = source.mipLevel;
            t2b->source.aspect = ConvertAspect(source.texture->GetFormat(), source.aspect);
            t2b->destination.buffer = destination->buffer;
            t2b->destination.offset = dstLayout.offset;
            t2b->destination.blocksPerRow = blockInfo.BytesToBlocks(dstLayout.bytesPerRow);
            t2b->destination.rowsPerImage = BlockCount{dstLayout.rowsPerImage};
            t2b->copySize = *copySize;

            return {};
        },
        "encoding %s.CopyTextureToBuffer(%s, %s, %s).", this, source.texture, destination->buffer,
        copySize);
}

void CommandEncoder::APICopyTextureToTexture(const TexelCopyTextureInfo* sourceOrig,
                                             const TexelCopyTextureInfo* destinationOrig,
                                             const Extent3D* copySize) {
    TexelCopyTextureInfo source = sourceOrig->WithTrivialFrontendDefaults();
    TexelCopyTextureInfo destination = destinationOrig->WithTrivialFrontendDefaults();

    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(source.texture));
                DAWN_TRY(GetDevice()->ValidateObject(destination.texture));

                DAWN_INVALID_IF(source.texture->GetFormat().IsMultiPlanar() ||
                                    destination.texture->GetFormat().IsMultiPlanar(),
                                "Copying between a multiplanar texture and another texture is "
                                "currently not allowed.");
                DAWN_TRY_CONTEXT(ValidateTexelCopyTextureInfo(GetDevice(), source, *copySize),
                                 "validating source %s.", source.texture);
                DAWN_TRY_CONTEXT(ValidateTexelCopyTextureInfo(GetDevice(), destination, *copySize),
                                 "validating destination %s.", destination.texture);

                DAWN_TRY_CONTEXT(ValidateTextureCopyRange(GetDevice(), source, *copySize),
                                 "validating source %s copy range.", source.texture);
                DAWN_TRY_CONTEXT(ValidateTextureCopyRange(GetDevice(), destination, *copySize),
                                 "validating source %s copy range.", destination.texture);

                DAWN_TRY(ValidateTextureToTextureCopyRestrictions(GetDevice(), source, destination,
                                                                  *copySize));

                DAWN_TRY(ValidateCanUseAs(source.texture, wgpu::TextureUsage::CopySrc,
                                          mUsageValidationMode));
                DAWN_TRY(ValidateCanUseAs(destination.texture, wgpu::TextureUsage::CopyDst,
                                          mUsageValidationMode));

                if (GetDevice()->IsCompatibilityMode()) {
                    DAWN_TRY(ValidateSourceTextureFormatForTextureToTextureCopyInCompatibilityMode(
                        source.texture));
                }
            }

            mTopLevelTextures.insert(source.texture);
            mTopLevelTextures.insert(destination.texture);

            Aspect aspect = ConvertAspect(source.texture->GetFormat(), source.aspect);
            DAWN_CHECK(aspect ==
                       ConvertAspect(destination.texture->GetFormat(), destination.aspect));

            TextureCopy src;
            src.texture = source.texture;
            src.origin = source.origin;
            src.mipLevel = source.mipLevel;
            src.aspect = aspect;

            TextureCopy dst;
            dst.texture = destination.texture;
            dst.origin = destination.origin;
            dst.mipLevel = destination.mipLevel;
            dst.aspect = aspect;

            // Emulate a T2T copy with a T2B copy and a B2T copy.
            if (ShouldUseT2B2TForT2T(GetDevice(), src.texture->GetFormat(),
                                     dst.texture->GetFormat())) {
                // Calculate needed buffer size to hold copied texel data.
                const TexelBlockInfo& blockInfo = GetBlockInfo(source);
                const uint32_t bytesPerRow =
                    Align(4 * copySize->width, kTextureBytesPerRowAlignment);
                const uint32_t rowsPerImage = copySize->height;
                uint64_t requiredBytes;
                DAWN_TRY_ASSIGN(
                    requiredBytes,
                    ComputeRequiredBytesInCopy(blockInfo, *copySize, bytesPerRow, rowsPerImage));

                // Create an intermediate dst buffer.
                BufferDescriptor descriptor = {};
                descriptor.size = Align(requiredBytes, 4);
                descriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
                Ref<BufferBase> intermediateBuffer;
                DAWN_TRY_ASSIGN(intermediateBuffer, GetDevice()->CreateBuffer(&descriptor));

                TexelCopyBufferInfo buf;
                buf.buffer = intermediateBuffer.Get();
                buf.layout.bytesPerRow = bytesPerRow;
                buf.layout.rowsPerImage = rowsPerImage;

                APICopyTextureToBuffer(&source, &buf, copySize);
                APICopyBufferToTexture(&buf, &destination, copySize);

                return {};
            }

            const bool blitDepth =
                (aspect & Aspect::Depth) &&
                GetDevice()->IsToggleEnabled(
                    Toggle::UseBlitForDepthTextureToTextureCopyToNonzeroSubresource) &&
                copySize->depthOrArrayLayers > 0 &&
                (dst.mipLevel > 0 || dst.origin.z > TexelCount{0u} ||
                 copySize->depthOrArrayLayers > 1);

            // If we're not using a blit, or there are aspects other than depth,
            // issue the copy. This is because if there's also stencil, we still need the copy
            // command to copy the stencil portion.
            if (!blitDepth || aspect != Aspect::Depth) {
                CopyTextureToTextureCmd* copy =
                    allocator->Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture);
                copy->source = src;
                copy->destination = dst;
                copy->copySize = *copySize;
            }

            // Use a blit to copy the depth aspect.
            if (blitDepth) {
                // This function might create new resources. Need to lock the Device.
                // TODO(crbug.com/dawn/1618): In future, all temp resources should be created at
                // Command Submit time, so the locking would be removed from here at that point.
                auto deviceGuard = GetDevice()->GetGuard();

                DAWN_TRY_CONTEXT(BlitDepthToDepth(GetDevice(), this, src, dst, *copySize),
                                 "copying depth aspect from %s to %s using blit workaround.",
                                 source.texture, destination.texture);
            }

            return {};
        },
        "encoding %s.CopyTextureToTexture(%s, %s, %s).", this, source.texture, destination.texture,
        copySize);
}

void CommandEncoder::APIClearBuffer(BufferBase* buffer, uint64_t offset, uint64_t size) {
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(buffer));

                uint64_t bufferSize = buffer->GetSize();
                DAWN_INVALID_IF(offset > bufferSize,
                                "Buffer offset (%u) is larger than the size (%u) of %s.", offset,
                                bufferSize, buffer);

                uint64_t remainingSize = bufferSize - offset;
                if (size == wgpu::kWholeSize) {
                    size = remainingSize;
                } else {
                    DAWN_INVALID_IF(size > remainingSize,
                                    "Buffer range (offset: %u, size: %u) doesn't fit in "
                                    "the size (%u) of %s.",
                                    offset, size, bufferSize, buffer);
                }

                DAWN_TRY_CONTEXT(ValidateCanUseAs(buffer, wgpu::BufferUsage::CopyDst),
                                 "validating buffer %s usage.", buffer);

                // Size must be a multiple of 4 bytes on macOS.
                DAWN_INVALID_IF(size % 4 != 0, "Fill size (%u) is not a multiple of 4 bytes.",
                                size);

                // Offset must be multiples of 4 bytes on macOS.
                DAWN_INVALID_IF(offset % 4 != 0, "Offset (%u) is not a multiple of 4 bytes,",
                                offset);

            } else {
                if (size == wgpu::kWholeSize) {
                    DAWN_CHECK(buffer->GetSize() >= offset);
                    size = buffer->GetSize() - offset;
                }
            }

            mTopLevelBuffers.insert(buffer);

            ClearBufferCmd* cmd = allocator->Allocate<ClearBufferCmd>(Command::ClearBuffer);
            cmd->buffer = buffer;
            cmd->offset = offset;
            cmd->size = size;

            return {};
        },
        "encoding %s.ClearBuffer(%s, %u, %u).", this, buffer, offset, size);
}

void CommandEncoder::APIInjectValidationError(StringView messageIn) {
    std::string_view message = utils::NormalizeMessageString(messageIn);
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator*) -> MaybeError {
            return DAWN_MAKE_ERROR(InternalErrorType::Validation, std::string(message));
        },
        "injecting validation error: %s.", message);
}

void CommandEncoder::APIInsertDebugMarker(StringView markerIn) {
    std::string_view marker = utils::NormalizeMessageString(markerIn);
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            InsertDebugMarkerCmd* cmd =
                allocator->Allocate<InsertDebugMarkerCmd>(Command::InsertDebugMarker);
            AddNullTerminatedString(allocator, marker, &cmd->length);
            return {};
        },
        "encoding %s.InsertDebugMarker(%s).", this, marker);
}

void CommandEncoder::APIPopDebugGroup() {
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_INVALID_IF(mDebugGroupStackSize == 0,
                                "PopDebugGroup called when no debug groups are currently pushed.");
            }
            allocator->Allocate<PopDebugGroupCmd>(Command::PopDebugGroup);
            mDebugGroupStackSize--;
            mEncodingContext.PopDebugGroupLabel();

            return {};
        },
        "encoding %s.PopDebugGroup().", this);
}

void CommandEncoder::APIPushDebugGroup(StringView groupLabelIn) {
    std::string_view groupLabel = utils::NormalizeMessageString(groupLabelIn);
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            PushDebugGroupCmd* cmd =
                allocator->Allocate<PushDebugGroupCmd>(Command::PushDebugGroup);
            const char* label = AddNullTerminatedString(allocator, groupLabel, &cmd->length);

            mDebugGroupStackSize++;
            mEncodingContext.PushDebugGroupLabel(std::string_view(label, cmd->length));

            return {};
        },
        "encoding %s.PushDebugGroup(%s).", this, groupLabel);
}

void CommandEncoder::APIResolveQuerySet(QuerySetBase* querySet,
                                        uint32_t firstQueryUntyped,
                                        uint32_t queryCountUntyped,
                                        BufferBase* destination,
                                        uint64_t destinationOffset) {
    QueryIndex firstQuery{firstQueryUntyped};
    QueryIndex queryCount{queryCountUntyped};

    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(querySet));
                DAWN_TRY(GetDevice()->ValidateObject(destination));

                DAWN_TRY(ValidateQuerySetResolve(querySet, firstQuery, queryCount, destination,
                                                 destinationOffset));

                DAWN_TRY(ValidateCanUseAs(destination, wgpu::BufferUsage::QueryResolve));
            }

            TrackUsedQuerySet(querySet);
            mTopLevelBuffers.insert(destination);

            ResolveQuerySetCmd* cmd =
                allocator->Allocate<ResolveQuerySetCmd>(Command::ResolveQuerySet);
            cmd->querySet = querySet;
            cmd->firstQuery = firstQuery;
            cmd->queryCount = queryCount;
            cmd->destination = destination;
            cmd->destinationOffset = destinationOffset;

            if (querySet->GetQueryType() != wgpu::QueryType::Timestamp) {
                return {};
            }

            const bool needsConversion =
                GetDevice()->GetTimestampPeriodInNS() != 1.0f &&
                !GetDevice()->IsToggleEnabled(Toggle::DisableTimestampQueryConversion);
            const bool needsQuantization =
                GetDevice()->IsToggleEnabled(Toggle::TimestampQuantization) &&
                !GetDevice()->AreTimestampsQuantized();
            if (!needsConversion && !needsQuantization) {
                return {};
            }

            auto deviceGuard = GetDevice()->GetGuard();
            return EncodeTimestampsToNanosecondsConversion(this, querySet, firstQuery, queryCount,
                                                           destination, destinationOffset);
        },
        "encoding %s.ResolveQuerySet(%s, %u, %u, %s, %u).", this, querySet, firstQuery, queryCount,
        destination, destinationOffset);
}

void CommandEncoder::APIWriteBuffer(BufferBase* buffer,
                                    uint64_t bufferOffset,
                                    const uint8_t* data,
                                    uint64_t size) {
    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateWriteBuffer(GetDevice(), buffer, bufferOffset, size));
            }

            WriteBufferCmd* cmd = allocator->Allocate<WriteBufferCmd>(Command::WriteBuffer);
            cmd->buffer = buffer;
            cmd->offset = bufferOffset;
            cmd->size = size;

            uint8_t* inlinedData = allocator->AllocateData<uint8_t>(size);
            DAWN_UNSAFE_TODO(memcpy(inlinedData, data, size));

            mTopLevelBuffers.insert(buffer);

            return {};
        },
        "encoding %s.WriteBuffer(%s, %u, ..., %u).", this, buffer, bufferOffset, size);
}

void CommandEncoder::APIWriteTimestamp(QuerySetBase* querySet, uint32_t queryIndexUntyped) {
    QueryIndex queryIndex{queryIndexUntyped};

    mEncodingContext.TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            DAWN_INVALID_IF(!GetDevice()->IsToggleEnabled(Toggle::AllowUnsafeAPIs),
                            "writeTimestamp requires enabling toggle allow_unsafe_apis.");

            if (GetDevice()->IsValidationEnabled()) {
                DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex));
            }

            TrackUsedQuerySet(querySet);

            WriteTimestampCmd* cmd =
                allocator->Allocate<WriteTimestampCmd>(Command::WriteTimestamp);
            cmd->querySet = querySet;
            cmd->queryIndex = queryIndex;

            return {};
        },
        "encoding %s.WriteTimestamp(%s, %u).", this, querySet, queryIndex);
}

CommandBufferBase* CommandEncoder::APIFinish(const CommandBufferDescriptor* descriptor) {
    // This function will create new object, need to lock the Device.
    auto deviceGuard = GetDevice()->GetGuard();

    Ref<CommandBufferBase> commandBuffer;
    if (GetDevice()->ConsumedError(Finish(descriptor), &commandBuffer, "finishing %s.", this)) {
        Ref<CommandBufferBase> errorCommandBuffer =
            CommandBufferBase::MakeError(GetDevice(), descriptor ? descriptor->label : nullptr);
        errorCommandBuffer->SetEncoderLabel(this->GetLabel());
        return ReturnToAPI(std::move(errorCommandBuffer));
    }

    DAWN_CHECK(!IsError());
    return ReturnToAPI(std::move(commandBuffer));
}

ResultOrError<Ref<CommandBufferBase>> CommandEncoder::Finish(
    const CommandBufferDescriptor* descriptor) {
    DeviceBase* device = GetDevice();

    TRACE_EVENT0(device->GetPlatform(), Recording, "CommandEncoder::Finish");

    // Even if mEncodingContext.Finish() validation fails, calling it will mutate the internal
    // state of the encoding context. The internal state is set to finished, and subsequent
    // calls to encode commands will generate errors.
    DAWN_TRY(mEncodingContext.Finish());
    DAWN_TRY(device->ValidateIsAlive());

    if (device->IsValidationEnabled()) {
        DAWN_TRY(ValidateFinish());
    }

    const CommandBufferDescriptor defaultDescriptor = {};
    if (descriptor == nullptr) {
        descriptor = &defaultDescriptor;
    }

    return device->CreateCommandBuffer(this, descriptor);
}

// Implementation of the command buffer validation that can be precomputed before submit
MaybeError CommandEncoder::ValidateFinish() const {
    TRACE_EVENT0(GetDevice()->GetPlatform(), Validation, "CommandEncoder::ValidateFinish");
    DAWN_TRY(GetDevice()->ValidateObject(this));

    for (const RenderPassResourceUsage& passUsage : mEncodingContext.GetRenderPassUsages()) {
        DAWN_TRY_CONTEXT(ValidateSyncScopeResourceUsage(passUsage),
                         "validating render pass usage.");
    }

    for (const ComputePassResourceUsage& passUsage : mEncodingContext.GetComputePassUsages()) {
        for (const SyncScopeResourceUsage& scope : passUsage.dispatchUsages) {
            DAWN_TRY_CONTEXT(ValidateSyncScopeResourceUsage(scope),
                             "validating compute pass usage.");
        }
    }

    DAWN_INVALID_IF(
        mDebugGroupStackSize != 0,
        "PushDebugGroup called %u time(s) without a corresponding PopDebugGroup prior to "
        "calling Finish.",
        mDebugGroupStackSize);

    return {};
}

CommandEncoder::InternalUsageScope CommandEncoder::MakeInternalUsageScope() {
    return InternalUsageScope(this);
}

CommandEncoder::InternalUsageScope::InternalUsageScope(CommandEncoder* encoder)
    : mEncoder(encoder), mUsageValidationMode(mEncoder->mUsageValidationMode) {
    mEncoder->mUsageValidationMode = UsageValidationMode::Internal;
}

CommandEncoder::InternalUsageScope::~InternalUsageScope() {
    mEncoder->mUsageValidationMode = mUsageValidationMode;
}

}  // namespace dawn::native
