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

#include "dawn_native/d3d12/CommandBufferD3D12.h"

#include "common/Assert.h"
#include "dawn_native/BindGroupAndStorageBarrierTracker.h"
#include "dawn_native/CommandEncoder.h"
#include "dawn_native/CommandValidation.h"
#include "dawn_native/Commands.h"
#include "dawn_native/EnumMaskIterator.h"
#include "dawn_native/RenderBundle.h"
#include "dawn_native/d3d12/BindGroupD3D12.h"
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
#include "dawn_native/d3d12/BufferD3D12.h"
#include "dawn_native/d3d12/CommandRecordingContext.h"
#include "dawn_native/d3d12/ComputePipelineD3D12.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/QuerySetD3D12.h"
#include "dawn_native/d3d12/RenderPassBuilderD3D12.h"
#include "dawn_native/d3d12/RenderPipelineD3D12.h"
#include "dawn_native/d3d12/SamplerD3D12.h"
#include "dawn_native/d3d12/SamplerHeapCacheD3D12.h"
#include "dawn_native/d3d12/ShaderVisibleDescriptorAllocatorD3D12.h"
#include "dawn_native/d3d12/StagingDescriptorAllocatorD3D12.h"
#include "dawn_native/d3d12/TextureCopySplitter.h"
#include "dawn_native/d3d12/TextureD3D12.h"
#include "dawn_native/d3d12/UtilsD3D12.h"

#include <deque>

namespace dawn_native { namespace d3d12 {

    namespace {

        DXGI_FORMAT DXGIIndexFormat(wgpu::IndexFormat format) {
            switch (format) {
                case wgpu::IndexFormat::Undefined:
                    return DXGI_FORMAT_UNKNOWN;
                case wgpu::IndexFormat::Uint16:
                    return DXGI_FORMAT_R16_UINT;
                case wgpu::IndexFormat::Uint32:
                    return DXGI_FORMAT_R32_UINT;
                default:
                    UNREACHABLE();
            }
        }

        D3D12_QUERY_TYPE D3D12QueryType(wgpu::QueryType type) {
            switch (type) {
                case wgpu::QueryType::Occlusion:
                    return D3D12_QUERY_TYPE_OCCLUSION;
                case wgpu::QueryType::PipelineStatistics:
                    return D3D12_QUERY_TYPE_PIPELINE_STATISTICS;
                case wgpu::QueryType::Timestamp:
                    return D3D12_QUERY_TYPE_TIMESTAMP;
                default:
                    UNREACHABLE();
            }
        }

        bool CanUseCopyResource(const TextureCopy& src,
                                const TextureCopy& dst,
                                const Extent3D& copySize) {
            // Checked by validation
            ASSERT(src.texture->GetSampleCount() == dst.texture->GetSampleCount());
            ASSERT(src.texture->GetFormat().format == dst.texture->GetFormat().format);
            ASSERT(src.aspect == dst.aspect);

            const Extent3D& srcSize = src.texture->GetSize();
            const Extent3D& dstSize = dst.texture->GetSize();

            // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist-copyresource
            // In order to use D3D12's copy resource, the textures must be the same dimensions, and
            // the copy must be of the entire resource.
            // TODO(dawn:129): Support 1D textures.
            return src.aspect == src.texture->GetFormat().aspects &&
                   src.texture->GetDimension() == dst.texture->GetDimension() &&  //
                   dst.texture->GetNumMipLevels() == 1 &&                         //
                   src.texture->GetNumMipLevels() == 1 &&  // A copy command is of a single mip, so
                                                           // if a resource has more than one, we
                                                           // definitely cannot use CopyResource.
                   copySize.width == dstSize.width &&      //
                   copySize.width == srcSize.width &&      //
                   copySize.height == dstSize.height &&    //
                   copySize.height == srcSize.height &&    //
                   copySize.depth == dstSize.depth &&      //
                   copySize.depth == srcSize.depth;
        }

        void RecordCopyTextureToBufferFromTextureCopySplit(ID3D12GraphicsCommandList* commandList,
                                                           const Texture2DCopySplit& baseCopySplit,
                                                           Buffer* buffer,
                                                           uint64_t baseOffset,
                                                           uint64_t bufferBytesPerRow,
                                                           Texture* texture,
                                                           uint32_t textureMiplevel,
                                                           uint32_t textureSlice,
                                                           Aspect aspect) {
            const D3D12_TEXTURE_COPY_LOCATION textureLocation =
                ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureSlice,
                                                     aspect);

            const uint64_t offset = baseCopySplit.offset + baseOffset;

            for (uint32_t i = 0; i < baseCopySplit.count; ++i) {
                const Texture2DCopySplit::CopyInfo& info = baseCopySplit.copies[i];

                // TODO(jiawei.shao@intel.com): pre-compute bufferLocation and sourceRegion as
                // members in Texture2DCopySplit::CopyInfo.
                const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
                    ComputeBufferLocationForCopyTextureRegion(texture, buffer->GetD3D12Resource(),
                                                              info.bufferSize, offset,
                                                              bufferBytesPerRow, aspect);
                const D3D12_BOX sourceRegion =
                    ComputeD3D12BoxFromOffsetAndSize(info.textureOffset, info.copySize);

                commandList->CopyTextureRegion(&bufferLocation, info.bufferOffset.x,
                                               info.bufferOffset.y, info.bufferOffset.z,
                                               &textureLocation, &sourceRegion);
            }
        }

        void RecordWriteTimestampCmd(ID3D12GraphicsCommandList* commandList,
                                     WriteTimestampCmd* cmd) {
            QuerySet* querySet = ToBackend(cmd->querySet.Get());
            ASSERT(D3D12QueryType(querySet->GetQueryType()) == D3D12_QUERY_TYPE_TIMESTAMP);
            commandList->EndQuery(querySet->GetQueryHeap(), D3D12_QUERY_TYPE_TIMESTAMP,
                                  cmd->queryIndex);
        }
    }  // anonymous namespace

    class BindGroupStateTracker : public BindGroupAndStorageBarrierTrackerBase<false, uint64_t> {
        using Base = BindGroupAndStorageBarrierTrackerBase;

      public:
        BindGroupStateTracker(Device* device)
            : BindGroupAndStorageBarrierTrackerBase(),
              mDevice(device),
              mViewAllocator(device->GetViewShaderVisibleDescriptorAllocator()),
              mSamplerAllocator(device->GetSamplerShaderVisibleDescriptorAllocator()) {
        }

        void SetInComputePass(bool inCompute_) {
            mInCompute = inCompute_;
        }

        void OnSetPipeline(PipelineBase* pipeline) {
            // Invalidate the root sampler tables previously set in the root signature.
            // This is because changing the pipeline layout also changes the root signature.
            const PipelineLayout* pipelineLayout = ToBackend(pipeline->GetLayout());
            if (mLastAppliedPipelineLayout != pipelineLayout) {
                mBoundRootSamplerTables = {};
            }

            Base::OnSetPipeline(pipeline);
        }

