14
14
#include " llvm/ADT/StringRef.h"
15
15
#include " llvm/Analysis/DXILMetadataAnalysis.h"
16
16
#include " llvm/Analysis/DXILResource.h"
17
+ #include " llvm/BinaryFormat/DXContainer.h"
18
+ #include " llvm/Frontend/HLSL/HLSLBinding.h"
17
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/Support/DXILABI.h"
26
+ #include < utility>
23
27
24
28
#define DEBUG_TYPE " dxil-post-optimization-validation"
25
29
@@ -116,11 +120,12 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
116
120
}
117
121
}
118
122
119
- static void reportRegNotBound (Module &M,
120
- llvm::hlsl::rootsig::RangeInfo Unbound) {
123
+ static void
124
+ reportRegNotBound (Module &M, ResourceClass Class,
125
+ llvm::dxil::ResourceInfo::ResourceBinding Unbound) {
121
126
SmallString<128 > Message;
122
127
raw_svector_ostream OS (Message);
123
- OS << " register " << getResourceClassName (Unbound. Class )
128
+ OS << " register " << getResourceClassName (Class)
124
129
<< " (space=" << Unbound.Space << " , register=" << Unbound.LowerBound
125
130
<< " )"
126
131
<< " does not have a binding in the Root Signature" ;
@@ -155,12 +160,9 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
155
160
}
156
161
}
157
162
158
- static hlsl::rootsig::RootSignatureBindingValidation
159
- initRSBindingValidation (const mcdxbc::RootSignatureDesc &RSD,
160
- dxbc::ShaderVisibility Visibility) {
161
-
162
- hlsl::rootsig::RootSignatureBindingValidation Validation;
163
-
163
+ static void trackRootSigDescBinding (hlsl::BindingInfoBuilder &Builder,
164
+ const mcdxbc::RootSignatureDesc &RSD,
165
+ dxbc::ShaderVisibility Visibility) {
164
166
for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
165
167
const auto &[Type, Loc] =
166
168
RSD.ParametersContainer .getTypeAndLocForParameter (I);
@@ -175,15 +177,10 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
175
177
case llvm::to_underlying (dxbc::RootParameterType::Constants32Bit): {
176
178
dxbc::RTS0::v1::RootConstants Const =
177
179
RSD.ParametersContainer .getConstant (Loc);
178
-
179
- hlsl::rootsig::RangeInfo Binding;
180
- Binding.LowerBound = Const.ShaderRegister ;
181
- Binding.Space = Const.RegisterSpace ;
182
- Binding.UpperBound = Binding.LowerBound ;
183
-
184
- // Root Constants Bind to CBuffers
185
- Validation.addBinding (ResourceClass::CBuffer, Binding);
186
-
180
+ Builder.trackBinding (dxil::ResourceClass::CBuffer, Const.RegisterSpace ,
181
+ Const.ShaderRegister ,
182
+ Const.ShaderRegister + Const.Num32BitValues ,
183
+ nullptr );
187
184
break ;
188
185
}
189
186
@@ -192,32 +189,25 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
192
189
case llvm::to_underlying (dxbc::RootParameterType::CBV): {
193
190
dxbc::RTS0::v2::RootDescriptor Desc =
194
191
RSD.ParametersContainer .getRootDescriptor (Loc);
192
+ Builder.trackBinding (ParameterToResourceClass (Type), Desc.RegisterSpace ,
193
+ Desc.ShaderRegister , Desc.ShaderRegister , nullptr );
195
194
196
- hlsl::rootsig::RangeInfo Binding;
197
- Binding.LowerBound = Desc.ShaderRegister ;
198
- Binding.Space = Desc.RegisterSpace ;
199
- Binding.UpperBound = Binding.LowerBound ;
200
-
201
- Validation.addBinding (ParameterToResourceClass (Type), Binding);
202
195
break ;
203
196
}
204
197
case llvm::to_underlying (dxbc::RootParameterType::DescriptorTable): {
205
198
const mcdxbc::DescriptorTable &Table =
206
199
RSD.ParametersContainer .getDescriptorTable (Loc);
207
200
208
201
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges ) {
209
- hlsl::rootsig::RangeInfo Binding;
210
- Binding.LowerBound = Range.BaseShaderRegister ;
211
- Binding.Space = Range.RegisterSpace ;
212
- Binding.UpperBound = Binding.LowerBound + Range.NumDescriptors - 1 ;
213
- Validation.addBinding (RangeToResourceClass (Range.RangeType ), Binding);
202
+ Builder.trackBinding (RangeToResourceClass (Range.RangeType ),
203
+ Range.RegisterSpace , Range.BaseShaderRegister ,
204
+ Range.BaseShaderRegister + Range.NumDescriptors ,
205
+ nullptr );
214
206
}
215
207
break ;
216
208
}
217
209
}
218
210
}
219
-
220
- return Validation;
221
211
}
222
212
223
213
std::optional<mcdxbc::RootSignatureDesc>
@@ -232,30 +222,6 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
232
222
return RootSigDesc;
233
223
}
234
224
235
- static void reportUnboundRegisters (
236
- Module &M,
237
- const llvm::hlsl::rootsig::RootSignatureBindingValidation &Validation,
238
- ResourceClass Class,
239
- const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator>
240
- &Resources) {
241
- SmallVector<hlsl::rootsig::RangeInfo> Ranges;
242
- for (auto Res = Resources.begin (), End = Resources.end (); Res != End; Res++) {
243
- ResourceInfo::ResourceBinding ResBinding = Res->getBinding ();
244
- hlsl::rootsig::RangeInfo Range;
245
- Range.Space = ResBinding.Space ;
246
- Range.LowerBound = ResBinding.LowerBound ;
247
- Range.UpperBound = Range.LowerBound + ResBinding.Size - 1 ;
248
- Range.Class = Class;
249
- Ranges.push_back (Range);
250
- }
251
-
252
- SmallVector<hlsl::rootsig::RangeInfo> Unbounds =
253
- hlsl::rootsig::findUnboundRanges (Ranges,
254
- Validation.getBindingsOfType (Class));
255
- for (const auto &Unbound : Unbounds)
256
- reportRegNotBound (M, Unbound);
257
- }
258
-
259
225
static void reportErrors (Module &M, DXILResourceMap &DRM,
260
226
DXILResourceBindingInfo &DRBI,
261
227
RootSignatureBindingInfo &RSBI,
@@ -271,15 +237,29 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
271
237
272
238
if (auto RSD = getRootSignature (RSBI, MMI)) {
273
239
274
- llvm::hlsl::rootsig::RootSignatureBindingValidation Validation =
275
- initRSBindingValidation (*RSD, tripleToVisibility (MMI.ShaderProfile ));
276
-
277
- reportUnboundRegisters (M, Validation, ResourceClass::CBuffer,
278
- DRM.cbuffers ());
279
- reportUnboundRegisters (M, Validation, ResourceClass::UAV, DRM.uavs ());
280
- reportUnboundRegisters (M, Validation, ResourceClass::Sampler,
281
- DRM.samplers ());
282
- reportUnboundRegisters (M, Validation, ResourceClass::SRV, DRM.srvs ());
240
+ hlsl::BindingInfoBuilder Builder;
241
+ dxbc::ShaderVisibility Visibility = tripleToVisibility (MMI.ShaderProfile );
242
+ trackRootSigDescBinding (Builder, *RSD, Visibility);
243
+
244
+ bool HasOverlap;
245
+ hlsl::BindingInfo Info = Builder.calculateBindingInfo (HasOverlap);
246
+
247
+ for (const auto &ResList :
248
+ {std::make_pair (ResourceClass::SRV, DRM.srvs ()),
249
+ std::make_pair (ResourceClass::UAV, DRM.uavs ()),
250
+ std::make_pair (ResourceClass::CBuffer, DRM.cbuffers ()),
251
+ std::make_pair (ResourceClass::Sampler, DRM.samplers ())}) {
252
+ for (auto Res : ResList.second ) {
253
+ llvm::dxil::ResourceInfo::ResourceBinding ResBinding = Res.getBinding ();
254
+ llvm::hlsl::BindingInfo::BindingRange ResRange (
255
+ ResBinding.LowerBound , ResBinding.LowerBound + ResBinding.Size );
256
+
257
+ auto IsBound = Info.isBound (ResList.first , ResBinding.Space , ResRange);
258
+ if (!IsBound) {
259
+ reportRegNotBound (M, ResList.first , ResBinding);
260
+ }
261
+ }
262
+ }
283
263
}
284
264
}
285
265
} // namespace
0 commit comments