// 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 "dawn/native/RenderEncoderBase.h"

#include <math.h>
#include <cstring>
#include <utility>

#include "dawn/common/Constants.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/CommandEncoder.h"
#include "dawn/native/CommandValidation.h"
#include "dawn/native/Commands.h"
#include "dawn/native/Device.h"
#include "dawn/native/RenderPipeline.h"
#include "dawn/native/ValidationUtils_autogen.h"

namespace dawn::native {

RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
                                     StringView label,
                                     EncodingContext* encodingContext,
                                     Ref<AttachmentState> attachmentState,
                                     bool depthReadOnly,
                                     bool stencilReadOnly)
    : ProgrammableEncoder(device, label, encodingContext),
      mIndirectDrawMetadata(device->GetLimits()),
      mAttachmentState(std::move(attachmentState)),
      mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
      mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
    mDepthReadOnly = depthReadOnly;
    mStencilReadOnly = stencilReadOnly;
}

RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
                                     EncodingContext* encodingContext,
                                     ErrorTag errorTag,
                                     StringView label)
    : ProgrammableEncoder(device, encodingContext, errorTag, label),
      mIndirectDrawMetadata(device->GetLimits()),
      mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
      mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {}

void RenderEncoderBase::DestroyImpl(DestroyReason reason) {
    // Remove reference to the attachment state so that we don't have lingering references to
    // it preventing it from being uncached in the device.
    mAttachmentState = nullptr;
}

const AttachmentState* RenderEncoderBase::GetAttachmentState() const {
    DAWN_ASSERT(!IsError());
    DAWN_ASSERT(mAttachmentState != nullptr);
    return mAttachmentState.Get();
}

bool RenderEncoderBase::IsDepthReadOnly() const {
    DAWN_ASSERT(!IsError());
    return mDepthReadOnly;
}

bool RenderEncoderBase::IsStencilReadOnly() const {
    DAWN_ASSERT(!IsError());
    return mStencilReadOnly;
}

uint64_t RenderEncoderBase::GetDrawCount() const {
    DAWN_ASSERT(!IsError());
    return mDrawCount;
}

Ref<AttachmentState> RenderEncoderBase::AcquireAttachmentState() {
    return std::move(mAttachmentState);
}

void RenderEncoderBase::APIDraw(uint32_t vertexCount,
                                uint32_t instanceCount,
                                uint32_t firstVertex,
                                uint32_t firstInstance) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                if (vertexCount == 0) {
                    GetDevice()->EmitWarningOnce(absl::StrFormat(
                        "Calling %s.Draw with a vertex count of 0 is unusual.", this));
                }
                if (instanceCount == 0) {
                    GetDevice()->EmitWarningOnce(absl::StrFormat(
                        "Calling %s.Draw with an instance count of 0 is unusual.", this));
                }

                DAWN_TRY(mCommandBufferState.ValidateCanDraw());

                if (!GetDevice()->HasFlexibleTextureViews()) {
                    DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture());
                }

                DAWN_INVALID_IF(mDisableBaseInstance && firstInstance != 0,
                                "First instance (%u) must be zero.", firstInstance);

                DAWN_TRY(mCommandBufferState.ValidateBufferInRangeForVertexBuffer(vertexCount,
                                                                                  firstVertex));
                DAWN_TRY(mCommandBufferState.ValidateBufferInRangeForInstanceBuffer(instanceCount,
                                                                                    firstInstance));
            }

            DrawCmd* draw = allocator->Allocate<DrawCmd>(Command::Draw);
            draw->vertexCount = vertexCount;
            draw->instanceCount = instanceCount;
            draw->firstVertex = firstVertex;
            draw->firstInstance = firstInstance;

            mDrawCount++;

            return {};
        },
        "encoding %s.Draw(%u, %u, %u, %u).", this, vertexCount, instanceCount, firstVertex,
        firstInstance);
}

