// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn_native/CommandEncoder.h"

#include "common/BitSetIterator.h"
#include "common/Math.h"
#include "dawn_native/BindGroup.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/CommandBuffer.h"
#include "dawn_native/CommandBufferStateTracker.h"
#include "dawn_native/CommandValidation.h"
#include "dawn_native/Commands.h"
#include "dawn_native/ComputePassEncoder.h"
#include "dawn_native/Device.h"
#include "dawn_native/ErrorData.h"
#include "dawn_native/ObjectType_autogen.h"
#include "dawn_native/QueryHelper.h"
#include "dawn_native/QuerySet.h"
#include "dawn_native/Queue.h"
#include "dawn_native/RenderPassEncoder.h"
#include "dawn_native/RenderPipeline.h"
#include "dawn_native/ValidationUtils_autogen.h"
#include "dawn_platform/DawnPlatform.h"
#include "dawn_platform/tracing/TraceEvent.h"

#include <cmath>
#include <map>

namespace dawn_native {

    namespace {

        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 TextureDataLayout& 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 ValidateTextureDepthStencilToBufferCopyRestrictions(
            const ImageCopyTexture& src) {
            Aspect aspectUsed;
            DAWN_TRY_ASSIGN(aspectUsed, SingleAspectUsedByImageCopyTexture(src));
            if (aspectUsed == Aspect::Depth) {
                switch (src.texture->GetFormat().format) {
                    case wgpu::TextureFormat::Depth24Plus:
                    case wgpu::TextureFormat::Depth24PlusStencil8:
                        return DAWN_FORMAT_VALIDATION_ERROR(
                            "The depth aspect of %s format %s cannot be selected in a texture to "
                            "buffer copy.",
                            src.texture, src.texture->GetFormat().format);
                    case wgpu::TextureFormat::Depth32Float:
                    case wgpu::TextureFormat::Depth16Unorm:
                        break;

                    default:
                        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 ValidateOrSetAttachmentSize(const TextureViewBase* attachment,
                                               uint32_t* width,
                                               uint32_t* height) {
            const Extent3D& attachmentSize =
                attachment->GetTexture()->GetMipLevelVirtualSize(attachment->GetBaseMipLevel());

            if (*width == 0) {
                DAWN_ASSERT(*height == 0);
                *width = attachmentSize.width;
                *height = attachmentSize.height;
                DAWN_ASSERT(*width != 0 && *height != 0);
            } else {
                DAWN_INVALID_IF(
                    *width != attachmentSize.width || *height != attachmentSize.height,
                    "Attachment %s size (width: %u, height: %u) does not match the size of the "
                    "other attachments (width: %u, height: %u).",
                    attachment, attachmentSize.width, attachmentSize.height, *width, *height);
            }

            return {};
        }

        MaybeError ValidateOrSetColorAttachmentSampleCount(const TextureViewBase* colorAttachment,
                                                           uint32_t* sampleCount) {
            if (*sampleCount == 0) {
                *sampleCount = colorAttachment->GetTexture()->GetSampleCount();
                DAWN_ASSERT(*sampleCount != 0);
            } else {
                DAWN_INVALID_IF(
                    *sampleCount != colorAttachment->GetTexture()->GetSampleCount(),
                    "Color attachment %s sample count (%u) does not match the sample count of the "
                    "other attachments (%u).",
                    colorAttachment, colorAttachment->GetTexture()->GetSampleCount(), *sampleCount);
            }

            return {};
        }

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

            const TextureViewBase* resolveTarget = colorAttachment.resolveTarget;
            const TextureViewBase* attachment = colorAttachment.view;
            DAWN_TRY(device->ValidateObject(colorAttachment.resolveTarget));
            DAWN_TRY(ValidateCanUseAs(colorAttachment.resolveTarget->GetTexture(),
                                      wgpu::TextureUsage::RenderAttachment));

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

            const Extent3D& colorTextureSize =
                attachment->GetTexture()->GetMipLevelVirtualSize(attachment->GetBaseMipLevel());
            const Extent3D& resolveTextureSize =
                resolveTarget->GetTexture()->GetMipLevelVirtualSize(
                    resolveTarget->GetBaseMipLevel());
            DAWN_INVALID_IF(
                colorTextureSize.width != resolveTextureSize.width ||
                    colorTextureSize.height != resolveTextureSize.height,
                "The Resolve target %s size (width: %u, height: %u) does not match the color "
                "attachment %s size (width: %u, height: %u).",
                resolveTarget, resolveTextureSize.width, resolveTextureSize.height, attachment,
                colorTextureSize.width, colorTextureSize.height);

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

            return {};
        }

        MaybeError ValidateRenderPassColorAttachment(
            DeviceBase* device,
            const RenderPassColorAttachment& colorAttachment,
            uint32_t* width,
            uint32_t* height,
            uint32_t* sampleCount) {
            TextureViewBase* attachment = colorAttachment.view;
            DAWN_TRY(device->ValidateObject(attachment));
            DAWN_TRY(
                ValidateCanUseAs(attachment->GetTexture(), wgpu::TextureUsage::RenderAttachment));

            DAWN_INVALID_IF(!(attachment->GetAspects() & Aspect::Color) ||
                                !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));

            if (colorAttachment.loadOp == wgpu::LoadOp::Clear) {
                DAWN_INVALID_IF(std::isnan(colorAttachment.clearColor.r) ||
                                    std::isnan(colorAttachment.clearColor.g) ||
                                    std::isnan(colorAttachment.clearColor.b) ||
                                    std::isnan(colorAttachment.clearColor.a),
                                "Color clear value (%s) contain a NaN.",
                                &colorAttachment.clearColor);
            }

            DAWN_TRY(ValidateOrSetColorAttachmentSampleCount(attachment, sampleCount));

            DAWN_TRY(ValidateResolveTarget(device, colorAttachment));

            DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment));
            DAWN_TRY(ValidateOrSetAttachmentSize(attachment, width, height));

