@@ -84,9 +84,57 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
84
84
}
85
85
}
86
86
}
87
- uint64_t combine_uint32_to_uint64 (uint32_t high, uint32_t low) {
88
- return (static_cast <uint64_t >(high) << 32 ) | low;
87
+
88
+ static void reportRegNotBound (Module &M, Twine Type,
89
+ ResourceInfo::ResourceBinding Binding) {
90
+ SmallString<128 > Message;
91
+ raw_svector_ostream OS (Message);
92
+ OS << " register " << Type << " (space=" << Binding.Space
93
+ << " , register=" << Binding.LowerBound << " )"
94
+ << " is not defined in Root Signature" ;
95
+ M.getContext ().diagnose (DiagnosticInfoGeneric (Message));
96
+ }
97
+
98
+ static dxbc::ShaderVisibility
99
+ tripleToVisibility (llvm::Triple::EnvironmentType ET) {
100
+ assert ((ET == Triple::Pixel || ET == Triple::Vertex ||
101
+ ET == Triple::Geometry || ET == Triple::Hull ||
102
+ ET == Triple::Domain || ET == Triple::Mesh ||
103
+ ET == Triple::Compute) &&
104
+ " Invalid Triple to shader stage conversion" );
105
+
106
+ switch (ET) {
107
+ case Triple::Pixel:
108
+ return dxbc::ShaderVisibility::Pixel;
109
+ case Triple::Vertex:
110
+ return dxbc::ShaderVisibility::Vertex;
111
+ case Triple::Geometry:
112
+ return dxbc::ShaderVisibility::Geometry;
113
+ case Triple::Hull:
114
+ return dxbc::ShaderVisibility::Hull;
115
+ case Triple::Domain:
116
+ return dxbc::ShaderVisibility::Domain;
117
+ case Triple::Mesh:
118
+ return dxbc::ShaderVisibility::Mesh;
119
+ case Triple::Compute:
120
+ return dxbc::ShaderVisibility::All;
121
+ default :
122
+ llvm_unreachable (" Invalid triple to shader stage conversion" );
89
123
}
124
+ }
125
+
126
+ std::optional<mcdxbc::RootSignatureDesc>
127
+ getRootSignature (RootSignatureBindingInfo &RSBI,
128
+ dxil::ModuleMetadataInfo &MMI) {
129
+ if (MMI.EntryPropertyVec .size () == 0 )
130
+ return std::nullopt;
131
+ std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
132
+ RSBI.getDescForFunction (MMI.EntryPropertyVec [0 ].Entry );
133
+ if (!RootSigDesc)
134
+ return std::nullopt;
135
+ return RootSigDesc;
136
+ }
137
+
90
138
static void reportErrors (Module &M, DXILResourceMap &DRM,
91
139
DXILResourceBindingInfo &DRBI,
92
140
RootSignatureBindingInfo &RSBI,
@@ -99,57 +147,95 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
99
147
100
148
assert (!DRBI.hasImplicitBinding () && " implicit bindings should be handled in "
101
149
" DXILResourceImplicitBinding pass" );
102
- // Assuming this is used to validate only the root signature assigned to the
103
- // entry function.
104
- // Start test stuff
105
- if (MMI.EntryPropertyVec .size () == 0 )
106
- return ;
107
150
108
- std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
109
- RSBI.getDescForFunction (MMI.EntryPropertyVec [0 ].Entry );
110
- if (!RootSigDesc)
111
- return ;
151
+ if (auto RSD = getRootSignature (RSBI, MMI)) {
152
+
153
+ RootSignatureBindingValidation Validation;
154
+ Validation.addRsBindingInfo (*RSD, tripleToVisibility (MMI.ShaderProfile ));
155
+
156
+ for (const auto &CBuf : DRM.cbuffers ()) {
157
+ ResourceInfo::ResourceBinding Binding = CBuf.getBinding ();
158
+ if (!Validation.checkCregBinding (Binding))
159
+ reportRegNotBound (M, " cbuffer" , Binding);
160
+ }
161
+
162
+ for (const auto &CBuf : DRM.srvs ()) {
163
+ ResourceInfo::ResourceBinding Binding = CBuf.getBinding ();
164
+ if (!Validation.checkTRegBinding (Binding))
165
+ reportRegNotBound (M, " srv" , Binding);
166
+ }
112
167
113
- using MapT = llvm::IntervalMap<uint64_t , llvm::dxil::ResourceInfo::ResourceBinding, sizeof (llvm::dxil::ResourceInfo::ResourceBinding), llvm::IntervalMapInfo<uint64_t >>;
114
- MapT::Allocator Allocator;
115
- MapT BindingsMap (Allocator);
116
- auto RSD = *RootSigDesc;
117
- for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
168
+ for (const auto &CBuf : DRM.uavs ()) {
169
+ ResourceInfo::ResourceBinding Binding = CBuf.getBinding ();
170
+ if (!Validation.checkURegBinding (Binding))
171
+ reportRegNotBound (M, " uav" , Binding);
172
+ }
173
+ }
174
+ }
175
+ } // namespace
176
+
177
+ void RootSignatureBindingValidation::addRsBindingInfo (
178
+ mcdxbc::RootSignatureDesc &RSD, dxbc::ShaderVisibility Visibility) {
179
+ for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
118
180
const auto &[Type, Loc] =
119
- RootSigDesc->ParametersContainer .getTypeAndLocForParameter (I);
181
+ RSD.ParametersContainer .getTypeAndLocForParameter (I);
182
+
183
+ const auto &Header = RSD.ParametersContainer .getHeader (I);
120
184
switch (Type) {
121
- case llvm::to_underlying (dxbc::RootParameterType::CBV):{
185
+ case llvm::to_underlying (dxbc::RootParameterType::SRV):
186
+ case llvm::to_underlying (dxbc::RootParameterType::UAV):
187
+ case llvm::to_underlying (dxbc::RootParameterType::CBV): {
122
188
dxbc::RTS0::v2::RootDescriptor Desc =
123
- RootSigDesc-> ParametersContainer .getRootDescriptor (Loc);
189
+ RSD. ParametersContainer .getRootDescriptor (Loc);
124
190
125
- llvm::dxil::ResourceInfo::ResourceBinding Binding;
126
- Binding.LowerBound = Desc.ShaderRegister ;
127
- Binding.Space = Desc.RegisterSpace ;
128
- Binding.Size = 1 ;
191
+ if (Header.ShaderVisibility ==
192
+ llvm::to_underlying (dxbc::ShaderVisibility::All) ||
193
+ Header.ShaderVisibility == llvm::to_underlying (Visibility))
194
+ addRange (Desc, Type);
195
+ break ;
196
+ }
197
+ case llvm::to_underlying (dxbc::RootParameterType::DescriptorTable): {
198
+ const mcdxbc::DescriptorTable &Table =
199
+ RSD.ParametersContainer .getDescriptorTable (Loc);
129
200
130
- BindingsMap.insert (combine_uint32_to_uint64 (Binding.Space , Binding.LowerBound ), combine_uint32_to_uint64 (Binding.Space , Binding.LowerBound + Binding.Size -1 ), Binding);
201
+ for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges ) {
202
+ if (Range.RangeType ==
203
+ llvm::to_underlying (dxbc::DescriptorRangeType::Sampler))
204
+ continue ;
205
+
206
+ if (Header.ShaderVisibility ==
207
+ llvm::to_underlying (dxbc::ShaderVisibility::All) ||
208
+ Header.ShaderVisibility == llvm::to_underlying (Visibility))
209
+ addRange (Range);
210
+ }
131
211
break ;
132
212
}
133
- // case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):{
134
- // mcdxbc::DescriptorTable Table =
135
- // RootSigDesc->ParametersContainer.getDescriptorTable(Loc);
136
- // for (const dxbc::RTS0::v2::DescriptorRange &Range : Table){
137
- // Range.
138
- // }
139
-
140
- // break;
141
- // }
142
213
}
143
-
144
214
}
215
+ }
145
216
146
- for (const auto &CBuf : DRM.cbuffers ()) {
147
- auto Binding = CBuf.getBinding ();
148
- if (!BindingsMap.overlaps (combine_uint32_to_uint64 (Binding.Space , Binding.LowerBound ), combine_uint32_to_uint64 (Binding.Space , Binding.LowerBound + Binding.Size -1 )))
149
- auto X = 1 ;
150
- }
217
+ bool RootSignatureBindingValidation::checkCregBinding (
218
+ ResourceInfo::ResourceBinding Binding) {
219
+ return CRegBindingsMap.overlaps (
220
+ combineUint32ToUint64 (Binding.Space , Binding.LowerBound ),
221
+ combineUint32ToUint64 (Binding.Space ,
222
+ Binding.LowerBound + Binding.Size - 1 ));
223
+ }
224
+
225
+ bool RootSignatureBindingValidation::checkTRegBinding (
226
+ ResourceInfo::ResourceBinding Binding) {
227
+ return TRegBindingsMap.overlaps (
228
+ combineUint32ToUint64 (Binding.Space , Binding.LowerBound ),
229
+ combineUint32ToUint64 (Binding.Space , Binding.LowerBound + Binding.Size ));
230
+ }
231
+
232
+ bool RootSignatureBindingValidation::checkURegBinding (
233
+ ResourceInfo::ResourceBinding Binding) {
234
+ return URegBindingsMap.overlaps (
235
+ combineUint32ToUint64 (Binding.Space , Binding.LowerBound ),
236
+ combineUint32ToUint64 (Binding.Space ,
237
+ Binding.LowerBound + Binding.Size - 1 ));
151
238
}
152
- } // namespace
153
239
154
240
PreservedAnalyses
155
241
DXILPostOptimizationValidation::run (Module &M, ModuleAnalysisManager &MAM) {
0 commit comments