@@ -40,6 +40,13 @@ static bool reportError(LLVMContext *Ctx, Twine Message,
4040 return true ;
4141}
4242
43+ static bool reportValueError (LLVMContext *Ctx, Twine ParamName, uint32_t Value,
44+ DiagnosticSeverity Severity = DS_Error) {
45+ Ctx->diagnose (DiagnosticInfoGeneric (
46+ " Invalid value for " + ParamName + " : " + Twine (Value), Severity));
47+ return true ;
48+ }
49+
4350static bool parseRootFlags (LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
4451 MDNode *RootFlagNode) {
4552
@@ -52,6 +59,45 @@ static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
5259 return false ;
5360}
5461
62+ static bool extractMdValue (uint32_t &Value, MDNode *Node, unsigned int OpId) {
63+
64+ auto *CI = mdconst::extract<ConstantInt>(Node->getOperand (OpId));
65+ if (CI == nullptr )
66+ return true ;
67+
68+ Value = CI->getZExtValue ();
69+ return false ;
70+ }
71+
72+ static bool parseRootConstants (LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
73+ MDNode *RootFlagNode) {
74+
75+ if (RootFlagNode->getNumOperands () != 5 )
76+ return reportError (Ctx, " Invalid format for RootConstants Element" );
77+
78+ mcdxbc::RootParameter NewParameter;
79+ NewParameter.Header .ParameterType = dxbc::RootParameterType::Constants32Bit;
80+
81+ uint32_t SV;
82+ if (extractMdValue (SV, RootFlagNode, 1 ))
83+ return reportError (Ctx, " Invalid value for ShaderVisibility" );
84+
85+ NewParameter.Header .ShaderVisibility = (dxbc::ShaderVisibility)SV;
86+
87+ if (extractMdValue (NewParameter.Constants .ShaderRegister , RootFlagNode, 2 ))
88+ return reportError (Ctx, " Invalid value for ShaderRegister" );
89+
90+ if (extractMdValue (NewParameter.Constants .RegisterSpace , RootFlagNode, 3 ))
91+ return reportError (Ctx, " Invalid value for RegisterSpace" );
92+
93+ if (extractMdValue (NewParameter.Constants .Num32BitValues , RootFlagNode, 4 ))
94+ return reportError (Ctx, " Invalid value for Num32BitValues" );
95+
96+ RSD.Parameters .push_back (NewParameter);
97+
98+ return false ;
99+ }
100+
55101static bool parseRootSignatureElement (LLVMContext *Ctx,
56102 mcdxbc::RootSignatureDesc &RSD,
57103 MDNode *Element) {
@@ -62,12 +108,16 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
62108 RootSignatureElementKind ElementKind =
63109 StringSwitch<RootSignatureElementKind>(ElementText->getString ())
64110 .Case (" RootFlags" , RootSignatureElementKind::RootFlags)
111+ .Case (" RootConstants" , RootSignatureElementKind::RootConstants)
65112 .Default (RootSignatureElementKind::Error);
66113
67114 switch (ElementKind) {
68115
69116 case RootSignatureElementKind::RootFlags:
70117 return parseRootFlags (Ctx, RSD, Element);
118+ case RootSignatureElementKind::RootConstants:
119+ return parseRootConstants (Ctx, RSD, Element);
120+ break ;
71121 case RootSignatureElementKind::Error:
72122 return reportError (Ctx, " Invalid Root Signature Element: " +
73123 ElementText->getString ());
@@ -94,10 +144,56 @@ static bool parse(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
94144
95145static bool verifyRootFlag (uint32_t Flags) { return (Flags & ~0xfff ) == 0 ; }
96146
147+ static bool verifyShaderVisibility (dxbc::ShaderVisibility Flags) {
148+ switch (Flags) {
149+
150+ case dxbc::ShaderVisibility::All:
151+ case dxbc::ShaderVisibility::Vertex:
152+ case dxbc::ShaderVisibility::Hull:
153+ case dxbc::ShaderVisibility::Domain:
154+ case dxbc::ShaderVisibility::Geometry:
155+ case dxbc::ShaderVisibility::Pixel:
156+ case dxbc::ShaderVisibility::Amplification:
157+ case dxbc::ShaderVisibility::Mesh:
158+ return true ;
159+ }
160+
161+ return false ;
162+ }
163+
164+ static bool verifyParameterType (dxbc::RootParameterType Flags) {
165+ switch (Flags) {
166+ case dxbc::RootParameterType::Constants32Bit:
167+ return true ;
168+ }
169+
170+ return false ;
171+ }
172+
173+ static bool verifyVersion (uint32_t Version) {
174+ return (Version == 1 || Version == 2 );
175+ }
176+
97177static bool validate (LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
178+
179+ if (!verifyVersion (RSD.Header .Version )) {
180+ return reportValueError (Ctx, " Version" , RSD.Header .Version );
181+ }
182+
98183 if (!verifyRootFlag (RSD.Header .Flags )) {
99- return reportError (Ctx, " Invalid Root Signature flag value" );
184+ return reportValueError (Ctx, " RootFlags" , RSD.Header .Flags );
185+ }
186+
187+ for (const auto &P : RSD.Parameters ) {
188+ if (!verifyShaderVisibility (P.Header .ShaderVisibility ))
189+ return reportValueError (Ctx, " ShaderVisibility" ,
190+ (uint32_t )P.Header .ShaderVisibility );
191+
192+ if (!verifyParameterType (P.Header .ParameterType ))
193+ return reportValueError (Ctx, " ParameterType" ,
194+ (uint32_t )P.Header .ParameterType );
100195 }
196+
101197 return false ;
102198}
103199
@@ -211,6 +307,28 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
211307 OS << indent (Space) << " NumStaticSamplers: " << 0 << " :\n " ;
212308 OS << indent (Space) << " StaticSamplersOffset: "
213309 << sizeof (RS.Header ) + RS.Parameters .size_in_bytes () << " :\n " ;
310+
311+ Space++;
312+ for (auto const &P : RS.Parameters ) {
313+ OS << indent (Space) << " Parameter Type: " << &P.Header .ParameterType
314+ << " :\n " ;
315+ OS << indent (Space) << " Shader Visibility: " << &P.Header .ShaderVisibility
316+ << " :\n " ;
317+ OS << indent (Space) << " Parameter Offset: " << &P.Header .ParameterOffset
318+ << " :\n " ;
319+ switch (P.Header .ParameterType ) {
320+ case dxbc::RootParameterType::Constants32Bit:
321+ OS << indent (Space) << " Register Space: " << &P.Constants .RegisterSpace
322+ << " :\n " ;
323+ OS << indent (Space)
324+ << " Shader Register: " << &P.Constants .ShaderRegister << " :\n " ;
325+ OS << indent (Space)
326+ << " Num 32 Bit Values: " << &P.Constants .Num32BitValues << " :\n " ;
327+ break ;
328+ }
329+ }
330+ Space--;
331+
214332 Space--;
215333 // end root signature header
216334 }
0 commit comments