// Copyright 2017 The NXT 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 "backend/CommandBuffer.h"

#include "backend/BindGroup.h"
#include "backend/Buffer.h"
#include "backend/CommandBufferStateTracker.h"
#include "backend/Commands.h"
#include "backend/ComputePipeline.h"
#include "backend/Device.h"
#include "backend/InputState.h"
#include "backend/PipelineLayout.h"
#include "backend/RenderPipeline.h"
#include "backend/Texture.h"

#include <cstring>
#include <map>

namespace backend {

    namespace {

        bool ValidateCopyLocationFitsInTexture(CommandBufferBuilder* builder,
                                               const TextureCopyLocation& location) {
            const TextureBase* texture = location.texture.Get();
            if (location.level >= texture->GetNumMipLevels()) {
                builder->HandleError("Copy mip-level out of range");
                return false;
            }

            // All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid
            // overflows.
            uint64_t level = location.level;
            if (uint64_t(location.x) + uint64_t(location.width) >
                    (static_cast<uint64_t>(texture->GetWidth()) >> level) ||
                uint64_t(location.y) + uint64_t(location.height) >
                    (static_cast<uint64_t>(texture->GetHeight()) >> level)) {
                builder->HandleError("Copy would touch outside of the texture");
                return false;
            }

            // TODO(cwallez@chromium.org): Check the depth bound differently for 2D arrays and 3D
            // textures
            if (location.z != 0 || location.depth != 1) {
                builder->HandleError("No support for z != 0 and depth != 1 for now");
                return false;
            }

            return true;
        }

        bool FitsInBuffer(const BufferBase* buffer, uint32_t offset, uint32_t size) {
            uint32_t bufferSize = buffer->GetSize();
            return offset <= bufferSize && (size <= (bufferSize - offset));
        }

        bool ValidateCopySizeFitsInBuffer(CommandBufferBuilder* builder,
                                          const BufferCopyLocation& location,
                                          uint32_t dataSize) {
            if (!FitsInBuffer(location.buffer.Get(), location.offset, dataSize)) {
                builder->HandleError("Copy would overflow the buffer");
                return false;
            }

            return true;
        }

        bool ValidateTexelBufferOffset(CommandBufferBuilder* builder,
                                       TextureBase* texture,
                                       const BufferCopyLocation& location) {
            uint32_t texelSize =
                static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat()));
            if (location.offset % texelSize != 0) {
                builder->HandleError("Buffer offset must be a multiple of the texel size");
                return false;
            }

