// 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/Commands.h"
#include "backend/CommandBufferStateTracker.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;
        }

    }

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

}
