// 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/RenderPipelineD3D12.h"

#include "common/Assert.h"
#include "common/Log.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/ShaderModuleD3D12.h"
#include "dawn_native/d3d12/TextureD3D12.h"
#include "dawn_native/d3d12/UtilsD3D12.h"

#include <d3dcompiler.h>

namespace dawn_native { namespace d3d12 {

    namespace {
        DXGI_FORMAT VertexFormatType(wgpu::VertexFormat format) {
            switch (format) {
                case wgpu::VertexFormat::Uint8x2:
                    return DXGI_FORMAT_R8G8_UINT;
                case wgpu::VertexFormat::Uint8x4:
                    return DXGI_FORMAT_R8G8B8A8_UINT;
                case wgpu::VertexFormat::Sint8x2:
                    return DXGI_FORMAT_R8G8_SINT;
                case wgpu::VertexFormat::Sint8x4:
                    return DXGI_FORMAT_R8G8B8A8_SINT;
                case wgpu::VertexFormat::Unorm8x2:
                    return DXGI_FORMAT_R8G8_UNORM;
                case wgpu::VertexFormat::Unorm8x4:
                    return DXGI_FORMAT_R8G8B8A8_UNORM;
                case wgpu::VertexFormat::Snorm8x2:
                    return DXGI_FORMAT_R8G8_SNORM;
                case wgpu::VertexFormat::Snorm8x4:
                    return DXGI_FORMAT_R8G8B8A8_SNORM;
                case wgpu::VertexFormat::Uint16x2:
                    return DXGI_FORMAT_R16G16_UINT;
                case wgpu::VertexFormat::Uint16x4:
                    return DXGI_FORMAT_R16G16B16A16_UINT;
                case wgpu::VertexFormat::Sint16x2:
                    return DXGI_FORMAT_R16G16_SINT;
                case wgpu::VertexFormat::Sint16x4:
                    return DXGI_FORMAT_R16G16B16A16_SINT;
                case wgpu::VertexFormat::Unorm16x2:
                    return DXGI_FORMAT_R16G16_UNORM;
                case wgpu::VertexFormat::Unorm16x4:
                    return DXGI_FORMAT_R16G16B16A16_UNORM;
                case wgpu::VertexFormat::Snorm16x2:
                    return DXGI_FORMAT_R16G16_SNORM;
                case wgpu::VertexFormat::Snorm16x4:
                    return DXGI_FORMAT_R16G16B16A16_SNORM;
                case wgpu::VertexFormat::Float16x2:
                    return DXGI_FORMAT_R16G16_FLOAT;
                case wgpu::VertexFormat::Float16x4:
                    return DXGI_FORMAT_R16G16B16A16_FLOAT;
                case wgpu::VertexFormat::Float32:
                    return DXGI_FORMAT_R32_FLOAT;
                case wgpu::VertexFormat::Float32x2:
                    return DXGI_FORMAT_R32G32_FLOAT;
                case wgpu::VertexFormat::Float32x3:
                    return DXGI_FORMAT_R32G32B32_FLOAT;
                case wgpu::VertexFormat::Float32x4:
                    return DXGI_FORMAT_R32G32B32A32_FLOAT;
                case wgpu::VertexFormat::Uint32:
                    return DXGI_FORMAT_R32_UINT;
                case wgpu::VertexFormat::Uint32x2:
                    return DXGI_FORMAT_R32G32_UINT;
                case wgpu::VertexFormat::Uint32x3:
                    return DXGI_FORMAT_R32G32B32_UINT;
                case wgpu::VertexFormat::Uint32x4:
                    return DXGI_FORMAT_R32G32B32A32_UINT;
                case wgpu::VertexFormat::Sint32:
                    return DXGI_FORMAT_R32_SINT;
                case wgpu::VertexFormat::Sint32x2:
                    return DXGI_FORMAT_R32G32_SINT;
                case wgpu::VertexFormat::Sint32x3:
                    return DXGI_FORMAT_R32G32B32_SINT;
                case wgpu::VertexFormat::Sint32x4:
                    return DXGI_FORMAT_R32G32B32A32_SINT;
                default:
                    UNREACHABLE();
            }
        }

        D3D12_INPUT_CLASSIFICATION InputStepModeFunction(wgpu::InputStepMode mode) {
            switch (mode) {
                case wgpu::InputStepMode::Vertex:
                    return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
                case wgpu::InputStepMode::Instance:
                    return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
            }
        }

