// Copyright 2017 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/d3d12/PipelineLayoutD3D12.h"

#include <limits>
#include <sstream>
#include <utility>

#include "src/dawn/native/d3d/D3DError.h"
#include "src/dawn/native/d3d12/BindGroupLayoutD3D12.h"
#include "src/dawn/native/d3d12/DeviceD3D12.h"
#include "src/dawn/native/d3d12/PlatformFunctionsD3D12.h"
#include "src/dawn/native/d3d12/ResourceTableD3D12.h"
#include "src/dawn/native/d3d12/UtilsD3D12.h"
#include "src/utils/assert.h"
#include "src/utils/compiler.h"

using Microsoft::WRL::ComPtr;

namespace dawn::native::d3d12 {
namespace {

// Reserve register names for internal use. This registers map to bindings in the shader,
// but are not directly related to allocation of the root signature.
// In the root signature, it the index of the root parameter where these registers are
// used that determines the layout of the root signature.
// TODO(crbug.com/366291600): Use Immediates to support internal constants.
static constexpr uint32_t kRenderOrComputeInternalRegisterSpace = kMaxBindGroups + 1;
static constexpr uint32_t kRenderOrComputeInternalBaseRegister = 0;

static constexpr uint32_t kDynamicStorageBufferLengthsRegisterSpace = kMaxBindGroups + 2;
static constexpr uint32_t kDynamicStorageBufferLengthsBaseRegister = 0;

static constexpr uint32_t kDynamicStorageBufferOffsetsRegisterSpace = kMaxBindGroups + 3;
static constexpr uint32_t kDynamicStorageBufferOffsetsBaseRegister = 0;

static constexpr uint32_t kImmediatesRegisterSpace = kMaxBindGroups + 4;
static constexpr uint32_t kImmediatesBaseRegister = 0;

// Keep this last as we need a large range of register spaces for resource table descriptors,
// one per resource type. For example, for all texture types, we need 26 spaces.
static constexpr uint32_t kBaseResourceTableRegisterSpace = kMaxBindGroups + 5;

static constexpr uint32_t kInvalidResourceTableRootParameterIndex =
    std::numeric_limits<uint32_t>::max();
static constexpr uint32_t kInvalidDynamicStorageBufferLengthsParameterIndex =
    std::numeric_limits<uint32_t>::max();
static constexpr uint32_t kInvalidDynamicStorageBufferOffsetsParameterIndex =
    std::numeric_limits<uint32_t>::max();
static constexpr uint32_t kInvalidDynamicUniformBufferParameterIndex =
    std::numeric_limits<uint32_t>::max();
static constexpr uint32_t kInvalidImmediatesParameterIndex = std::numeric_limits<uint32_t>::max();

D3D12_ROOT_PARAMETER_TYPE RootParameterType(wgpu::BufferBindingType type) {
    switch (type) {
        case wgpu::BufferBindingType::Uniform:
            return D3D12_ROOT_PARAMETER_TYPE_CBV;
        case wgpu::BufferBindingType::Storage:
        case kInternalStorageBufferBinding:
            return D3D12_ROOT_PARAMETER_TYPE_UAV;
        case wgpu::BufferBindingType::ReadOnlyStorage:
        case kInternalReadOnlyStorageBufferBinding:
            return D3D12_ROOT_PARAMETER_TYPE_SRV;
        case wgpu::BufferBindingType::BindingNotUsed:
        case wgpu::BufferBindingType::Undefined:
        default:
            DAWN_UNREACHABLE();
    }
}

HRESULT SerializeRootParameter1_0(Device* device,
                                  const D3D12_VERSIONED_ROOT_SIGNATURE_DESC& rootSignature1_1,
                                  ID3DBlob** ppBlob,
                                  ID3DBlob** ppErrorBlob) {
    std::vector<std::vector<D3D12_DESCRIPTOR_RANGE>> allDescriptorRanges1_0;
    std::vector<D3D12_ROOT_PARAMETER> rootParameters1_0(rootSignature1_1.Desc_1_1.NumParameters);
    for (size_t i = 0; i < rootParameters1_0.size(); ++i) {
        const D3D12_ROOT_PARAMETER1& rootParameter1_1 =
            DAWN_UNSAFE_TODO(rootSignature1_1.Desc_1_1.pParameters[i]);

        rootParameters1_0[i].ParameterType = rootParameter1_1.ParameterType;
        rootParameters1_0[i].ShaderVisibility = rootParameter1_1.ShaderVisibility;

        switch (rootParameters1_0[i].ParameterType) {
            case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
                rootParameters1_0[i].Constants = rootParameter1_1.Constants;
                break;

            case D3D12_ROOT_PARAMETER_TYPE_CBV:
            case D3D12_ROOT_PARAMETER_TYPE_SRV:
            case D3D12_ROOT_PARAMETER_TYPE_UAV:
                rootParameters1_0[i].Descriptor.RegisterSpace =
                    rootParameter1_1.Descriptor.RegisterSpace;
                rootParameters1_0[i].Descriptor.ShaderRegister =
                    rootParameter1_1.Descriptor.ShaderRegister;
                break;

            case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
                rootParameters1_0[i].DescriptorTable.NumDescriptorRanges =
                    rootParameter1_1.DescriptorTable.NumDescriptorRanges;
                if (rootParameters1_0[i].DescriptorTable.NumDescriptorRanges > 0) {
                    std::vector<D3D12_DESCRIPTOR_RANGE> descriptorRanges1_0(
                        rootParameters1_0[i].DescriptorTable.NumDescriptorRanges);
                    for (uint32_t index = 0;
                         index < rootParameter1_1.DescriptorTable.NumDescriptorRanges; ++index) {
                        const D3D12_DESCRIPTOR_RANGE1& descriptorRange1_1 = DAWN_UNSAFE_TODO(
                            rootParameter1_1.DescriptorTable.pDescriptorRanges[index]);
                        descriptorRanges1_0[index].BaseShaderRegister =
                            descriptorRange1_1.BaseShaderRegister;
                        descriptorRanges1_0[index].NumDescriptors =
                            descriptorRange1_1.NumDescriptors;
                        descriptorRanges1_0[index].OffsetInDescriptorsFromTableStart =
                            descriptorRange1_1.OffsetInDescriptorsFromTableStart;
                        descriptorRanges1_0[index].RangeType = descriptorRange1_1.RangeType;
                        descriptorRanges1_0[index].RegisterSpace = descriptorRange1_1.RegisterSpace;
                    }
                    allDescriptorRanges1_0.push_back(descriptorRanges1_0);
                    rootParameters1_0[i].DescriptorTable.pDescriptorRanges =
                        allDescriptorRanges1_0.back().data();
                }
                break;

            default:
                DAWN_UNREACHABLE();
                break;
        }
    }

    D3D12_ROOT_SIGNATURE_DESC rootSignatureDescriptor;
    rootSignatureDescriptor.NumParameters = static_cast<uint32_t>(rootParameters1_0.size());
    rootSignatureDescriptor.pParameters = rootParameters1_0.data();
    rootSignatureDescriptor.NumStaticSamplers = 0;
    rootSignatureDescriptor.pStaticSamplers = nullptr;
    rootSignatureDescriptor.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;

    return device->GetFunctions()->d3d12SerializeRootSignature(
        &rootSignatureDescriptor, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob);
}

}  // anonymous namespace

ResultOrError<Ref<PipelineLayout>> PipelineLayout::Create(
    Device* device,
    const UnpackedPtr<PipelineLayoutDescriptor>& descriptor) {
    Ref<PipelineLayout> layout = AcquireRef(new PipelineLayout(device, descriptor));
    DAWN_TRY(layout->Initialize());
    return layout;
}

MaybeError PipelineLayout::Initialize() {
    BindGroupMask bindGroupMask = GetBindGroupLayoutsMask();
    BindGroupIndex highestBindGroupIndex = GetHighestBitIndexPlusOne(bindGroupMask);
    PerBindGroup<const CachedObject*> cachedObjects;
    for (BindGroupIndex i : Range(highestBindGroupIndex)) {
        if (bindGroupMask[i]) {
            cachedObjects[i] = GetBindGroupLayout(i);
        } else {
            cachedObjects[i] = GetDevice()->GetEmptyBindGroupLayout()->GetInternalBindGroupLayout();
        }
    }

    // Record bind group layout objects and user immediate data size into pipeline layout cache key.
    // It represents pipeline layout base attributes and ignored future changes caused by internal
    // immediate data size from pipeline.
    uint32_t numSetLayoutsWithHoles =
        static_cast<uint32_t>(GetHighestBitIndexPlusOne(bindGroupMask));
    StreamIn(&mCacheKey, stream::Iterable(cachedObjects.data(), numSetLayoutsWithHoles),
             GetImmediateDataRangeByteSize());

    DAWN_TRY(BuildBaseRootParameters());

    return {};
}

ResultOrError<Ref<PipelineLayoutHandle>> PipelineLayout::GetOrCreatePipelineLayoutHandle(
    const ImmediateMask& pipelineImmediateMask) {
    // Check cache
    Ref<PipelineLayoutHandle> pipelineLayoutHandle;
    mPipelineLayoutHandles.Use([&](auto pipelineLayoutHandles) {
        auto it = pipelineLayoutHandles->find(pipelineImmediateMask);
        if (it != pipelineLayoutHandles->end()) {
            pipelineLayoutHandle = it->second;
        }
    });

    if (pipelineLayoutHandle != nullptr) {
        return pipelineLayoutHandle;
    }

    DAWN_TRY_ASSIGN(pipelineLayoutHandle, CreatePipelineLayoutHandle(pipelineImmediateMask));

    return mPipelineLayoutHandles.Use([&](auto pipelineLayoutHandles) {
        return pipelineLayoutHandles
            ->insert({pipelineImmediateMask, std::move(pipelineLayoutHandle)})
            .first->second;
    });
}

MaybeError PipelineLayout::BuildBaseRootParameters() {
    // Parameters are D3D12_ROOT_PARAMETER_TYPE which is either a root table, constant, or
    // descriptor.
    std::vector<D3D12_ROOT_PARAMETER1> rootParameters;
    std::vector<D3D12_STATIC_SAMPLER_DESC> staticSamplers;

    size_t rangesCount = 0;
    size_t staticSamplerCount = 0;
    for (BindGroupIndex group : GetBindGroupLayoutsMask()) {
        const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group));
        rangesCount += bindGroupLayout->GetCbvUavSrvDescriptorRanges().size() +
                       bindGroupLayout->GetSamplerDescriptorRanges().size();
        staticSamplerCount += bindGroupLayout->GetStaticSamplerCount();
    }

    ResourceTable::DescriptorRanges resourceTableRanges;
    if (UsesResourceTable()) {
        DAWN_TRY_ASSIGN(resourceTableRanges, ResourceTable::GetDescriptorRanges(*this));
        rangesCount += resourceTableRanges.cbvUavSrvs.size() + resourceTableRanges.samplers.size();
    }

    // We are taking pointers to `ranges`, so we cannot let it resize while we're pushing to it.
    std::vector<D3D12_DESCRIPTOR_RANGE1> ranges(rangesCount);
    staticSamplers.reserve(staticSamplerCount);

    uint32_t rangeIndex = 0;

    // Set the root descriptor table parameter and copy ranges. An optional registerSpace can be
    // passed in and is set only on ranges with kRegisterSpacePlaceholder. Returns whether or not
    // the parameter was set. A root parameter is not set if the number of ranges is 0.
    auto SetRootDescriptorTable = [&](std::span<const D3D12_DESCRIPTOR_RANGE1> descriptorRanges,
                                      uint32_t registerSpace =
                                          kRegisterSpacePlaceholder) -> std::optional<uint32_t> {
        auto rangeCount = descriptorRanges.size();
        if (rangeCount == 0) {
            return {};
        }

        D3D12_ROOT_PARAMETER1 rootParameter = {};
        rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
        rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
        rootParameter.DescriptorTable.NumDescriptorRanges = static_cast<uint32_t>(rangeCount);
        rootParameter.DescriptorTable.pDescriptorRanges = &ranges[rangeIndex];

        for (auto& range : descriptorRanges) {
            ranges[rangeIndex] = range;
            if (range.RegisterSpace == kRegisterSpacePlaceholder) {
                ranges[rangeIndex].RegisterSpace = registerSpace;
            }
            rangeIndex++;
        }

        rootParameters.emplace_back(rootParameter);
        return static_cast<uint32_t>(rootParameters.size() - 1);
    };

    mResourceTableCbvUavSrvRootParameterIndex = kInvalidResourceTableRootParameterIndex;
    mResourceTableSamplerRootParameterIndex = kInvalidResourceTableRootParameterIndex;
    if (UsesResourceTable()) {
        if (auto paramIndex = SetRootDescriptorTable(resourceTableRanges.cbvUavSrvs)) {
            mResourceTableCbvUavSrvRootParameterIndex = *paramIndex;
        }
        if (auto paramIndex = SetRootDescriptorTable(resourceTableRanges.samplers)) {
            mResourceTableSamplerRootParameterIndex = *paramIndex;
        }
    }

    for (BindGroupIndex group : GetBindGroupLayoutsMask()) {
        const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group));

        // Note that CbvUavSrvDescriptorRanges includes dynamic storage buffers.
        if (auto paramIndex = SetRootDescriptorTable(
                bindGroupLayout->GetCbvUavSrvDescriptorRanges(), static_cast<uint32_t>(group))) {
            mCbvUavSrvRootParameterIndices[group] = *paramIndex;
        }
        if (auto paramIndex = SetRootDescriptorTable(bindGroupLayout->GetSamplerDescriptorRanges(),
                                                     static_cast<uint32_t>(group))) {
            mSamplerRootParameterIndices[group] = *paramIndex;
        }

        // Combine the static samplers from the all of the bind group layouts to one vector.
        for (auto& samplerDesc : bindGroupLayout->GetStaticSamplers()) {
            auto& newSampler = staticSamplers.emplace_back(samplerDesc);
            newSampler.RegisterSpace = static_cast<uint32_t>(group);
        }

        // Init root descriptors in root signatures for dynamic uniform buffer bindings.
        // Dynamic buffer bindings are packed at the beginning of the layout binding info.
        // Resize the vector to include entries for both dynamic uniform and storage buffers, even
        // though we only write to the uniform entries, so that we can index them correctly.
        mDynamicUniformRootParameterIndices[group].resize(
            bindGroupLayout->GetDynamicBufferCount(), kInvalidDynamicUniformBufferParameterIndex);
        for (BindingIndex dynamicBindingIndex : bindGroupLayout->GetDynamicBufferIndices()) {
            if (GetBindGroupLayout(group)->IsStorageBufferBinding(dynamicBindingIndex)) {
                // Dynamic storage buffers are stored in the root descriptor table
                continue;
            }

            const BindingInfo& bindingInfo = bindGroupLayout->GetBindingInfo(dynamicBindingIndex);

            if (bindingInfo.visibility == wgpu::ShaderStage::None) {
                // Skip dynamic buffers that are not visible. D3D12 does not have None
                // visibility.
                continue;
            }

            D3D12_ROOT_PARAMETER1 rootParameter = {};

            // Setup root descriptor.
            D3D12_ROOT_DESCRIPTOR1 rootDescriptor;
            rootDescriptor.ShaderRegister = bindGroupLayout->GetShaderRegister(dynamicBindingIndex);
            rootDescriptor.RegisterSpace = static_cast<uint32_t>(group);
            // Using D3D12_ROOT_DESCRIPTOR_FLAG_NONE means using DATA_STATIC_WHILE_SET_AT_EXECUTE
            // for CBV/SRV and using DATA_VOLATILE for UAV, which is allowed because currently in
            // Dawn the views with dynamic offsets are always re-applied every time before a draw or
            // a dispatch call.
            rootDescriptor.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE;

            // Set root descriptors in root signatures.
            rootParameter.Descriptor = rootDescriptor;

            // Set parameter types according to bind group layout descriptor.
            rootParameter.ParameterType =
                RootParameterType(std::get<BufferBindingInfo>(bindingInfo.bindingLayout).type);

            // Set visibilities according to bind group layout descriptor.
            rootParameter.ShaderVisibility = ShaderVisibilityType(bindingInfo.visibility);

            mDynamicUniformRootParameterIndices[group][dynamicBindingIndex] = rootParameters.size();
            rootParameters.emplace_back(rootParameter);
        }
    }

    // Make sure that we added exactly the number of elements we expected. If we added more,
    // |ranges| will have resized and the pointers in the |rootParameter|s will be invalid.
    DAWN_ASSERT(rangeIndex == rangesCount);

    // For dynamic storage buffers, we store the length and offset of each binding as root
    // constants. Lengths and offsets are bound to separate groups, but share the same binding value
    // (aka register offset). Here we populate mDynamicStorageBufferInfo with this mapping of
    // dynamic storage buffer bind group to register offset, which will be used to update the root
    // constant values, as well as to tell Tint to emit loads from these root constant values for
    // lengths and offsets. Each bind group's length/offset data is stored contiguously in the root
    // constant, so we also compute and store the first register offset for each group where the
    // data should start.
    uint32_t dynamicStorageBufferInfoShaderRegisterOffset = 0;
    for (BindGroupIndex group : GetBindGroupLayoutsMask()) {
        const BindGroupLayoutInternalBase* bgl = GetBindGroupLayout(group);
        const size_t dynamicStorageBufferCount =
            static_cast<size_t>(bgl->GetDynamicStorageBufferCount());

        BindGroupDynamicStorageBufferInfo info;
        info.firstRegisterOffset = dynamicStorageBufferInfoShaderRegisterOffset;
        info.bindingAndRegisterOffsets.reserve(dynamicStorageBufferCount);

        for (BindingIndex bindingIndex : bgl->GetDynamicBufferIndices()) {
            if (bgl->IsStorageBufferBinding(bindingIndex)) {
                info.bindingAndRegisterOffsets.push_back(
                    {bgl->GetBindingInfo(bindingIndex).binding,
                     dynamicStorageBufferInfoShaderRegisterOffset++});
            }
        }
        DAWN_ASSERT(info.bindingAndRegisterOffsets.size() == dynamicStorageBufferCount);
        mDynamicStorageBufferInfo[group] = std::move(info);
    }

    if (dynamicStorageBufferInfoShaderRegisterOffset > 0) {
        auto createRootConstants = [&](uint32_t num32BitValues, uint32_t registerSpace,
                                       uint32_t shaderRegister) -> uint32_t {
            D3D12_ROOT_PARAMETER1 rootParam{};
            rootParam.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
            rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
            rootParam.Constants.Num32BitValues = num32BitValues;
            rootParam.Constants.RegisterSpace = registerSpace;
            rootParam.Constants.ShaderRegister = shaderRegister;
            rootParameters.emplace_back(rootParam);
            return static_cast<uint32_t>(rootParameters.size() - 1);
        };

        // Create the same number of root constants for both the lengths and the offsets of each
        // dynamic storage buffer
        mDynamicStorageBufferLengthsParameterIndex = createRootConstants(
            dynamicStorageBufferInfoShaderRegisterOffset, kDynamicStorageBufferLengthsRegisterSpace,
            kDynamicStorageBufferLengthsBaseRegister);
        mDynamicStorageBufferOffsetsParameterIndex = createRootConstants(
            dynamicStorageBufferInfoShaderRegisterOffset, kDynamicStorageBufferOffsetsRegisterSpace,
            kDynamicStorageBufferOffsetsBaseRegister);
    } else {
        mDynamicStorageBufferLengthsParameterIndex =
            kInvalidDynamicStorageBufferLengthsParameterIndex;
        mDynamicStorageBufferOffsetsParameterIndex =
            kInvalidDynamicStorageBufferOffsetsParameterIndex;
    }

    // Stash the layout-invariant parameters so each PipelineLayoutHandle can be built from them
    // without recomputing or mutating shared state. The descriptor table entries in rootParameters
    // point into ranges; moving the vectors into the const struct preserves those pointers and
    // keeps them immutable thereafter.
    mInvariantParams.emplace(std::move(rootParameters), std::move(ranges),
                             std::move(staticSamplers));

    return {};
}

