@@ -40,6 +40,13 @@ static bool reportError(LLVMContext *Ctx, Twine Message,
40
40
return true ;
41
41
}
42
42
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
+
43
50
static bool parseRootFlags (LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
44
51
MDNode *RootFlagNode) {
45
52
@@ -52,6 +59,45 @@ static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
52
59
return false ;
53
60
}
54
61
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
+
55
101
static bool parseRootSignatureElement (LLVMContext *Ctx,
56
102
mcdxbc::RootSignatureDesc &RSD,
57
103
MDNode *Element) {
@@ -62,12 +108,16 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
62
108
RootSignatureElementKind ElementKind =
63
109
StringSwitch<RootSignatureElementKind>(ElementText->getString ())
64
110
.Case (" RootFlags" , RootSignatureElementKind::RootFlags)
111
+ .Case (" RootConstants" , RootSignatureElementKind::RootConstants)
65
112
.Default (RootSignatureElementKind::Error);
66
113
67
114
switch (ElementKind) {
68
115
69
116
case RootSignatureElementKind::RootFlags:
70
117
return parseRootFlags (Ctx, RSD, Element);
118
+ case RootSignatureElementKind::RootConstants:
119
+ return parseRootConstants (Ctx, RSD, Element);
120
+ break ;
71
121
case RootSignatureElementKind::Error:
72
122
return reportError (Ctx, " Invalid Root Signature Element: " +
73
123
ElementText->getString ());
@@ -94,10 +144,56 @@ static bool parse(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
94
144
95
145
static bool verifyRootFlag (uint32_t Flags) { return (Flags & ~0xfff ) == 0 ; }
96
146
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
+
97
177
static 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
+
98
183
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 );
100
195
}
196
+
101
197
return false ;
102
198
}
103
199
@@ -211,6 +307,28 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
211
307
OS << indent (Space) << " NumStaticSamplers: " << 0 << " :\n " ;
212
308
OS << indent (Space) << " StaticSamplersOffset: "
213
309
<< 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
+
214
332
Space--;
215
333
// end root signature header
216
334
}
0 commit comments