        D3D12_PRIMITIVE_TOPOLOGY D3D12PrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
            switch (primitiveTopology) {
                case wgpu::PrimitiveTopology::PointList:
                    return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
                case wgpu::PrimitiveTopology::LineList:
                    return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
                case wgpu::PrimitiveTopology::LineStrip:
                    return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
                case wgpu::PrimitiveTopology::TriangleList:
                    return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
                case wgpu::PrimitiveTopology::TriangleStrip:
                    return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
            }
        }

        D3D12_PRIMITIVE_TOPOLOGY_TYPE D3D12PrimitiveTopologyType(
            wgpu::PrimitiveTopology primitiveTopology) {
            switch (primitiveTopology) {
                case wgpu::PrimitiveTopology::PointList:
                    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
                case wgpu::PrimitiveTopology::LineList:
                case wgpu::PrimitiveTopology::LineStrip:
                    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
                case wgpu::PrimitiveTopology::TriangleList:
                case wgpu::PrimitiveTopology::TriangleStrip:
                    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
            }
        }

        D3D12_CULL_MODE D3D12CullMode(wgpu::CullMode mode) {
            switch (mode) {
                case wgpu::CullMode::None:
                    return D3D12_CULL_MODE_NONE;
                case wgpu::CullMode::Front:
                    return D3D12_CULL_MODE_FRONT;
                case wgpu::CullMode::Back:
                    return D3D12_CULL_MODE_BACK;
            }
        }

        D3D12_BLEND D3D12Blend(wgpu::BlendFactor factor) {
            switch (factor) {
                case wgpu::BlendFactor::Zero:
                    return D3D12_BLEND_ZERO;
                case wgpu::BlendFactor::One:
                    return D3D12_BLEND_ONE;
                case wgpu::BlendFactor::Src:
                    return D3D12_BLEND_SRC_COLOR;
                case wgpu::BlendFactor::OneMinusSrc:
                    return D3D12_BLEND_INV_SRC_COLOR;
                case wgpu::BlendFactor::SrcAlpha:
                    return D3D12_BLEND_SRC_ALPHA;
                case wgpu::BlendFactor::OneMinusSrcAlpha:
                    return D3D12_BLEND_INV_SRC_ALPHA;
                case wgpu::BlendFactor::Dst:
                    return D3D12_BLEND_DEST_COLOR;
                case wgpu::BlendFactor::OneMinusDst:
                    return D3D12_BLEND_INV_DEST_COLOR;
                case wgpu::BlendFactor::DstAlpha:
                    return D3D12_BLEND_DEST_ALPHA;
                case wgpu::BlendFactor::OneMinusDstAlpha:
                    return D3D12_BLEND_INV_DEST_ALPHA;
                case wgpu::BlendFactor::SrcAlphaSaturated:
                    return D3D12_BLEND_SRC_ALPHA_SAT;
                case wgpu::BlendFactor::Constant:
                    return D3D12_BLEND_BLEND_FACTOR;
                case wgpu::BlendFactor::OneMinusConstant:
                    return D3D12_BLEND_INV_BLEND_FACTOR;

                // Deprecated blend factors should be normalized prior to this call.
                case wgpu::BlendFactor::SrcColor:
                case wgpu::BlendFactor::OneMinusSrcColor:
                case wgpu::BlendFactor::DstColor:
                case wgpu::BlendFactor::OneMinusDstColor:
                case wgpu::BlendFactor::BlendColor:
                case wgpu::BlendFactor::OneMinusBlendColor:
                    UNREACHABLE();
            }
        }

        // When a blend factor is defined for the alpha channel, any of the factors that don't
        // explicitly state that they apply to alpha should be treated as their explicitly-alpha
        // equivalents. See: https://github.com/gpuweb/gpuweb/issues/65
        D3D12_BLEND D3D12AlphaBlend(wgpu::BlendFactor factor) {
            switch (factor) {
                case wgpu::BlendFactor::Src:
                    return D3D12_BLEND_SRC_ALPHA;
                case wgpu::BlendFactor::OneMinusSrc:
                    return D3D12_BLEND_INV_SRC_ALPHA;
                case wgpu::BlendFactor::Dst:
                    return D3D12_BLEND_DEST_ALPHA;
                case wgpu::BlendFactor::OneMinusDst:
                    return D3D12_BLEND_INV_DEST_ALPHA;

                // Other blend factors translate to the same D3D12 enum as the color blend factors.
                default:
                    return D3D12Blend(factor);
            }
        }

