================ @@ -0,0 +1,194 @@ +//===- RootSignatureMetadata.h - HLSL Root Signature helpers --------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file This file implements a library for working with HLSL Root Signatures +/// and their metadata representation. +/// +//===----------------------------------------------------------------------===// + +#include "llvm/Frontend/HLSL/RootSignatureMetadata.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Metadata.h" +#include "llvm/Support/ScopedPrinter.h" + +namespace llvm { +namespace hlsl { +namespace rootsig { + +static const EnumEntry<dxil::ResourceClass> ResourceClassNames[] = { + {"CBV", dxil::ResourceClass::CBuffer}, + {"SRV", dxil::ResourceClass::SRV}, + {"UAV", dxil::ResourceClass::UAV}, + {"Sampler", dxil::ResourceClass::Sampler}, +}; + +static std::optional<StringRef> getResourceName(dxil::ResourceClass Class) { + for (const auto &ClassEnum : ResourceClassNames) + if (ClassEnum.Value == Class) + return ClassEnum.Name; + return std::nullopt; +} + +namespace { + +// We use the OverloadVisit with std::visit to ensure the compiler catches if a +// new RootElement variant type is added but it's metadata generation isn't +// handled. +template <class... Ts> struct OverloadedVisit : Ts... { + using Ts::operator()...; +}; +template <class... Ts> OverloadedVisit(Ts...) -> OverloadedVisit<Ts...>; + +} // namespace + +MDNode *MetadataBuilder::BuildRootSignature() { + const auto Visitor = OverloadedVisit{ + [this](const dxbc::RootFlags &Flags) -> MDNode * { + return BuildRootFlags(Flags); + }, + [this](const RootConstants &Constants) -> MDNode * { + return BuildRootConstants(Constants); + }, + [this](const RootDescriptor &Descriptor) -> MDNode * { + return BuildRootDescriptor(Descriptor); + }, + [this](const DescriptorTableClause &Clause) -> MDNode * { + return BuildDescriptorTableClause(Clause); + }, + [this](const DescriptorTable &Table) -> MDNode * { + return BuildDescriptorTable(Table); + }, + [this](const StaticSampler &Sampler) -> MDNode * { + return BuildStaticSampler(Sampler); + }, + }; + + for (const RootElement &Element : Elements) { + MDNode *ElementMD = std::visit(Visitor, Element); + assert(ElementMD != nullptr && + "Root Element must be initialized and validated"); + GeneratedMetadata.push_back(ElementMD); + } + + return MDNode::get(Ctx, GeneratedMetadata); +} + +MDNode *MetadataBuilder::BuildRootFlags(const dxbc::RootFlags &Flags) { + IRBuilder<> Builder(Ctx); + Metadata *Operands[] = { + MDString::get(Ctx, "RootFlags"), + ConstantAsMetadata::get(Builder.getInt32(llvm::to_underlying(Flags))), + }; + return MDNode::get(Ctx, Operands); +} + +MDNode *MetadataBuilder::BuildRootConstants(const RootConstants &Constants) { + IRBuilder<> Builder(Ctx); + Metadata *Operands[] = { + MDString::get(Ctx, "RootConstants"), + ConstantAsMetadata::get( + Builder.getInt32(llvm::to_underlying(Constants.Visibility))), + ConstantAsMetadata::get(Builder.getInt32(Constants.Reg.Number)), + ConstantAsMetadata::get(Builder.getInt32(Constants.Space)), + ConstantAsMetadata::get(Builder.getInt32(Constants.Num32BitConstants)), + }; + return MDNode::get(Ctx, Operands); +} + +MDNode *MetadataBuilder::BuildRootDescriptor(const RootDescriptor &Descriptor) { + IRBuilder<> Builder(Ctx); + std::optional<StringRef> ResName = getResourceName( + dxil::ResourceClass(llvm::to_underlying(Descriptor.Type))); + assert(ResName && "Provided an invalid Resource Class"); + llvm::SmallString<7> Name({"Root", *ResName}); ---------------- inbelic wrote:
7 is sufficient, there are only three possible values of `ResName`: "CBV", "UAV" or "SRV" https://github.com/llvm/llvm-project/pull/146124 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits