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 ()) {
@@ -87,12 +133,13 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
87
133
}
88
134
}
89
135
90
- static void reportRegNotBound (Module &M, Twine Type,
91
- ResourceInfo::ResourceBinding Binding ) {
136
+ static void reportRegNotBound (Module &M,
137
+ llvm::hlsl::rootsig::RangeInfo Unbound ) {
92
138
SmallString<128 > Message;
93
139
raw_svector_ostream OS (Message);
94
- OS << " register " << Type << " (space=" << Binding.Space
95
- << " , register=" << Binding.LowerBound << " )"
140
+ OS << " register " << ResourceClassToString (Unbound.Class )
141
+ << " (space=" << Unbound.Space << " , register=" << Unbound.LowerBound
142
+ << " )"
96
143
<< " is not defined in Root Signature" ;
97
144
M.getContext ().diagnose (DiagnosticInfoGeneric (Message));
98
145
}
@@ -125,24 +172,11 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
125
172
}
126
173
}
127
174
128
- static uint32_t parameterToRangeType (uint32_t Type) {
129
- switch (Type) {
130
- case llvm::to_underlying (dxbc::RootParameterType::CBV):
131
- return llvm::to_underlying (dxbc::DescriptorRangeType::CBV);
132
- case llvm::to_underlying (dxbc::RootParameterType::SRV):
133
- return llvm::to_underlying (dxbc::DescriptorRangeType::SRV);
134
- case llvm::to_underlying (dxbc::RootParameterType::UAV):
135
- return llvm::to_underlying (dxbc::DescriptorRangeType::UAV);
136
- default :
137
- llvm_unreachable (" Root Parameter Type has no Range Type equivalent" );
138
- }
139
- }
140
-
141
- static RootSignatureBindingValidation
175
+ static hlsl::rootsig::RootSignatureBindingValidation
142
176
initRSBindingValidation (const mcdxbc::RootSignatureDesc &RSD,
143
177
dxbc::ShaderVisibility Visibility) {
144
178
145
- RootSignatureBindingValidation Validation;
179
+ hlsl::rootsig:: RootSignatureBindingValidation Validation;
146
180
147
181
for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
148
182
const auto &[Type, Loc] =
@@ -159,14 +193,13 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
159
193
dxbc::RTS0::v1::RootConstants Const =
160
194
RSD.ParametersContainer .getConstant (Loc);
161
195
162
- llvm::dxil::ResourceInfo::ResourceBinding Binding;
196
+ hlsl::rootsig::RangeInfo Binding;
163
197
Binding.LowerBound = Const.ShaderRegister ;
164
198
Binding.Space = Const.RegisterSpace ;
165
- Binding.Size = 1 ;
199
+ Binding.UpperBound = Binding. LowerBound ;
166
200
167
201
// Root Constants Bind to CBuffers
168
- Validation.addBinding (llvm::to_underlying (dxbc::DescriptorRangeType::CBV),
169
- Binding);
202
+ Validation.addBinding (ResourceClass::CBuffer, Binding);
170
203
171
204
break ;
172
205
}
@@ -177,24 +210,24 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
177
210
dxbc::RTS0::v2::RootDescriptor Desc =
178
211
RSD.ParametersContainer .getRootDescriptor (Loc);
179
212
180
- llvm::dxil::ResourceInfo::ResourceBinding Binding;
213
+ hlsl::rootsig::RangeInfo Binding;
181
214
Binding.LowerBound = Desc.ShaderRegister ;
182
215
Binding.Space = Desc.RegisterSpace ;
183
- Binding.Size = 1 ;
216
+ Binding.UpperBound = Binding. LowerBound ;
184
217
185
- Validation.addBinding (parameterToRangeType (Type), Binding);
218
+ Validation.addBinding (ParameterToResourceClass (Type), Binding);
186
219
break ;
187
220
}
188
221
case llvm::to_underlying (dxbc::RootParameterType::DescriptorTable): {
189
222
const mcdxbc::DescriptorTable &Table =
190
223
RSD.ParametersContainer .getDescriptorTable (Loc);
191
224
192
225
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges ) {
193
- llvm::dxil::ResourceInfo::ResourceBinding Binding;
226
+ hlsl::rootsig::RangeInfo Binding;
194
227
Binding.LowerBound = Range.BaseShaderRegister ;
195
228
Binding.Space = Range.RegisterSpace ;
196
- Binding.Size = Range.NumDescriptors ;
197
- Validation.addBinding (Range.RangeType , Binding);
229
+ Binding.UpperBound = Binding. LowerBound + Range.NumDescriptors - 1 ;
230
+ Validation.addBinding (RangeToResourceClass ( Range.RangeType ) , Binding);
198
231
}
199
232
break ;
200
233
}
@@ -218,25 +251,26 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
218
251
219
252
static void reportUnboundRegisters (
220
253
Module &M,
221
- const llvm::ArrayRef<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings,
254
+ const llvm::hlsl::rootsig::RootSignatureBindingValidation &Validation,
255
+ ResourceClass Class,
222
256
const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator>
223
257
&Resources) {
258
+ SmallVector<hlsl::rootsig::RangeInfo> Ranges;
224
259
for (auto Res = Resources.begin (), End = Resources.end (); Res != End; Res++) {
225
- bool Bound = false ;
226
260
ResourceInfo::ResourceBinding ResBinding = Res->getBinding ();
227
- for (const auto &Binding : Bindings) {
228
- if (ResBinding.Space == Binding.Space &&
229
- ResBinding.LowerBound >= Binding.LowerBound &&
230
- ResBinding.LowerBound + ResBinding.Size - 1 <
231
- Binding.LowerBound + Binding.Size ) {
232
- Bound = true ;
233
- break ;
234
- }
235
- }
236
- if (!Bound) {
237
- reportRegNotBound (M, Res->getName (), Res->getBinding ());
238
- }
261
+ hlsl::rootsig::RangeInfo Range;
262
+ Range.Space = ResBinding.Space ;
263
+ Range.LowerBound = ResBinding.LowerBound ;
264
+ Range.UpperBound = Range.LowerBound + ResBinding.Size - 1 ;
265
+ Range.Class = Class;
266
+ Ranges.push_back (Range);
239
267
}
268
+
269
+ SmallVector<hlsl::rootsig::RangeInfo> Unbounds =
270
+ hlsl::rootsig::findUnboundRanges (Ranges,
271
+ Validation.getBindingsOfType (Class));
272
+ for (const auto &Unbound : Unbounds)
273
+ reportRegNotBound (M, Unbound);
240
274
}
241
275
242
276
static void reportErrors (Module &M, DXILResourceMap &DRM,
@@ -254,21 +288,15 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
254
288
255
289
if (auto RSD = getRootSignature (RSBI, MMI)) {
256
290
257
- RootSignatureBindingValidation Validation =
291
+ llvm::hlsl::rootsig:: RootSignatureBindingValidation Validation =
258
292
initRSBindingValidation (*RSD, tripleToVisibility (MMI.ShaderProfile ));
259
293
260
- reportUnboundRegisters (
261
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::CBV),
262
- DRM.cbuffers ());
263
- reportUnboundRegisters (
264
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::UAV),
265
- DRM.uavs ());
266
- reportUnboundRegisters (
267
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::Sampler),
268
- DRM.samplers ());
269
- reportUnboundRegisters (
270
- M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::SRV),
271
- DRM.srvs ());
294
+ reportUnboundRegisters (M, Validation, ResourceClass::CBuffer,
295
+ DRM.cbuffers ());
296
+ reportUnboundRegisters (M, Validation, ResourceClass::UAV, DRM.uavs ());
297
+ reportUnboundRegisters (M, Validation, ResourceClass::Sampler,
298
+ DRM.samplers ());
299
+ reportUnboundRegisters (M, Validation, ResourceClass::SRV, DRM.srvs ());
272
300
}
273
301
}
274
302
} // namespace
0 commit comments