        D3D12_BLEND_OP D3D12BlendOperation(wgpu::BlendOperation operation) {
            switch (operation) {
                case wgpu::BlendOperation::Add:
                    return D3D12_BLEND_OP_ADD;
                case wgpu::BlendOperation::Subtract:
                    return D3D12_BLEND_OP_SUBTRACT;
                case wgpu::BlendOperation::ReverseSubtract:
                    return D3D12_BLEND_OP_REV_SUBTRACT;
                case wgpu::BlendOperation::Min:
                    return D3D12_BLEND_OP_MIN;
                case wgpu::BlendOperation::Max:
                    return D3D12_BLEND_OP_MAX;
            }
        }

        uint8_t D3D12RenderTargetWriteMask(wgpu::ColorWriteMask writeMask) {
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Red) ==
                              D3D12_COLOR_WRITE_ENABLE_RED,
                          "ColorWriteMask values must match");
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Green) ==
                              D3D12_COLOR_WRITE_ENABLE_GREEN,
                          "ColorWriteMask values must match");
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Blue) ==
                              D3D12_COLOR_WRITE_ENABLE_BLUE,
                          "ColorWriteMask values must match");
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Alpha) ==
                              D3D12_COLOR_WRITE_ENABLE_ALPHA,
                          "ColorWriteMask values must match");
            return static_cast<uint8_t>(writeMask);
        }

        D3D12_RENDER_TARGET_BLEND_DESC ComputeColorDesc(const ColorTargetState* state) {
            D3D12_RENDER_TARGET_BLEND_DESC blendDesc;
            blendDesc.BlendEnable = state->blend != nullptr;
            if (blendDesc.BlendEnable) {
                blendDesc.SrcBlend = D3D12Blend(state->blend->color.srcFactor);
                blendDesc.DestBlend = D3D12Blend(state->blend->color.dstFactor);
                blendDesc.BlendOp = D3D12BlendOperation(state->blend->color.operation);
                blendDesc.SrcBlendAlpha = D3D12AlphaBlend(state->blend->alpha.srcFactor);
                blendDesc.DestBlendAlpha = D3D12AlphaBlend(state->blend->alpha.dstFactor);
                blendDesc.BlendOpAlpha = D3D12BlendOperation(state->blend->alpha.operation);
            }
            blendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(state->writeMask);
            blendDesc.LogicOpEnable = false;
            blendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
            return blendDesc;
        }

        D3D12_STENCIL_OP StencilOp(wgpu::StencilOperation op) {
            switch (op) {
                case wgpu::StencilOperation::Keep:
                    return D3D12_STENCIL_OP_KEEP;
                case wgpu::StencilOperation::Zero:
                    return D3D12_STENCIL_OP_ZERO;
                case wgpu::StencilOperation::Replace:
                    return D3D12_STENCIL_OP_REPLACE;
                case wgpu::StencilOperation::IncrementClamp:
                    return D3D12_STENCIL_OP_INCR_SAT;
                case wgpu::StencilOperation::DecrementClamp:
                    return D3D12_STENCIL_OP_DECR_SAT;
                case wgpu::StencilOperation::Invert:
                    return D3D12_STENCIL_OP_INVERT;
                case wgpu::StencilOperation::IncrementWrap:
                    return D3D12_STENCIL_OP_INCR;
                case wgpu::StencilOperation::DecrementWrap:
                    return D3D12_STENCIL_OP_DECR;
            }
        }

        D3D12_DEPTH_STENCILOP_DESC StencilOpDesc(const StencilStateFaceDescriptor descriptor) {
            D3D12_DEPTH_STENCILOP_DESC desc;

            desc.StencilFailOp = StencilOp(descriptor.failOp);
            desc.StencilDepthFailOp = StencilOp(descriptor.depthFailOp);
            desc.StencilPassOp = StencilOp(descriptor.passOp);
            desc.StencilFunc = ToD3D12ComparisonFunc(descriptor.compare);

            return desc;
        }

        D3D12_DEPTH_STENCIL_DESC ComputeDepthStencilDesc(const DepthStencilState* descriptor) {
            D3D12_DEPTH_STENCIL_DESC mDepthStencilDescriptor;
            mDepthStencilDescriptor.DepthEnable = TRUE;
            mDepthStencilDescriptor.DepthWriteMask = descriptor->depthWriteEnabled
                                                         ? D3D12_DEPTH_WRITE_MASK_ALL
                                                         : D3D12_DEPTH_WRITE_MASK_ZERO;
            mDepthStencilDescriptor.DepthFunc = ToD3D12ComparisonFunc(descriptor->depthCompare);

            mDepthStencilDescriptor.StencilEnable = StencilTestEnabled(descriptor) ? TRUE : FALSE;
            mDepthStencilDescriptor.StencilReadMask =
                static_cast<UINT8>(descriptor->stencilReadMask);
            mDepthStencilDescriptor.StencilWriteMask =
                static_cast<UINT8>(descriptor->stencilWriteMask);

            mDepthStencilDescriptor.FrontFace = StencilOpDesc(descriptor->stencilFront);
            mDepthStencilDescriptor.BackFace = StencilOpDesc(descriptor->stencilBack);
            return mDepthStencilDescriptor;
        }

        D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ComputeIndexBufferStripCutValue(
            wgpu::PrimitiveTopology primitiveTopology,
            wgpu::IndexFormat indexFormat) {
            if (primitiveTopology != wgpu::PrimitiveTopology::TriangleStrip &&
                primitiveTopology != wgpu::PrimitiveTopology::LineStrip) {
                return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
            }

            switch (indexFormat) {
                case wgpu::IndexFormat::Uint16:
                    return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF;
                case wgpu::IndexFormat::Uint32:
                    return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF;
                case wgpu::IndexFormat::Undefined:
                    return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
            }
        }

    }  // anonymous namespace

    ResultOrError<Ref<RenderPipeline>> RenderPipeline::Create(
        Device* device,
        const RenderPipelineDescriptor* descriptor) {
        Ref<RenderPipeline> pipeline = AcquireRef(new RenderPipeline(device, descriptor));
        DAWN_TRY(pipeline->Initialize(descriptor));
        return pipeline;
    }

    MaybeError RenderPipeline::Initialize(const RenderPipelineDescriptor* descriptor) {
        Device* device = ToBackend(GetDevice());
        uint32_t compileFlags = 0;

        if (device->IsToggleEnabled(Toggle::EmitHLSLDebugSymbols)) {
            compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
        }

        // SPRIV-cross does matrix multiplication expecting row major matrices
        compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;

        D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptorD3D12 = {};

        PerStage<const char*> entryPoints;
        entryPoints[SingleShaderStage::Vertex] = descriptor->vertex.entryPoint;
        entryPoints[SingleShaderStage::Fragment] = descriptor->fragment->entryPoint;

        PerStage<ShaderModule*> modules;
        modules[SingleShaderStage::Vertex] = ToBackend(descriptor->vertex.module);
        modules[SingleShaderStage::Fragment] = ToBackend(descriptor->fragment->module);

        PerStage<D3D12_SHADER_BYTECODE*> shaders;
        shaders[SingleShaderStage::Vertex] = &descriptorD3D12.VS;
        shaders[SingleShaderStage::Fragment] = &descriptorD3D12.PS;

        PerStage<CompiledShader> compiledShader;
        wgpu::ShaderStage renderStages = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
        for (auto stage : IterateStages(renderStages)) {
            DAWN_TRY_ASSIGN(compiledShader[stage],
                            modules[stage]->Compile(entryPoints[stage], stage,
                                                    ToBackend(GetLayout()), compileFlags));
            *shaders[stage] = compiledShader[stage].GetD3D12ShaderBytecode();
        }

        mFirstOffsetInfo = compiledShader[SingleShaderStage::Vertex].firstOffsetInfo;

        PipelineLayout* layout = ToBackend(GetLayout());

        descriptorD3D12.pRootSignature = layout->GetRootSignature();

        // D3D12 logs warnings if any empty input state is used
        std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes> inputElementDescriptors;
        if (GetAttributeLocationsUsed().any()) {
            descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors);
        }

        descriptorD3D12.IBStripCutValue =
            ComputeIndexBufferStripCutValue(GetPrimitiveTopology(), GetStripIndexFormat());

        descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
        descriptorD3D12.RasterizerState.CullMode = D3D12CullMode(GetCullMode());
        descriptorD3D12.RasterizerState.FrontCounterClockwise =
            (GetFrontFace() == wgpu::FrontFace::CCW) ? TRUE : FALSE;
        descriptorD3D12.RasterizerState.DepthBias = GetDepthBias();
        descriptorD3D12.RasterizerState.DepthBiasClamp = GetDepthBiasClamp();
        descriptorD3D12.RasterizerState.SlopeScaledDepthBias = GetDepthBiasSlopeScale();
        descriptorD3D12.RasterizerState.DepthClipEnable = TRUE;
        descriptorD3D12.RasterizerState.MultisampleEnable = (GetSampleCount() > 1) ? TRUE : FALSE;
        descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
        descriptorD3D12.RasterizerState.ForcedSampleCount = 0;
        descriptorD3D12.RasterizerState.ConservativeRaster =
            D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;

        if (HasDepthStencilAttachment()) {
            descriptorD3D12.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
        }

        for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
            descriptorD3D12.RTVFormats[static_cast<uint8_t>(i)] =
                D3D12TextureFormat(GetColorAttachmentFormat(i));
            descriptorD3D12.BlendState.RenderTarget[static_cast<uint8_t>(i)] =
                ComputeColorDesc(GetColorTargetState(i));
        }
        descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());

        descriptorD3D12.BlendState.AlphaToCoverageEnable = IsAlphaToCoverageEnabled();
        descriptorD3D12.BlendState.IndependentBlendEnable = TRUE;

        descriptorD3D12.DepthStencilState = ComputeDepthStencilDesc(GetDepthStencilState());

        descriptorD3D12.SampleMask = GetSampleMask();
        descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());
        descriptorD3D12.SampleDesc.Count = GetSampleCount();
        descriptorD3D12.SampleDesc.Quality = 0;

        mD3d12PrimitiveTopology = D3D12PrimitiveTopology(GetPrimitiveTopology());

        DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateGraphicsPipelineState(
                                  &descriptorD3D12, IID_PPV_ARGS(&mPipelineState)),
                              "D3D12 create graphics pipeline state"));
        return {};
    }

    RenderPipeline::~RenderPipeline() {
        ToBackend(GetDevice())->ReferenceUntilUnused(mPipelineState);
    }

    D3D12_PRIMITIVE_TOPOLOGY RenderPipeline::GetD3D12PrimitiveTopology() const {
        return mD3d12PrimitiveTopology;
    }

    ID3D12PipelineState* RenderPipeline::GetPipelineState() const {
        return mPipelineState.Get();
    }

    const FirstOffsetInfo& RenderPipeline::GetFirstOffsetInfo() const {
        return mFirstOffsetInfo;
    }

    D3D12_INPUT_LAYOUT_DESC RenderPipeline::ComputeInputLayout(
        std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors) {
        unsigned int count = 0;
        for (VertexAttributeLocation loc : IterateBitSet(GetAttributeLocationsUsed())) {
            D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++];

            const VertexAttributeInfo& attribute = GetAttribute(loc);

            // If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the
            // SemanticIndex N
            inputElementDescriptor.SemanticName = "TEXCOORD";
            inputElementDescriptor.SemanticIndex = static_cast<uint8_t>(loc);
            inputElementDescriptor.Format = VertexFormatType(attribute.format);
            inputElementDescriptor.InputSlot = static_cast<uint8_t>(attribute.vertexBufferSlot);

            const VertexBufferInfo& input = GetVertexBuffer(attribute.vertexBufferSlot);

            inputElementDescriptor.AlignedByteOffset = attribute.offset;
            inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
            if (inputElementDescriptor.InputSlotClass ==
                D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) {
                inputElementDescriptor.InstanceDataStepRate = 0;
            } else {
                inputElementDescriptor.InstanceDataStepRate = 1;
            }
        }

        D3D12_INPUT_LAYOUT_DESC inputLayoutDescriptor;
        inputLayoutDescriptor.pInputElementDescs = &(*inputElementDescriptors)[0];
        inputLayoutDescriptor.NumElements = count;
        return inputLayoutDescriptor;
    }

}}  // namespace dawn_native::d3d12