            return {};
        }

        MaybeError ValidateRenderPassDepthStencilAttachment(
            DeviceBase* device,
            const RenderPassDepthStencilAttachment* depthStencilAttachment,
            uint32_t* width,
            uint32_t* height,
            uint32_t* sampleCount) {
            DAWN_ASSERT(depthStencilAttachment != nullptr);

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

            const Format& format = attachment->GetFormat();
            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);

            DAWN_INVALID_IF(attachment->GetAspects() != format.aspects,
                            "The depth stencil attachment %s must encompass all aspects.",
                            attachment);

            DAWN_TRY(ValidateLoadOp(depthStencilAttachment->depthLoadOp));
            DAWN_TRY(ValidateLoadOp(depthStencilAttachment->stencilLoadOp));
            DAWN_TRY(ValidateStoreOp(depthStencilAttachment->depthStoreOp));
            DAWN_TRY(ValidateStoreOp(depthStencilAttachment->stencilStoreOp));

            DAWN_INVALID_IF(
                attachment->GetAspects() == (Aspect::Depth | Aspect::Stencil) &&
                    depthStencilAttachment->depthReadOnly !=
                        depthStencilAttachment->stencilReadOnly,
                "depthReadOnly (%u) and stencilReadOnly (%u) must be the same when texture aspect "
                "is 'all'.",
                depthStencilAttachment->depthReadOnly, depthStencilAttachment->stencilReadOnly);

            DAWN_INVALID_IF(
                depthStencilAttachment->depthReadOnly &&
                    (depthStencilAttachment->depthLoadOp != wgpu::LoadOp::Load ||
                     depthStencilAttachment->depthStoreOp != wgpu::StoreOp::Store),
                "depthLoadOp (%s) is not %s or depthStoreOp (%s) is not %s when depthReadOnly "
                "is true.",
                depthStencilAttachment->depthLoadOp, wgpu::LoadOp::Load,
                depthStencilAttachment->depthStoreOp, wgpu::StoreOp::Store);

