// 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/CreatePipelineAsyncTask.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::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 VertexStepModeFunction(wgpu::VertexStepMode mode) {
            switch (mode) {
                case wgpu::VertexStepMode::Vertex:
                    return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
                case wgpu::VertexStepMode::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;
            }
        }

        // 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 StencilFaceState& 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

    Ref<RenderPipeline> RenderPipeline::CreateUninitialized(
        Device* device,
        const RenderPipelineDescriptor* descriptor) {
        return AcquireRef(new RenderPipeline(device, descriptor));
    }

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

        if (!device->IsToggleEnabled(Toggle::UseDXC) &&
            !device->IsToggleEnabled(Toggle::FxcOptimizations)) {
            compileFlags |= D3DCOMPILE_OPTIMIZATION_LEVEL0;
        }

        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;

        // FXC can miscompile code that depends on special float values (NaN, INF, etc) when IEEE
        // strictness is not enabled. See crbug.com/tint/976.
        compileFlags |= D3DCOMPILE_IEEE_STRICTNESS;

        D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptorD3D12 = {};

        PerStage<ProgrammableStage> pipelineStages = GetAllStages();

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

        PerStage<CompiledShader> compiledShader;

        for (auto stage : IterateStages(GetStageMask())) {
            DAWN_TRY_ASSIGN(
                compiledShader[stage],
                ToBackend(pipelineStages[stage].module)
                    ->Compile(pipelineStages[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"));

        SetLabelImpl();

        return {};
    }

    RenderPipeline::~RenderPipeline() = default;

    void RenderPipeline::DestroyImpl() {
        RenderPipelineBase::DestroyImpl();
        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;
    }

    void RenderPipeline::SetLabelImpl() {
        SetDebugName(ToBackend(GetDevice()), GetPipelineState(), "Dawn_RenderPipeline", GetLabel());
    }

    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 = VertexStepModeFunction(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;
    }

    void RenderPipeline::InitializeAsync(Ref<RenderPipelineBase> renderPipeline,
                                         WGPUCreateRenderPipelineAsyncCallback callback,
                                         void* userdata) {
        std::unique_ptr<CreateRenderPipelineAsyncTask> asyncTask =
            std::make_unique<CreateRenderPipelineAsyncTask>(std::move(renderPipeline), callback,
                                                            userdata);
        CreateRenderPipelineAsyncTask::RunAsync(std::move(asyncTask));
    }

}  // namespace dawn::native::d3d12
