1414#include " llvm/ADT/StringRef.h"
1515#include " llvm/Analysis/DXILMetadataAnalysis.h"
1616#include " llvm/Analysis/DXILResource.h"
17+ #include " llvm/BinaryFormat/DXContainer.h"
18+ #include " llvm/Frontend/HLSL/HLSLBinding.h"
1719#include " llvm/Frontend/HLSL/RootSignatureValidations.h"
1820#include " llvm/IR/DiagnosticInfo.h"
1921#include " llvm/IR/Instructions.h"
2022#include " llvm/IR/IntrinsicsDirectX.h"
2123#include " llvm/IR/Module.h"
2224#include " llvm/InitializePasses.h"
25+ #include " llvm/Support/DXILABI.h"
26+ #include < utility>
2327
2428#define DEBUG_TYPE " dxil-post-optimization-validation"
2529
@@ -116,11 +120,12 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
116120 }
117121}
118122
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) {
121126 SmallString<128 > Message;
122127 raw_svector_ostream OS (Message);
123- OS << " register " << getResourceClassName (Unbound. Class )
128+ OS << " register " << getResourceClassName (Class)
124129 << " (space=" << Unbound.Space << " , register=" << Unbound.LowerBound
125130 << " )"
126131 << " does not have a binding in the Root Signature" ;
@@ -155,12 +160,9 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
155160 }
156161}
157162
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) {
164166 for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
165167 const auto &[Type, Loc] =
166168 RSD.ParametersContainer .getTypeAndLocForParameter (I);
@@ -175,15 +177,10 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
175177 case llvm::to_underlying (dxbc::RootParameterType::Constants32Bit): {
176178 dxbc::RTS0::v1::RootConstants Const =
177179 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 );
187184 break ;
188185 }
189186
@@ -192,32 +189,25 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD,
192189 case llvm::to_underlying (dxbc::RootParameterType::CBV): {
193190 dxbc::RTS0::v2::RootDescriptor Desc =
194191 RSD.ParametersContainer .getRootDescriptor (Loc);
192+ Builder.trackBinding (ParameterToResourceClass (Type), Desc.RegisterSpace ,
193+ Desc.ShaderRegister , Desc.ShaderRegister , nullptr );
195194
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);
202195 break ;
203196 }
204197 case llvm::to_underlying (dxbc::RootParameterType::DescriptorTable): {
205198 const mcdxbc::DescriptorTable &Table =
206199 RSD.ParametersContainer .getDescriptorTable (Loc);
207200
208201 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 );
214206 }
215207 break ;
216208 }
217209 }
218210 }
219-
220- return Validation;
221211}
222212
223213std::optional<mcdxbc::RootSignatureDesc>
@@ -232,30 +222,6 @@ getRootSignature(RootSignatureBindingInfo &RSBI,
232222 return RootSigDesc;
233223}
234224
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-
259225static void reportErrors (Module &M, DXILResourceMap &DRM,
260226 DXILResourceBindingInfo &DRBI,
261227 RootSignatureBindingInfo &RSBI,
@@ -271,15 +237,29 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
271237
272238 if (auto RSD = getRootSignature (RSBI, MMI)) {
273239
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+ }
283263 }
284264}
285265} // namespace
0 commit comments