            DAWN_INVALID_IF(depthStencilAttachment->stencilReadOnly &&
                                (depthStencilAttachment->stencilLoadOp != wgpu::LoadOp::Load ||
                                 depthStencilAttachment->stencilStoreOp != wgpu::StoreOp::Store),
                            "stencilLoadOp (%s) is not %s or stencilStoreOp (%s) is not %s when "
                            "stencilReadOnly is true.",
                            depthStencilAttachment->stencilLoadOp, wgpu::LoadOp::Load,
                            depthStencilAttachment->stencilStoreOp, wgpu::StoreOp::Store);

            DAWN_INVALID_IF(depthStencilAttachment->depthLoadOp == wgpu::LoadOp::Clear &&
                                std::isnan(depthStencilAttachment->clearDepth),
                            "Depth clear value is NaN.");

            // *sampleCount == 0 must only happen when there is no color attachment. In that case we
            // do not need to validate the sample count of the depth stencil attachment.
            const uint32_t depthStencilSampleCount = attachment->GetTexture()->GetSampleCount();
            if (*sampleCount != 0) {
                DAWN_INVALID_IF(
                    depthStencilSampleCount != *sampleCount,
                    "The depth stencil attachment %s sample count (%u) does not match the sample "
                    "count of the other attachments (%u).",
                    attachment, depthStencilSampleCount, *sampleCount);
            } else {
                *sampleCount = depthStencilSampleCount;
            }

            DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment));
            DAWN_TRY(ValidateOrSetAttachmentSize(attachment, width, height));

            return {};
        }

        MaybeError ValidateRenderPassDescriptor(DeviceBase* device,
                                                const RenderPassDescriptor* descriptor,
                                                uint32_t* width,
                                                uint32_t* height,
                                                uint32_t* sampleCount) {
            DAWN_INVALID_IF(
                descriptor->colorAttachmentCount > kMaxColorAttachments,
                "Color attachment count (%u) exceeds the maximum number of color attachments (%u).",
                descriptor->colorAttachmentCount, kMaxColorAttachments);

            for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
                DAWN_TRY_CONTEXT(
                    ValidateRenderPassColorAttachment(device, descriptor->colorAttachments[i],
                                                      width, height, sampleCount),
                    "validating colorAttachments[%u].", i);
            }

            if (descriptor->depthStencilAttachment != nullptr) {
                DAWN_TRY_CONTEXT(
                    ValidateRenderPassDepthStencilAttachment(
                        device, descriptor->depthStencilAttachment, width, height, sampleCount),
                    "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);
            }

            DAWN_INVALID_IF(descriptor->colorAttachmentCount == 0 &&
                                descriptor->depthStencilAttachment == nullptr,
                            "Render pass has no attachments.");

            return {};
        }

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

        MaybeError ValidateQuerySetResolve(const QuerySetBase* querySet,
                                           uint32_t firstQuery,
                                           uint32_t 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 % 256 != 0,
                            "The destination buffer %s offset (%u) is not a multiple of 256.",
                            destination, destinationOffset);

            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,
                                                           uint32_t firstQuery,
                                                           uint32_t queryCount,
                                                           BufferBase* destination,
                                                           uint64_t destinationOffset) {
            DeviceBase* device = encoder->GetDevice();

            // The availability got from query set is a reference to vector<bool>, need to covert
            // bool to uint32_t due to a user input in pipeline must not contain a bool type in
            // WGSL.
            std::vector<uint32_t> availability{querySet->GetQueryAvailability().begin(),
                                               querySet->GetQueryAvailability().end()};

            // Timestamp availability storage buffer
            BufferDescriptor availabilityDesc = {};
            availabilityDesc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst;
            availabilityDesc.size = querySet->GetQueryCount() * sizeof(uint32_t);
            Ref<BufferBase> availabilityBuffer;
            DAWN_TRY_ASSIGN(availabilityBuffer, device->CreateBuffer(&availabilityDesc));

            DAWN_TRY(device->GetQueue()->WriteBuffer(availabilityBuffer.Get(), 0,
                                                     availability.data(),
                                                     availability.size() * sizeof(uint32_t)));

            // Timestamp params uniform buffer
            TimestampParams params = {firstQuery, queryCount,
                                      static_cast<uint32_t>(destinationOffset),
                                      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, destination, availabilityBuffer.Get(), paramsBuffer.Get());
        }

        bool IsReadOnlyDepthStencilAttachment(
            const RenderPassDepthStencilAttachment* depthStencilAttachment) {
            DAWN_ASSERT(depthStencilAttachment != nullptr);
            Aspect aspects = depthStencilAttachment->view->GetAspects();
            DAWN_ASSERT(IsSubset(aspects, Aspect::Depth | Aspect::Stencil));

            if ((aspects & Aspect::Depth) && !depthStencilAttachment->depthReadOnly) {
                return false;
            }
            if (aspects & Aspect::Stencil && !depthStencilAttachment->stencilReadOnly) {
                return false;
            }
            return true;
        }

    }  // namespace

    CommandEncoder::CommandEncoder(DeviceBase* device, const CommandEncoderDescriptor* descriptor)
        : ApiObjectBase(device, descriptor->label), mEncodingContext(device, this) {
        TrackInDevice();
    }

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

    void CommandEncoder::DestroyImpl() {
        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);
    }

    void CommandEncoder::TrackQueryAvailability(QuerySetBase* querySet, uint32_t queryIndex) {
        DAWN_ASSERT(querySet != nullptr);

        if (GetDevice()->IsValidationEnabled()) {
            TrackUsedQuerySet(querySet);
        }

        // Set the query at queryIndex to available for resolving in query set.
        querySet->SetQueryAvailability(queryIndex, true);
    }

    // Implementation of the API's command recording methods

    ComputePassEncoder* CommandEncoder::APIBeginComputePass(
        const ComputePassDescriptor* descriptor) {
        DeviceBase* device = GetDevice();

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

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

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

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

            ComputePassEncoder* passEncoder =
                new ComputePassEncoder(device, descriptor, this, &mEncodingContext);
            mEncodingContext.EnterPass(passEncoder);
            return passEncoder;
        }

        return ComputePassEncoder::MakeError(device, this, &mEncodingContext);
    }

    RenderPassEncoder* CommandEncoder::APIBeginRenderPass(const RenderPassDescriptor* descriptor) {
        DeviceBase* device = GetDevice();

        RenderPassResourceUsageTracker usageTracker;

        uint32_t width = 0;
        uint32_t height = 0;
        bool depthReadOnly = false;
        bool stencilReadOnly = false;
        Ref<AttachmentState> attachmentState;
        bool success = mEncodingContext.TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                uint32_t sampleCount = 0;

                DAWN_TRY(ValidateRenderPassDescriptor(device, descriptor, &width, &height,
                                                      &sampleCount));

                ASSERT(width > 0 && height > 0 && sampleCount > 0);

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

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

                for (ColorAttachmentIndex index :
                     IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
                    uint8_t i = static_cast<uint8_t>(index);
                    TextureViewBase* view = descriptor->colorAttachments[i].view;
                    TextureViewBase* resolveTarget = descriptor->colorAttachments[i].resolveTarget;

                    cmd->colorAttachments[index].view = view;
                    cmd->colorAttachments[index].resolveTarget = resolveTarget;
                    cmd->colorAttachments[index].loadOp = descriptor->colorAttachments[i].loadOp;
                    cmd->colorAttachments[index].storeOp = descriptor->colorAttachments[i].storeOp;
                    cmd->colorAttachments[index].clearColor =
                        descriptor->colorAttachments[i].clearColor;

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

                    if (resolveTarget != nullptr) {
                        usageTracker.TextureViewUsedAs(resolveTarget,
                                                       wgpu::TextureUsage::RenderAttachment);
                    }
                }

                if (cmd->attachmentState->HasDepthStencilAttachment()) {
                    TextureViewBase* view = descriptor->depthStencilAttachment->view;

                    cmd->depthStencilAttachment.view = view;
                    cmd->depthStencilAttachment.clearDepth =
                        descriptor->depthStencilAttachment->clearDepth;
                    cmd->depthStencilAttachment.clearStencil =
                        descriptor->depthStencilAttachment->clearStencil;
                    cmd->depthStencilAttachment.depthLoadOp =
                        descriptor->depthStencilAttachment->depthLoadOp;
                    cmd->depthStencilAttachment.depthStoreOp =
                        descriptor->depthStencilAttachment->depthStoreOp;
                    cmd->depthStencilAttachment.stencilLoadOp =
                        descriptor->depthStencilAttachment->stencilLoadOp;
                    cmd->depthStencilAttachment.stencilStoreOp =
                        descriptor->depthStencilAttachment->stencilStoreOp;
                    cmd->depthStencilAttachment.depthReadOnly =
                        descriptor->depthStencilAttachment->depthReadOnly;
                    cmd->depthStencilAttachment.stencilReadOnly =
                        descriptor->depthStencilAttachment->stencilReadOnly;

                    if (IsReadOnlyDepthStencilAttachment(descriptor->depthStencilAttachment)) {
                        // TODO(dawn:485): Readonly depth/stencil attachment is not fully
                        // implemented. Disallow it as unsafe until the implementaion is completed.
                        DAWN_INVALID_IF(
                            device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs),
                            "Readonly depth/stencil attachment is disallowed because it's not "
                            "fully implemented");

                        usageTracker.TextureViewUsedAs(view, kReadOnlyRenderAttachment);
                    } else {
                        usageTracker.TextureViewUsedAs(view, wgpu::TextureUsage::RenderAttachment);
                    }

                    depthReadOnly = descriptor->depthStencilAttachment->depthReadOnly;
                    stencilReadOnly = descriptor->depthStencilAttachment->stencilReadOnly;
                }

                cmd->width = width;
                cmd->height = height;

                cmd->occlusionQuerySet = descriptor->occlusionQuerySet;

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

        if (success) {
            RenderPassEncoder* passEncoder = new RenderPassEncoder(
                device, descriptor, this, &mEncodingContext, std::move(usageTracker),
                std::move(attachmentState), descriptor->occlusionQuerySet, width, height,
                depthReadOnly, stencilReadOnly);
            mEncodingContext.EnterPass(passEncoder);
            return passEncoder;
        }

        return RenderPassEncoder::MakeError(device, this, &mEncodingContext);
    }

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

    void CommandEncoder::APICopyBufferToTexture(const ImageCopyBuffer* source,
                                                const ImageCopyTexture* destination,
                                                const Extent3D* copySize) {
        mEncodingContext.TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (GetDevice()->IsValidationEnabled()) {
                    DAWN_TRY(ValidateImageCopyBuffer(GetDevice(), *source));
                    DAWN_TRY_CONTEXT(ValidateCanUseAs(source->buffer, wgpu::BufferUsage::CopySrc),
                                     "validating source %s usage.", source->buffer);

                    DAWN_TRY(ValidateImageCopyTexture(GetDevice(), *destination, *copySize));
                    DAWN_TRY_CONTEXT(
                        ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst),
                        "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 TexelBlockInfo& blockInfo =
                    destination->texture->GetFormat().GetAspectInfo(destination->aspect).block;
                if (GetDevice()->IsValidationEnabled()) {
                    DAWN_TRY(ValidateLinearTextureCopyOffset(
                        source->layout, blockInfo,
                        destination->texture->GetFormat().HasDepthOrStencil()));
                    DAWN_TRY(ValidateLinearTextureData(source->layout, source->buffer->GetSize(),
                                                       blockInfo, *copySize));

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

                TextureDataLayout srcLayout = source->layout;
                ApplyDefaultTextureDataLayoutOptions(&srcLayout, blockInfo, *copySize);

                CopyBufferToTextureCmd* copy =
                    allocator->Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
                copy->source.buffer = source->buffer;
                copy->source.offset = srcLayout.offset;
                copy->source.bytesPerRow = srcLayout.bytesPerRow;
                copy->source.rowsPerImage = srcLayout.rowsPerImage;
                copy->destination.texture = destination->texture;
                copy->destination.origin = destination->origin;
                copy->destination.mipLevel = destination->mipLevel;
                copy->destination.aspect =
                    ConvertAspect(destination->texture->GetFormat(), destination->aspect);
                copy->copySize = *copySize;

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

    void CommandEncoder::APICopyTextureToBuffer(const ImageCopyTexture* source,
                                                const ImageCopyBuffer* destination,
                                                const Extent3D* copySize) {
        mEncodingContext.TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (GetDevice()->IsValidationEnabled()) {
                    DAWN_TRY(ValidateImageCopyTexture(GetDevice(), *source, *copySize));
                    DAWN_TRY_CONTEXT(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc),
                                     "validating source %s usage.", source->texture);
                    DAWN_TRY(ValidateTextureSampleCountInBufferCopyCommands(source->texture));
                    DAWN_TRY(ValidateTextureDepthStencilToBufferCopyRestrictions(*source));

                    DAWN_TRY(ValidateImageCopyBuffer(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));
                }
                const TexelBlockInfo& blockInfo =
                    source->texture->GetFormat().GetAspectInfo(source->aspect).block;
                if (GetDevice()->IsValidationEnabled()) {
                    DAWN_TRY(ValidateLinearTextureCopyOffset(
                        destination->layout, blockInfo,
                        source->texture->GetFormat().HasDepthOrStencil()));
                    DAWN_TRY(ValidateLinearTextureData(
                        destination->layout, destination->buffer->GetSize(), blockInfo, *copySize));

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

                TextureDataLayout dstLayout = destination->layout;
                ApplyDefaultTextureDataLayoutOptions(&dstLayout, blockInfo, *copySize);

                CopyTextureToBufferCmd* copy =
                    allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
                copy->source.texture = source->texture;
                copy->source.origin = source->origin;
                copy->source.mipLevel = source->mipLevel;
                copy->source.aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
                copy->destination.buffer = destination->buffer;
                copy->destination.offset = dstLayout.offset;
                copy->destination.bytesPerRow = dstLayout.bytesPerRow;
                copy->destination.rowsPerImage = dstLayout.rowsPerImage;
                copy->copySize = *copySize;

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

    void CommandEncoder::APICopyTextureToTexture(const ImageCopyTexture* source,
                                                 const ImageCopyTexture* destination,
                                                 const Extent3D* copySize) {
        APICopyTextureToTextureHelper<false>(source, destination, copySize);
    }

    void CommandEncoder::APICopyTextureToTextureInternal(const ImageCopyTexture* source,
                                                         const ImageCopyTexture* destination,
                                                         const Extent3D* copySize) {
        APICopyTextureToTextureHelper<true>(source, destination, copySize);
    }

    template <bool Internal>
    void CommandEncoder::APICopyTextureToTextureHelper(const ImageCopyTexture* source,
                                                       const ImageCopyTexture* destination,
                                                       const Extent3D* copySize) {
        mEncodingContext.TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (GetDevice()->IsValidationEnabled()) {
                    DAWN_TRY(GetDevice()->ValidateObject(source->texture));
                    DAWN_TRY(GetDevice()->ValidateObject(destination->texture));

                    DAWN_TRY_CONTEXT(ValidateImageCopyTexture(GetDevice(), *source, *copySize),
                                     "validating source %s.", source->texture);
                    DAWN_TRY_CONTEXT(ValidateImageCopyTexture(GetDevice(), *destination, *copySize),
                                     "validating destination %s.", destination->texture);

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

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

                    // For internal usages (CopyToCopyInternal) we don't care if the user has added
                    // CopySrc as a usage for this texture, but we will always add it internally.
                    if (Internal) {
                        DAWN_TRY(
                            ValidateInternalCanUseAs(source->texture, wgpu::TextureUsage::CopySrc));
                        DAWN_TRY(ValidateInternalCanUseAs(destination->texture,
                                                          wgpu::TextureUsage::CopyDst));
                    } else {
                        DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc));
                        DAWN_TRY(
                            ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst));
                    }

                    mTopLevelTextures.insert(source->texture);
                    mTopLevelTextures.insert(destination->texture);
                }

                CopyTextureToTextureCmd* copy =
                    allocator->Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture);
                copy->source.texture = source->texture;
                copy->source.origin = source->origin;
                copy->source.mipLevel = source->mipLevel;
                copy->source.aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
                copy->destination.texture = destination->texture;
                copy->destination.origin = destination->origin;
                copy->destination.mipLevel = destination->mipLevel;
                copy->destination.aspect =
                    ConvertAspect(destination->texture->GetFormat(), destination->aspect);
                copy->copySize = *copySize;

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

    void CommandEncoder::APIInjectValidationError(const char* message) {
        if (mEncodingContext.CheckCurrentEncoder(this)) {
            mEncodingContext.HandleError(DAWN_VALIDATION_ERROR(message));
        }
    }

    void CommandEncoder::APIInsertDebugMarker(const char* groupLabel) {
        mEncodingContext.TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                InsertDebugMarkerCmd* cmd =
                    allocator->Allocate<InsertDebugMarkerCmd>(Command::InsertDebugMarker);
                cmd->length = strlen(groupLabel);

                char* label = allocator->AllocateData<char>(cmd->length + 1);
                memcpy(label, groupLabel, cmd->length + 1);

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

    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(const char* groupLabel) {
        mEncodingContext.TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                PushDebugGroupCmd* cmd =
                    allocator->Allocate<PushDebugGroupCmd>(Command::PushDebugGroup);
                cmd->length = strlen(groupLabel);

                char* label = allocator->AllocateData<char>(cmd->length + 1);
                memcpy(label, groupLabel, cmd->length + 1);

                mDebugGroupStackSize++;
                mEncodingContext.PushDebugGroupLabel(groupLabel);

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

    void CommandEncoder::APIResolveQuerySet(QuerySetBase* querySet,
                                            uint32_t firstQuery,
                                            uint32_t queryCount,
                                            BufferBase* destination,
                                            uint64_t destinationOffset) {
        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;

                // Encode internal compute pipeline for timestamp query
                if (querySet->GetQueryType() == wgpu::QueryType::Timestamp) {
                    DAWN_TRY(EncodeTimestampsToNanosecondsConversion(
                        this, querySet, firstQuery, queryCount, destination, destinationOffset));
                }

                return {};
            },
            "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);
                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 queryIndex) {
        mEncodingContext.TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (GetDevice()->IsValidationEnabled()) {
                    DAWN_TRY(GetDevice()->ValidateObject(querySet));
                    DAWN_TRY(ValidateTimestampQuery(querySet, queryIndex));
                }

                TrackQueryAvailability(querySet, queryIndex);

                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) {
        Ref<CommandBufferBase> commandBuffer;
        if (GetDevice()->ConsumedError(FinishInternal(descriptor), &commandBuffer)) {
            return CommandBufferBase::MakeError(GetDevice());
        }
        ASSERT(!IsError());
        return commandBuffer.Detach();
    }

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

        // 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 {};
    }

}  // namespace dawn_native