ResultOrError<Ref<PipelineLayoutHandle>> PipelineLayout::CreatePipelineLayoutHandle(
    const ImmediateMask& pipelineImmediateMask) {
    Device* device = ToBackend(GetDevice());
    DAWN_ASSERT(mInvariantParams.has_value());

    // Start from the layout-invariant base parameters and append the immediates root parameter,
    // whose size depends on the pipeline's internal immediate usage. Everything here operates on
    // locals so that this method has no side effects and can run concurrently on pipeline-creation
    // worker threads. The descriptor table entries copied from rootParameters keep pointing into
    // mInvariantParams->ranges, which is stable for the lifetime of the layout.
    std::vector<D3D12_ROOT_PARAMETER1> rootParameters = mInvariantParams->rootParameters;
    uint32_t immediatesParameterIndex = kInvalidImmediatesParameterIndex;
    if (pipelineImmediateMask.count() > 0) {
        D3D12_ROOT_PARAMETER1 immediates{};
        immediates.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
        immediates.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
        immediates.Constants.Num32BitValues = pipelineImmediateMask.count();
        immediates.Constants.RegisterSpace = kImmediatesRegisterSpace;
        immediates.Constants.ShaderRegister = kImmediatesBaseRegister;
        immediatesParameterIndex = static_cast<uint32_t>(rootParameters.size());
        rootParameters.emplace_back(immediates);
    }

    D3D12_VERSIONED_ROOT_SIGNATURE_DESC versionedRootSignatureDescriptor = {};
    versionedRootSignatureDescriptor.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;
    versionedRootSignatureDescriptor.Desc_1_1.NumParameters =
        static_cast<uint32_t>(rootParameters.size());
    versionedRootSignatureDescriptor.Desc_1_1.pParameters = rootParameters.data();
    versionedRootSignatureDescriptor.Desc_1_1.NumStaticSamplers =
        static_cast<uint32_t>(mInvariantParams->staticSamplers.size());
    versionedRootSignatureDescriptor.Desc_1_1.pStaticSamplers =
        mInvariantParams->staticSamplers.data();
    versionedRootSignatureDescriptor.Desc_1_1.Flags =
        D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;

    ComPtr<ID3DBlob> rootSignatureBlob;
    DAWN_TRY([&]() -> MaybeError {
        ComPtr<ID3DBlob> error;
        if (device->IsToggleEnabled(Toggle::D3D12UseRootSignatureVersion1_1) &&
            SUCCEEDED(device->GetFunctions()->SerializeVersionedRootSignature(
                &versionedRootSignatureDescriptor, &rootSignatureBlob, &error))) [[likely]] {
            return {};
        }
        // If using root signature version 1.1 failed, try again with root signature version 1.0.
        // Some drivers appear to run an outdated version of the DXIL validator and can't support
        // 1.1.
        // Note that retrying again is OK because whether we use version 1.0 or 1.1 doesn't
        // affect anything else except pipeline layout creation. Nothing else in Dawn cares
        // what decision we made here.
        // TODO(crbug.com/1512318): Add some telemetry so we log how often/when this happens.
        std::ostringstream messageStream;
        if (error) {
            messageStream << static_cast<const char*>(error->GetBufferPointer()) << "\n";
        }
        HRESULT hr = SerializeRootParameter1_0(device, versionedRootSignatureDescriptor,
                                               &rootSignatureBlob, &error);
        if (SUCCEEDED(hr)) [[likely]] {
            return {};
        }
        if (error) {
            messageStream << static_cast<const char*>(error->GetBufferPointer()) << "\n";
        }
        messageStream << "D3D12 serialize root signature";
        DAWN_TRY(CheckHRESULT(hr, messageStream.str().c_str()));
        return {};
    }());

    ComPtr<ID3D12RootSignature> rootSignature;
    DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateRootSignature(
                              0, rootSignatureBlob->GetBufferPointer(),
                              rootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&rootSignature)),
                          "D3D12 create root signature"));

    return PipelineLayoutHandle::Create(ToBackend(GetDevice()), std::move(rootSignature),
                                        std::move(rootSignatureBlob), immediatesParameterIndex,
                                        pipelineImmediateMask);
}

