13
13
#include " llvm/ADT/SmallString.h"
14
14
#include " llvm/Analysis/DXILMetadataAnalysis.h"
15
15
#include " llvm/Analysis/DXILResource.h"
16
+ #include " llvm/BinaryFormat/DXContainer.h"
16
17
#include " llvm/IR/DiagnosticInfo.h"
17
18
#include " llvm/IR/Instructions.h"
18
19
#include " llvm/IR/IntrinsicsDirectX.h"
19
20
#include " llvm/IR/Module.h"
20
21
#include " llvm/InitializePasses.h"
22
+ #include < cstdint>
21
23
22
24
#define DEBUG_TYPE " dxil-post-optimization-validation"
23
25
24
26
using namespace llvm ;
25
27
using namespace llvm ::dxil;
26
28
27
- namespace {
28
- static ResourceClass RangeToResourceClass (uint32_t RangeType) {
29
+ static ResourceClass toResourceClass (dxbc::DescriptorRangeType RangeType) {
29
30
using namespace dxbc ;
30
- switch (static_cast <DescriptorRangeType>( RangeType) ) {
31
+ switch (RangeType) {
31
32
case DescriptorRangeType::SRV:
32
33
return ResourceClass::SRV;
33
34
case DescriptorRangeType::UAV:
@@ -39,20 +40,21 @@ static ResourceClass RangeToResourceClass(uint32_t RangeType) {
39
40
}
40
41
}
41
42
42
- ResourceClass ParameterToResourceClass ( uint32_t Type) {
43
+ static ResourceClass toResourceClass (dxbc::RootParameterType Type) {
43
44
using namespace dxbc ;
44
45
switch (Type) {
45
- case llvm::to_underlying ( RootParameterType::Constants32Bit) :
46
+ case RootParameterType::Constants32Bit:
46
47
return ResourceClass::CBuffer;
47
- case llvm::to_underlying ( RootParameterType::SRV) :
48
+ case RootParameterType::SRV:
48
49
return ResourceClass::SRV;
49
- case llvm::to_underlying ( RootParameterType::UAV) :
50
+ case RootParameterType::UAV:
50
51
return ResourceClass::UAV;
51
- case llvm::to_underlying ( RootParameterType::CBV) :
52
+ case RootParameterType::CBV:
52
53
return ResourceClass::CBuffer;
53
- default :
54
- llvm_unreachable ( " Unknown RootParameterType " ) ;
54
+ case dxbc::RootParameterType::DescriptorTable :
55
+ break ;
55
56
}
57
+ llvm_unreachable (" Unconvertible RootParameterType" );
56
58
}
57
59
58
60
static void reportInvalidDirection (Module &M, DXILResourceMap &DRM) {
@@ -131,12 +133,6 @@ static void reportOverlappingRegisters(
131
133
132
134
static dxbc::ShaderVisibility
133
135
tripleToVisibility (llvm::Triple::EnvironmentType ET) {
134
- assert ((ET == Triple::Pixel || ET == Triple::Vertex ||
135
- ET == Triple::Geometry || ET == Triple::Hull ||
136
- ET == Triple::Domain || ET == Triple::Mesh ||
137
- ET == Triple::Compute) &&
138
- " Invalid Triple to shader stage conversion" );
139
-
140
136
switch (ET) {
141
137
case Triple::Pixel:
142
138
return dxbc::ShaderVisibility::Pixel;
@@ -157,73 +153,80 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
157
153
}
158
154
}
159
155
160
- static void trackRootSigDescBinding (hlsl::BindingInfoBuilder &Builder,
161
- const mcdxbc::RootSignatureDesc &RSD,
162
- dxbc::ShaderVisibility Visibility) {
163
- for (size_t I = 0 ; I < RSD.ParametersContainer .size (); I++) {
164
- const auto &[Type, Loc] =
165
- RSD.ParametersContainer .getTypeAndLocForParameter (I);
166
-
167
- const auto &Header = RSD.ParametersContainer .getHeader (I);
168
- if (Header.ShaderVisibility !=
169
- llvm::to_underlying (dxbc::ShaderVisibility::All) &&
170
- Header.ShaderVisibility != llvm::to_underlying (Visibility))
171
- continue ;
156
+ static void validateRootSignature (Module &M,
157
+ const mcdxbc::RootSignatureDesc &RSD,
158
+ dxil::ModuleMetadataInfo &MMI) {
172
159
173
- switch (Type) {
174
- case llvm::to_underlying (dxbc::RootParameterType::Constants32Bit): {
160
+ hlsl::BindingInfoBuilder Builder;
161
+ dxbc::ShaderVisibility Visibility = tripleToVisibility (MMI.ShaderProfile );
162
+
163
+ for (const mcdxbc::RootParameterInfo &ParamInfo : RSD.ParametersContainer ) {
164
+ dxbc::ShaderVisibility ParamVisibility =
165
+ static_cast <dxbc::ShaderVisibility>(ParamInfo.Header .ShaderVisibility );
166
+ if (ParamVisibility != dxbc::ShaderVisibility::All &&
167
+ ParamVisibility != Visibility)
168
+ continue ;
169
+ dxbc::RootParameterType ParamType =
170
+ static_cast <dxbc::RootParameterType>(ParamInfo.Header .ParameterType );
171
+ switch (ParamType) {
172
+ case dxbc::RootParameterType::Constants32Bit: {
175
173
dxbc::RTS0::v1::RootConstants Const =
176
- RSD.ParametersContainer .getConstant (Loc );
174
+ RSD.ParametersContainer .getConstant (ParamInfo. Location );
177
175
Builder.trackBinding (dxil::ResourceClass::CBuffer, Const.RegisterSpace ,
178
- Const.ShaderRegister ,
179
- Const.ShaderRegister + Const.Num32BitValues , &Const);
176
+ Const.ShaderRegister , Const.ShaderRegister , nullptr );
180
177
break ;
181
178
}
182
179
183
- case llvm::to_underlying ( dxbc::RootParameterType::SRV) :
184
- case llvm::to_underlying ( dxbc::RootParameterType::UAV) :
185
- case llvm::to_underlying ( dxbc::RootParameterType::CBV) : {
180
+ case dxbc::RootParameterType::SRV:
181
+ case dxbc::RootParameterType::UAV:
182
+ case dxbc::RootParameterType::CBV: {
186
183
dxbc::RTS0::v2::RootDescriptor Desc =
187
- RSD.ParametersContainer .getRootDescriptor (Loc);
188
- Builder.trackBinding (ParameterToResourceClass (Type), Desc.RegisterSpace ,
189
- Desc.ShaderRegister , Desc.ShaderRegister , &Desc);
184
+ RSD.ParametersContainer .getRootDescriptor (ParamInfo.Location );
185
+ Builder.trackBinding (toResourceClass (static_cast <dxbc::RootParameterType>(
186
+ ParamInfo.Header .ParameterType )),
187
+ Desc.RegisterSpace , Desc.ShaderRegister ,
188
+ Desc.ShaderRegister , nullptr );
190
189
191
190
break ;
192
191
}
193
- case llvm::to_underlying ( dxbc::RootParameterType::DescriptorTable) : {
192
+ case dxbc::RootParameterType::DescriptorTable: {
194
193
const mcdxbc::DescriptorTable &Table =
195
- RSD.ParametersContainer .getDescriptorTable (Loc );
194
+ RSD.ParametersContainer .getDescriptorTable (ParamInfo. Location );
196
195
197
196
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges ) {
198
- Builder.trackBinding (RangeToResourceClass (Range.RangeType ),
199
- Range.RegisterSpace , Range.BaseShaderRegister ,
200
- Range.NumDescriptors == ~0U
201
- ? Range.NumDescriptors
202
- : Range.BaseShaderRegister +
203
- Range.NumDescriptors ,
204
- &Range);
197
+ uint32_t UpperBound =
198
+ Range.NumDescriptors == ~0U
199
+ ? Range.BaseShaderRegister
200
+ : Range.BaseShaderRegister + Range.NumDescriptors - 1 ;
201
+ Builder.trackBinding (
202
+ toResourceClass (
203
+ static_cast <dxbc::DescriptorRangeType>(Range.RangeType )),
204
+ Range.RegisterSpace , Range.BaseShaderRegister , UpperBound, nullptr );
205
205
}
206
206
break ;
207
207
}
208
208
}
209
209
}
210
210
211
- for (auto &S : RSD.StaticSamplers ) {
211
+ for (const dxbc::RTS0::v1::StaticSampler &S : RSD.StaticSamplers )
212
212
Builder.trackBinding (dxil::ResourceClass::Sampler, S.RegisterSpace ,
213
- S.ShaderRegister , S.ShaderRegister , &S);
214
- }
213
+ S.ShaderRegister , S.ShaderRegister , nullptr );
214
+
215
+ hlsl::BindingInfo Info = Builder.calculateBindingInfo (
216
+ [&M](const llvm::hlsl::BindingInfoBuilder &Builder,
217
+ const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
218
+ const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
219
+ Builder.findOverlapping (ReportedBinding);
220
+ reportOverlappingRegisters (M, ReportedBinding, Overlaping);
221
+ });
215
222
}
216
223
217
- std::optional< mcdxbc::RootSignatureDesc>
224
+ static mcdxbc::RootSignatureDesc *
218
225
getRootSignature (RootSignatureBindingInfo &RSBI,
219
226
dxil::ModuleMetadataInfo &MMI) {
220
227
if (MMI.EntryPropertyVec .size () == 0 )
221
- return std::nullopt;
222
- std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
223
- RSBI.getDescForFunction (MMI.EntryPropertyVec [0 ].Entry );
224
- if (!RootSigDesc)
225
- return std::nullopt;
226
- return RootSigDesc;
228
+ return nullptr ;
229
+ return RSBI.getDescForFunction (MMI.EntryPropertyVec [0 ].Entry );
227
230
}
228
231
229
232
static void reportErrors (Module &M, DXILResourceMap &DRM,
@@ -239,21 +242,9 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
239
242
assert (!DRBI.hasImplicitBinding () && " implicit bindings should be handled in "
240
243
" DXILResourceImplicitBinding pass" );
241
244
242
- if (auto RSD = getRootSignature (RSBI, MMI)) {
243
-
244
- hlsl::BindingInfoBuilder Builder;
245
- dxbc::ShaderVisibility Visibility = tripleToVisibility (MMI.ShaderProfile );
246
- trackRootSigDescBinding (Builder, *RSD, Visibility);
247
- hlsl::BindingInfo Info = Builder.calculateBindingInfo (
248
- [&M](const llvm::hlsl::BindingInfoBuilder &Builder,
249
- const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
250
- const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
251
- Builder.findOverlapping (ReportedBinding);
252
- reportOverlappingRegisters (M, ReportedBinding, Overlaping);
253
- });
254
- }
245
+ if (mcdxbc::RootSignatureDesc *RSD = getRootSignature (RSBI, MMI))
246
+ validateRootSignature (M, *RSD, MMI);
255
247
}
256
- } // namespace
257
248
258
249
PreservedAnalyses
259
250
DXILPostOptimizationValidation::run (Module &M, ModuleAnalysisManager &MAM) {
0 commit comments