10
10
#include " DXILRootSignature.h"
11
11
#include " DXILShaderFlags.h"
12
12
#include " DirectX.h"
13
+ #include " llvm/ADT/STLForwardCompat.h"
13
14
#include " llvm/ADT/SmallString.h"
15
+ #include " llvm/ADT/iterator_range.h"
14
16
#include " llvm/Analysis/DXILMetadataAnalysis.h"
15
17
#include " llvm/Analysis/DXILResource.h"
18
+ #include " llvm/BinaryFormat/DXContainer.h"
16
19
#include " llvm/IR/DiagnosticInfo.h"
17
20
#include " llvm/IR/Instructions.h"
18
21
#include " llvm/IR/IntrinsicsDirectX.h"
@@ -123,6 +126,70 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
123
126
}
124
127
}
125
128
129
+ static uint32_t parameterToRangeType (uint32_t Type) {
130
+ switch (Type) {
131
+ case llvm::to_underlying (dxbc::RootParameterType::CBV):
132
+ return llvm::to_underlying (dxbc::DescriptorRangeType::CBV);
133
+ break ;
134
+ case llvm::to_underlying (dxbc::RootParameterType::SRV):
135
+ return llvm::to_underlying (dxbc::DescriptorRangeType::SRV);
136
+ break ;
137
+ case llvm::to_underlying (dxbc::RootParameterType::UAV):
138
+ return llvm::to_underlying (dxbc::DescriptorRangeType::UAV);
139
+ break ;
140
+ default :
141
+ llvm_unreachable (" Root Parameter Type has no Range Type equivalent" );
142
+ }
143
+ }
144
+
145
+ static RootSignatureBindingValidation initRsBindingValdation (const mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) {
146
+
147
+ RootSignatureBindingValidation Validation;
148
+
149
+ for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
150
+ const auto &[Type, Loc] =
151
+ RSD.ParametersContainer .getTypeAndLocForParameter (I);
152
+
153
+ const auto &Header = RSD.ParametersContainer .getHeader (I);
154
+ if (Header.ShaderVisibility !=
155
+ llvm::to_underlying (dxbc::ShaderVisibility::All) &&
156
+ Header.ShaderVisibility != llvm::to_underlying (Visibility))
157
+ continue ;
158
+
159
+ switch (Type) {
160
+ case llvm::to_underlying (dxbc::RootParameterType::SRV):
161
+ case llvm::to_underlying (dxbc::RootParameterType::UAV):
162
+ case llvm::to_underlying (dxbc::RootParameterType::CBV): {
163
+ dxbc::RTS0::v2::RootDescriptor Desc =
164
+ RSD.ParametersContainer .getRootDescriptor (Loc);
165
+
166
+ llvm::dxil::ResourceInfo::ResourceBinding Binding;
167
+ Binding.LowerBound = Desc.ShaderRegister ;
168
+ Binding.Space = Desc.RegisterSpace ;
169
+ Binding.Size = 1 ;
170
+
171
+ Validation.addBinding (parameterToRangeType (Type), Binding);
172
+ break ;
173
+ }
174
+ case llvm::to_underlying (dxbc::RootParameterType::DescriptorTable): {
175
+ const mcdxbc::DescriptorTable &Table =
176
+ RSD.ParametersContainer .getDescriptorTable (Loc);
177
+
178
+ for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges ) {
179
+ llvm::dxil::ResourceInfo::ResourceBinding Binding;
180
+ Binding.LowerBound = Range.BaseShaderRegister ;
181
+ Binding.Space = Range.RegisterSpace ;
182
+ Binding.Size = Range.NumDescriptors ;
183
+ Validation.addBinding (Range.RangeType , Binding);
184
+ }
185
+ break ;
186
+ }
187
+ }
188
+ }
189
+
190
+ return Validation;
191
+ }
192
+
126
193
std::optional<mcdxbc::RootSignatureDesc>
127
194
getRootSignature (RootSignatureBindingInfo &RSBI,
128
195
dxil::ModuleMetadataInfo &MMI) {
@@ -135,6 +202,27 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
135
202
return RootSigDesc;
136
203
}
137
204
205
+ static void reportUnboundRegisters (
206
+ Module &M,
207
+ const std::vector<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings,
208
+ iterator_range<SmallVector<dxil::ResourceInfo>::iterator> &Resources) {
209
+ for (auto Res = Resources.begin (), End = Resources.end (); Res != End; Res++) {
210
+ bool Bound = false ;
211
+ ResourceInfo::ResourceBinding ResBinding = Res->getBinding ();
212
+ for (const auto &Binding : Bindings) {
213
+ if (ResBinding.Space == Binding.Space &&
214
+ ResBinding.LowerBound >= Binding.LowerBound &&
215
+ ResBinding.LowerBound < Binding.LowerBound + Binding.Size ) {
216
+ Bound = true ;
217
+ break ;
218
+ }
219
+ }
220
+ if (!Bound) {
221
+ reportRegNotBound (M, Res->getName (), Res->getBinding ());
222
+ }
223
+ }
224
+ }
225
+
138
226
static void reportErrors (Module &M, DXILResourceMap &DRM,
139
227
DXILResourceBindingInfo &DRBI,
140
228
RootSignatureBindingInfo &RSBI,
@@ -150,72 +238,21 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
150
238
151
239
if (auto RSD = getRootSignature (RSBI, MMI)) {
152
240
153
- RootSignatureBindingValidation Validation;
154
- Validation.addRsBindingInfo (*RSD, tripleToVisibility (MMI.ShaderProfile ));
155
-
156
- for (const ResourceInfo &CBuf : DRM.cbuffers ()) {
157
- ResourceInfo::ResourceBinding Binding = CBuf.getBinding ();
158
- if (!Validation.checkCRegBinding (Binding))
159
- reportRegNotBound (M, " cbuffer" , Binding);
160
- }
161
-
162
- for (const ResourceInfo &SRV : DRM.srvs ()) {
163
- ResourceInfo::ResourceBinding Binding = SRV.getBinding ();
164
- if (!Validation.checkTRegBinding (Binding))
165
- reportRegNotBound (M, " srv" , Binding);
166
- }
241
+ RootSignatureBindingValidation Validation = initRsBindingValdation (*RSD, tripleToVisibility (MMI.ShaderProfile ));
167
242
168
- for (const ResourceInfo &UAV : DRM.uavs ()) {
169
- ResourceInfo::ResourceBinding Binding = UAV.getBinding ();
170
- if (!Validation.checkURegBinding (Binding))
171
- reportRegNotBound (M, " uav" , Binding);
172
- }
243
+ auto Cbufs = DRM.cbuffers ();
244
+ auto SRVs = DRM.srvs ();
245
+ auto UAVs = DRM.uavs ();
246
+ auto Samplers = DRM.samplers ();
173
247
174
- for (const ResourceInfo &Sampler : DRM.samplers ()) {
175
- ResourceInfo::ResourceBinding Binding = Sampler.getBinding ();
176
- if (!Validation.checkSamplerBinding (Binding))
177
- reportRegNotBound (M, " sampler" , Binding);
178
- }
248
+ reportUnboundRegisters (M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::CBV), Cbufs);
249
+ reportUnboundRegisters (M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::UAV), UAVs);
250
+ reportUnboundRegisters (M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::Sampler), Samplers);
251
+ reportUnboundRegisters (M, Validation.getBindingsOfType (dxbc::DescriptorRangeType::SRV), SRVs);
179
252
}
180
253
}
181
254
} // namespace
182
255
183
- void RootSignatureBindingValidation::addRsBindingInfo (
184
- mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) {
185
- for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
186
- const auto &[Type, Loc] =
187
- RSD.ParametersContainer .getTypeAndLocForParameter (I);
188
-
189
- const auto &Header = RSD.ParametersContainer .getHeader (I);
190
- switch (Type) {
191
- case llvm::to_underlying (dxbc::RootParameterType::SRV):
192
- case llvm::to_underlying (dxbc::RootParameterType::UAV):
193
- case llvm::to_underlying (dxbc::RootParameterType::CBV): {
194
- dxbc::RTS0::v2::RootDescriptor Desc =
195
- RSD.ParametersContainer .getRootDescriptor (Loc);
196
-
197
- if (Header.ShaderVisibility ==
198
- llvm::to_underlying (dxbc::ShaderVisibility::All) ||
199
- Header.ShaderVisibility == llvm::to_underlying (Visibility))
200
- addRange (Desc, Type);
201
- break ;
202
- }
203
- case llvm::to_underlying (dxbc::RootParameterType::DescriptorTable): {
204
- const mcdxbc::DescriptorTable &Table =
205
- RSD.ParametersContainer .getDescriptorTable (Loc);
206
-
207
- for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges ) {
208
- if (Header.ShaderVisibility ==
209
- llvm::to_underlying (dxbc::ShaderVisibility::All) ||
210
- Header.ShaderVisibility == llvm::to_underlying (Visibility))
211
- addRange (Range);
212
- }
213
- break ;
214
- }
215
- }
216
- }
217
- }
218
-
219
256
PreservedAnalyses
220
257
DXILPostOptimizationValidation::run (Module &M, ModuleAnalysisManager &MAM) {
221
258
DXILResourceMap &DRM = MAM.getResult <DXILResourceAnalysis>(M);
@@ -252,8 +289,8 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
252
289
void getAnalysisUsage (llvm::AnalysisUsage &AU) const override {
253
290
AU.addRequired <DXILResourceWrapperPass>();
254
291
AU.addRequired <DXILResourceBindingWrapperPass>();
255
- AU.addRequired <RootSignatureAnalysisWrapper>();
256
292
AU.addRequired <DXILMetadataAnalysisWrapperPass>();
293
+ AU.addRequired <RootSignatureAnalysisWrapper>();
257
294
AU.addPreserved <DXILResourceWrapperPass>();
258
295
AU.addPreserved <DXILResourceBindingWrapperPass>();
259
296
AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
@@ -269,6 +306,7 @@ INITIALIZE_PASS_BEGIN(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
269
306
INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)
270
307
INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
271
308
INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
309
+ INITIALIZE_PASS_DEPENDENCY(RootSignatureAnalysisWrapper)
272
310
INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
273
311
" DXIL Post Optimization Validation" , false , false )
274
312
0 commit comments