void RenderEncoderBase::APIDrawIndexed(uint32_t indexCount,
                                       uint32_t instanceCount,
                                       uint32_t firstIndex,
                                       int32_t baseVertex,
                                       uint32_t firstInstance) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                if (indexCount == 0) {
                    GetDevice()->EmitWarningOnce(absl::StrFormat(
                        "Calling %s.Draw with an index count of 0 is unusual.", this));
                }
                if (instanceCount == 0) {
                    GetDevice()->EmitWarningOnce(absl::StrFormat(
                        "Calling %s.Draw with an instance count of 0 is unusual.", this));
                }

                DAWN_TRY(mCommandBufferState.ValidateCanDrawIndexed());

                if (!GetDevice()->HasFlexibleTextureViews()) {
                    DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture());
                }

                DAWN_INVALID_IF(mDisableBaseInstance && firstInstance != 0,
                                "First instance (%u) must be zero.", firstInstance);

                DAWN_INVALID_IF(mDisableBaseVertex && baseVertex != 0,
                                "Base vertex (%u) must be zero.", baseVertex);

                DAWN_TRY(mCommandBufferState.ValidateIndexBufferInRange(indexCount, firstIndex));

                // DrawIndexed only validate instance step mode vertex buffer
                DAWN_TRY(mCommandBufferState.ValidateBufferInRangeForInstanceBuffer(instanceCount,
                                                                                    firstInstance));
            }

            DrawIndexedCmd* draw = allocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed);
            draw->indexCount = indexCount;
            draw->instanceCount = instanceCount;
            draw->firstIndex = firstIndex;
            draw->baseVertex = baseVertex;
            draw->firstInstance = firstInstance;

            mDrawCount++;

            return {};
        },
        "encoding %s.DrawIndexed(%u, %u, %u, %i, %u).", this, indexCount, instanceCount, firstIndex,
        baseVertex, firstInstance);
}

void RenderEncoderBase::APIDrawIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
                DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));
                DAWN_TRY(mCommandBufferState.ValidateCanDraw());
                if (!GetDevice()->HasFlexibleTextureViews()) {
                    DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture());
                }

                DAWN_INVALID_IF(indirectOffset % 4 != 0,
                                "Indirect offset (%u) is not a multiple of 4.", indirectOffset);

                DAWN_INVALID_IF(
                    indirectOffset >= indirectBuffer->GetSize() ||
                        kDrawIndirectSize > indirectBuffer->GetSize() - indirectOffset,
                    "Indirect offset (%u) is out of bounds of indirect buffer %s size (%u).",
                    indirectOffset, indirectBuffer, indirectBuffer->GetSize());
            }

            DrawIndirectCmd* cmd = allocator->Allocate<DrawIndirectCmd>(Command::DrawIndirect);

            bool duplicateBaseVertexInstance =
                GetDevice()->ShouldDuplicateParametersForDrawIndirect(
                    mCommandBufferState.GetRenderPipeline());
            if (NeedsIndirectGPUValidation() &&
                (IsValidationEnabled() || duplicateBaseVertexInstance)) {
                // Later, EncodeIndirectDrawValidationCommands will allocate a scratch storage
                // buffer which will store the validated or duplicated indirect data. The buffer
                // and offset will be updated to point to it.
                // |EncodeIndirectDrawValidationCommands| is called at the end of encoding the
                // render pass, while the |cmd| pointer is still valid.
                cmd->indirectBuffer = nullptr;

                mIndirectDrawMetadata.AddIndirectDraw(indirectBuffer, indirectOffset,
                                                      duplicateBaseVertexInstance, cmd);

                // We only set usage as `kIndirectBufferForFrontendValidation` so that the indirect
                // usage can be ignored in the backends because `indirectBuffer` is actually not
                // used as an indirect buffer.
                mUsageTracker.BufferUsedAs(indirectBuffer, kIndirectBufferForFrontendValidation);
            } else {
                cmd->indirectBuffer = indirectBuffer;
                cmd->indirectOffset = indirectOffset;

                mUsageTracker.BufferUsedAs(indirectBuffer,
                                           kIndirectBufferForFrontendValidation |
                                               kIndirectBufferForBackendResourceTracking);
            }

            mDrawCount++;

            return {};
        },
        "encoding %s.DrawIndirect(%s, %u).", this, indirectBuffer, indirectOffset);
}