void PipelineLayout::DestroyImpl(DestroyReason reason) {
    PipelineLayoutBase::DestroyImpl(reason);
    mPipelineLayoutHandles->clear();
}

uint32_t PipelineLayout::GetResourceTableCbvUavSrvRootParameterIndex() const {
    DAWN_ASSERT(mResourceTableCbvUavSrvRootParameterIndex !=
                kInvalidResourceTableRootParameterIndex);
    return mResourceTableCbvUavSrvRootParameterIndex;
}

uint32_t PipelineLayout::GetResourceTableSamplerRootParameterIndex() const {
    DAWN_ASSERT(mResourceTableSamplerRootParameterIndex != kInvalidResourceTableRootParameterIndex);
    return mResourceTableSamplerRootParameterIndex;
}

uint32_t PipelineLayout::GetBaseResourceTableRegisterSpace() const {
    return kBaseResourceTableRegisterSpace;
}

uint32_t PipelineLayout::GetCbvUavSrvRootParameterIndex(BindGroupIndex group) const {
    DAWN_ASSERT(group < kMaxBindGroupsTyped);
    return mCbvUavSrvRootParameterIndices[group];
}

uint32_t PipelineLayout::GetSamplerRootParameterIndex(BindGroupIndex group) const {
    DAWN_ASSERT(group < kMaxBindGroupsTyped);
    return mSamplerRootParameterIndices[group];
}