        MaybeError Apply(CommandRecordingContext* commandContext) {
            // Bindgroups are allocated in shader-visible descriptor heaps which are managed by a
            // ringbuffer. There can be a single shader-visible descriptor heap of each type bound
            // at any given time. This means that when we switch heaps, all other currently bound
            // bindgroups must be re-populated. Bindgroups can fail allocation gracefully which is
            // the signal to change the bounded heaps.
            // Re-populating all bindgroups after the last one fails causes duplicated allocations
            // to occur on overflow.
            // TODO(bryan.bernhart@intel.com): Consider further optimization.
            bool didCreateBindGroupViews = true;
            bool didCreateBindGroupSamplers = true;
            for (BindGroupIndex index : IterateBitSet(mDirtyBindGroups)) {
                BindGroup* group = ToBackend(mBindGroups[index]);
                didCreateBindGroupViews = group->PopulateViews(mViewAllocator);
                didCreateBindGroupSamplers = group->PopulateSamplers(mDevice, mSamplerAllocator);
                if (!didCreateBindGroupViews && !didCreateBindGroupSamplers) {
                    break;
                }
            }

            ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();

            if (!didCreateBindGroupViews || !didCreateBindGroupSamplers) {
                if (!didCreateBindGroupViews) {
                    DAWN_TRY(mViewAllocator->AllocateAndSwitchShaderVisibleHeap());
                }

                if (!didCreateBindGroupSamplers) {
                    DAWN_TRY(mSamplerAllocator->AllocateAndSwitchShaderVisibleHeap());
                }

                mDirtyBindGroupsObjectChangedOrIsDynamic |= mBindGroupLayoutsMask;
                mDirtyBindGroups |= mBindGroupLayoutsMask;

                // Must be called before applying the bindgroups.
                SetID3D12DescriptorHeaps(commandList);

                for (BindGroupIndex index : IterateBitSet(mBindGroupLayoutsMask)) {
                    BindGroup* group = ToBackend(mBindGroups[index]);
                    didCreateBindGroupViews = group->PopulateViews(mViewAllocator);
                    didCreateBindGroupSamplers =
                        group->PopulateSamplers(mDevice, mSamplerAllocator);
                    ASSERT(didCreateBindGroupViews);
                    ASSERT(didCreateBindGroupSamplers);
                }
            }

            for (BindGroupIndex index : IterateBitSet(mDirtyBindGroupsObjectChangedOrIsDynamic)) {
                BindGroup* group = ToBackend(mBindGroups[index]);
                ApplyBindGroup(commandList, ToBackend(mPipelineLayout), index, group,
                               mDynamicOffsetCounts[index], mDynamicOffsets[index].data());
            }

            if (mInCompute) {
                for (BindGroupIndex index : IterateBitSet(mBindGroupLayoutsMask)) {
                    for (BindingIndex binding : IterateBitSet(mBindingsNeedingBarrier[index])) {
                        wgpu::BindingType bindingType = mBindingTypes[index][binding];
                        switch (bindingType) {
                            case wgpu::BindingType::StorageBuffer:
                                static_cast<Buffer*>(mBindings[index][binding])
                                    ->TrackUsageAndTransitionNow(commandContext,
                                                                 wgpu::BufferUsage::Storage);
                                break;

                            case wgpu::BindingType::ReadonlyStorageTexture: {
                                TextureViewBase* view =
                                    static_cast<TextureViewBase*>(mBindings[index][binding]);
                                ToBackend(view->GetTexture())
                                    ->TrackUsageAndTransitionNow(commandContext,
                                                                 kReadonlyStorageTexture,
                                                                 view->GetSubresourceRange());
                                break;
                            }
                            case wgpu::BindingType::WriteonlyStorageTexture: {
                                TextureViewBase* view =
                                    static_cast<TextureViewBase*>(mBindings[index][binding]);
                                ToBackend(view->GetTexture())
                                    ->TrackUsageAndTransitionNow(commandContext,
                                                                 wgpu::TextureUsage::Storage,
                                                                 view->GetSubresourceRange());
                                break;
                            }
                            case wgpu::BindingType::StorageTexture:
                                // Not implemented.

                            case wgpu::BindingType::UniformBuffer:
                            case wgpu::BindingType::ReadonlyStorageBuffer:
                            case wgpu::BindingType::Sampler:
                            case wgpu::BindingType::ComparisonSampler:
                            case wgpu::BindingType::SampledTexture:
                                // Don't require barriers.

                            default:
                                UNREACHABLE();
                                break;
                        }
                    }
                }
            }
            DidApply();

            return {};
        }

        void SetID3D12DescriptorHeaps(ID3D12GraphicsCommandList* commandList) {
            ASSERT(commandList != nullptr);
            std::array<ID3D12DescriptorHeap*, 2> descriptorHeaps = {
                mViewAllocator->GetShaderVisibleHeap(), mSamplerAllocator->GetShaderVisibleHeap()};
            ASSERT(descriptorHeaps[0] != nullptr);
            ASSERT(descriptorHeaps[1] != nullptr);
            commandList->SetDescriptorHeaps(descriptorHeaps.size(), descriptorHeaps.data());
        }

      private:
        void ApplyBindGroup(ID3D12GraphicsCommandList* commandList,
                            const PipelineLayout* pipelineLayout,
                            BindGroupIndex index,
                            BindGroup* group,
                            uint32_t dynamicOffsetCountIn,
                            const uint64_t* dynamicOffsetsIn) {
            ityp::span<BindingIndex, const uint64_t> dynamicOffsets(
                dynamicOffsetsIn, BindingIndex(dynamicOffsetCountIn));
            ASSERT(dynamicOffsets.size() == group->GetLayout()->GetDynamicBufferCount());

            // Usually, the application won't set the same offsets many times,
            // so always try to apply dynamic offsets even if the offsets stay the same
            if (dynamicOffsets.size() != BindingIndex(0)) {
                // Update dynamic offsets.
                // Dynamic buffer bindings are packed at the beginning of the layout.
                for (BindingIndex bindingIndex{0}; bindingIndex < dynamicOffsets.size();
                     ++bindingIndex) {
                    const BindingInfo& bindingInfo =
                        group->GetLayout()->GetBindingInfo(bindingIndex);
                    if (bindingInfo.visibility == wgpu::ShaderStage::None) {
                        // Skip dynamic buffers that are not visible. D3D12 does not have None
                        // visibility.
                        continue;
                    }

                    uint32_t parameterIndex =
                        pipelineLayout->GetDynamicRootParameterIndex(index, bindingIndex);
                    BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);

                    // Calculate buffer locations that root descriptors links to. The location
                    // is (base buffer location + initial offset + dynamic offset)
                    uint64_t dynamicOffset = dynamicOffsets[bindingIndex];
                    uint64_t offset = binding.offset + dynamicOffset;
                    D3D12_GPU_VIRTUAL_ADDRESS bufferLocation =
                        ToBackend(binding.buffer)->GetVA() + offset;

                    switch (bindingInfo.type) {
                        case wgpu::BindingType::UniformBuffer:
                            if (mInCompute) {
                                commandList->SetComputeRootConstantBufferView(parameterIndex,
                                                                              bufferLocation);
                            } else {
                                commandList->SetGraphicsRootConstantBufferView(parameterIndex,
                                                                               bufferLocation);
                            }
                            break;
                        case wgpu::BindingType::StorageBuffer:
                            if (mInCompute) {
                                commandList->SetComputeRootUnorderedAccessView(parameterIndex,
                                                                               bufferLocation);
                            } else {
                                commandList->SetGraphicsRootUnorderedAccessView(parameterIndex,
                                                                                bufferLocation);
                            }
                            break;
                        case wgpu::BindingType::ReadonlyStorageBuffer:
                            if (mInCompute) {
                                commandList->SetComputeRootShaderResourceView(parameterIndex,
                                                                              bufferLocation);
                            } else {
                                commandList->SetGraphicsRootShaderResourceView(parameterIndex,
                                                                               bufferLocation);
                            }
                            break;
                        case wgpu::BindingType::SampledTexture:
                        case wgpu::BindingType::Sampler:
                        case wgpu::BindingType::ComparisonSampler:
                        case wgpu::BindingType::StorageTexture:
                        case wgpu::BindingType::ReadonlyStorageTexture:
                        case wgpu::BindingType::WriteonlyStorageTexture:
                            UNREACHABLE();
                            break;
                    }
                }
            }