void RenderEncoderBase::APIDrawIndexedIndirect(BufferBase* indirectBuffer,
                                               uint64_t indirectOffset) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
                DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));
                DAWN_TRY(mCommandBufferState.ValidateCanDrawIndexed());
                if (!GetDevice()->HasFlexibleTextureViews()) {
                    DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture());
                }

                DAWN_INVALID_IF(indirectOffset % 4 != 0,
                                "Indirect offset (%u) is not a multiple of 4.", indirectOffset);

                DAWN_INVALID_IF(
                    (indirectOffset >= indirectBuffer->GetSize() ||
                     kDrawIndexedIndirectSize > indirectBuffer->GetSize() - indirectOffset),
                    "Indirect offset (%u) is out of bounds of indirect buffer %s size (%u).",
                    indirectOffset, indirectBuffer, indirectBuffer->GetSize());
            }

            DrawIndexedIndirectCmd* cmd =
                allocator->Allocate<DrawIndexedIndirectCmd>(Command::DrawIndexedIndirect);

            bool duplicateBaseVertexInstance =
                GetDevice()->ShouldDuplicateParametersForDrawIndirect(
                    mCommandBufferState.GetRenderPipeline());
            bool applyIndexBufferOffsetToFirstIndex =
                GetDevice()->ShouldApplyIndexBufferOffsetToFirstIndex();
            if (NeedsIndirectGPUValidation() &&
                (IsValidationEnabled() || duplicateBaseVertexInstance ||
                 applyIndexBufferOffsetToFirstIndex)) {
                // Later, EncodeIndirectDrawValidationCommands will allocate a scratch storage
                // buffer which will store the validated or duplicated indirect data. The buffer
                // and offset will be updated to point to it.
                // |EncodeIndirectDrawValidationCommands| is called at the end of encoding the
                // render pass, while the |cmd| pointer is still valid.
                cmd->indirectBuffer = nullptr;

                mIndirectDrawMetadata.AddIndexedIndirectDraw(
                    mCommandBufferState.GetIndexFormat(), mCommandBufferState.GetIndexBufferSize(),
                    mCommandBufferState.GetIndexBufferOffset(), indirectBuffer, indirectOffset,
                    duplicateBaseVertexInstance, cmd);

                // We only set usage as `kIndirectBufferForFrontendValidation` so that the indirect
                // usage can be ignored in the backends because `indirectBuffer` is actually not
                // used as an indirect buffer.
                mUsageTracker.BufferUsedAs(indirectBuffer, kIndirectBufferForFrontendValidation);
            } else {
                cmd->indirectBuffer = indirectBuffer;
                cmd->indirectOffset = indirectOffset;

                mUsageTracker.BufferUsedAs(indirectBuffer,
                                           kIndirectBufferForFrontendValidation |
                                               kIndirectBufferForBackendResourceTracking);
            }

            mDrawCount++;

            return {};
        },
        "encoding %s.DrawIndexedIndirect(%s, %u).", this, indirectBuffer, indirectOffset);
}

