// 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::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::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::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::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>();
                    RenderPassDescriptorBase* info = cmd->info.Get();
                    if (!mState->BeginRenderPass(info)) {
                        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::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->HaveRenderPass()) {
                        HandleError("Can't set stencil reference without an active render pass");
                        return false;
                    }
                } break;

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

                case Command::SetScissorRect: {
                    mIterator.NextCommand<SetScissorRectCmd>();
                    if (!mState->HaveRenderPass()) {
                        HandleError("Can't set scissor rect without an active render pass");
                        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(RenderPassDescriptorBase* info) {
        BeginRenderPassCmd* cmd = mAllocator.Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
        new (cmd) BeginRenderPassCmd;
        cmd->info = info;
    }

    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::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
