Path: blob/main/contrib/llvm-project/llvm/lib/Target/DirectX/DXILRootSignature.cpp
213799 views
//===- DXILRootSignature.cpp - DXIL Root Signature helper objects -------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file This file contains helper objects and APIs for working with DXIL9/// Root Signatures.10///11//===----------------------------------------------------------------------===//12#include "DXILRootSignature.h"13#include "DirectX.h"14#include "llvm/ADT/StringSwitch.h"15#include "llvm/ADT/Twine.h"16#include "llvm/Analysis/DXILMetadataAnalysis.h"17#include "llvm/BinaryFormat/DXContainer.h"18#include "llvm/Frontend/HLSL/RootSignatureValidations.h"19#include "llvm/IR/Constants.h"20#include "llvm/IR/DiagnosticInfo.h"21#include "llvm/IR/Function.h"22#include "llvm/IR/LLVMContext.h"23#include "llvm/IR/Metadata.h"24#include "llvm/IR/Module.h"25#include "llvm/InitializePasses.h"26#include "llvm/Pass.h"27#include "llvm/Support/Error.h"28#include "llvm/Support/ErrorHandling.h"29#include "llvm/Support/raw_ostream.h"30#include <cstdint>31#include <optional>32#include <utility>3334using namespace llvm;35using namespace llvm::dxil;3637static bool reportError(LLVMContext *Ctx, Twine Message,38DiagnosticSeverity Severity = DS_Error) {39Ctx->diagnose(DiagnosticInfoGeneric(Message, Severity));40return true;41}4243static bool reportValueError(LLVMContext *Ctx, Twine ParamName,44uint32_t Value) {45Ctx->diagnose(DiagnosticInfoGeneric(46"Invalid value for " + ParamName + ": " + Twine(Value), DS_Error));47return true;48}4950static std::optional<uint32_t> extractMdIntValue(MDNode *Node,51unsigned int OpId) {52if (auto *CI =53mdconst::dyn_extract<ConstantInt>(Node->getOperand(OpId).get()))54return CI->getZExtValue();55return std::nullopt;56}5758static std::optional<float> extractMdFloatValue(MDNode *Node,59unsigned int OpId) {60if (auto *CI = mdconst::dyn_extract<ConstantFP>(Node->getOperand(OpId).get()))61return CI->getValueAPF().convertToFloat();62return std::nullopt;63}6465static std::optional<StringRef> extractMdStringValue(MDNode *Node,66unsigned int OpId) {67MDString *NodeText = dyn_cast<MDString>(Node->getOperand(OpId));68if (NodeText == nullptr)69return std::nullopt;70return NodeText->getString();71}7273static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,74MDNode *RootFlagNode) {7576if (RootFlagNode->getNumOperands() != 2)77return reportError(Ctx, "Invalid format for RootFlag Element");7879if (std::optional<uint32_t> Val = extractMdIntValue(RootFlagNode, 1))80RSD.Flags = *Val;81else82return reportError(Ctx, "Invalid value for RootFlag");8384return false;85}8687static bool parseRootConstants(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,88MDNode *RootConstantNode) {8990if (RootConstantNode->getNumOperands() != 5)91return reportError(Ctx, "Invalid format for RootConstants Element");9293dxbc::RTS0::v1::RootParameterHeader Header;94// The parameter offset doesn't matter here - we recalculate it during95// serialization Header.ParameterOffset = 0;96Header.ParameterType =97llvm::to_underlying(dxbc::RootParameterType::Constants32Bit);9899if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 1))100Header.ShaderVisibility = *Val;101else102return reportError(Ctx, "Invalid value for ShaderVisibility");103104dxbc::RTS0::v1::RootConstants Constants;105if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 2))106Constants.ShaderRegister = *Val;107else108return reportError(Ctx, "Invalid value for ShaderRegister");109110if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 3))111Constants.RegisterSpace = *Val;112else113return reportError(Ctx, "Invalid value for RegisterSpace");114115if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 4))116Constants.Num32BitValues = *Val;117else118return reportError(Ctx, "Invalid value for Num32BitValues");119120RSD.ParametersContainer.addParameter(Header, Constants);121122return false;123}124125static bool parseRootDescriptors(LLVMContext *Ctx,126mcdxbc::RootSignatureDesc &RSD,127MDNode *RootDescriptorNode,128RootSignatureElementKind ElementKind) {129assert(ElementKind == RootSignatureElementKind::SRV ||130ElementKind == RootSignatureElementKind::UAV ||131ElementKind == RootSignatureElementKind::CBV &&132"parseRootDescriptors should only be called with RootDescriptor "133"element kind.");134if (RootDescriptorNode->getNumOperands() != 5)135return reportError(Ctx, "Invalid format for Root Descriptor Element");136137dxbc::RTS0::v1::RootParameterHeader Header;138switch (ElementKind) {139case RootSignatureElementKind::SRV:140Header.ParameterType = llvm::to_underlying(dxbc::RootParameterType::SRV);141break;142case RootSignatureElementKind::UAV:143Header.ParameterType = llvm::to_underlying(dxbc::RootParameterType::UAV);144break;145case RootSignatureElementKind::CBV:146Header.ParameterType = llvm::to_underlying(dxbc::RootParameterType::CBV);147break;148default:149llvm_unreachable("invalid Root Descriptor kind");150break;151}152153if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 1))154Header.ShaderVisibility = *Val;155else156return reportError(Ctx, "Invalid value for ShaderVisibility");157158dxbc::RTS0::v2::RootDescriptor Descriptor;159if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 2))160Descriptor.ShaderRegister = *Val;161else162return reportError(Ctx, "Invalid value for ShaderRegister");163164if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 3))165Descriptor.RegisterSpace = *Val;166else167return reportError(Ctx, "Invalid value for RegisterSpace");168169if (RSD.Version == 1) {170RSD.ParametersContainer.addParameter(Header, Descriptor);171return false;172}173assert(RSD.Version > 1);174175if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 4))176Descriptor.Flags = *Val;177else178return reportError(Ctx, "Invalid value for Root Descriptor Flags");179180RSD.ParametersContainer.addParameter(Header, Descriptor);181return false;182}183184static bool parseDescriptorRange(LLVMContext *Ctx,185mcdxbc::DescriptorTable &Table,186MDNode *RangeDescriptorNode) {187188if (RangeDescriptorNode->getNumOperands() != 6)189return reportError(Ctx, "Invalid format for Descriptor Range");190191dxbc::RTS0::v2::DescriptorRange Range;192193std::optional<StringRef> ElementText =194extractMdStringValue(RangeDescriptorNode, 0);195196if (!ElementText.has_value())197return reportError(Ctx, "Descriptor Range, first element is not a string.");198199Range.RangeType =200StringSwitch<uint32_t>(*ElementText)201.Case("CBV", llvm::to_underlying(dxbc::DescriptorRangeType::CBV))202.Case("SRV", llvm::to_underlying(dxbc::DescriptorRangeType::SRV))203.Case("UAV", llvm::to_underlying(dxbc::DescriptorRangeType::UAV))204.Case("Sampler",205llvm::to_underlying(dxbc::DescriptorRangeType::Sampler))206.Default(~0U);207208if (Range.RangeType == ~0U)209return reportError(Ctx, "Invalid Descriptor Range type: " + *ElementText);210211if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 1))212Range.NumDescriptors = *Val;213else214return reportError(Ctx, "Invalid value for Number of Descriptor in Range");215216if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 2))217Range.BaseShaderRegister = *Val;218else219return reportError(Ctx, "Invalid value for BaseShaderRegister");220221if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 3))222Range.RegisterSpace = *Val;223else224return reportError(Ctx, "Invalid value for RegisterSpace");225226if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 4))227Range.OffsetInDescriptorsFromTableStart = *Val;228else229return reportError(Ctx,230"Invalid value for OffsetInDescriptorsFromTableStart");231232if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 5))233Range.Flags = *Val;234else235return reportError(Ctx, "Invalid value for Descriptor Range Flags");236237Table.Ranges.push_back(Range);238return false;239}240241static bool parseDescriptorTable(LLVMContext *Ctx,242mcdxbc::RootSignatureDesc &RSD,243MDNode *DescriptorTableNode) {244const unsigned int NumOperands = DescriptorTableNode->getNumOperands();245if (NumOperands < 2)246return reportError(Ctx, "Invalid format for Descriptor Table");247248dxbc::RTS0::v1::RootParameterHeader Header;249if (std::optional<uint32_t> Val = extractMdIntValue(DescriptorTableNode, 1))250Header.ShaderVisibility = *Val;251else252return reportError(Ctx, "Invalid value for ShaderVisibility");253254mcdxbc::DescriptorTable Table;255Header.ParameterType =256llvm::to_underlying(dxbc::RootParameterType::DescriptorTable);257258for (unsigned int I = 2; I < NumOperands; I++) {259MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I));260if (Element == nullptr)261return reportError(Ctx, "Missing Root Element Metadata Node.");262263if (parseDescriptorRange(Ctx, Table, Element))264return true;265}266267RSD.ParametersContainer.addParameter(Header, Table);268return false;269}270271static bool parseStaticSampler(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,272MDNode *StaticSamplerNode) {273if (StaticSamplerNode->getNumOperands() != 14)274return reportError(Ctx, "Invalid format for Static Sampler");275276dxbc::RTS0::v1::StaticSampler Sampler;277if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 1))278Sampler.Filter = *Val;279else280return reportError(Ctx, "Invalid value for Filter");281282if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 2))283Sampler.AddressU = *Val;284else285return reportError(Ctx, "Invalid value for AddressU");286287if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 3))288Sampler.AddressV = *Val;289else290return reportError(Ctx, "Invalid value for AddressV");291292if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 4))293Sampler.AddressW = *Val;294else295return reportError(Ctx, "Invalid value for AddressW");296297if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 5))298Sampler.MipLODBias = *Val;299else300return reportError(Ctx, "Invalid value for MipLODBias");301302if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 6))303Sampler.MaxAnisotropy = *Val;304else305return reportError(Ctx, "Invalid value for MaxAnisotropy");306307if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 7))308Sampler.ComparisonFunc = *Val;309else310return reportError(Ctx, "Invalid value for ComparisonFunc ");311312if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 8))313Sampler.BorderColor = *Val;314else315return reportError(Ctx, "Invalid value for ComparisonFunc ");316317if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 9))318Sampler.MinLOD = *Val;319else320return reportError(Ctx, "Invalid value for MinLOD");321322if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 10))323Sampler.MaxLOD = *Val;324else325return reportError(Ctx, "Invalid value for MaxLOD");326327if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 11))328Sampler.ShaderRegister = *Val;329else330return reportError(Ctx, "Invalid value for ShaderRegister");331332if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 12))333Sampler.RegisterSpace = *Val;334else335return reportError(Ctx, "Invalid value for RegisterSpace");336337if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 13))338Sampler.ShaderVisibility = *Val;339else340return reportError(Ctx, "Invalid value for ShaderVisibility");341342RSD.StaticSamplers.push_back(Sampler);343return false;344}345346static bool parseRootSignatureElement(LLVMContext *Ctx,347mcdxbc::RootSignatureDesc &RSD,348MDNode *Element) {349std::optional<StringRef> ElementText = extractMdStringValue(Element, 0);350if (!ElementText.has_value())351return reportError(Ctx, "Invalid format for Root Element");352353RootSignatureElementKind ElementKind =354StringSwitch<RootSignatureElementKind>(*ElementText)355.Case("RootFlags", RootSignatureElementKind::RootFlags)356.Case("RootConstants", RootSignatureElementKind::RootConstants)357.Case("RootCBV", RootSignatureElementKind::CBV)358.Case("RootSRV", RootSignatureElementKind::SRV)359.Case("RootUAV", RootSignatureElementKind::UAV)360.Case("DescriptorTable", RootSignatureElementKind::DescriptorTable)361.Case("StaticSampler", RootSignatureElementKind::StaticSamplers)362.Default(RootSignatureElementKind::Error);363364switch (ElementKind) {365366case RootSignatureElementKind::RootFlags:367return parseRootFlags(Ctx, RSD, Element);368case RootSignatureElementKind::RootConstants:369return parseRootConstants(Ctx, RSD, Element);370case RootSignatureElementKind::CBV:371case RootSignatureElementKind::SRV:372case RootSignatureElementKind::UAV:373return parseRootDescriptors(Ctx, RSD, Element, ElementKind);374case RootSignatureElementKind::DescriptorTable:375return parseDescriptorTable(Ctx, RSD, Element);376case RootSignatureElementKind::StaticSamplers:377return parseStaticSampler(Ctx, RSD, Element);378case RootSignatureElementKind::Error:379return reportError(Ctx, "Invalid Root Signature Element: " + *ElementText);380}381382llvm_unreachable("Unhandled RootSignatureElementKind enum.");383}384385static bool parse(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,386MDNode *Node) {387bool HasError = false;388389// Loop through the Root Elements of the root signature.390for (const auto &Operand : Node->operands()) {391MDNode *Element = dyn_cast<MDNode>(Operand);392if (Element == nullptr)393return reportError(Ctx, "Missing Root Element Metadata Node.");394395HasError = HasError || parseRootSignatureElement(Ctx, RSD, Element);396}397398return HasError;399}400401static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {402403if (!llvm::hlsl::rootsig::verifyVersion(RSD.Version)) {404return reportValueError(Ctx, "Version", RSD.Version);405}406407if (!llvm::hlsl::rootsig::verifyRootFlag(RSD.Flags)) {408return reportValueError(Ctx, "RootFlags", RSD.Flags);409}410411for (const mcdxbc::RootParameterInfo &Info : RSD.ParametersContainer) {412if (!dxbc::isValidShaderVisibility(Info.Header.ShaderVisibility))413return reportValueError(Ctx, "ShaderVisibility",414Info.Header.ShaderVisibility);415416assert(dxbc::isValidParameterType(Info.Header.ParameterType) &&417"Invalid value for ParameterType");418419switch (Info.Header.ParameterType) {420421case llvm::to_underlying(dxbc::RootParameterType::CBV):422case llvm::to_underlying(dxbc::RootParameterType::UAV):423case llvm::to_underlying(dxbc::RootParameterType::SRV): {424const dxbc::RTS0::v2::RootDescriptor &Descriptor =425RSD.ParametersContainer.getRootDescriptor(Info.Location);426if (!llvm::hlsl::rootsig::verifyRegisterValue(Descriptor.ShaderRegister))427return reportValueError(Ctx, "ShaderRegister",428Descriptor.ShaderRegister);429430if (!llvm::hlsl::rootsig::verifyRegisterSpace(Descriptor.RegisterSpace))431return reportValueError(Ctx, "RegisterSpace", Descriptor.RegisterSpace);432433if (RSD.Version > 1) {434if (!llvm::hlsl::rootsig::verifyRootDescriptorFlag(RSD.Version,435Descriptor.Flags))436return reportValueError(Ctx, "RootDescriptorFlag", Descriptor.Flags);437}438break;439}440case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {441const mcdxbc::DescriptorTable &Table =442RSD.ParametersContainer.getDescriptorTable(Info.Location);443for (const dxbc::RTS0::v2::DescriptorRange &Range : Table) {444if (!llvm::hlsl::rootsig::verifyRangeType(Range.RangeType))445return reportValueError(Ctx, "RangeType", Range.RangeType);446447if (!llvm::hlsl::rootsig::verifyRegisterSpace(Range.RegisterSpace))448return reportValueError(Ctx, "RegisterSpace", Range.RegisterSpace);449450if (!llvm::hlsl::rootsig::verifyNumDescriptors(Range.NumDescriptors))451return reportValueError(Ctx, "NumDescriptors", Range.NumDescriptors);452453if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(454RSD.Version, Range.RangeType, Range.Flags))455return reportValueError(Ctx, "DescriptorFlag", Range.Flags);456}457break;458}459}460}461462for (const dxbc::RTS0::v1::StaticSampler &Sampler : RSD.StaticSamplers) {463if (!llvm::hlsl::rootsig::verifySamplerFilter(Sampler.Filter))464return reportValueError(Ctx, "Filter", Sampler.Filter);465466if (!llvm::hlsl::rootsig::verifyAddress(Sampler.AddressU))467return reportValueError(Ctx, "AddressU", Sampler.AddressU);468469if (!llvm::hlsl::rootsig::verifyAddress(Sampler.AddressV))470return reportValueError(Ctx, "AddressV", Sampler.AddressV);471472if (!llvm::hlsl::rootsig::verifyAddress(Sampler.AddressW))473return reportValueError(Ctx, "AddressW", Sampler.AddressW);474475if (!llvm::hlsl::rootsig::verifyMipLODBias(Sampler.MipLODBias))476return reportValueError(Ctx, "MipLODBias", Sampler.MipLODBias);477478if (!llvm::hlsl::rootsig::verifyMaxAnisotropy(Sampler.MaxAnisotropy))479return reportValueError(Ctx, "MaxAnisotropy", Sampler.MaxAnisotropy);480481if (!llvm::hlsl::rootsig::verifyComparisonFunc(Sampler.ComparisonFunc))482return reportValueError(Ctx, "ComparisonFunc", Sampler.ComparisonFunc);483484if (!llvm::hlsl::rootsig::verifyBorderColor(Sampler.BorderColor))485return reportValueError(Ctx, "BorderColor", Sampler.BorderColor);486487if (!llvm::hlsl::rootsig::verifyLOD(Sampler.MinLOD))488return reportValueError(Ctx, "MinLOD", Sampler.MinLOD);489490if (!llvm::hlsl::rootsig::verifyLOD(Sampler.MaxLOD))491return reportValueError(Ctx, "MaxLOD", Sampler.MaxLOD);492493if (!llvm::hlsl::rootsig::verifyRegisterValue(Sampler.ShaderRegister))494return reportValueError(Ctx, "ShaderRegister", Sampler.ShaderRegister);495496if (!llvm::hlsl::rootsig::verifyRegisterSpace(Sampler.RegisterSpace))497return reportValueError(Ctx, "RegisterSpace", Sampler.RegisterSpace);498499if (!dxbc::isValidShaderVisibility(Sampler.ShaderVisibility))500return reportValueError(Ctx, "ShaderVisibility",501Sampler.ShaderVisibility);502}503504return false;505}506507static SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc>508analyzeModule(Module &M) {509510/** Root Signature are specified as following in the metadata:511512!dx.rootsignatures = !{!2} ; list of function/root signature pairs513!2 = !{ ptr @main, !3 } ; function, root signature514!3 = !{ !4, !5, !6, !7 } ; list of root signature elements515516So for each MDNode inside dx.rootsignatures NamedMDNode517(the Root parameter of this function), the parsing process needs518to loop through each of its operands and process the function,519signature pair.520*/521522LLVMContext *Ctx = &M.getContext();523524SmallDenseMap<const Function *, mcdxbc::RootSignatureDesc> RSDMap;525526NamedMDNode *RootSignatureNode = M.getNamedMetadata("dx.rootsignatures");527if (RootSignatureNode == nullptr)528return RSDMap;529530for (const auto &RSDefNode : RootSignatureNode->operands()) {531if (RSDefNode->getNumOperands() != 3) {532reportError(Ctx, "Invalid Root Signature metadata - expected function, "533"signature, and version.");534continue;535}536537// Function was pruned during compilation.538const MDOperand &FunctionPointerMdNode = RSDefNode->getOperand(0);539if (FunctionPointerMdNode == nullptr) {540reportError(541Ctx, "Function associated with Root Signature definition is null.");542continue;543}544545ValueAsMetadata *VAM =546llvm::dyn_cast<ValueAsMetadata>(FunctionPointerMdNode.get());547if (VAM == nullptr) {548reportError(Ctx, "First element of root signature is not a Value");549continue;550}551552Function *F = dyn_cast<Function>(VAM->getValue());553if (F == nullptr) {554reportError(Ctx, "First element of root signature is not a Function");555continue;556}557558Metadata *RootElementListOperand = RSDefNode->getOperand(1).get();559560if (RootElementListOperand == nullptr) {561reportError(Ctx, "Root Element mdnode is null.");562continue;563}564565MDNode *RootElementListNode = dyn_cast<MDNode>(RootElementListOperand);566if (RootElementListNode == nullptr) {567reportError(Ctx, "Root Element is not a metadata node.");568continue;569}570mcdxbc::RootSignatureDesc RSD;571if (std::optional<uint32_t> Version = extractMdIntValue(RSDefNode, 2))572RSD.Version = *Version;573else {574reportError(Ctx, "Invalid RSDefNode value, expected constant int");575continue;576}577578// Clang emits the root signature data in dxcontainer following a specific579// sequence. First the header, then the root parameters. So the header580// offset will always equal to the header size.581RSD.RootParameterOffset = sizeof(dxbc::RTS0::v1::RootSignatureHeader);582583// static sampler offset is calculated when writting dxcontainer.584RSD.StaticSamplersOffset = 0u;585586if (parse(Ctx, RSD, RootElementListNode) || validate(Ctx, RSD)) {587return RSDMap;588}589590RSDMap.insert(std::make_pair(F, RSD));591}592593return RSDMap;594}595596AnalysisKey RootSignatureAnalysis::Key;597598RootSignatureAnalysis::Result599RootSignatureAnalysis::run(Module &M, ModuleAnalysisManager &AM) {600return RootSignatureBindingInfo(analyzeModule(M));601}602603//===----------------------------------------------------------------------===//604605PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,606ModuleAnalysisManager &AM) {607608RootSignatureBindingInfo &RSDMap = AM.getResult<RootSignatureAnalysis>(M);609610OS << "Root Signature Definitions"611<< "\n";612for (const Function &F : M) {613auto It = RSDMap.find(&F);614if (It == RSDMap.end())615continue;616const auto &RS = It->second;617OS << "Definition for '" << F.getName() << "':\n";618// start root signature header619OS << "Flags: " << format_hex(RS.Flags, 8) << "\n"620<< "Version: " << RS.Version << "\n"621<< "RootParametersOffset: " << RS.RootParameterOffset << "\n"622<< "NumParameters: " << RS.ParametersContainer.size() << "\n";623for (size_t I = 0; I < RS.ParametersContainer.size(); I++) {624const auto &[Type, Loc] =625RS.ParametersContainer.getTypeAndLocForParameter(I);626const dxbc::RTS0::v1::RootParameterHeader Header =627RS.ParametersContainer.getHeader(I);628629OS << "- Parameter Type: " << Type << "\n"630<< " Shader Visibility: " << Header.ShaderVisibility << "\n";631632switch (Type) {633case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {634const dxbc::RTS0::v1::RootConstants &Constants =635RS.ParametersContainer.getConstant(Loc);636OS << " Register Space: " << Constants.RegisterSpace << "\n"637<< " Shader Register: " << Constants.ShaderRegister << "\n"638<< " Num 32 Bit Values: " << Constants.Num32BitValues << "\n";639break;640}641case llvm::to_underlying(dxbc::RootParameterType::CBV):642case llvm::to_underlying(dxbc::RootParameterType::UAV):643case llvm::to_underlying(dxbc::RootParameterType::SRV): {644const dxbc::RTS0::v2::RootDescriptor &Descriptor =645RS.ParametersContainer.getRootDescriptor(Loc);646OS << " Register Space: " << Descriptor.RegisterSpace << "\n"647<< " Shader Register: " << Descriptor.ShaderRegister << "\n";648if (RS.Version > 1)649OS << " Flags: " << Descriptor.Flags << "\n";650break;651}652case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {653const mcdxbc::DescriptorTable &Table =654RS.ParametersContainer.getDescriptorTable(Loc);655OS << " NumRanges: " << Table.Ranges.size() << "\n";656657for (const dxbc::RTS0::v2::DescriptorRange Range : Table) {658OS << " - Range Type: " << Range.RangeType << "\n"659<< " Register Space: " << Range.RegisterSpace << "\n"660<< " Base Shader Register: " << Range.BaseShaderRegister << "\n"661<< " Num Descriptors: " << Range.NumDescriptors << "\n"662<< " Offset In Descriptors From Table Start: "663<< Range.OffsetInDescriptorsFromTableStart << "\n";664if (RS.Version > 1)665OS << " Flags: " << Range.Flags << "\n";666}667break;668}669}670}671OS << "NumStaticSamplers: " << 0 << "\n";672OS << "StaticSamplersOffset: " << RS.StaticSamplersOffset << "\n";673}674return PreservedAnalyses::all();675}676677//===----------------------------------------------------------------------===//678bool RootSignatureAnalysisWrapper::runOnModule(Module &M) {679FuncToRsMap = std::make_unique<RootSignatureBindingInfo>(680RootSignatureBindingInfo(analyzeModule(M)));681return false;682}683684void RootSignatureAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {685AU.setPreservesAll();686AU.addPreserved<DXILMetadataAnalysisWrapperPass>();687}688689char RootSignatureAnalysisWrapper::ID = 0;690691INITIALIZE_PASS_BEGIN(RootSignatureAnalysisWrapper,692"dxil-root-signature-analysis",693"DXIL Root Signature Analysis", true, true)694INITIALIZE_PASS_END(RootSignatureAnalysisWrapper,695"dxil-root-signature-analysis",696"DXIL Root Signature Analysis", true, true)697698699