void RenderEncoderBase::APIMultiDrawIndirect(BufferBase* indirectBuffer,
                                             uint64_t indirectOffset,
                                             uint32_t maxDrawCount,
                                             BufferBase* drawCountBuffer,
                                             uint64_t drawCountBufferOffset) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_INVALID_IF(!GetDevice()->HasFeature(Feature::MultiDrawIndirect),
                                "%s is not enabled.", wgpu::FeatureName::MultiDrawIndirect);

                DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
                DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));

                DAWN_INVALID_IF(indirectOffset % 4 != 0,
                                "Indirect offset (%u) is not a multiple of 4.", indirectOffset);

                DAWN_INVALID_IF(indirectOffset >= indirectBuffer->GetSize(),
                                "Indirect offset (%u) is larger than or equal to the size (%u) of "
                                "the indirect buffer.",
                                indirectOffset, indirectBuffer->GetSize());

                // maxDrawCount * kDrawIndirectSize can't overflow because
                // kDrawIndirectSize is a uint64_t which results in a uint64_t
                DAWN_INVALID_IF(
                    indirectBuffer->GetSize() - indirectOffset < maxDrawCount * kDrawIndirectSize,
                    "Indirect Buffer size (%u) and offset (%u) can not hold maxDrawCount "
                    "(%u) draw commands.",
                    indirectBuffer->GetSize(), indirectOffset, maxDrawCount);

                // draw count buffer is optional
                if (drawCountBuffer != nullptr) {
                    DAWN_TRY(GetDevice()->ValidateObject(drawCountBuffer));
                    DAWN_TRY(ValidateCanUseAs(drawCountBuffer, wgpu::BufferUsage::Indirect));

                    DAWN_INVALID_IF(drawCountBufferOffset % 4 != 0,
                                    "Draw count buffer offset (%u) is not a multiple of 4.",
                                    drawCountBufferOffset);

                    DAWN_INVALID_IF(
                        drawCountBufferOffset >= drawCountBuffer->GetSize(),
                        "Draw count buffer offset (%u) is larger than or equal to the size "
                        "(%u) of the draw count buffer.",
                        drawCountBufferOffset, drawCountBuffer->GetSize());

                    // Can't underflow because the offset is checked to be smaller than the buffer.
                    DAWN_INVALID_IF(drawCountBuffer->GetSize() - drawCountBufferOffset < 4,
                                    "Draw count buffer offset (%u) is out of bounds of the draw "
                                    "count buffer %s size (%u).",
                                    drawCountBufferOffset, drawCountBuffer,
                                    drawCountBuffer->GetSize());
                }

                DAWN_TRY(mCommandBufferState.ValidateCanDraw());

                if (!GetDevice()->HasFlexibleTextureViews()) {
                    DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture());
                }
            }

            MultiDrawIndirectCmd* cmd =
                allocator->Allocate<MultiDrawIndirectCmd>(Command::MultiDrawIndirect);

            cmd->indirectBuffer = indirectBuffer;
            cmd->indirectOffset = indirectOffset;
            cmd->maxDrawCount = maxDrawCount;
            cmd->drawCountBuffer = drawCountBuffer;
            cmd->drawCountOffset = drawCountBufferOffset;

            bool duplicateBaseVertexInstance =
                GetDevice()->ShouldDuplicateParametersForDrawIndirect(
                    mCommandBufferState.GetRenderPipeline());

            mIndirectDrawMetadata.AddMultiDrawIndirect(
                mCommandBufferState.GetRenderPipeline()->GetPrimitiveTopology(),
                duplicateBaseVertexInstance, cmd);

            if (NeedsIndirectGPUValidation() &&
                (IsValidationEnabled() ||
                 GetDevice()->MayRequireDuplicationOfIndirectParameters())) {
                // We only set usage as `kIndirectBufferForFrontendValidation` because
                // `indirectBuffer` may not be used as an indirect buffer. The usage of
                // `indirectBuffer` may be updated in `EncodeIndirectDrawValidationCommands()` in
                // `EncodingContext::ExitRenderPass()`, which is only called when above conditions
                // are both met.
                mUsageTracker.BufferUsedAs(indirectBuffer, kIndirectBufferForFrontendValidation);
            } else {
                mUsageTracker.BufferUsedAs(indirectBuffer,
                                           kIndirectBufferForFrontendValidation |
                                               kIndirectBufferForBackendResourceTracking);
            }
            if (drawCountBuffer != nullptr) {
                mUsageTracker.BufferUsedAs(drawCountBuffer,
                                           kIndirectBufferForFrontendValidation |
                                               kIndirectBufferForBackendResourceTracking);
            }

            mDrawCount += maxDrawCount;

            return {};
        },
        "encoding %s.MultiDrawIndirect(%s, %u, %u, %s, %u).", this, indirectBuffer, indirectOffset,
        maxDrawCount, drawCountBuffer, drawCountBufferOffset);
}