            // It's not necessary to update descriptor tables if only the dynamic offset changed.
            if (!mDirtyBindGroups[index]) {
                return;
            }

            const uint32_t cbvUavSrvCount =
                ToBackend(group->GetLayout())->GetCbvUavSrvDescriptorCount();
            const uint32_t samplerCount =
                ToBackend(group->GetLayout())->GetSamplerDescriptorCount();

            if (cbvUavSrvCount > 0) {
                uint32_t parameterIndex = pipelineLayout->GetCbvUavSrvRootParameterIndex(index);
                const D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor = group->GetBaseViewDescriptor();
                if (mInCompute) {
                    commandList->SetComputeRootDescriptorTable(parameterIndex, baseDescriptor);
                } else {
                    commandList->SetGraphicsRootDescriptorTable(parameterIndex, baseDescriptor);
                }
            }

            if (samplerCount > 0) {
                uint32_t parameterIndex = pipelineLayout->GetSamplerRootParameterIndex(index);
                const D3D12_GPU_DESCRIPTOR_HANDLE baseDescriptor =
                    group->GetBaseSamplerDescriptor();
                // Check if the group requires its sampler table to be set in the pipeline.
                // This because sampler heap allocations could be cached and use the same table.
                if (mBoundRootSamplerTables[index].ptr != baseDescriptor.ptr) {
                    if (mInCompute) {
                        commandList->SetComputeRootDescriptorTable(parameterIndex, baseDescriptor);
                    } else {
                        commandList->SetGraphicsRootDescriptorTable(parameterIndex, baseDescriptor);
                    }

                    mBoundRootSamplerTables[index] = baseDescriptor;
                }
            }
        }

        Device* mDevice;

        bool mInCompute = false;

        ityp::array<BindGroupIndex, D3D12_GPU_DESCRIPTOR_HANDLE, kMaxBindGroups>
            mBoundRootSamplerTables = {};

