7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " DXILPostOptimizationValidation.h"
10
+ #include " DXILRootSignature.h"
10
11
#include " DXILShaderFlags.h"
11
12
#include " DirectX.h"
12
13
#include " llvm/ADT/STLForwardCompat.h"
15
16
#include " llvm/Analysis/DXILMetadataAnalysis.h"
16
17
#include " llvm/Analysis/DXILResource.h"
17
18
#include " llvm/BinaryFormat/DXContainer.h"
19
+ #include " llvm/Frontend/HLSL/RootSignatureValidations.h"
18
20
#include " llvm/IR/DiagnosticInfo.h"
19
21
#include " llvm/IR/Instructions.h"
20
22
#include " llvm/IR/IntrinsicsDirectX.h"
21
23
#include " llvm/IR/Module.h"
22
24
#include " llvm/InitializePasses.h"
25
+ #include " llvm/MC/DXContainerRootSignature.h"
26
+ #include " llvm/Support/DXILABI.h"
23
27
24
28
#define DEBUG_TYPE " dxil-post-optimization-validation"
25
29
26
30
using namespace llvm ;
27
31
using namespace llvm ::dxil;
28
32
29
33
namespace {
34
+ static const char *ResourceClassToString (llvm::dxil::ResourceClass Class) {
35
+ switch (Class) {
36
+ case ResourceClass::SRV:
37
+ return " SRV" ;
38
+ case ResourceClass::UAV:
39
+ return " UAV" ;
40
+ case ResourceClass::CBuffer:
41
+ return " CBuffer" ;
42
+ case ResourceClass::Sampler:
43
+ return " Sampler" ;
44
+ }
45
+ }
46
+
47
+ static ResourceClass RangeToResourceClass (uint32_t RangeType) {
48
+ using namespace dxbc ;
49
+ switch (static_cast <DescriptorRangeType>(RangeType)) {
50
+ case DescriptorRangeType::SRV:
51
+ return ResourceClass::SRV;
52
+ case DescriptorRangeType::UAV:
53
+ return ResourceClass::UAV;
54
+ case DescriptorRangeType::CBV:
55
+ return ResourceClass::CBuffer;
56
+ case DescriptorRangeType::Sampler:
57
+ return ResourceClass::Sampler;
58
+ }
59
+ }
60
+
61
+ ResourceClass ParameterToResourceClass (uint32_t Type) {
62
+ using namespace dxbc ;
63
+ switch (Type) {
64
+ case llvm::to_underlying (RootParameterType::Constants32Bit):
65
+ return ResourceClass::CBuffer;
66
+ case llvm::to_underlying (RootParameterType::SRV):
67
+ return ResourceClass::SRV;
68
+ case llvm::to_underlying (RootParameterType::UAV):
69
+ return ResourceClass::UAV;
70
+ case llvm::to_underlying (RootParameterType::CBV):
71
+ return ResourceClass::CBuffer;
72
+ default :
73
+ llvm_unreachable (" Unknown RootParameterType" );
74
+ }
75
+ }
30
76
31
77
static void reportInvalidDirection (Module &M, DXILResourceMap &DRM) {
32
78
for (const auto &UAV : DRM.uavs ()) {
@@ -98,12 +144,13 @@ reportInvalidHandleTyBoundInRs(Module &M, Twine Type,
98
144
M.getContext ().diagnose (DiagnosticInfoGeneric (Message));
99
145
}
100
146
101
- static void reportRegNotBound (Module &M, Twine Type,
102
- ResourceInfo::ResourceBinding Binding ) {
147
+ static void reportRegNotBound (Module &M,
148
+ llvm::hlsl::rootsig::RangeInfo Unbound ) {
103
149
SmallString<128 > Message;
104
150
raw_svector_ostream OS (Message);
105
- OS << " register " << Type << " (space=" << Binding.Space
106
- << " , register=" << Binding.LowerBound << " )"
151
+ OS << " register " << ResourceClassToString (Unbound.Class )
152
+ << " (space=" << Unbound.Space << " , register=" << Unbound.LowerBound
153
+ << " )"
107
154
<< " is not defined in Root Signature" ;
108
155
M.getContext ().diagnose (DiagnosticInfoGeneric (Message));
109
156
}
@@ -136,24 +183,11 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
136
183
}
137
184
}
138
185
139
- static uint32_t parameterToRangeType (uint32_t Type) {
140
- switch (Type) {
141
- case llvm::to_underlying (dxbc::RootParameterType::CBV):
142
- return llvm::to_underlying (dxbc::DescriptorRangeType::CBV);
143
- case llvm::to_underlying (dxbc::RootParameterType::SRV):
144
- return llvm::to_underlying (dxbc::DescriptorRangeType::SRV);
145
- case llvm::to_underlying (dxbc::RootParameterType::UAV):
146
- return llvm::to_underlying (dxbc::DescriptorRangeType::UAV);
147
- default :
148
- llvm_unreachable (" Root Parameter Type has no Range Type equivalent" );
149
- }
150
- }
151
-
152
- static RootSignatureBindingValidation
186
+ static hlsl::rootsig::RootSignatureBindingValidation
153
187
initRSBindingValidation (const mcdxbc::RootSignatureDesc &RSD,
154
188
dxbc::ShaderVisibility Visibility) {
155
189
156
- RootSignatureBindingValidation Validation;
190
+ hlsl::rootsig:: RootSignatureBindingValidation Validation;
157
191
158
192
for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
159
193
const auto &[Type, Loc] =
@@ -170,14 +204,13 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
170
204
dxbc::RTS0::v1::RootConstants Const =
171
205
RSD.ParametersContainer .getConstant (Loc);
172
206
173
- llvm::dxil::ResourceInfo::ResourceBinding Binding;
207
+ hlsl::rootsig::RangeInfo Binding;
174
208
Binding.LowerBound = Const.ShaderRegister ;
175
209
Binding.Space = Const.RegisterSpace ;
176
- Binding.Size = 1 ;
210
+ Binding.UpperBound = Binding. LowerBound ;
177
211
178
212
// Root Constants Bind to CBuffers
179
- Validation.addBinding (llvm::to_underlying (dxbc::DescriptorRangeType::CBV),
180
- Binding);
213
+ Validation.addBinding (ResourceClass::CBuffer, Binding);
181
214
182
215
break ;
183
216
}
@@ -188,24 +221,24 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
188
221
dxbc::RTS0::v2::RootDescriptor Desc =
189
222
RSD.ParametersContainer .getRootDescriptor (Loc);
190
223
191
- llvm::dxil::ResourceInfo::ResourceBinding Binding;
224
+ hlsl::rootsig::RangeInfo Binding;
192
225
Binding.LowerBound = Desc.ShaderRegister ;
193
226
Binding.Space = Desc.RegisterSpace ;
194
- Binding.Size = 1 ;
227
+ Binding.UpperBound = Binding. LowerBound ;
195
228
196
- Validation.addBinding (parameterToRangeType (Type), Binding);
229
+ Validation.addBinding (ParameterToResourceClass (Type), Binding);
197
230
break ;
198
231
}
199
232
case llvm::to_underlying (dxbc::RootParameterType::DescriptorTable): {
200
233
const mcdxbc::DescriptorTable &Table =
201
234
RSD.ParametersContainer .getDescriptorTable (Loc);
202
235
203
236
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges ) {
204
- llvm::dxil::ResourceInfo::ResourceBinding Binding;
237
+ hlsl::rootsig::RangeInfo Binding;
205
238
Binding.LowerBound = Range.BaseShaderRegister ;
206
239
Binding.Space = Range.RegisterSpace ;
207
- Binding.Size = Range.NumDescriptors ;
208
- Validation.addBinding (Range.RangeType , Binding);
240
+ Binding.UpperBound = Binding. LowerBound + Range.NumDescriptors - 1 ;
241
+ Validation.addBinding (RangeToResourceClass ( Range.RangeType ) , Binding);
209
242
}
210
243
break ;
211
244
}
@@ -227,34 +260,42 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
227
260
return RootSigDesc;
228
261
}
229
262
230
- static void reportInvalidRegistersBinding (
263
+ static void reportInvalidHandleTy (
264
+ Module &M,
265
+ const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator>
266
+ &Resources) {
267
+ for (auto Res = Resources.begin (), End = Resources.end (); Res != End; Res++) {
268
+ TargetExtType *Handle = Res->getHandleTy ();
269
+ auto *TypedBuffer = dyn_cast_or_null<TypedBufferExtType>(Handle);
270
+ auto *Texture = dyn_cast_or_null<TextureExtType>(Handle);
271
+
272
+ if (TypedBuffer != nullptr || Texture != nullptr )
273
+ reportInvalidHandleTyBoundInRs (M, Res->getName (), Res->getBinding ());
274
+ }
275
+ }
276
+
277
+ static void reportUnboundRegisters (
231
278
Module &M,
232
- const llvm::ArrayRef<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings,
279
+ const llvm::hlsl::rootsig::RootSignatureBindingValidation &Validation,
280
+ ResourceClass Class,
233
281
const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator>
234
282
&Resources) {
283
+ SmallVector<hlsl::rootsig::RangeInfo> Ranges;
235
284
for (auto Res = Resources.begin (), End = Resources.end (); Res != End; Res++) {
236
- bool Bound = false ;
237
285
ResourceInfo::ResourceBinding ResBinding = Res->getBinding ();
238
- for (const auto &Binding : Bindings) {
239
- if (ResBinding.Space == Binding.Space &&
240
- ResBinding.LowerBound >= Binding.LowerBound &&
241
- ResBinding.LowerBound + ResBinding.Size - 1 <
242
- Binding.LowerBound + Binding.Size ) {
243
- Bound = true ;
244
- break ;
245
- }
246
- }
247
- if (!Bound) {
248
- reportRegNotBound (M, Res->getName (), Res->getBinding ());
249
- } else {
250
- TargetExtType *Handle = Res->getHandleTy ();
251
- auto *TypedBuffer = dyn_cast_or_null<TypedBufferExtType>(Handle);
252
- auto *Texture = dyn_cast_or_null<TextureExtType>(Handle);
253
-
254
- if (TypedBuffer != nullptr || Texture != nullptr )
255
- reportInvalidHandleTyBoundInRs (M, Res->getName (), Res->getBinding ());
256
- }
286
+ hlsl::rootsig::RangeInfo Range;
287
+ Range.Space = ResBinding.Space ;
288
+ Range.LowerBound = ResBinding.LowerBound ;
289
+ Range.UpperBound = Range.LowerBound + ResBinding.Size - 1 ;
290
+ Range.Class = Class;
291
+ Ranges.push_back (Range);
257
292
}
293
+
294
+ SmallVector<hlsl::rootsig::RangeInfo> Unbounds =
295
+ hlsl::rootsig::findUnboundRanges (Ranges,
296
+ Validation.getBindingsOfType (Class));
297
+ for (const auto &Unbound : Unbounds)
298
+ reportRegNotBound (M, Unbound);
258
299
}
259
300
260
301
static void reportErrors (Module &M, DXILResourceMap &DRM,
@@ -272,21 +313,20 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
272
313
273
314
if (auto RSD = getRootSignature (RSBI, MMI)) {
274
315
275
- RootSignatureBindingValidation Validation =
316
+ llvm::hlsl::rootsig:: RootSignatureBindingValidation Validation =
276
317
initRSBindingValidation (*RSD, tripleToVisibility (MMI.ShaderProfile ));
277
318
278
- reportInvalidRegistersBinding (
279
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::CBV),
280
- DRM.cbuffers ());
281
- reportInvalidRegistersBinding (
282
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::UAV),
283
- DRM.uavs ());
284
- reportInvalidRegistersBinding (
285
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::Sampler),
286
- DRM.samplers ());
287
- reportInvalidRegistersBinding (
288
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::SRV),
289
- DRM.srvs ());
319
+ reportUnboundRegisters (M, Validation, ResourceClass::CBuffer,
320
+ DRM.cbuffers ());
321
+ reportUnboundRegisters (M, Validation, ResourceClass::UAV, DRM.uavs ());
322
+ reportUnboundRegisters (M, Validation, ResourceClass::Sampler,
323
+ DRM.samplers ());
324
+ reportUnboundRegisters (M, Validation, ResourceClass::SRV, DRM.srvs ());
325
+
326
+ reportInvalidHandleTy (M, DRM.cbuffers ());
327
+ reportInvalidHandleTy (M, DRM.srvs ());
328
+ reportInvalidHandleTy (M, DRM.uavs ());
329
+ reportInvalidHandleTy (M, DRM.samplers ());
290
330
}
291
331
}
292
332
} // namespace
0 commit comments