void RenderEncoderBase::APIMultiDrawIndexedIndirect(BufferBase* indirectBuffer,
                                                    uint64_t indirectOffset,
                                                    uint32_t maxDrawCount,
                                                    BufferBase* drawCountBuffer,
                                                    uint64_t drawCountBufferOffset) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_INVALID_IF(!GetDevice()->HasFeature(Feature::MultiDrawIndirect),
                                "%s is not enabled.", wgpu::FeatureName::MultiDrawIndirect);

                DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
                DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));

                DAWN_INVALID_IF(indirectOffset % 4 != 0,
                                "Indirect offset (%u) is not a multiple of 4.", indirectOffset);

                DAWN_INVALID_IF(indirectOffset >= indirectBuffer->GetSize(),
                                "Indirect offset (%u) is larger than or equal to the size (%u) of "
                                "the indirect buffer.",
                                indirectOffset, indirectBuffer->GetSize());

                // maxDrawCount * kDrawIndexedIndirectSize can't overflow because
                // kDrawIndexedIndirectSize is a uint64_t which results in a uint64_t
                DAWN_INVALID_IF(
                    indirectBuffer->GetSize() - indirectOffset <
                        maxDrawCount * kDrawIndexedIndirectSize,
                    "Indirect Buffer size (%u) and offset (%u) can not hold maxDrawCount "
                    "(%u) draw commands.",
                    indirectBuffer->GetSize(), indirectOffset, maxDrawCount);

                // draw count buffer is optional
                if (drawCountBuffer != nullptr) {
                    DAWN_TRY(GetDevice()->ValidateObject(drawCountBuffer));
                    DAWN_TRY(ValidateCanUseAs(drawCountBuffer, wgpu::BufferUsage::Indirect));

                    DAWN_INVALID_IF(drawCountBufferOffset % 4 != 0,
                                    "Draw count buffer offset (%u) is not a multiple of 4.",
                                    drawCountBufferOffset);

                    DAWN_INVALID_IF(
                        drawCountBufferOffset >= drawCountBuffer->GetSize(),
                        "Draw count buffer offset (%u) is larger than or equal to the size "
                        "(%u) of the draw count buffer.",
                        drawCountBufferOffset, drawCountBuffer->GetSize());

                    // Can't underflow because the offset is checked to be smaller than the buffer.
                    DAWN_INVALID_IF(drawCountBuffer->GetSize() - drawCountBufferOffset < 4,
                                    "Draw count buffer offset (%u) is out of bounds of the draw "
                                    "count buffer %s size (%u).",
                                    drawCountBufferOffset, drawCountBuffer,
                                    drawCountBuffer->GetSize());
                }

                DAWN_TRY(mCommandBufferState.ValidateCanDrawIndexed());

                if (!GetDevice()->HasFlexibleTextureViews()) {
                    DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture());
                }
            }

            MultiDrawIndexedIndirectCmd* cmd =
                allocator->Allocate<MultiDrawIndexedIndirectCmd>(Command::MultiDrawIndexedIndirect);

            cmd->indirectBuffer = indirectBuffer;
            cmd->indirectOffset = indirectOffset;
            cmd->maxDrawCount = maxDrawCount;
            cmd->drawCountBuffer = drawCountBuffer;
            cmd->drawCountOffset = drawCountBufferOffset;

            bool duplicateBaseVertexInstance =
                GetDevice()->ShouldDuplicateParametersForDrawIndirect(
                    mCommandBufferState.GetRenderPipeline());

            mIndirectDrawMetadata.AddMultiDrawIndexedIndirect(
                mCommandBufferState.GetIndexBuffer(), mCommandBufferState.GetIndexFormat(),
                mCommandBufferState.GetIndexBufferSize(),
                mCommandBufferState.GetIndexBufferOffset(),
                mCommandBufferState.GetRenderPipeline()->GetPrimitiveTopology(),
                duplicateBaseVertexInstance, cmd);

            if (NeedsIndirectGPUValidation() &&
                (IsValidationEnabled() ||
                 GetDevice()->MayRequireDuplicationOfIndirectParameters())) {
                // We only set usage as `kIndirectBufferForFrontendValidation` because
                // `indirectBuffer` may not be used as an indirect buffer. The usage of
                // `indirectBuffer` may be updated in `EncodeIndirectDrawValidationCommands()` in
                // `EncodingContext::ExitRenderPass()`, which is only called when above conditions
                // are both met.
                mUsageTracker.BufferUsedAs(indirectBuffer, kIndirectBufferForFrontendValidation);
            } else {
                mUsageTracker.BufferUsedAs(indirectBuffer,
                                           kIndirectBufferForFrontendValidation |
                                               kIndirectBufferForBackendResourceTracking);
            }
            if (drawCountBuffer != nullptr) {
                mUsageTracker.BufferUsedAs(drawCountBuffer,
                                           kIndirectBufferForFrontendValidation |
                                               kIndirectBufferForBackendResourceTracking);
            }

            mDrawCount += maxDrawCount;

            return {};
        },
        "encoding %s.MultiDrawIndexedIndirect(%s, %u, %u, %s, %u).", this, indirectBuffer,
        indirectOffset, maxDrawCount, drawCountBuffer, drawCountBufferOffset);
}

void RenderEncoderBase::APISetPipeline(RenderPipelineBase* pipeline) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(pipeline));

                DAWN_INVALID_IF(pipeline->GetAttachmentState() != mAttachmentState.Get(),
                                "Attachment state of %s is not compatible with %s.\n"
                                "%s expects an attachment state of %s.\n"
                                "%s has an attachment state of %s.",
                                pipeline, this, this, mAttachmentState.Get(), pipeline,
                                pipeline->GetAttachmentState());

                DAWN_INVALID_IF(pipeline->WritesDepth() && mDepthReadOnly,
                                "%s writes depth while %s's depthReadOnly is true", pipeline, this);

                DAWN_INVALID_IF(pipeline->WritesStencil() && mStencilReadOnly,
                                "%s writes stencil while %s's stencilReadOnly is true", pipeline,
                                this);
            }

            mCommandBufferState.SetRenderPipeline(pipeline);

            SetRenderPipelineCmd* cmd =
                allocator->Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
            cmd->pipeline = pipeline;

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

void RenderEncoderBase::APISetIndexBuffer(BufferBase* buffer,
                                          wgpu::IndexFormat format,
                                          uint64_t offset,
                                          uint64_t size) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_TRY(GetDevice()->ValidateObject(buffer));
                DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Index));

                DAWN_TRY(ValidateIndexFormat(format));

                DAWN_INVALID_IF(format == wgpu::IndexFormat::Undefined,
                                "Index format must be specified");

                DAWN_INVALID_IF(offset % uint64_t(IndexFormatSize(format)) != 0,
                                "Index buffer offset (%u) is not a multiple of the size (%u) "
                                "of %s.",
                                offset, IndexFormatSize(format), format);

                uint64_t bufferSize = buffer->GetSize();
                DAWN_INVALID_IF(offset > bufferSize,
                                "Index 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,
                                    "Index buffer range (offset: %u, size: %u) doesn't fit in "
                                    "the size (%u) of "
                                    "%s.",
                                    offset, size, bufferSize, buffer);
                }
            } else {
                if (size == wgpu::kWholeSize) {
                    DAWN_ASSERT(buffer->GetSize() >= offset);
                    size = buffer->GetSize() - offset;
                }
            }

            mCommandBufferState.SetIndexBuffer(buffer, format, offset, size);

            SetIndexBufferCmd* cmd =
                allocator->Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
            cmd->buffer = buffer;
            cmd->format = format;
            cmd->offset = offset;
            cmd->size = size;

            mUsageTracker.BufferUsedAs(buffer, wgpu::BufferUsage::Index);

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