const PipelineLayout::DynamicStorageBufferInfo& PipelineLayout::GetDynamicStorageBufferInfo()
    const {
    return mDynamicStorageBufferInfo;
}

uint32_t PipelineLayout::GetDynamicUniformRootParameterIndex(BindGroupIndex group,
                                                             BindingIndex bindingIndex) const {
    DAWN_ASSERT(group < kMaxBindGroupsTyped);
    DAWN_ASSERT(std::get<BufferBindingInfo>(
                    GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).bindingLayout)
                    .hasDynamicOffset);
    DAWN_ASSERT(GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).visibility !=
                wgpu::ShaderStage::None);
    DAWN_ASSERT(std::get<BufferBindingInfo>(
                    GetBindGroupLayout(group)->GetBindingInfo(bindingIndex).bindingLayout)
                    .type == wgpu::BufferBindingType::Uniform);

    return mDynamicUniformRootParameterIndices[group][bindingIndex];
}

uint32_t PipelineLayout::GetFirstIndexOffsetRegisterSpace() const {
    return kRenderOrComputeInternalRegisterSpace;
}

uint32_t PipelineLayout::GetFirstIndexOffsetShaderRegister() const {
    return kRenderOrComputeInternalBaseRegister;
}

uint32_t PipelineLayout::GetNumWorkgroupsRegisterSpace() const {
    return kRenderOrComputeInternalRegisterSpace;
}

