LLVM 19.0.0git
DXILResource.cpp
Go to the documentation of this file.
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
10#include "llvm/ADT/APInt.h"
12
13using namespace llvm;
14using namespace dxil;
15
16bool ResourceInfo::isUAV() const { return RC == ResourceClass::UAV; }
17
18bool ResourceInfo::isCBuffer() const { return RC == ResourceClass::CBuffer; }
19
20bool ResourceInfo::isSampler() const { return RC == ResourceClass::Sampler; }
21
22bool ResourceInfo::isStruct() const {
23 return Kind == ResourceKind::StructuredBuffer;
24}
25
26bool ResourceInfo::isTyped() const {
27 switch (Kind) {
38 return true;
47 return false;
50 llvm_unreachable("Invalid resource kind");
51 }
52}
53
54bool ResourceInfo::isFeedback() const {
55 return Kind == ResourceKind::FeedbackTexture2D ||
57}
58
59bool ResourceInfo::isMultiSample() const {
60 return Kind == ResourceKind::Texture2DMS ||
62}
63
65 ResourceBinding Binding, uint32_t UniqueID,
67 ResourceKind Kind) {
68 ResourceInfo RI(ResourceClass::SRV, Kind, Symbol, Name, Binding, UniqueID);
69 assert(RI.isTyped() && !(RI.isStruct() || RI.isMultiSample()) &&
70 "Invalid ResourceKind for SRV constructor.");
71 RI.Typed.ElementTy = ElementTy;
72 RI.Typed.ElementCount = ElementCount;
73 return RI;
74}
75
77 ResourceBinding Binding,
78 uint32_t UniqueID) {
80 Binding, UniqueID);
81 return RI;
82}
83
85 ResourceBinding Binding,
86 uint32_t UniqueID, uint32_t Stride,
87 Align Alignment) {
89 Name, Binding, UniqueID);
90 RI.Struct.Stride = Stride;
91 RI.Struct.Alignment = Alignment;
92 return RI;
93}
94
96 ResourceBinding Binding,
97 uint32_t UniqueID, ElementType ElementTy,
99 uint32_t SampleCount) {
101 Binding, UniqueID);
102 RI.Typed.ElementTy = ElementTy;
103 RI.Typed.ElementCount = ElementCount;
104 RI.MultiSample.Count = SampleCount;
105 return RI;
106}
107
109 Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID,
110 ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount) {
112 Name, Binding, UniqueID);
113 RI.Typed.ElementTy = ElementTy;
114 RI.Typed.ElementCount = ElementCount;
115 RI.MultiSample.Count = SampleCount;
116 return RI;
117}
118
120 ResourceBinding Binding, uint32_t UniqueID,
122 bool GloballyCoherent, bool IsROV,
123 ResourceKind Kind) {
124 ResourceInfo RI(ResourceClass::UAV, Kind, Symbol, Name, Binding, UniqueID);
125 assert(RI.isTyped() && !(RI.isStruct() || RI.isMultiSample()) &&
126 "Invalid ResourceKind for UAV constructor.");
127 RI.Typed.ElementTy = ElementTy;
128 RI.Typed.ElementCount = ElementCount;
129 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
130 RI.UAVFlags.IsROV = IsROV;
131 RI.UAVFlags.HasCounter = false;
132 return RI;
133}
134
136 ResourceBinding Binding,
137 uint32_t UniqueID, bool GloballyCoherent,
138 bool IsROV) {
140 Binding, UniqueID);
141 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
142 RI.UAVFlags.IsROV = IsROV;
143 RI.UAVFlags.HasCounter = false;
144 return RI;
145}
146
148 ResourceBinding Binding,
149 uint32_t UniqueID,
150 uint32_t Stride, Align Alignment,
151 bool GloballyCoherent, bool IsROV,
152 bool HasCounter) {
154 Name, Binding, UniqueID);
155 RI.Struct.Stride = Stride;
156 RI.Struct.Alignment = Alignment;
157 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
158 RI.UAVFlags.IsROV = IsROV;
159 RI.UAVFlags.HasCounter = HasCounter;
160 return RI;
161}
162
165 ResourceBinding Binding, uint32_t UniqueID,
167 uint32_t SampleCount, bool GloballyCoherent) {
169 Binding, UniqueID);
170 RI.Typed.ElementTy = ElementTy;
171 RI.Typed.ElementCount = ElementCount;
172 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
173 RI.UAVFlags.IsROV = false;
174 RI.UAVFlags.HasCounter = false;
175 RI.MultiSample.Count = SampleCount;
176 return RI;
177}
178
181 ResourceBinding Binding, uint32_t UniqueID,
183 uint32_t SampleCount, bool GloballyCoherent) {
185 Name, Binding, UniqueID);
186 RI.Typed.ElementTy = ElementTy;
187 RI.Typed.ElementCount = ElementCount;
188 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
189 RI.UAVFlags.IsROV = false;
190 RI.UAVFlags.HasCounter = false;
191 RI.MultiSample.Count = SampleCount;
192 return RI;
193}
194
196 ResourceBinding Binding,
197 uint32_t UniqueID,
198 SamplerFeedbackType FeedbackTy) {
200 Name, Binding, UniqueID);
201 RI.UAVFlags.GloballyCoherent = false;
202 RI.UAVFlags.IsROV = false;
203 RI.UAVFlags.HasCounter = false;
204 RI.Feedback.Type = FeedbackTy;
205 return RI;
206}
207
210 ResourceBinding Binding, uint32_t UniqueID,
211 SamplerFeedbackType FeedbackTy) {
213 Symbol, Name, Binding, UniqueID);
214 RI.UAVFlags.GloballyCoherent = false;
215 RI.UAVFlags.IsROV = false;
216 RI.UAVFlags.HasCounter = false;
217 RI.Feedback.Type = FeedbackTy;
218 return RI;
219}
220
222 ResourceBinding Binding, uint32_t UniqueID,
223 uint32_t Size) {
225 Binding, UniqueID);
226 RI.CBufferSize = Size;
227 return RI;
228}
229
231 ResourceBinding Binding, uint32_t UniqueID,
232 SamplerType SamplerTy) {
234 Binding, UniqueID);
235 RI.SamplerTy = SamplerTy;
236 return RI;
237}
238
240 if (std::tie(Symbol, Name, Binding, UniqueID, RC, Kind) !=
241 std::tie(RHS.Symbol, RHS.Name, RHS.Binding, RHS.UniqueID, RHS.RC,
242 RHS.Kind))
243 return false;
244 if (isCBuffer())
245 return CBufferSize == RHS.CBufferSize;
246 if (isSampler())
247 return SamplerTy == RHS.SamplerTy;
248 if (isUAV() && UAVFlags != RHS.UAVFlags)
249 return false;
250
251 if (isStruct())
252 return Struct == RHS.Struct;
253 if (isFeedback())
254 return Feedback == RHS.Feedback;
255 if (isTyped() && Typed != RHS.Typed)
256 return false;
257
258 if (isMultiSample())
259 return MultiSample == RHS.MultiSample;
260
261 assert((Kind == ResourceKind::RawBuffer) && "Unhandled resource kind");
262 return true;
263}
264
267
268 Type *I32Ty = Type::getInt32Ty(Ctx);
269 Type *I1Ty = Type::getInt1Ty(Ctx);
270 auto getIntMD = [&I32Ty](uint32_t V) {
272 Constant::getIntegerValue(I32Ty, APInt(32, V)));
273 };
274 auto getBoolMD = [&I1Ty](uint32_t V) {
276 Constant::getIntegerValue(I1Ty, APInt(1, V)));
277 };
278
279 MDVals.push_back(getIntMD(UniqueID));
280 MDVals.push_back(ValueAsMetadata::get(Symbol));
281 MDVals.push_back(MDString::get(Ctx, Name));
282 MDVals.push_back(getIntMD(Binding.Space));
283 MDVals.push_back(getIntMD(Binding.LowerBound));
284 MDVals.push_back(getIntMD(Binding.Size));
285
286 if (isCBuffer()) {
287 MDVals.push_back(getIntMD(CBufferSize));
288 MDVals.push_back(nullptr);
289 } else if (isSampler()) {
290 MDVals.push_back(getIntMD(llvm::to_underlying(SamplerTy)));
291 MDVals.push_back(nullptr);
292 } else {
293 MDVals.push_back(getIntMD(llvm::to_underlying(Kind)));
294
295 if (isUAV()) {
296 MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
297 MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
298 MDVals.push_back(getBoolMD(UAVFlags.IsROV));
299 } else {
300 // All SRVs include sample count in the metadata, but it's only meaningful
301 // for multi-sampled textured. Also, UAVs can be multisampled in SM6.7+,
302 // but this just isn't reflected in the metadata at all.
303 uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
304 MDVals.push_back(getIntMD(SampleCount));
305 }
306
307 // Further properties are attached to a metadata list of tag-value pairs.
309 if (isStruct()) {
310 Tags.push_back(
312 Tags.push_back(getIntMD(Struct.Stride));
313 } else if (isTyped()) {
315 Tags.push_back(getIntMD(llvm::to_underlying(Typed.ElementTy)));
316 } else if (isFeedback()) {
317 Tags.push_back(
319 Tags.push_back(getIntMD(llvm::to_underlying(Feedback.Type)));
320 }
321 MDVals.push_back(Tags.empty() ? nullptr : MDNode::get(Ctx, Tags));
322 }
323
324 return MDNode::get(Ctx, MDVals);
325}
326
327std::pair<uint32_t, uint32_t> ResourceInfo::getAnnotateProps() const {
329 uint32_t AlignLog2 = isStruct() ? Log2(Struct.Alignment) : 0;
330 bool IsUAV = isUAV();
331 bool IsROV = IsUAV ? UAVFlags.IsROV : 0;
332 bool IsGloballyCoherent = IsUAV ? UAVFlags.GloballyCoherent : 0;
333 uint8_t SamplerCmpOrHasCounter = 0;
334 if (IsUAV)
335 SamplerCmpOrHasCounter = UAVFlags.HasCounter;
336 else if (isSampler())
337 SamplerCmpOrHasCounter = SamplerTy == SamplerType::Comparison;
338
339 // TODO: Document this format. Currently the only reference is the
340 // implementation of dxc's DxilResourceProperties struct.
341 uint32_t Word0 = 0;
342 Word0 |= ResourceKind & 0xFF;
343 Word0 |= (AlignLog2 & 0xF) << 8;
344 Word0 |= (IsUAV & 1) << 12;
345 Word0 |= (IsROV & 1) << 13;
346 Word0 |= (IsGloballyCoherent & 1) << 14;
347 Word0 |= (SamplerCmpOrHasCounter & 1) << 15;
348
349 uint32_t Word1 = 0;
350 if (isStruct())
351 Word1 = Struct.Stride;
352 else if (isCBuffer())
353 Word1 = CBufferSize;
354 else if (isFeedback())
355 Word1 = llvm::to_underlying(Feedback.Type);
356 else if (isTyped()) {
357 uint32_t CompType = llvm::to_underlying(Typed.ElementTy);
358 uint32_t CompCount = Typed.ElementCount;
359 uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
360
361 Word1 |= (CompType & 0xFF) << 0;
362 Word1 |= (CompCount & 0xFF) << 8;
363 Word1 |= (SampleCount & 0xFF) << 16;
364 }
365
366 return {Word0, Word1};
367}
368
369#define DEBUG_TYPE "dxil-resource"
This file implements a class to represent arbitrary precision integral constant values and operations...
std::string Name
uint64_t Size
if(VerifyEach)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * RHS
Class for arbitrary precision integers.
Definition: APInt.h:78
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:528
static Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
Definition: Constants.cpp:400
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1541
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:600
Tuple of metadata.
Definition: Metadata.h:1470
bool empty() const
Definition: SmallVector.h:94
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getInt1Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
static ValueAsMetadata * get(Value *V)
Definition: Metadata.cpp:495
LLVM Value Representation.
Definition: Value.h:74
static ResourceInfo RWTexture2DMSArray(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount, bool GloballyCoherent)
static ResourceInfo Texture2DMSArray(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount)
static ResourceInfo SRV(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::ElementType ElementTy, uint32_t ElementCount, dxil::ResourceKind Kind)
static ResourceInfo RWRawBuffer(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, bool GloballyCoherent, bool IsROV)
static ResourceInfo FeedbackTexture2DArray(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::SamplerFeedbackType FeedbackTy)
std::pair< uint32_t, uint32_t > getAnnotateProps() const
static ResourceInfo UAV(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::ElementType ElementTy, uint32_t ElementCount, bool GloballyCoherent, bool IsROV, dxil::ResourceKind Kind)
static ResourceInfo Sampler(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::SamplerType SamplerTy)
static ResourceInfo StructuredBuffer(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, uint32_t Stride, Align Alignment)
static ResourceInfo Texture2DMS(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount)
dxil::SamplerType SamplerTy
Definition: DXILResource.h:94
static ResourceInfo RawBuffer(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID)
bool operator==(const ResourceInfo &RHS) const
static ResourceInfo RWStructuredBuffer(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, uint32_t Stride, Align Alignment, bool GloballyCoherent, bool IsROV, bool HasCounter)
static ResourceInfo RWTexture2DMS(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount, bool GloballyCoherent)
static ResourceInfo CBuffer(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, uint32_t Size)
MDTuple * getAsMetadata(LLVMContext &Ctx) const
static ResourceInfo FeedbackTexture2D(Value *Symbol, StringRef Name, ResourceBinding Binding, uint32_t UniqueID, dxil::SamplerFeedbackType FeedbackTy)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ResourceKind
The kind of resource for an SRV or UAV resource.
Definition: DXILABI.h:51
SamplerFeedbackType
Definition: DXILABI.h:111
ElementType
The element type of an SRV or UAV resource.
Definition: DXILABI.h:75
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39