1515#include " llvm/IR/Metadata.h"
1616#include " llvm/IR/Module.h"
1717#include " llvm/InitializePasses.h"
18+ #include " llvm/MC/DXContainerRootSignature.h"
19+ #include " llvm/Support/Casting.h"
1820#include " llvm/Support/ErrorHandling.h"
21+ #include < memory>
1922
2023#define DEBUG_TYPE " dxil-metadata-analysis"
2124
2225using namespace llvm ;
2326using namespace dxil ;
27+ using namespace llvm ::mcdxbc;
28+
29+ static bool parseRootFlags (MDNode *RootFlagNode, RootSignatureDesc *Desc) {
30+
31+ assert (RootFlagNode->getNumOperands () == 2 &&
32+ " Invalid format for RootFlag Element" );
33+ auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand (1 ));
34+ auto Value = (RootSignatureFlags)Flag->getZExtValue ();
35+
36+ if ((Value & ~RootSignatureFlags::ValidFlags) != RootSignatureFlags::None)
37+ return true ;
38+
39+ Desc->Flags = Value;
40+ return false ;
41+ }
42+
43+ static bool parseRootSignatureElement (MDNode *Element,
44+ RootSignatureDesc *Desc) {
45+ MDString *ElementText = cast<MDString>(Element->getOperand (0 ));
46+
47+ assert (ElementText != nullptr && " First preoperty of element is not " );
48+
49+ RootSignatureElementKind ElementKind =
50+ StringSwitch<RootSignatureElementKind>(ElementText->getString ())
51+ .Case (" RootFlags" , RootSignatureElementKind::RootFlags)
52+ .Case (" RootConstants" , RootSignatureElementKind::RootConstants)
53+ .Case (" RootCBV" , RootSignatureElementKind::RootDescriptor)
54+ .Case (" RootSRV" , RootSignatureElementKind::RootDescriptor)
55+ .Case (" RootUAV" , RootSignatureElementKind::RootDescriptor)
56+ .Case (" Sampler" , RootSignatureElementKind::RootDescriptor)
57+ .Case (" DescriptorTable" , RootSignatureElementKind::DescriptorTable)
58+ .Case (" StaticSampler" , RootSignatureElementKind::StaticSampler)
59+ .Default (RootSignatureElementKind::None);
60+
61+ switch (ElementKind) {
62+
63+ case RootSignatureElementKind::RootFlags: {
64+ return parseRootFlags (Element, Desc);
65+ break ;
66+ }
67+
68+ case RootSignatureElementKind::RootConstants:
69+ case RootSignatureElementKind::RootDescriptor:
70+ case RootSignatureElementKind::DescriptorTable:
71+ case RootSignatureElementKind::StaticSampler:
72+ case RootSignatureElementKind::None:
73+ llvm_unreachable (" Not Implemented yet" );
74+ break ;
75+ }
76+
77+ return true ;
78+ }
79+
80+ bool parseRootSignature (RootSignatureDesc *Desc, int32_t Version,
81+ NamedMDNode *Root) {
82+ Desc->Version = Version;
83+ bool HasError = false ;
84+
85+ for (unsigned int Sid = 0 ; Sid < Root->getNumOperands (); Sid++) {
86+ // This should be an if, for error handling
87+ MDNode *Node = cast<MDNode>(Root->getOperand (Sid));
88+
89+ // Not sure what use this for...
90+ Metadata *Func = Node->getOperand (0 ).get ();
91+
92+ // This should be an if, for error handling
93+ MDNode *Elements = cast<MDNode>(Node->getOperand (1 ).get ());
94+
95+ for (unsigned int Eid = 0 ; Eid < Elements->getNumOperands (); Eid++) {
96+ MDNode *Element = cast<MDNode>(Elements->getOperand (Eid));
97+
98+ HasError = HasError || parseRootSignatureElement (Element, Desc);
99+ }
100+ }
101+ return HasError;
102+ }
24103
25104static ModuleMetadataInfo collectMetadataInfo (Module &M) {
26105 ModuleMetadataInfo MMDAI;
27106 Triple TT (Triple (M.getTargetTriple ()));
28107 MMDAI.DXILVersion = TT.getDXILVersion ();
29108 MMDAI.ShaderModelVersion = TT.getOSVersion ();
30109 MMDAI.ShaderProfile = TT.getEnvironment ();
110+
31111 NamedMDNode *ValidatorVerNode = M.getNamedMetadata (" dx.valver" );
32112 if (ValidatorVerNode) {
33113 auto *ValVerMD = cast<MDNode>(ValidatorVerNode->getOperand (0 ));
@@ -37,6 +117,15 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) {
37117 VersionTuple (MajorMD->getZExtValue (), MinorMD->getZExtValue ());
38118 }
39119
120+ NamedMDNode *RootSignatureNode = M.getNamedMetadata (" dx.rootsignatures" );
121+ if (RootSignatureNode) {
122+ mcdxbc::RootSignatureDesc Desc;
123+
124+ parseRootSignature (&Desc, 1 , RootSignatureNode);
125+
126+ MMDAI.RootSignatureDesc = Desc;
127+ }
128+
40129 // For all HLSL Shader functions
41130 for (auto &F : M.functions ()) {
42131 if (!F.hasFnAttribute (" hlsl.shader" ))
0 commit comments