uint32_t PipelineLayout::GetNumWorkgroupsShaderRegister() const {
    return kRenderOrComputeInternalBaseRegister;
}

uint32_t PipelineLayout::GetDynamicStorageBufferLengthsRegisterSpace() const {
    return kDynamicStorageBufferLengthsRegisterSpace;
}

uint32_t PipelineLayout::GetDynamicStorageBufferLengthsShaderRegister() const {
    return kDynamicStorageBufferLengthsBaseRegister;
}

uint32_t PipelineLayout::GetDynamicStorageBufferLengthsParameterIndex() const {
    DAWN_ASSERT(mDynamicStorageBufferLengthsParameterIndex !=
                kInvalidDynamicStorageBufferLengthsParameterIndex);
    return mDynamicStorageBufferLengthsParameterIndex;
}

uint32_t PipelineLayout::GetDynamicStorageBufferOffsetsRegisterSpace() const {
    return kDynamicStorageBufferOffsetsRegisterSpace;
}

uint32_t PipelineLayout::GetDynamicStorageBufferOffsetsShaderRegister() const {
    return kDynamicStorageBufferOffsetsBaseRegister;
}

uint32_t PipelineLayout::GetDynamicStorageBufferOffsetsParameterIndex() const {
    DAWN_ASSERT(mDynamicStorageBufferOffsetsParameterIndex !=
                kInvalidDynamicStorageBufferOffsetsParameterIndex);
    return mDynamicStorageBufferOffsetsParameterIndex;
}

uint32_t PipelineLayout::GetImmediatesRegisterSpace() const {
    return kImmediatesRegisterSpace;
}

uint32_t PipelineLayout::GetImmediatesShaderRegister() const {
    return kImmediatesBaseRegister;
}

}  // namespace dawn::native::d3d12