void RenderEncoderBase::APISetVertexBuffer(uint32_t slot,
                                           BufferBase* buffer,
                                           uint64_t offset,
                                           uint64_t size) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_INVALID_IF(slot >= kMaxVertexBuffers,
                                "Vertex buffer slot (%u) is larger the maximum (%u)", slot,
                                kMaxVertexBuffers - 1);

                if (buffer == nullptr) {
                    DAWN_INVALID_IF(offset != 0, "Offset (%u) must be 0 if buffer is null", offset);
                    DAWN_INVALID_IF(
                        size != 0 && size != wgpu::kWholeSize,
                        "Size (%u) must be either 0 or wgpu::kWholeSize if buffer is null", size);
                } else {
                    DAWN_TRY(GetDevice()->ValidateObject(buffer));
                    DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Vertex));
                    DAWN_INVALID_IF(offset % 4 != 0,
                                    "Vertex buffer offset (%u) is not a multiple of 4", offset);

                    uint64_t bufferSize = buffer->GetSize();
                    DAWN_INVALID_IF(offset > bufferSize,
                                    "Vertex 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,
                                        "Vertex buffer range (offset: %u, size: %u) doesn't fit in "
                                        "the size (%u) "
                                        "of %s.",
                                        offset, size, bufferSize, buffer);
                    }
                }
            } else {
                if (size == wgpu::kWholeSize && buffer != nullptr) {
                    DAWN_ASSERT(buffer->GetSize() >= offset);
                    size = buffer->GetSize() - offset;
                }
            }

            VertexBufferSlot vbSlot = VertexBufferSlot(static_cast<uint8_t>(slot));
            if (buffer == nullptr) {
                mCommandBufferState.UnsetVertexBuffer(vbSlot);
            } else {
                mCommandBufferState.SetVertexBuffer(vbSlot, size);

                SetVertexBufferCmd* cmd =
                    allocator->Allocate<SetVertexBufferCmd>(Command::SetVertexBuffer);
                cmd->slot = vbSlot;
                cmd->buffer = buffer;
                cmd->offset = offset;
                cmd->size = size;

                mUsageTracker.BufferUsedAs(buffer, wgpu::BufferUsage::Vertex);
            }
            return {};
        },
        "encoding %s.SetVertexBuffer(%u, %s, %u, %u).", this, slot, buffer, offset, size);
}

void RenderEncoderBase::APISetBindGroup(uint32_t groupIndexIn,
                                        BindGroupBase* group,
                                        uint32_t dynamicOffsetCount,
                                        const uint32_t* dynamicOffsets) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            BindGroupIndex groupIndex(groupIndexIn);

            if (IsValidationEnabled()) {
                DAWN_TRY(
                    ValidateSetBindGroup(groupIndex, group, dynamicOffsetCount, dynamicOffsets));
            }

            if (group == nullptr) {
                mCommandBufferState.UnsetBindGroup(groupIndex);
            } else {
                RecordSetBindGroup(allocator, groupIndex, group, dynamicOffsetCount,
                                   dynamicOffsets);
                mCommandBufferState.SetBindGroup(groupIndex, group, dynamicOffsetCount,
                                                 dynamicOffsets);
                mUsageTracker.AddBindGroup(group);
            }

            return {};
        },
        "encoding %s.SetBindGroup(%u, %s, %u, ...).", this, groupIndexIn, group,
        dynamicOffsetCount);
}

void RenderEncoderBase::APISetImmediates(uint32_t offset, const void* data, size_t size) {
    mEncodingContext->TryEncode(
        this,
        [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                DAWN_TRY(ValidateSetImmediates(offset, size));
            }

            // Skip SetImmediates when uploading constants are empty.
            if (size == 0) {
                return {};
            }

            SetImmediatesCmd* cmd = allocator->Allocate<SetImmediatesCmd>(Command::SetImmediates);
            cmd->offset = offset;
            cmd->size = size;
            uint8_t* immediateDatas = allocator->AllocateData<uint8_t>(cmd->size);
            memcpy(immediateDatas, data, size);

            mCommandBufferState.SetImmediateData(offset, size);

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

}  // namespace dawn::native