        ShaderVisibleDescriptorAllocator* mViewAllocator;
        ShaderVisibleDescriptorAllocator* mSamplerAllocator;
    };

    namespace {
        class VertexBufferTracker {
          public:
            void OnSetVertexBuffer(uint32_t slot, Buffer* buffer, uint64_t offset, uint64_t size) {
                mStartSlot = std::min(mStartSlot, slot);
                mEndSlot = std::max(mEndSlot, slot + 1);

                auto* d3d12BufferView = &mD3D12BufferViews[slot];
                d3d12BufferView->BufferLocation = buffer->GetVA() + offset;
                d3d12BufferView->SizeInBytes = size;
                // The bufferView stride is set based on the vertex state before a draw.
            }

            void Apply(ID3D12GraphicsCommandList* commandList,
                       const RenderPipeline* renderPipeline) {
                ASSERT(renderPipeline != nullptr);

                std::bitset<kMaxVertexBuffers> vertexBufferSlotsUsed =
                    renderPipeline->GetVertexBufferSlotsUsed();

                uint32_t startSlot = mStartSlot;
                uint32_t endSlot = mEndSlot;

                // If the vertex state has changed, we need to update the StrideInBytes
                // for the D3D12 buffer views. We also need to extend the dirty range to
                // touch all these slots because the stride may have changed.
                if (mLastAppliedRenderPipeline != renderPipeline) {
                    mLastAppliedRenderPipeline = renderPipeline;

                    for (uint32_t slot : IterateBitSet(vertexBufferSlotsUsed)) {
                        startSlot = std::min(startSlot, slot);
                        endSlot = std::max(endSlot, slot + 1);
                        mD3D12BufferViews[slot].StrideInBytes =
                            renderPipeline->GetVertexBuffer(slot).arrayStride;
                    }
                }

                if (endSlot <= startSlot) {
                    return;
                }

                // mD3D12BufferViews is kept up to date with the most recent data passed
                // to SetVertexBuffer. This makes it correct to only track the start
                // and end of the dirty range. When Apply is called,
                // we will at worst set non-dirty vertex buffers in duplicate.
                uint32_t count = endSlot - startSlot;
                commandList->IASetVertexBuffers(startSlot, count, &mD3D12BufferViews[startSlot]);

                mStartSlot = kMaxVertexBuffers;
                mEndSlot = 0;
            }

          private:
            // startSlot and endSlot indicate the range of dirty vertex buffers.
            // If there are multiple calls to SetVertexBuffer, the start and end
            // represent the union of the dirty ranges (the union may have non-dirty
            // data in the middle of the range).
            const RenderPipeline* mLastAppliedRenderPipeline = nullptr;
            uint32_t mStartSlot = kMaxVertexBuffers;
            uint32_t mEndSlot = 0;
            std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexBuffers> mD3D12BufferViews = {};
        };

        class IndexBufferTracker {
          public:
            void OnSetIndexBuffer(Buffer* buffer, wgpu::IndexFormat format, uint64_t offset,
                                  uint64_t size) {
                mD3D12BufferView.BufferLocation = buffer->GetVA() + offset;
                mD3D12BufferView.SizeInBytes = size;
                mBufferIndexFormat = DXGIIndexFormat(format);

                // We don't need to dirty the state unless BufferLocation or SizeInBytes
                // change, but most of the time this will always be the case.
                mLastAppliedIndexFormat = DXGI_FORMAT_UNKNOWN;
            }

            void OnSetPipeline(const RenderPipelineBase* pipeline) {
                mPipelineIndexFormat =
                    DXGIIndexFormat(pipeline->GetVertexStateDescriptor()->indexFormat);
            }

            void Apply(ID3D12GraphicsCommandList* commandList) {
                DXGI_FORMAT newIndexFormat = mBufferIndexFormat;
                if (newIndexFormat == DXGI_FORMAT_UNKNOWN) {
                    newIndexFormat = mPipelineIndexFormat;
                }

                if (newIndexFormat != mLastAppliedIndexFormat) {
                    mD3D12BufferView.Format = newIndexFormat;
                    commandList->IASetIndexBuffer(&mD3D12BufferView);
                    mLastAppliedIndexFormat = newIndexFormat;
                }
            }

          private:
            DXGI_FORMAT mBufferIndexFormat = DXGI_FORMAT_UNKNOWN;
            DXGI_FORMAT mPipelineIndexFormat = DXGI_FORMAT_UNKNOWN;
            DXGI_FORMAT mLastAppliedIndexFormat = DXGI_FORMAT_UNKNOWN;
            D3D12_INDEX_BUFFER_VIEW mD3D12BufferView = {};
        };

        void ResolveMultisampledRenderPass(CommandRecordingContext* commandContext,
                                           BeginRenderPassCmd* renderPass) {
            ASSERT(renderPass != nullptr);

            for (uint32_t i :
                 IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
                TextureViewBase* resolveTarget =
                    renderPass->colorAttachments[i].resolveTarget.Get();
                if (resolveTarget == nullptr) {
                    continue;
                }

                TextureViewBase* colorView = renderPass->colorAttachments[i].view.Get();
                Texture* colorTexture = ToBackend(colorView->GetTexture());
                Texture* resolveTexture = ToBackend(resolveTarget->GetTexture());

                // Transition the usages of the color attachment and resolve target.
                colorTexture->TrackUsageAndTransitionNow(commandContext,
                                                         D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
                                                         colorView->GetSubresourceRange());
                resolveTexture->TrackUsageAndTransitionNow(commandContext,
                                                           D3D12_RESOURCE_STATE_RESOLVE_DEST,
                                                           resolveTarget->GetSubresourceRange());

                // Do MSAA resolve with ResolveSubResource().
                ID3D12Resource* colorTextureHandle = colorTexture->GetD3D12Resource();
                ID3D12Resource* resolveTextureHandle = resolveTexture->GetD3D12Resource();
                const uint32_t resolveTextureSubresourceIndex = resolveTexture->GetSubresourceIndex(
                    resolveTarget->GetBaseMipLevel(), resolveTarget->GetBaseArrayLayer(),
                    Aspect::Color);
                constexpr uint32_t kColorTextureSubresourceIndex = 0;
                commandContext->GetCommandList()->ResolveSubresource(
                    resolveTextureHandle, resolveTextureSubresourceIndex, colorTextureHandle,
                    kColorTextureSubresourceIndex, colorTexture->GetD3D12Format());
            }
        }

    }  // anonymous namespace

    CommandBuffer::CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor)
        : CommandBufferBase(encoder, descriptor) {
    }

    MaybeError CommandBuffer::RecordCommands(CommandRecordingContext* commandContext) {
        Device* device = ToBackend(GetDevice());
        BindGroupStateTracker bindingTracker(device);

        ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();

        // Make sure we use the correct descriptors for this command list. Could be done once per
        // actual command list but here is ok because there should be few command buffers.
        bindingTracker.SetID3D12DescriptorHeaps(commandList);

        // Records the necessary barriers for the resource usage pre-computed by the frontend
        auto PrepareResourcesForSubmission = [](CommandRecordingContext* commandContext,
                                                const PassResourceUsage& usages) -> bool {
            std::vector<D3D12_RESOURCE_BARRIER> barriers;

            ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();

            wgpu::BufferUsage bufferUsages = wgpu::BufferUsage::None;

            for (size_t i = 0; i < usages.buffers.size(); ++i) {
                Buffer* buffer = ToBackend(usages.buffers[i]);

                // TODO(jiawei.shao@intel.com): clear storage buffers with
                // ClearUnorderedAccessView*().
                buffer->GetDevice()->ConsumedError(buffer->EnsureDataInitialized(commandContext));

                D3D12_RESOURCE_BARRIER barrier;
                if (buffer->TrackUsageAndGetResourceBarrier(commandContext, &barrier,
                                                            usages.bufferUsages[i])) {
                    barriers.push_back(barrier);
                }
                bufferUsages |= usages.bufferUsages[i];
            }

            for (size_t i = 0; i < usages.textures.size(); ++i) {
                Texture* texture = ToBackend(usages.textures[i]);
                // Clear textures that are not output attachments. Output attachments will be
                // cleared during record render pass if the texture subresource has not been
                // initialized before the render pass.
                if (!(usages.textureUsages[i].usage & wgpu::TextureUsage::OutputAttachment)) {
                    texture->EnsureSubresourceContentInitialized(commandContext,
                                                                 texture->GetAllSubresources());
                }
            }

            wgpu::TextureUsage textureUsages = wgpu::TextureUsage::None;

            for (size_t i = 0; i < usages.textures.size(); ++i) {
                ToBackend(usages.textures[i])
                    ->TrackUsageAndGetResourceBarrierForPass(commandContext, &barriers,
                                                             usages.textureUsages[i]);
                textureUsages |= usages.textureUsages[i].usage;
            }

            if (barriers.size()) {
                commandList->ResourceBarrier(barriers.size(), barriers.data());
            }

            return (bufferUsages & wgpu::BufferUsage::Storage ||
                    textureUsages & wgpu::TextureUsage::Storage);
        };

        const std::vector<PassResourceUsage>& passResourceUsages = GetResourceUsages().perPass;
        uint32_t nextPassNumber = 0;

        Command type;
        while (mCommands.NextCommandId(&type)) {
            switch (type) {
                case Command::BeginComputePass: {
                    mCommands.NextCommand<BeginComputePassCmd>();

                    PrepareResourcesForSubmission(commandContext,
                                                  passResourceUsages[nextPassNumber]);
                    bindingTracker.SetInComputePass(true);
                    DAWN_TRY(RecordComputePass(commandContext, &bindingTracker));

                    nextPassNumber++;
                    break;
                }

                case Command::BeginRenderPass: {
                    BeginRenderPassCmd* beginRenderPassCmd =
                        mCommands.NextCommand<BeginRenderPassCmd>();

                    const bool passHasUAV = PrepareResourcesForSubmission(
                        commandContext, passResourceUsages[nextPassNumber]);
                    bindingTracker.SetInComputePass(false);

                    LazyClearRenderPassAttachments(beginRenderPassCmd);
                    DAWN_TRY(RecordRenderPass(commandContext, &bindingTracker, beginRenderPassCmd,
                                              passHasUAV));

                    nextPassNumber++;
                    break;
                }

                case Command::CopyBufferToBuffer: {
                    CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
                    Buffer* srcBuffer = ToBackend(copy->source.Get());
                    Buffer* dstBuffer = ToBackend(copy->destination.Get());

                    DAWN_TRY(srcBuffer->EnsureDataInitialized(commandContext));
                    DAWN_TRY(dstBuffer->EnsureDataInitializedAsDestination(
                        commandContext, copy->destinationOffset, copy->size));

                    srcBuffer->TrackUsageAndTransitionNow(commandContext,
                                                          wgpu::BufferUsage::CopySrc);
                    dstBuffer->TrackUsageAndTransitionNow(commandContext,
                                                          wgpu::BufferUsage::CopyDst);

                    commandList->CopyBufferRegion(
                        dstBuffer->GetD3D12Resource(), copy->destinationOffset,
                        srcBuffer->GetD3D12Resource(), copy->sourceOffset, copy->size);
                    break;
                }

                case Command::CopyBufferToTexture: {
                    CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
                    Buffer* buffer = ToBackend(copy->source.buffer.Get());
                    Texture* texture = ToBackend(copy->destination.texture.Get());

                    DAWN_TRY(buffer->EnsureDataInitialized(commandContext));

                    ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
                    SubresourceRange subresources =
                        GetSubresourcesAffectedByCopy(copy->destination, copy->copySize);

                    if (IsCompleteSubresourceCopiedTo(texture, copy->copySize,
                                                      copy->destination.mipLevel)) {
                        texture->SetIsSubresourceContentInitialized(true, subresources);
                    } else {
                        texture->EnsureSubresourceContentInitialized(commandContext, subresources);
                    }

                    buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopySrc);
                    texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopyDst,
                                                        subresources);

                    // compute the copySplits and record the CopyTextureRegion commands
                    CopyBufferToTextureWithCopySplit(
                        commandContext, copy->destination, copy->copySize, texture,
                        buffer->GetD3D12Resource(), copy->source.offset, copy->source.bytesPerRow,
                        copy->source.rowsPerImage, subresources.aspects);

                    break;
                }

                case Command::CopyTextureToBuffer: {
                    CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
                    Texture* texture = ToBackend(copy->source.texture.Get());
                    Buffer* buffer = ToBackend(copy->destination.buffer.Get());

                    DAWN_TRY(buffer->EnsureDataInitializedAsDestination(commandContext, copy));

                    ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
                    SubresourceRange subresources =
                        GetSubresourcesAffectedByCopy(copy->source, copy->copySize);

                    texture->EnsureSubresourceContentInitialized(commandContext, subresources);

                    texture->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc,
                                                        subresources);
                    buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopyDst);

                    const TexelBlockInfo& blockInfo =
                        texture->GetFormat().GetTexelBlockInfo(copy->source.aspect);

                    // See comments around ComputeTextureCopySplits() for more details.
                    const TextureCopySplits copySplits = ComputeTextureCopySplits(
                        copy->source.origin, copy->copySize, blockInfo, copy->destination.offset,
                        copy->destination.bytesPerRow, copy->destination.rowsPerImage);

                    const uint64_t bytesPerSlice =
                        copy->destination.bytesPerRow *
                        (copy->destination.rowsPerImage / blockInfo.blockHeight);

                    // copySplits.copies2D[1] is always calculated for the second copy slice with
                    // extra "bytesPerSlice" copy offset compared with the first copy slice. So
                    // here we use an array bufferOffsetsForNextSlice to record the extra offsets
                    // for each copy slice: bufferOffsetsForNextSlice[0] is the extra offset for
                    // the next copy slice that uses copySplits.copies2D[0], and
                    // bufferOffsetsForNextSlice[1] is the extra offset for the next copy slice
                    // that uses copySplits.copies2D[1].
                    std::array<uint64_t, TextureCopySplits::kMaxTextureCopySplits>
                        bufferOffsetsForNextSlice = {{0u, 0u}};
                    for (uint32_t copySlice = 0; copySlice < copy->copySize.depth; ++copySlice) {
                        const uint32_t splitIndex = copySlice % copySplits.copies2D.size();

                        const Texture2DCopySplit& copySplitPerLayerBase =
                            copySplits.copies2D[splitIndex];
                        const uint64_t bufferOffsetForNextSlice =
                            bufferOffsetsForNextSlice[splitIndex];
                        const uint32_t copyTextureLayer = copySlice + copy->source.origin.z;

                        RecordCopyTextureToBufferFromTextureCopySplit(
                            commandList, copySplitPerLayerBase, buffer, bufferOffsetForNextSlice,
                            copy->destination.bytesPerRow, texture, copy->source.mipLevel,
                            copyTextureLayer, subresources.aspects);

                        bufferOffsetsForNextSlice[splitIndex] +=
                            bytesPerSlice * copySplits.copies2D.size();
                    }

                    break;
                }

                case Command::CopyTextureToTexture: {
                    CopyTextureToTextureCmd* copy =
                        mCommands.NextCommand<CopyTextureToTextureCmd>();

                    Texture* source = ToBackend(copy->source.texture.Get());
                    Texture* destination = ToBackend(copy->destination.texture.Get());

                    SubresourceRange srcRange =
                        GetSubresourcesAffectedByCopy(copy->source, copy->copySize);
                    SubresourceRange dstRange =
                        GetSubresourcesAffectedByCopy(copy->destination, copy->copySize);

                    source->EnsureSubresourceContentInitialized(commandContext, srcRange);
                    if (IsCompleteSubresourceCopiedTo(destination, copy->copySize,
                                                      copy->destination.mipLevel)) {
                        destination->SetIsSubresourceContentInitialized(true, dstRange);
                    } else {
                        destination->EnsureSubresourceContentInitialized(commandContext, dstRange);
                    }

                    if (copy->source.texture.Get() == copy->destination.texture.Get() &&
                        copy->source.mipLevel == copy->destination.mipLevel) {
                        // When there are overlapped subresources, the layout of the overlapped
                        // subresources should all be COMMON instead of what we set now. Currently
                        // it is not allowed to copy with overlapped subresources, but we still
                        // add the ASSERT here as a reminder for this possible misuse.
                        ASSERT(!IsRangeOverlapped(copy->source.origin.z, copy->destination.origin.z,
                                                  copy->copySize.depth));
                    }
                    source->TrackUsageAndTransitionNow(commandContext, wgpu::TextureUsage::CopySrc,
                                                       srcRange);
                    destination->TrackUsageAndTransitionNow(commandContext,
                                                            wgpu::TextureUsage::CopyDst, dstRange);

                    ASSERT(srcRange.aspects == dstRange.aspects);
                    if (CanUseCopyResource(copy->source, copy->destination, copy->copySize)) {
                        commandList->CopyResource(destination->GetD3D12Resource(),
                                                  source->GetD3D12Resource());
                    } else {
                        // TODO(jiawei.shao@intel.com): support copying with 1D and 3D textures.
                        ASSERT(source->GetDimension() == wgpu::TextureDimension::e2D &&
                               destination->GetDimension() == wgpu::TextureDimension::e2D);
                        const dawn_native::Extent3D copyExtentOneSlice = {
                            copy->copySize.width, copy->copySize.height, 1u};

                        for (Aspect aspect : IterateEnumMask(srcRange.aspects)) {
                            for (uint32_t slice = 0; slice < copy->copySize.depth; ++slice) {
                                D3D12_TEXTURE_COPY_LOCATION srcLocation =
                                    ComputeTextureCopyLocationForTexture(
                                        source, copy->source.mipLevel,
                                        copy->source.origin.z + slice, aspect);

                                D3D12_TEXTURE_COPY_LOCATION dstLocation =
                                    ComputeTextureCopyLocationForTexture(
                                        destination, copy->destination.mipLevel,
                                        copy->destination.origin.z + slice, aspect);

                                Origin3D sourceOriginInSubresource = copy->source.origin;
                                sourceOriginInSubresource.z = 0;
                                D3D12_BOX sourceRegion = ComputeD3D12BoxFromOffsetAndSize(
                                    sourceOriginInSubresource, copyExtentOneSlice);

                                commandList->CopyTextureRegion(
                                    &dstLocation, copy->destination.origin.x,
                                    copy->destination.origin.y, 0, &srcLocation, &sourceRegion);
                            }
                        }
                    }
                    break;
                }

                case Command::ResolveQuerySet: {
                    ResolveQuerySetCmd* cmd = mCommands.NextCommand<ResolveQuerySetCmd>();
                    QuerySet* querySet = ToBackend(cmd->querySet.Get());
                    Buffer* destination = ToBackend(cmd->destination.Get());

                    commandList->ResolveQueryData(
                        querySet->GetQueryHeap(), D3D12QueryType(querySet->GetQueryType()),
                        cmd->firstQuery, cmd->queryCount, destination->GetD3D12Resource(),
                        cmd->destinationOffset);

                    // TODO(hao.x.li@intel.com): Add compute shader to convert the query result
                    // (ticks) to timestamp (ns)

                    break;
                }

                case Command::WriteTimestamp: {
                    WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();

                    RecordWriteTimestampCmd(commandList, cmd);
                    break;
                }

                default: {
                    UNREACHABLE();
                    break;
                }
            }
        }

        return {};
    }

    MaybeError CommandBuffer::RecordComputePass(CommandRecordingContext* commandContext,
                                                BindGroupStateTracker* bindingTracker) {
        PipelineLayout* lastLayout = nullptr;
        ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();

        Command type;
        while (mCommands.NextCommandId(&type)) {
            switch (type) {
                case Command::Dispatch: {
                    DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();

                    DAWN_TRY(bindingTracker->Apply(commandContext));
                    commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z);
                    break;
                }

                case Command::DispatchIndirect: {
                    DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>();

                    DAWN_TRY(bindingTracker->Apply(commandContext));
                    Buffer* buffer = ToBackend(dispatch->indirectBuffer.Get());
                    ComPtr<ID3D12CommandSignature> signature =
                        ToBackend(GetDevice())->GetDispatchIndirectSignature();
                    commandList->ExecuteIndirect(signature.Get(), 1, buffer->GetD3D12Resource(),
                                                 dispatch->indirectOffset, nullptr, 0);
                    break;
                }

                case Command::EndComputePass: {
                    mCommands.NextCommand<EndComputePassCmd>();
                    return {};
                }

                case Command::SetComputePipeline: {
                    SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>();
                    ComputePipeline* pipeline = ToBackend(cmd->pipeline).Get();
                    PipelineLayout* layout = ToBackend(pipeline->GetLayout());

                    commandList->SetComputeRootSignature(layout->GetRootSignature());
                    commandList->SetPipelineState(pipeline->GetPipelineState());

                    bindingTracker->OnSetPipeline(pipeline);

                    lastLayout = layout;
                    break;
                }

                case Command::SetBindGroup: {
                    SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
                    BindGroup* group = ToBackend(cmd->group.Get());
                    uint32_t* dynamicOffsets = nullptr;

                    if (cmd->dynamicOffsetCount > 0) {
                        dynamicOffsets = mCommands.NextData<uint32_t>(cmd->dynamicOffsetCount);
                    }

                    bindingTracker->OnSetBindGroup(cmd->index, group, cmd->dynamicOffsetCount,
                                                   dynamicOffsets);
                    break;
                }

                case Command::InsertDebugMarker: {
                    InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
                    const char* label = mCommands.NextData<char>(cmd->length + 1);

                    if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
                        // PIX color is 1 byte per channel in ARGB format
                        constexpr uint64_t kPIXBlackColor = 0xff000000;
                        ToBackend(GetDevice())
                            ->GetFunctions()
                            ->pixSetMarkerOnCommandList(commandList, kPIXBlackColor, label);
                    }
                    break;
                }

                case Command::PopDebugGroup: {
                    mCommands.NextCommand<PopDebugGroupCmd>();

                    if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
                        ToBackend(GetDevice())
                            ->GetFunctions()
                            ->pixEndEventOnCommandList(commandList);
                    }
                    break;
                }

                case Command::PushDebugGroup: {
                    PushDebugGroupCmd* cmd = mCommands.NextCommand<PushDebugGroupCmd>();
                    const char* label = mCommands.NextData<char>(cmd->length + 1);

                    if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
                        // PIX color is 1 byte per channel in ARGB format
                        constexpr uint64_t kPIXBlackColor = 0xff000000;
                        ToBackend(GetDevice())
                            ->GetFunctions()
                            ->pixBeginEventOnCommandList(commandList, kPIXBlackColor, label);
                    }
                    break;
                }

                case Command::WriteTimestamp: {
                    WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();

                    RecordWriteTimestampCmd(commandList, cmd);
                    break;
                }

                default: {
                    UNREACHABLE();
                    break;
                }
            }
        }

        return {};
    }

    MaybeError CommandBuffer::SetupRenderPass(CommandRecordingContext* commandContext,
                                              BeginRenderPassCmd* renderPass,
                                              RenderPassBuilder* renderPassBuilder) {
        Device* device = ToBackend(GetDevice());

        for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
            RenderPassColorAttachmentInfo& attachmentInfo = renderPass->colorAttachments[i];
            TextureView* view = ToBackend(attachmentInfo.view.Get());

            // Set view attachment.
            CPUDescriptorHeapAllocation rtvAllocation;
            DAWN_TRY_ASSIGN(
                rtvAllocation,
                device->GetRenderTargetViewAllocator()->AllocateTransientCPUDescriptors());

            const D3D12_RENDER_TARGET_VIEW_DESC viewDesc = view->GetRTVDescriptor();
            const D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor = rtvAllocation.GetBaseDescriptor();

            device->GetD3D12Device()->CreateRenderTargetView(
                ToBackend(view->GetTexture())->GetD3D12Resource(), &viewDesc, baseDescriptor);

            renderPassBuilder->SetRenderTargetView(i, baseDescriptor);

            // Set color load operation.
            renderPassBuilder->SetRenderTargetBeginningAccess(
                i, attachmentInfo.loadOp, attachmentInfo.clearColor, view->GetD3D12Format());

            // Set color store operation.
            if (attachmentInfo.resolveTarget.Get() != nullptr) {
                TextureView* resolveDestinationView = ToBackend(attachmentInfo.resolveTarget.Get());
                Texture* resolveDestinationTexture =
                    ToBackend(resolveDestinationView->GetTexture());

                resolveDestinationTexture->TrackUsageAndTransitionNow(
                    commandContext, D3D12_RESOURCE_STATE_RESOLVE_DEST,
                    resolveDestinationView->GetSubresourceRange());

                renderPassBuilder->SetRenderTargetEndingAccessResolve(i, attachmentInfo.storeOp,
                                                                      view, resolveDestinationView);
            } else {
                renderPassBuilder->SetRenderTargetEndingAccess(i, attachmentInfo.storeOp);
            }
        }

        if (renderPass->attachmentState->HasDepthStencilAttachment()) {
            RenderPassDepthStencilAttachmentInfo& attachmentInfo =
                renderPass->depthStencilAttachment;
            TextureView* view = ToBackend(renderPass->depthStencilAttachment.view.Get());

            // Set depth attachment.
            CPUDescriptorHeapAllocation dsvAllocation;
            DAWN_TRY_ASSIGN(
                dsvAllocation,
                device->GetDepthStencilViewAllocator()->AllocateTransientCPUDescriptors());

            const D3D12_DEPTH_STENCIL_VIEW_DESC viewDesc = view->GetDSVDescriptor();
            const D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor = dsvAllocation.GetBaseDescriptor();

            device->GetD3D12Device()->CreateDepthStencilView(
                ToBackend(view->GetTexture())->GetD3D12Resource(), &viewDesc, baseDescriptor);

            renderPassBuilder->SetDepthStencilView(baseDescriptor);

            const bool hasDepth = view->GetTexture()->GetFormat().HasDepth();
            const bool hasStencil = view->GetTexture()->GetFormat().HasStencil();

            // Set depth/stencil load operations.
            if (hasDepth) {
                renderPassBuilder->SetDepthAccess(
                    attachmentInfo.depthLoadOp, attachmentInfo.depthStoreOp,
                    attachmentInfo.clearDepth, view->GetD3D12Format());
            } else {
                renderPassBuilder->SetDepthNoAccess();
            }

            if (hasStencil) {
                renderPassBuilder->SetStencilAccess(
                    attachmentInfo.stencilLoadOp, attachmentInfo.stencilStoreOp,
                    attachmentInfo.clearStencil, view->GetD3D12Format());
            } else {
                renderPassBuilder->SetStencilNoAccess();
            }

        } else {
            renderPassBuilder->SetDepthStencilNoAccess();
        }

        return {};
    }

    void CommandBuffer::EmulateBeginRenderPass(CommandRecordingContext* commandContext,
                                               const RenderPassBuilder* renderPassBuilder) const {
        ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();

        // Clear framebuffer attachments as needed.
        {
            for (uint32_t i = 0; i < renderPassBuilder->GetColorAttachmentCount(); i++) {
                // Load op - color
                if (renderPassBuilder->GetRenderPassRenderTargetDescriptors()[i]
                        .BeginningAccess.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) {
                    commandList->ClearRenderTargetView(
                        renderPassBuilder->GetRenderPassRenderTargetDescriptors()[i].cpuDescriptor,
                        renderPassBuilder->GetRenderPassRenderTargetDescriptors()[i]
                            .BeginningAccess.Clear.ClearValue.Color,
                        0, nullptr);
                }
            }

            if (renderPassBuilder->HasDepth()) {
                D3D12_CLEAR_FLAGS clearFlags = {};
                float depthClear = 0.0f;
                uint8_t stencilClear = 0u;

                if (renderPassBuilder->GetRenderPassDepthStencilDescriptor()
                        ->DepthBeginningAccess.Type ==
                    D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) {
                    clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
                    depthClear = renderPassBuilder->GetRenderPassDepthStencilDescriptor()
                                     ->DepthBeginningAccess.Clear.ClearValue.DepthStencil.Depth;
                }
                if (renderPassBuilder->GetRenderPassDepthStencilDescriptor()
                        ->StencilBeginningAccess.Type ==
                    D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR) {
                    clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
                    stencilClear =
                        renderPassBuilder->GetRenderPassDepthStencilDescriptor()
                            ->StencilBeginningAccess.Clear.ClearValue.DepthStencil.Stencil;
                }

                // TODO(kainino@chromium.org): investigate: should the Dawn clear
                // stencil type be uint8_t?
                if (clearFlags) {
                    commandList->ClearDepthStencilView(
                        renderPassBuilder->GetRenderPassDepthStencilDescriptor()->cpuDescriptor,
                        clearFlags, depthClear, stencilClear, 0, nullptr);
                }
            }
        }

        commandList->OMSetRenderTargets(
            renderPassBuilder->GetColorAttachmentCount(), renderPassBuilder->GetRenderTargetViews(),
            FALSE,
            renderPassBuilder->HasDepth()
                ? &renderPassBuilder->GetRenderPassDepthStencilDescriptor()->cpuDescriptor
                : nullptr);
    }

    MaybeError CommandBuffer::RecordRenderPass(CommandRecordingContext* commandContext,
                                               BindGroupStateTracker* bindingTracker,
                                               BeginRenderPassCmd* renderPass,
                                               const bool passHasUAV) {
        Device* device = ToBackend(GetDevice());
        const bool useRenderPass = device->IsToggleEnabled(Toggle::UseD3D12RenderPass);

        // renderPassBuilder must be scoped to RecordRenderPass because any underlying
        // D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS structs must remain
        // valid until after EndRenderPass() has been called.
        RenderPassBuilder renderPassBuilder(passHasUAV);

        DAWN_TRY(SetupRenderPass(commandContext, renderPass, &renderPassBuilder));

        // Use D3D12's native render pass API if it's available, otherwise emulate the
        // beginning and ending access operations.
        if (useRenderPass) {
            commandContext->GetCommandList4()->BeginRenderPass(
                renderPassBuilder.GetColorAttachmentCount(),
                renderPassBuilder.GetRenderPassRenderTargetDescriptors(),
                renderPassBuilder.HasDepth()
                    ? renderPassBuilder.GetRenderPassDepthStencilDescriptor()
                    : nullptr,
                renderPassBuilder.GetRenderPassFlags());
        } else {
            EmulateBeginRenderPass(commandContext, &renderPassBuilder);
        }

        ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();

        // Set up default dynamic state
        {
            uint32_t width = renderPass->width;
            uint32_t height = renderPass->height;
            D3D12_VIEWPORT viewport = {
                0.f, 0.f, static_cast<float>(width), static_cast<float>(height), 0.f, 1.f};
            D3D12_RECT scissorRect = {0, 0, static_cast<long>(width), static_cast<long>(height)};
            commandList->RSSetViewports(1, &viewport);
            commandList->RSSetScissorRects(1, &scissorRect);

            static constexpr std::array<float, 4> defaultBlendFactor = {0, 0, 0, 0};
            commandList->OMSetBlendFactor(&defaultBlendFactor[0]);
        }

        RenderPipeline* lastPipeline = nullptr;
        PipelineLayout* lastLayout = nullptr;
        VertexBufferTracker vertexBufferTracker = {};
        IndexBufferTracker indexBufferTracker = {};

        auto EncodeRenderBundleCommand = [&](CommandIterator* iter, Command type) -> MaybeError {
            switch (type) {
                case Command::Draw: {
                    DrawCmd* draw = iter->NextCommand<DrawCmd>();

                    DAWN_TRY(bindingTracker->Apply(commandContext));
                    vertexBufferTracker.Apply(commandList, lastPipeline);
                    commandList->DrawInstanced(draw->vertexCount, draw->instanceCount,
                                               draw->firstVertex, draw->firstInstance);
                    break;
                }

                case Command::DrawIndexed: {
                    DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();

                    DAWN_TRY(bindingTracker->Apply(commandContext));
                    indexBufferTracker.Apply(commandList);
                    vertexBufferTracker.Apply(commandList, lastPipeline);
                    commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
                                                      draw->firstIndex, draw->baseVertex,
                                                      draw->firstInstance);
                    break;
                }

                case Command::DrawIndirect: {
                    DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();

                    DAWN_TRY(bindingTracker->Apply(commandContext));
                    vertexBufferTracker.Apply(commandList, lastPipeline);
                    Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
                    ComPtr<ID3D12CommandSignature> signature =
                        ToBackend(GetDevice())->GetDrawIndirectSignature();
                    commandList->ExecuteIndirect(signature.Get(), 1, buffer->GetD3D12Resource(),
                                                 draw->indirectOffset, nullptr, 0);
                    break;
                }

                case Command::DrawIndexedIndirect: {
                    DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();

                    DAWN_TRY(bindingTracker->Apply(commandContext));
                    indexBufferTracker.Apply(commandList);
                    vertexBufferTracker.Apply(commandList, lastPipeline);
                    Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
                    ComPtr<ID3D12CommandSignature> signature =
                        ToBackend(GetDevice())->GetDrawIndexedIndirectSignature();
                    commandList->ExecuteIndirect(signature.Get(), 1, buffer->GetD3D12Resource(),
                                                 draw->indirectOffset, nullptr, 0);
                    break;
                }

                case Command::InsertDebugMarker: {
                    InsertDebugMarkerCmd* cmd = iter->NextCommand<InsertDebugMarkerCmd>();
                    const char* label = iter->NextData<char>(cmd->length + 1);

                    if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
                        // PIX color is 1 byte per channel in ARGB format
                        constexpr uint64_t kPIXBlackColor = 0xff000000;
                        ToBackend(GetDevice())
                            ->GetFunctions()
                            ->pixSetMarkerOnCommandList(commandList, kPIXBlackColor, label);
                    }
                    break;
                }

                case Command::PopDebugGroup: {
                    iter->NextCommand<PopDebugGroupCmd>();

                    if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
                        ToBackend(GetDevice())
                            ->GetFunctions()
                            ->pixEndEventOnCommandList(commandList);
                    }
                    break;
                }

                case Command::PushDebugGroup: {
                    PushDebugGroupCmd* cmd = iter->NextCommand<PushDebugGroupCmd>();
                    const char* label = iter->NextData<char>(cmd->length + 1);

                    if (ToBackend(GetDevice())->GetFunctions()->IsPIXEventRuntimeLoaded()) {
                        // PIX color is 1 byte per channel in ARGB format
                        constexpr uint64_t kPIXBlackColor = 0xff000000;
                        ToBackend(GetDevice())
                            ->GetFunctions()
                            ->pixBeginEventOnCommandList(commandList, kPIXBlackColor, label);
                    }
                    break;
                }

                case Command::SetRenderPipeline: {
                    SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
                    RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
                    PipelineLayout* layout = ToBackend(pipeline->GetLayout());

                    commandList->SetGraphicsRootSignature(layout->GetRootSignature());
                    commandList->SetPipelineState(pipeline->GetPipelineState());
                    commandList->IASetPrimitiveTopology(pipeline->GetD3D12PrimitiveTopology());

                    bindingTracker->OnSetPipeline(pipeline);
                    indexBufferTracker.OnSetPipeline(pipeline);

                    lastPipeline = pipeline;
                    lastLayout = layout;
                    break;
                }

                case Command::SetBindGroup: {
                    SetBindGroupCmd* cmd = iter->NextCommand<SetBindGroupCmd>();
                    BindGroup* group = ToBackend(cmd->group.Get());
                    uint32_t* dynamicOffsets = nullptr;

                    if (cmd->dynamicOffsetCount > 0) {
                        dynamicOffsets = iter->NextData<uint32_t>(cmd->dynamicOffsetCount);
                    }

                    bindingTracker->OnSetBindGroup(cmd->index, group, cmd->dynamicOffsetCount,
                                                   dynamicOffsets);
                    break;
                }

                case Command::SetIndexBuffer: {
                    SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();

                    indexBufferTracker.OnSetIndexBuffer(ToBackend(cmd->buffer.Get()), cmd->format,
                                                        cmd->offset, cmd->size);
                    break;
                }

                case Command::SetVertexBuffer: {
                    SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();

                    vertexBufferTracker.OnSetVertexBuffer(cmd->slot, ToBackend(cmd->buffer.Get()),
                                                          cmd->offset, cmd->size);
                    break;
                }

                default:
                    UNREACHABLE();
                    break;
            }
            return {};
        };

        Command type;
        while (mCommands.NextCommandId(&type)) {
            switch (type) {
                case Command::EndRenderPass: {
                    mCommands.NextCommand<EndRenderPassCmd>();
                    if (useRenderPass) {
                        commandContext->GetCommandList4()->EndRenderPass();
                    } else if (renderPass->attachmentState->GetSampleCount() > 1) {
                        ResolveMultisampledRenderPass(commandContext, renderPass);
                    }
                    return {};
                }

                case Command::SetStencilReference: {
                    SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();

                    commandList->OMSetStencilRef(cmd->reference);
                    break;
                }

                case Command::SetViewport: {
                    SetViewportCmd* cmd = mCommands.NextCommand<SetViewportCmd>();
                    D3D12_VIEWPORT viewport;
                    viewport.TopLeftX = cmd->x;
                    viewport.TopLeftY = cmd->y;
                    viewport.Width = cmd->width;
                    viewport.Height = cmd->height;
                    viewport.MinDepth = cmd->minDepth;
                    viewport.MaxDepth = cmd->maxDepth;

                    commandList->RSSetViewports(1, &viewport);
                    break;
                }

                case Command::SetScissorRect: {
                    SetScissorRectCmd* cmd = mCommands.NextCommand<SetScissorRectCmd>();
                    D3D12_RECT rect;
                    rect.left = cmd->x;
                    rect.top = cmd->y;
                    rect.right = cmd->x + cmd->width;
                    rect.bottom = cmd->y + cmd->height;

                    commandList->RSSetScissorRects(1, &rect);
                    break;
                }

                case Command::SetBlendColor: {
                    SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
                    commandList->OMSetBlendFactor(static_cast<const FLOAT*>(&cmd->color.r));
                    break;
                }

                case Command::ExecuteBundles: {
                    ExecuteBundlesCmd* cmd = mCommands.NextCommand<ExecuteBundlesCmd>();
                    auto bundles = mCommands.NextData<Ref<RenderBundleBase>>(cmd->count);

                    for (uint32_t i = 0; i < cmd->count; ++i) {
                        CommandIterator* iter = bundles[i]->GetCommands();
                        iter->Reset();
                        while (iter->NextCommandId(&type)) {
                            DAWN_TRY(EncodeRenderBundleCommand(iter, type));
                        }
                    }
                    break;
                }

                case Command::WriteTimestamp: {
                    WriteTimestampCmd* cmd = mCommands.NextCommand<WriteTimestampCmd>();

                    RecordWriteTimestampCmd(commandList, cmd);
                    break;
                }

                default: {
                    DAWN_TRY(EncodeRenderBundleCommand(&mCommands, type));
                    break;
                }
            }
        }
        return {};
    }
}}  // namespace dawn_native::d3d12