            return true;
        }

        bool ComputeTextureCopyBufferSize(CommandBufferBuilder*,
                                          const TextureCopyLocation& location,
                                          uint32_t rowPitch,
                                          uint32_t* bufferSize) {
            // TODO(cwallez@chromium.org): check for overflows
            *bufferSize = (rowPitch * (location.height - 1) + location.width) * location.depth;

            return true;
        }

        uint32_t ComputeDefaultRowPitch(TextureBase* texture, uint32_t width) {
            uint32_t texelSize = TextureFormatPixelSize(texture->GetFormat());
            return texelSize * width;
        }

        bool ValidateRowPitch(CommandBufferBuilder* builder,
                              const TextureCopyLocation& location,
                              uint32_t rowPitch) {
            if (rowPitch % kTextureRowPitchAlignment != 0) {
                builder->HandleError("Row pitch must be a multiple of 256");
                return false;
            }

            uint32_t texelSize = TextureFormatPixelSize(location.texture.Get()->GetFormat());
            if (rowPitch < location.width * texelSize) {
                builder->HandleError("Row pitch must not be less than the number of bytes per row");
                return false;
            }

            return true;
        }

    }  // namespace

    CommandBufferBase::CommandBufferBase(CommandBufferBuilder* builder)
        : mDevice(builder->mDevice),
          mBuffersTransitioned(std::move(builder->mState->mBuffersTransitioned)),
          mTexturesTransitioned(std::move(builder->mState->mTexturesTransitioned)) {
    }

    bool CommandBufferBase::ValidateResourceUsagesImmediate() {
        for (auto buffer : mBuffersTransitioned) {
            if (buffer->IsFrozen()) {
                mDevice->HandleError("Command buffer: cannot transition buffer with frozen usage");
                return false;
            }
        }
        for (auto texture : mTexturesTransitioned) {
            if (texture->IsFrozen()) {
                mDevice->HandleError("Command buffer: cannot transition texture with frozen usage");
                return false;
            }
        }
        return true;
    }

    DeviceBase* CommandBufferBase::GetDevice() {
        return mDevice;
    }

    void FreeCommands(CommandIterator* commands) {
        Command type;
        while (commands->NextCommandId(&type)) {
            switch (type) {
                case Command::BeginComputePass: {
                    BeginComputePassCmd* begin = commands->NextCommand<BeginComputePassCmd>();
                    begin->~BeginComputePassCmd();
                } break;
                case Command::BeginRenderPass: {
                    BeginRenderPassCmd* begin = commands->NextCommand<BeginRenderPassCmd>();
                    begin->~BeginRenderPassCmd();
                } break;
                case Command::BeginRenderSubpass: {
                    BeginRenderSubpassCmd* begin = commands->NextCommand<BeginRenderSubpassCmd>();
                    begin->~BeginRenderSubpassCmd();
                } break;
                case Command::CopyBufferToBuffer: {
                    CopyBufferToBufferCmd* copy = commands->NextCommand<CopyBufferToBufferCmd>();
                    copy->~CopyBufferToBufferCmd();
                } break;
                case Command::CopyBufferToTexture: {
                    CopyBufferToTextureCmd* copy = commands->NextCommand<CopyBufferToTextureCmd>();
                    copy->~CopyBufferToTextureCmd();
                } break;
                case Command::CopyTextureToBuffer: {
                    CopyTextureToBufferCmd* copy = commands->NextCommand<CopyTextureToBufferCmd>();
                    copy->~CopyTextureToBufferCmd();
                } break;
                case Command::Dispatch: {
                    DispatchCmd* dispatch = commands->NextCommand<DispatchCmd>();
                    dispatch->~DispatchCmd();
                } break;
                case Command::DrawArrays: {
                    DrawArraysCmd* draw = commands->NextCommand<DrawArraysCmd>();
                    draw->~DrawArraysCmd();
                } break;
                case Command::DrawElements: {
                    DrawElementsCmd* draw = commands->NextCommand<DrawElementsCmd>();
                    draw->~DrawElementsCmd();
                } break;
                case Command::EndComputePass: {
                    EndComputePassCmd* cmd = commands->NextCommand<EndComputePassCmd>();
                    cmd->~EndComputePassCmd();
                } break;
                case Command::EndRenderPass: {
                    EndRenderPassCmd* cmd = commands->NextCommand<EndRenderPassCmd>();
                    cmd->~EndRenderPassCmd();
                } break;
                case Command::EndRenderSubpass: {
                    EndRenderSubpassCmd* cmd = commands->NextCommand<EndRenderSubpassCmd>();
                    cmd->~EndRenderSubpassCmd();
                } break;
                case Command::SetComputePipeline: {
                    SetComputePipelineCmd* cmd = commands->NextCommand<SetComputePipelineCmd>();
                    cmd->~SetComputePipelineCmd();
                } break;
                case Command::SetRenderPipeline: {
                    SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
                    cmd->~SetRenderPipelineCmd();
                } break;
                case Command::SetPushConstants: {
                    SetPushConstantsCmd* cmd = commands->NextCommand<SetPushConstantsCmd>();
                    commands->NextData<uint32_t>(cmd->count);
                    cmd->~SetPushConstantsCmd();
                } break;
                case Command::SetStencilReference: {
                    SetStencilReferenceCmd* cmd = commands->NextCommand<SetStencilReferenceCmd>();
                    cmd->~SetStencilReferenceCmd();
                } break;
                case Command::SetScissorRect: {
                    SetScissorRectCmd* cmd = commands->NextCommand<SetScissorRectCmd>();
                    cmd->~SetScissorRectCmd();
                } break;
                case Command::SetBlendColor: {
                    SetBlendColorCmd* cmd = commands->NextCommand<SetBlendColorCmd>();
                    cmd->~SetBlendColorCmd();
                } break;
                case Command::SetBindGroup: {
                    SetBindGroupCmd* cmd = commands->NextCommand<SetBindGroupCmd>();
                    cmd->~SetBindGroupCmd();
                } break;
                case Command::SetIndexBuffer: {
                    SetIndexBufferCmd* cmd = commands->NextCommand<SetIndexBufferCmd>();
                    cmd->~SetIndexBufferCmd();
                } break;
                case Command::SetVertexBuffers: {
                    SetVertexBuffersCmd* cmd = commands->NextCommand<SetVertexBuffersCmd>();
                    auto buffers = commands->NextData<Ref<BufferBase>>(cmd->count);
                    for (size_t i = 0; i < cmd->count; ++i) {
                        (&buffers[i])->~Ref<BufferBase>();
                    }
                    commands->NextData<uint32_t>(cmd->count);
                    cmd->~SetVertexBuffersCmd();
                } break;
                case Command::TransitionBufferUsage: {
                    TransitionBufferUsageCmd* cmd =
                        commands->NextCommand<TransitionBufferUsageCmd>();
                    cmd->~TransitionBufferUsageCmd();
                } break;
                case Command::TransitionTextureUsage: {
                    TransitionTextureUsageCmd* cmd =
                        commands->NextCommand<TransitionTextureUsageCmd>();
                    cmd->~TransitionTextureUsageCmd();
                } break;
            }
        }
        commands->DataWasDestroyed();
    }

    void SkipCommand(CommandIterator* commands, Command type) {
        switch (type) {
            case Command::BeginComputePass:
                commands->NextCommand<BeginComputePassCmd>();
                break;

            case Command::BeginRenderPass:
                commands->NextCommand<BeginRenderPassCmd>();
                break;

            case Command::BeginRenderSubpass:
                commands->NextCommand<BeginRenderSubpassCmd>();
                break;

            case Command::CopyBufferToBuffer:
                commands->NextCommand<CopyBufferToBufferCmd>();
                break;

            case Command::CopyBufferToTexture:
                commands->NextCommand<CopyBufferToTextureCmd>();
                break;

            case Command::CopyTextureToBuffer:
                commands->NextCommand<CopyTextureToBufferCmd>();
                break;

            case Command::Dispatch:
                commands->NextCommand<DispatchCmd>();
                break;

            case Command::DrawArrays:
                commands->NextCommand<DrawArraysCmd>();
                break;

            case Command::DrawElements:
                commands->NextCommand<DrawElementsCmd>();
                break;

            case Command::EndComputePass:
                commands->NextCommand<EndComputePassCmd>();
                break;

            case Command::EndRenderPass:
                commands->NextCommand<EndRenderPassCmd>();
                break;

            case Command::EndRenderSubpass:
                commands->NextCommand<EndRenderSubpassCmd>();
                break;

            case Command::SetComputePipeline:
                commands->NextCommand<SetComputePipelineCmd>();
                break;

            case Command::SetRenderPipeline:
                commands->NextCommand<SetRenderPipelineCmd>();
                break;

            case Command::SetPushConstants: {
                auto* cmd = commands->NextCommand<SetPushConstantsCmd>();
                commands->NextData<uint32_t>(cmd->count);
            } break;

            case Command::SetStencilReference:
                commands->NextCommand<SetStencilReferenceCmd>();
                break;

            case Command::SetScissorRect:
                commands->NextCommand<SetScissorRectCmd>();
                break;

            case Command::SetBlendColor:
                commands->NextCommand<SetBlendColorCmd>();
                break;

            case Command::SetBindGroup:
                commands->NextCommand<SetBindGroupCmd>();
                break;

            case Command::SetIndexBuffer:
                commands->NextCommand<SetIndexBufferCmd>();
                break;

            case Command::SetVertexBuffers: {
                auto* cmd = commands->NextCommand<SetVertexBuffersCmd>();
                commands->NextData<Ref<BufferBase>>(cmd->count);
                commands->NextData<uint32_t>(cmd->count);
            } break;

            case Command::TransitionBufferUsage:
                commands->NextCommand<TransitionBufferUsageCmd>();
                break;

            case Command::TransitionTextureUsage:
                commands->NextCommand<TransitionTextureUsageCmd>();
                break;
        }
    }

    CommandBufferBuilder::CommandBufferBuilder(DeviceBase* device)
        : Builder(device), mState(std::make_unique<CommandBufferStateTracker>(this)) {
    }

    CommandBufferBuilder::~CommandBufferBuilder() {
        if (!mWereCommandsAcquired) {
            MoveToIterator();
            FreeCommands(&mIterator);
        }
    }

    bool CommandBufferBuilder::ValidateGetResult() {
        MoveToIterator();

        Command type;
        while (mIterator.NextCommandId(&type)) {
            switch (type) {
                case Command::BeginComputePass: {
                    mIterator.NextCommand<BeginComputePassCmd>();
                    if (!mState->BeginComputePass()) {
                        return false;
                    }
                } break;

                case Command::BeginRenderPass: {
                    BeginRenderPassCmd* cmd = mIterator.NextCommand<BeginRenderPassCmd>();
                    auto* renderPass = cmd->renderPass.Get();
                    auto* framebuffer = cmd->framebuffer.Get();
                    // TODO(kainino@chromium.org): null checks should not be necessary
                    if (renderPass == nullptr) {
                        HandleError("Render pass is invalid");
                        return false;
                    }
                    if (framebuffer == nullptr) {
                        HandleError("Framebuffer is invalid");
                        return false;
                    }
                    if (!mState->BeginRenderPass(renderPass, framebuffer)) {
                        return false;
                    }
                } break;

                case Command::BeginRenderSubpass: {
                    mIterator.NextCommand<BeginRenderSubpassCmd>();
                    if (!mState->BeginSubpass()) {
                        return false;
                    }
                } break;

                case Command::CopyBufferToBuffer: {
                    CopyBufferToBufferCmd* copy = mIterator.NextCommand<CopyBufferToBufferCmd>();
                    if (!ValidateCopySizeFitsInBuffer(this, copy->source, copy->size) ||
                        !ValidateCopySizeFitsInBuffer(this, copy->destination, copy->size) ||
                        !mState->ValidateCanCopy() ||
                        !mState->ValidateCanUseBufferAs(copy->source.buffer.Get(),
                                                        nxt::BufferUsageBit::TransferSrc) ||
                        !mState->ValidateCanUseBufferAs(copy->destination.buffer.Get(),
                                                        nxt::BufferUsageBit::TransferDst)) {
                        return false;
                    }
                } break;

                case Command::CopyBufferToTexture: {
                    CopyBufferToTextureCmd* copy = mIterator.NextCommand<CopyBufferToTextureCmd>();

                    uint32_t bufferCopySize = 0;
                    if (!ValidateRowPitch(this, copy->destination, copy->rowPitch) ||
                        !ComputeTextureCopyBufferSize(this, copy->destination, copy->rowPitch,
                                                      &bufferCopySize) ||
                        !ValidateCopyLocationFitsInTexture(this, copy->destination) ||
                        !ValidateCopySizeFitsInBuffer(this, copy->source, bufferCopySize) ||
                        !ValidateTexelBufferOffset(this, copy->destination.texture.Get(),
                                                   copy->source) ||
                        !mState->ValidateCanCopy() ||
                        !mState->ValidateCanUseBufferAs(copy->source.buffer.Get(),
                                                        nxt::BufferUsageBit::TransferSrc) ||
                        !mState->ValidateCanUseTextureAs(copy->destination.texture.Get(),
                                                         nxt::TextureUsageBit::TransferDst)) {
                        return false;
                    }
                } break;

                case Command::CopyTextureToBuffer: {
                    CopyTextureToBufferCmd* copy = mIterator.NextCommand<CopyTextureToBufferCmd>();

                    uint32_t bufferCopySize = 0;
                    if (!ValidateRowPitch(this, copy->source, copy->rowPitch) ||
                        !ComputeTextureCopyBufferSize(this, copy->source, copy->rowPitch,
                                                      &bufferCopySize) ||
                        !ValidateCopyLocationFitsInTexture(this, copy->source) ||
                        !ValidateCopySizeFitsInBuffer(this, copy->destination, bufferCopySize) ||
                        !ValidateTexelBufferOffset(this, copy->source.texture.Get(),
                                                   copy->destination) ||
                        !mState->ValidateCanCopy() ||
                        !mState->ValidateCanUseTextureAs(copy->source.texture.Get(),
                                                         nxt::TextureUsageBit::TransferSrc) ||
                        !mState->ValidateCanUseBufferAs(copy->destination.buffer.Get(),
                                                        nxt::BufferUsageBit::TransferDst)) {
                        return false;
                    }
                } break;

                case Command::Dispatch: {
                    mIterator.NextCommand<DispatchCmd>();
                    if (!mState->ValidateCanDispatch()) {
                        return false;
                    }
                } break;

                case Command::DrawArrays: {
                    mIterator.NextCommand<DrawArraysCmd>();
                    if (!mState->ValidateCanDrawArrays()) {
                        return false;
                    }
                } break;

                case Command::DrawElements: {
                    mIterator.NextCommand<DrawElementsCmd>();
                    if (!mState->ValidateCanDrawElements()) {
                        return false;
                    }
                } break;

                case Command::EndComputePass: {
                    mIterator.NextCommand<EndComputePassCmd>();
                    if (!mState->EndComputePass()) {
                        return false;
                    }
                } break;

                case Command::EndRenderPass: {
                    mIterator.NextCommand<EndRenderPassCmd>();
                    if (!mState->EndRenderPass()) {
                        return false;
                    }
                } break;

                case Command::EndRenderSubpass: {
                    mIterator.NextCommand<EndRenderSubpassCmd>();
                    if (!mState->EndSubpass()) {
                        return false;
                    }
                } break;

                case Command::SetComputePipeline: {
                    SetComputePipelineCmd* cmd = mIterator.NextCommand<SetComputePipelineCmd>();
                    ComputePipelineBase* pipeline = cmd->pipeline.Get();
                    if (!mState->SetComputePipeline(pipeline)) {
                        return false;
                    }
                } break;

                case Command::SetRenderPipeline: {
                    SetRenderPipelineCmd* cmd = mIterator.NextCommand<SetRenderPipelineCmd>();
                    RenderPipelineBase* pipeline = cmd->pipeline.Get();
                    if (!mState->SetRenderPipeline(pipeline)) {
                        return false;
                    }
                } break;

                case Command::SetPushConstants: {
                    SetPushConstantsCmd* cmd = mIterator.NextCommand<SetPushConstantsCmd>();
                    mIterator.NextData<uint32_t>(cmd->count);
                    // Validation of count and offset has already been done when the command was
                    // recorded because it impacts the size of an allocation in the
                    // CommandAllocator.
                    if (!mState->ValidateSetPushConstants(cmd->stages)) {
                        return false;
                    }
                } break;

                case Command::SetStencilReference: {
                    mIterator.NextCommand<SetStencilReferenceCmd>();
                    if (!mState->HaveRenderSubpass()) {
                        HandleError("Can't set stencil reference without an active render subpass");
                        return false;
                    }
                } break;

                case Command::SetBlendColor: {
                    mIterator.NextCommand<SetBlendColorCmd>();
                    if (!mState->HaveRenderSubpass()) {
                        HandleError("Can't set blend color without an active render subpass");
                        return false;
                    }
                } break;

                case Command::SetScissorRect: {
                    mIterator.NextCommand<SetScissorRectCmd>();
                    if (!mState->HaveRenderSubpass()) {
                        HandleError("Can't set scissor rect without an active render subpass");
                        return false;
                    }
                } break;

                case Command::SetBindGroup: {
                    SetBindGroupCmd* cmd = mIterator.NextCommand<SetBindGroupCmd>();
                    if (!mState->SetBindGroup(cmd->index, cmd->group.Get())) {
                        return false;
                    }
                } break;

                case Command::SetIndexBuffer: {
                    SetIndexBufferCmd* cmd = mIterator.NextCommand<SetIndexBufferCmd>();
                    if (!mState->SetIndexBuffer(cmd->buffer.Get())) {
                        return false;
                    }
                } break;

                case Command::SetVertexBuffers: {
                    SetVertexBuffersCmd* cmd = mIterator.NextCommand<SetVertexBuffersCmd>();
                    auto buffers = mIterator.NextData<Ref<BufferBase>>(cmd->count);
                    mIterator.NextData<uint32_t>(cmd->count);

                    for (uint32_t i = 0; i < cmd->count; ++i) {
                        mState->SetVertexBuffer(cmd->startSlot + i, buffers[i].Get());
                    }
                } break;

                case Command::TransitionBufferUsage: {
                    TransitionBufferUsageCmd* cmd =
                        mIterator.NextCommand<TransitionBufferUsageCmd>();
                    if (!mState->TransitionBufferUsage(cmd->buffer.Get(), cmd->usage)) {
                        return false;
                    }
                } break;

                case Command::TransitionTextureUsage: {
                    TransitionTextureUsageCmd* cmd =
                        mIterator.NextCommand<TransitionTextureUsageCmd>();
                    if (!mState->TransitionTextureUsage(cmd->texture.Get(), cmd->usage)) {
                        return false;
                    }

                } break;
            }
        }

        if (!mState->ValidateEndCommandBuffer()) {
            return false;
        }

        return true;
    }

    CommandIterator CommandBufferBuilder::AcquireCommands() {
        ASSERT(!mWereCommandsAcquired);
        mWereCommandsAcquired = true;
        return std::move(mIterator);
    }

    CommandBufferBase* CommandBufferBuilder::GetResultImpl() {
        MoveToIterator();
        return mDevice->CreateCommandBuffer(this);
    }

    void CommandBufferBuilder::BeginComputePass() {
        mAllocator.Allocate<BeginComputePassCmd>(Command::BeginComputePass);
    }

    void CommandBufferBuilder::BeginRenderPass(RenderPassBase* renderPass,
                                               FramebufferBase* framebuffer) {
        BeginRenderPassCmd* cmd = mAllocator.Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
        new (cmd) BeginRenderPassCmd;
        cmd->renderPass = renderPass;
        cmd->framebuffer = framebuffer;
    }

    void CommandBufferBuilder::BeginRenderSubpass() {
        mAllocator.Allocate<BeginRenderSubpassCmd>(Command::BeginRenderSubpass);
    }

    void CommandBufferBuilder::CopyBufferToBuffer(BufferBase* source,
                                                  uint32_t sourceOffset,
                                                  BufferBase* destination,
                                                  uint32_t destinationOffset,
                                                  uint32_t size) {
        CopyBufferToBufferCmd* copy =
            mAllocator.Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
        new (copy) CopyBufferToBufferCmd;
        copy->source.buffer = source;
        copy->source.offset = sourceOffset;
        copy->destination.buffer = destination;
        copy->destination.offset = destinationOffset;
        copy->size = size;
    }

    void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer,
                                                   uint32_t bufferOffset,
                                                   uint32_t rowPitch,
                                                   TextureBase* texture,
                                                   uint32_t x,
                                                   uint32_t y,
                                                   uint32_t z,
                                                   uint32_t width,
                                                   uint32_t height,
                                                   uint32_t depth,
                                                   uint32_t level) {
        if (rowPitch == 0) {
            rowPitch = ComputeDefaultRowPitch(texture, width);
        }
        CopyBufferToTextureCmd* copy =
            mAllocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
        new (copy) CopyBufferToTextureCmd;
        copy->source.buffer = buffer;
        copy->source.offset = bufferOffset;
        copy->destination.texture = texture;
        copy->destination.x = x;
        copy->destination.y = y;
        copy->destination.z = z;
        copy->destination.width = width;
        copy->destination.height = height;
        copy->destination.depth = depth;
        copy->destination.level = level;
        copy->rowPitch = rowPitch;
    }

    void CommandBufferBuilder::CopyTextureToBuffer(TextureBase* texture,
                                                   uint32_t x,
                                                   uint32_t y,
                                                   uint32_t z,
                                                   uint32_t width,
                                                   uint32_t height,
                                                   uint32_t depth,
                                                   uint32_t level,
                                                   BufferBase* buffer,
                                                   uint32_t bufferOffset,
                                                   uint32_t rowPitch) {
        if (rowPitch == 0) {
            rowPitch = ComputeDefaultRowPitch(texture, width);
        }
        CopyTextureToBufferCmd* copy =
            mAllocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
        new (copy) CopyTextureToBufferCmd;
        copy->source.texture = texture;
        copy->source.x = x;
        copy->source.y = y;
        copy->source.z = z;
        copy->source.width = width;
        copy->source.height = height;
        copy->source.depth = depth;
        copy->source.level = level;
        copy->destination.buffer = buffer;
        copy->destination.offset = bufferOffset;
        copy->rowPitch = rowPitch;
    }

    void CommandBufferBuilder::Dispatch(uint32_t x, uint32_t y, uint32_t z) {
        DispatchCmd* dispatch = mAllocator.Allocate<DispatchCmd>(Command::Dispatch);
        new (dispatch) DispatchCmd;
        dispatch->x = x;
        dispatch->y = y;
        dispatch->z = z;
    }

    void CommandBufferBuilder::DrawArrays(uint32_t vertexCount,
                                          uint32_t instanceCount,
                                          uint32_t firstVertex,
                                          uint32_t firstInstance) {
        DrawArraysCmd* draw = mAllocator.Allocate<DrawArraysCmd>(Command::DrawArrays);
        new (draw) DrawArraysCmd;
        draw->vertexCount = vertexCount;
        draw->instanceCount = instanceCount;
        draw->firstVertex = firstVertex;
        draw->firstInstance = firstInstance;
    }

    void CommandBufferBuilder::DrawElements(uint32_t indexCount,
                                            uint32_t instanceCount,
                                            uint32_t firstIndex,
                                            uint32_t firstInstance) {
        DrawElementsCmd* draw = mAllocator.Allocate<DrawElementsCmd>(Command::DrawElements);
        new (draw) DrawElementsCmd;
        draw->indexCount = indexCount;
        draw->instanceCount = instanceCount;
        draw->firstIndex = firstIndex;
        draw->firstInstance = firstInstance;
    }

    void CommandBufferBuilder::EndComputePass() {
        mAllocator.Allocate<EndComputePassCmd>(Command::EndComputePass);
    }

    void CommandBufferBuilder::EndRenderPass() {
        mAllocator.Allocate<EndRenderPassCmd>(Command::EndRenderPass);
    }

    void CommandBufferBuilder::EndRenderSubpass() {
        mAllocator.Allocate<EndRenderSubpassCmd>(Command::EndRenderSubpass);
    }

    void CommandBufferBuilder::SetComputePipeline(ComputePipelineBase* pipeline) {
        SetComputePipelineCmd* cmd =
            mAllocator.Allocate<SetComputePipelineCmd>(Command::SetComputePipeline);
        new (cmd) SetComputePipelineCmd;
        cmd->pipeline = pipeline;
    }

    void CommandBufferBuilder::SetRenderPipeline(RenderPipelineBase* pipeline) {
        SetRenderPipelineCmd* cmd =
            mAllocator.Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
        new (cmd) SetRenderPipelineCmd;
        cmd->pipeline = pipeline;
    }

    void CommandBufferBuilder::SetPushConstants(nxt::ShaderStageBit stages,
                                                uint32_t offset,
                                                uint32_t count,
                                                const void* data) {
        // TODO(cwallez@chromium.org): check for overflows
        if (offset + count > kMaxPushConstants) {
            HandleError("Setting too many push constants");
            return;
        }

        SetPushConstantsCmd* cmd =
            mAllocator.Allocate<SetPushConstantsCmd>(Command::SetPushConstants);
        new (cmd) SetPushConstantsCmd;
        cmd->stages = stages;
        cmd->offset = offset;
        cmd->count = count;

        uint32_t* values = mAllocator.AllocateData<uint32_t>(count);
        memcpy(values, data, count * sizeof(uint32_t));
    }

    void CommandBufferBuilder::SetStencilReference(uint32_t reference) {
        SetStencilReferenceCmd* cmd =
            mAllocator.Allocate<SetStencilReferenceCmd>(Command::SetStencilReference);
        new (cmd) SetStencilReferenceCmd;
        cmd->reference = reference;
    }

    void CommandBufferBuilder::SetBlendColor(float r, float g, float b, float a) {
        SetBlendColorCmd* cmd = mAllocator.Allocate<SetBlendColorCmd>(Command::SetBlendColor);
        new (cmd) SetBlendColorCmd;
        cmd->r = r;
        cmd->g = g;
        cmd->b = b;
        cmd->a = a;
    }

    void CommandBufferBuilder::SetScissorRect(uint32_t x,
                                              uint32_t y,
                                              uint32_t width,
                                              uint32_t height) {
        SetScissorRectCmd* cmd = mAllocator.Allocate<SetScissorRectCmd>(Command::SetScissorRect);
        new (cmd) SetScissorRectCmd;
        cmd->x = x;
        cmd->y = y;
        cmd->width = width;
        cmd->height = height;
    }

    void CommandBufferBuilder::SetBindGroup(uint32_t groupIndex, BindGroupBase* group) {
        if (groupIndex >= kMaxBindGroups) {
            HandleError("Setting bind group over the max");
            return;
        }

        SetBindGroupCmd* cmd = mAllocator.Allocate<SetBindGroupCmd>(Command::SetBindGroup);
        new (cmd) SetBindGroupCmd;
        cmd->index = groupIndex;
        cmd->group = group;
    }

    void CommandBufferBuilder::SetIndexBuffer(BufferBase* buffer, uint32_t offset) {
        // TODO(kainino@chromium.org): validation

        SetIndexBufferCmd* cmd = mAllocator.Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
        new (cmd) SetIndexBufferCmd;
        cmd->buffer = buffer;
        cmd->offset = offset;
    }

    void CommandBufferBuilder::SetVertexBuffers(uint32_t startSlot,
                                                uint32_t count,
                                                BufferBase* const* buffers,
                                                uint32_t const* offsets) {
        // TODO(kainino@chromium.org): validation

        SetVertexBuffersCmd* cmd =
            mAllocator.Allocate<SetVertexBuffersCmd>(Command::SetVertexBuffers);
        new (cmd) SetVertexBuffersCmd;
        cmd->startSlot = startSlot;
        cmd->count = count;

        Ref<BufferBase>* cmdBuffers = mAllocator.AllocateData<Ref<BufferBase>>(count);
        for (size_t i = 0; i < count; ++i) {
            new (&cmdBuffers[i]) Ref<BufferBase>(buffers[i]);
        }

        uint32_t* cmdOffsets = mAllocator.AllocateData<uint32_t>(count);
        memcpy(cmdOffsets, offsets, count * sizeof(uint32_t));
    }

    void CommandBufferBuilder::TransitionBufferUsage(BufferBase* buffer,
                                                     nxt::BufferUsageBit usage) {
        TransitionBufferUsageCmd* cmd =
            mAllocator.Allocate<TransitionBufferUsageCmd>(Command::TransitionBufferUsage);
        new (cmd) TransitionBufferUsageCmd;
        cmd->buffer = buffer;
        cmd->usage = usage;
    }

    void CommandBufferBuilder::TransitionTextureUsage(TextureBase* texture,
                                                      nxt::TextureUsageBit usage) {
        TransitionTextureUsageCmd* cmd =
            mAllocator.Allocate<TransitionTextureUsageCmd>(Command::TransitionTextureUsage);
        new (cmd) TransitionTextureUsageCmd;
        cmd->texture = texture;
        cmd->usage = usage;
    }

    void CommandBufferBuilder::MoveToIterator() {
        if (!mWasMovedToIterator) {
            mIterator = std::move(mAllocator);
            mWasMovedToIterator = true;
        }
    }

}  // namespace backend
