Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Utils/DXILResource.cpp
35271 views
1
//===- DXILResource.cpp - Tools to translate DXIL resources ---------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/Transforms/Utils/DXILResource.h"
10
#include "llvm/ADT/APInt.h"
11
#include "llvm/IR/DerivedTypes.h"
12
13
using namespace llvm;
14
using namespace dxil;
15
16
bool ResourceInfo::isUAV() const { return RC == ResourceClass::UAV; }
17
18
bool ResourceInfo::isCBuffer() const { return RC == ResourceClass::CBuffer; }
19
20
bool ResourceInfo::isSampler() const { return RC == ResourceClass::Sampler; }
21
22
bool ResourceInfo::isStruct() const {
23
return Kind == ResourceKind::StructuredBuffer;
24
}
25
26
bool ResourceInfo::isTyped() const {
27
switch (Kind) {
28
case ResourceKind::Texture1D:
29
case ResourceKind::Texture2D:
30
case ResourceKind::Texture2DMS:
31
case ResourceKind::Texture3D:
32
case ResourceKind::TextureCube:
33
case ResourceKind::Texture1DArray:
34
case ResourceKind::Texture2DArray:
35
case ResourceKind::Texture2DMSArray:
36
case ResourceKind::TextureCubeArray:
37
case ResourceKind::TypedBuffer:
38
return true;
39
case ResourceKind::RawBuffer:
40
case ResourceKind::StructuredBuffer:
41
case ResourceKind::FeedbackTexture2D:
42
case ResourceKind::FeedbackTexture2DArray:
43
case ResourceKind::CBuffer:
44
case ResourceKind::Sampler:
45
case ResourceKind::TBuffer:
46
case ResourceKind::RTAccelerationStructure:
47
return false;
48
case ResourceKind::Invalid:
49
case ResourceKind::NumEntries:
50
llvm_unreachable("Invalid resource kind");
51
}
52
llvm_unreachable("Unhandled ResourceKind enum");
53
}
54
55
bool ResourceInfo::isFeedback() const {
56
return Kind == ResourceKind::FeedbackTexture2D ||
57
Kind == ResourceKind::FeedbackTexture2DArray;
58
}
59
60
bool ResourceInfo::isMultiSample() const {
61
return Kind == ResourceKind::Texture2DMS ||
62
Kind == ResourceKind::Texture2DMSArray;
63
}
64
65
ResourceInfo ResourceInfo::SRV(Value *Symbol, StringRef Name,
66
ResourceBinding Binding, uint32_t UniqueID,
67
ElementType ElementTy, uint32_t ElementCount,
68
ResourceKind Kind) {
69
ResourceInfo RI(ResourceClass::SRV, Kind, Symbol, Name, Binding, UniqueID);
70
assert(RI.isTyped() && !(RI.isStruct() || RI.isMultiSample()) &&
71
"Invalid ResourceKind for SRV constructor.");
72
RI.Typed.ElementTy = ElementTy;
73
RI.Typed.ElementCount = ElementCount;
74
return RI;
75
}
76
77
ResourceInfo ResourceInfo::RawBuffer(Value *Symbol, StringRef Name,
78
ResourceBinding Binding,
79
uint32_t UniqueID) {
80
ResourceInfo RI(ResourceClass::SRV, ResourceKind::RawBuffer, Symbol, Name,
81
Binding, UniqueID);
82
return RI;
83
}
84
85
ResourceInfo ResourceInfo::StructuredBuffer(Value *Symbol, StringRef Name,
86
ResourceBinding Binding,
87
uint32_t UniqueID, uint32_t Stride,
88
Align Alignment) {
89
ResourceInfo RI(ResourceClass::SRV, ResourceKind::StructuredBuffer, Symbol,
90
Name, Binding, UniqueID);
91
RI.Struct.Stride = Stride;
92
RI.Struct.Alignment = Alignment;
93
return RI;
94
}
95
96
ResourceInfo ResourceInfo::Texture2DMS(Value *Symbol, StringRef Name,
97
ResourceBinding Binding,
98
uint32_t UniqueID, ElementType ElementTy,
99
uint32_t ElementCount,
100
uint32_t SampleCount) {
101
ResourceInfo RI(ResourceClass::SRV, ResourceKind::Texture2DMS, Symbol, Name,
102
Binding, UniqueID);
103
RI.Typed.ElementTy = ElementTy;
104
RI.Typed.ElementCount = ElementCount;
105
RI.MultiSample.Count = SampleCount;
106
return RI;
107
}
108
109
ResourceInfo ResourceInfo::Texture2DMSArray(
110
Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID,
111
ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount) {
112
ResourceInfo RI(ResourceClass::SRV, ResourceKind::Texture2DMSArray, Symbol,
113
Name, Binding, UniqueID);
114
RI.Typed.ElementTy = ElementTy;
115
RI.Typed.ElementCount = ElementCount;
116
RI.MultiSample.Count = SampleCount;
117
return RI;
118
}
119
120
ResourceInfo ResourceInfo::UAV(Value *Symbol, StringRef Name,
121
ResourceBinding Binding, uint32_t UniqueID,
122
ElementType ElementTy, uint32_t ElementCount,
123
bool GloballyCoherent, bool IsROV,
124
ResourceKind Kind) {
125
ResourceInfo RI(ResourceClass::UAV, Kind, Symbol, Name, Binding, UniqueID);
126
assert(RI.isTyped() && !(RI.isStruct() || RI.isMultiSample()) &&
127
"Invalid ResourceKind for UAV constructor.");
128
RI.Typed.ElementTy = ElementTy;
129
RI.Typed.ElementCount = ElementCount;
130
RI.UAVFlags.GloballyCoherent = GloballyCoherent;
131
RI.UAVFlags.IsROV = IsROV;
132
RI.UAVFlags.HasCounter = false;
133
return RI;
134
}
135
136
ResourceInfo ResourceInfo::RWRawBuffer(Value *Symbol, StringRef Name,
137
ResourceBinding Binding,
138
uint32_t UniqueID, bool GloballyCoherent,
139
bool IsROV) {
140
ResourceInfo RI(ResourceClass::UAV, ResourceKind::RawBuffer, Symbol, Name,
141
Binding, UniqueID);
142
RI.UAVFlags.GloballyCoherent = GloballyCoherent;
143
RI.UAVFlags.IsROV = IsROV;
144
RI.UAVFlags.HasCounter = false;
145
return RI;
146
}
147
148
ResourceInfo ResourceInfo::RWStructuredBuffer(Value *Symbol, StringRef Name,
149
ResourceBinding Binding,
150
uint32_t UniqueID,
151
uint32_t Stride, Align Alignment,
152
bool GloballyCoherent, bool IsROV,
153
bool HasCounter) {
154
ResourceInfo RI(ResourceClass::UAV, ResourceKind::StructuredBuffer, Symbol,
155
Name, Binding, UniqueID);
156
RI.Struct.Stride = Stride;
157
RI.Struct.Alignment = Alignment;
158
RI.UAVFlags.GloballyCoherent = GloballyCoherent;
159
RI.UAVFlags.IsROV = IsROV;
160
RI.UAVFlags.HasCounter = HasCounter;
161
return RI;
162
}
163
164
ResourceInfo
165
ResourceInfo::RWTexture2DMS(Value *Symbol, StringRef Name,
166
ResourceBinding Binding, uint32_t UniqueID,
167
ElementType ElementTy, uint32_t ElementCount,
168
uint32_t SampleCount, bool GloballyCoherent) {
169
ResourceInfo RI(ResourceClass::UAV, ResourceKind::Texture2DMS, Symbol, Name,
170
Binding, UniqueID);
171
RI.Typed.ElementTy = ElementTy;
172
RI.Typed.ElementCount = ElementCount;
173
RI.UAVFlags.GloballyCoherent = GloballyCoherent;
174
RI.UAVFlags.IsROV = false;
175
RI.UAVFlags.HasCounter = false;
176
RI.MultiSample.Count = SampleCount;
177
return RI;
178
}
179
180
ResourceInfo
181
ResourceInfo::RWTexture2DMSArray(Value *Symbol, StringRef Name,
182
ResourceBinding Binding, uint32_t UniqueID,
183
ElementType ElementTy, uint32_t ElementCount,
184
uint32_t SampleCount, bool GloballyCoherent) {
185
ResourceInfo RI(ResourceClass::UAV, ResourceKind::Texture2DMSArray, Symbol,
186
Name, Binding, UniqueID);
187
RI.Typed.ElementTy = ElementTy;
188
RI.Typed.ElementCount = ElementCount;
189
RI.UAVFlags.GloballyCoherent = GloballyCoherent;
190
RI.UAVFlags.IsROV = false;
191
RI.UAVFlags.HasCounter = false;
192
RI.MultiSample.Count = SampleCount;
193
return RI;
194
}
195
196
ResourceInfo ResourceInfo::FeedbackTexture2D(Value *Symbol, StringRef Name,
197
ResourceBinding Binding,
198
uint32_t UniqueID,
199
SamplerFeedbackType FeedbackTy) {
200
ResourceInfo RI(ResourceClass::UAV, ResourceKind::FeedbackTexture2D, Symbol,
201
Name, Binding, UniqueID);
202
RI.UAVFlags.GloballyCoherent = false;
203
RI.UAVFlags.IsROV = false;
204
RI.UAVFlags.HasCounter = false;
205
RI.Feedback.Type = FeedbackTy;
206
return RI;
207
}
208
209
ResourceInfo
210
ResourceInfo::FeedbackTexture2DArray(Value *Symbol, StringRef Name,
211
ResourceBinding Binding, uint32_t UniqueID,
212
SamplerFeedbackType FeedbackTy) {
213
ResourceInfo RI(ResourceClass::UAV, ResourceKind::FeedbackTexture2DArray,
214
Symbol, Name, Binding, UniqueID);
215
RI.UAVFlags.GloballyCoherent = false;
216
RI.UAVFlags.IsROV = false;
217
RI.UAVFlags.HasCounter = false;
218
RI.Feedback.Type = FeedbackTy;
219
return RI;
220
}
221
222
ResourceInfo ResourceInfo::CBuffer(Value *Symbol, StringRef Name,
223
ResourceBinding Binding, uint32_t UniqueID,
224
uint32_t Size) {
225
ResourceInfo RI(ResourceClass::CBuffer, ResourceKind::CBuffer, Symbol, Name,
226
Binding, UniqueID);
227
RI.CBufferSize = Size;
228
return RI;
229
}
230
231
ResourceInfo ResourceInfo::Sampler(Value *Symbol, StringRef Name,
232
ResourceBinding Binding, uint32_t UniqueID,
233
SamplerType SamplerTy) {
234
ResourceInfo RI(ResourceClass::Sampler, ResourceKind::Sampler, Symbol, Name,
235
Binding, UniqueID);
236
RI.SamplerTy = SamplerTy;
237
return RI;
238
}
239
240
bool ResourceInfo::operator==(const ResourceInfo &RHS) const {
241
if (std::tie(Symbol, Name, Binding, UniqueID, RC, Kind) !=
242
std::tie(RHS.Symbol, RHS.Name, RHS.Binding, RHS.UniqueID, RHS.RC,
243
RHS.Kind))
244
return false;
245
if (isCBuffer())
246
return CBufferSize == RHS.CBufferSize;
247
if (isSampler())
248
return SamplerTy == RHS.SamplerTy;
249
if (isUAV() && UAVFlags != RHS.UAVFlags)
250
return false;
251
252
if (isStruct())
253
return Struct == RHS.Struct;
254
if (isFeedback())
255
return Feedback == RHS.Feedback;
256
if (isTyped() && Typed != RHS.Typed)
257
return false;
258
259
if (isMultiSample())
260
return MultiSample == RHS.MultiSample;
261
262
assert((Kind == ResourceKind::RawBuffer) && "Unhandled resource kind");
263
return true;
264
}
265
266
MDTuple *ResourceInfo::getAsMetadata(LLVMContext &Ctx) const {
267
SmallVector<Metadata *, 11> MDVals;
268
269
Type *I32Ty = Type::getInt32Ty(Ctx);
270
Type *I1Ty = Type::getInt1Ty(Ctx);
271
auto getIntMD = [&I32Ty](uint32_t V) {
272
return ConstantAsMetadata::get(
273
Constant::getIntegerValue(I32Ty, APInt(32, V)));
274
};
275
auto getBoolMD = [&I1Ty](uint32_t V) {
276
return ConstantAsMetadata::get(
277
Constant::getIntegerValue(I1Ty, APInt(1, V)));
278
};
279
280
MDVals.push_back(getIntMD(UniqueID));
281
MDVals.push_back(ValueAsMetadata::get(Symbol));
282
MDVals.push_back(MDString::get(Ctx, Name));
283
MDVals.push_back(getIntMD(Binding.Space));
284
MDVals.push_back(getIntMD(Binding.LowerBound));
285
MDVals.push_back(getIntMD(Binding.Size));
286
287
if (isCBuffer()) {
288
MDVals.push_back(getIntMD(CBufferSize));
289
MDVals.push_back(nullptr);
290
} else if (isSampler()) {
291
MDVals.push_back(getIntMD(llvm::to_underlying(SamplerTy)));
292
MDVals.push_back(nullptr);
293
} else {
294
MDVals.push_back(getIntMD(llvm::to_underlying(Kind)));
295
296
if (isUAV()) {
297
MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
298
MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
299
MDVals.push_back(getBoolMD(UAVFlags.IsROV));
300
} else {
301
// All SRVs include sample count in the metadata, but it's only meaningful
302
// for multi-sampled textured. Also, UAVs can be multisampled in SM6.7+,
303
// but this just isn't reflected in the metadata at all.
304
uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
305
MDVals.push_back(getIntMD(SampleCount));
306
}
307
308
// Further properties are attached to a metadata list of tag-value pairs.
309
SmallVector<Metadata *> Tags;
310
if (isStruct()) {
311
Tags.push_back(
312
getIntMD(llvm::to_underlying(ExtPropTags::StructuredBufferStride)));
313
Tags.push_back(getIntMD(Struct.Stride));
314
} else if (isTyped()) {
315
Tags.push_back(getIntMD(llvm::to_underlying(ExtPropTags::ElementType)));
316
Tags.push_back(getIntMD(llvm::to_underlying(Typed.ElementTy)));
317
} else if (isFeedback()) {
318
Tags.push_back(
319
getIntMD(llvm::to_underlying(ExtPropTags::SamplerFeedbackKind)));
320
Tags.push_back(getIntMD(llvm::to_underlying(Feedback.Type)));
321
}
322
MDVals.push_back(Tags.empty() ? nullptr : MDNode::get(Ctx, Tags));
323
}
324
325
return MDNode::get(Ctx, MDVals);
326
}
327
328
std::pair<uint32_t, uint32_t> ResourceInfo::getAnnotateProps() const {
329
uint32_t ResourceKind = llvm::to_underlying(Kind);
330
uint32_t AlignLog2 = isStruct() ? Log2(Struct.Alignment) : 0;
331
bool IsUAV = isUAV();
332
bool IsROV = IsUAV && UAVFlags.IsROV;
333
bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent;
334
uint8_t SamplerCmpOrHasCounter = 0;
335
if (IsUAV)
336
SamplerCmpOrHasCounter = UAVFlags.HasCounter;
337
else if (isSampler())
338
SamplerCmpOrHasCounter = SamplerTy == SamplerType::Comparison;
339
340
// TODO: Document this format. Currently the only reference is the
341
// implementation of dxc's DxilResourceProperties struct.
342
uint32_t Word0 = 0;
343
Word0 |= ResourceKind & 0xFF;
344
Word0 |= (AlignLog2 & 0xF) << 8;
345
Word0 |= (IsUAV & 1) << 12;
346
Word0 |= (IsROV & 1) << 13;
347
Word0 |= (IsGloballyCoherent & 1) << 14;
348
Word0 |= (SamplerCmpOrHasCounter & 1) << 15;
349
350
uint32_t Word1 = 0;
351
if (isStruct())
352
Word1 = Struct.Stride;
353
else if (isCBuffer())
354
Word1 = CBufferSize;
355
else if (isFeedback())
356
Word1 = llvm::to_underlying(Feedback.Type);
357
else if (isTyped()) {
358
uint32_t CompType = llvm::to_underlying(Typed.ElementTy);
359
uint32_t CompCount = Typed.ElementCount;
360
uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
361
362
Word1 |= (CompType & 0xFF) << 0;
363
Word1 |= (CompCount & 0xFF) << 8;
364
Word1 |= (SampleCount & 0xFF) << 16;
365
}
366
367
return {Word0, Word1};
368
}
369
370
#define DEBUG_TYPE "dxil-resource"
371
372