77// ===----------------------------------------------------------------------===//
88
99#include " DXILPostOptimizationValidation.h"
10+ #include " DXILRootSignature.h"
1011#include " DXILShaderFlags.h"
1112#include " DirectX.h"
13+ #include " llvm/ADT/STLForwardCompat.h"
1214#include " llvm/ADT/SmallString.h"
1315#include " llvm/Analysis/DXILMetadataAnalysis.h"
1416#include " llvm/Analysis/DXILResource.h"
17+ #include " llvm/BinaryFormat/DXContainer.h"
1518#include " llvm/IR/DiagnosticInfo.h"
1619#include " llvm/IR/Instructions.h"
1720#include " llvm/IR/IntrinsicsDirectX.h"
@@ -85,7 +88,9 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
8588}
8689
8790static void reportErrors (Module &M, DXILResourceMap &DRM,
88- DXILResourceBindingInfo &DRBI) {
91+ DXILResourceBindingInfo &DRBI,
92+ RootSignatureBindingInfo &RSBI,
93+ dxil::ModuleMetadataInfo &MMI) {
8994 if (DRM.hasInvalidCounterDirection ())
9095 reportInvalidDirection (M, DRM);
9196
@@ -94,14 +99,41 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
9499
95100 assert (!DRBI.hasImplicitBinding () && " implicit bindings should be handled in "
96101 " DXILResourceImplicitBinding pass" );
102+ // Assuming this is used to validate only the root signature assigned to the
103+ // entry function.
104+ std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
105+ RSBI.getDescForFunction (MMI.EntryPropertyVec [0 ].Entry );
106+ if (!RootSigDesc)
107+ return ;
108+
109+ for (const mcdxbc::RootParameterInfo &Info :
110+ RootSigDesc->ParametersContainer ) {
111+ const auto &[Type, Loc] =
112+ RootSigDesc->ParametersContainer .getTypeAndLocForParameter (
113+ Info.Location );
114+ switch (Type) {
115+ case llvm::to_underlying (dxbc::RootParameterType::CBV):
116+ dxbc::RTS0::v2::RootDescriptor Desc =
117+ RootSigDesc->ParametersContainer .getRootDescriptor (Loc);
118+
119+ llvm::dxil::ResourceInfo::ResourceBinding Binding;
120+ Binding.LowerBound = Desc.ShaderRegister ;
121+ Binding.Space = Desc.RegisterSpace ;
122+ Binding.Size = 1 ;
123+ break ;
124+ }
125+ }
97126}
98127} // namespace
99128
100129PreservedAnalyses
101130DXILPostOptimizationValidation::run (Module &M, ModuleAnalysisManager &MAM) {
102131 DXILResourceMap &DRM = MAM.getResult <DXILResourceAnalysis>(M);
103132 DXILResourceBindingInfo &DRBI = MAM.getResult <DXILResourceBindingAnalysis>(M);
104- reportErrors (M, DRM, DRBI);
133+ RootSignatureBindingInfo &RSBI = MAM.getResult <RootSignatureAnalysis>(M);
134+ ModuleMetadataInfo &MMI = MAM.getResult <DXILMetadataAnalysis>(M);
135+
136+ reportErrors (M, DRM, DRBI, RSBI, MMI);
105137 return PreservedAnalyses::all ();
106138}
107139
@@ -113,7 +145,13 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
113145 getAnalysis<DXILResourceWrapperPass>().getResourceMap ();
114146 DXILResourceBindingInfo &DRBI =
115147 getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo ();
116- reportErrors (M, DRM, DRBI);
148+
149+ RootSignatureBindingInfo &RSBI =
150+ getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo ();
151+ dxil::ModuleMetadataInfo &MMI =
152+ getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata ();
153+
154+ reportErrors (M, DRM, DRBI, RSBI, MMI);
117155 return false ;
118156 }
119157 StringRef getPassName () const override {
@@ -125,10 +163,13 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
125163 void getAnalysisUsage (llvm::AnalysisUsage &AU) const override {
126164 AU.addRequired <DXILResourceWrapperPass>();
127165 AU.addRequired <DXILResourceBindingWrapperPass>();
166+ AU.addRequired <RootSignatureAnalysisWrapper>();
167+ AU.addRequired <DXILMetadataAnalysisWrapperPass>();
128168 AU.addPreserved <DXILResourceWrapperPass>();
129169 AU.addPreserved <DXILResourceBindingWrapperPass>();
130170 AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
131171 AU.addPreserved <ShaderFlagsAnalysisWrapper>();
172+ AU.addPreserved <RootSignatureAnalysisWrapper>();
132173 }
133174};
134175char DXILPostOptimizationValidationLegacy::ID = 0 ;
0 commit comments