LLVM 20.0.0git
DXILResource.cpp
Go to the documentation of this file.
1//===- DXILResource.cpp - Representations of 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#include "llvm/IR/Metadata.h"
13
14using namespace llvm;
15using namespace dxil;
16
17bool ResourceInfo::isUAV() const { return RC == ResourceClass::UAV; }
18
19bool ResourceInfo::isCBuffer() const { return RC == ResourceClass::CBuffer; }
20
21bool ResourceInfo::isSampler() const { return RC == ResourceClass::Sampler; }
22
23bool ResourceInfo::isStruct() const {
24 return Kind == ResourceKind::StructuredBuffer;
25}
26
27bool ResourceInfo::isTyped() const {
28 switch (Kind) {
39 return true;
48 return false;
51 llvm_unreachable("Invalid resource kind");
52 }
53 llvm_unreachable("Unhandled ResourceKind enum");
54}
55
56bool ResourceInfo::isFeedback() const {
57 return Kind == ResourceKind::FeedbackTexture2D ||
59}
60
61bool ResourceInfo::isMultiSample() const {
62 return Kind == ResourceKind::Texture2DMS ||
64}
65
68 ResourceKind Kind) {
69 ResourceInfo RI(ResourceClass::SRV, Kind, Symbol, Name);
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
79 return RI;
80}
81
83 uint32_t Stride, Align Alignment) {
85 Name);
86 RI.Struct.Stride = Stride;
87 RI.Struct.Alignment = Alignment;
88 return RI;
89}
90
92 ElementType ElementTy,
94 uint32_t SampleCount) {
96 RI.Typed.ElementTy = ElementTy;
97 RI.Typed.ElementCount = ElementCount;
98 RI.MultiSample.Count = SampleCount;
99 return RI;
100}
101
103 ElementType ElementTy,
105 uint32_t SampleCount) {
107 Name);
108 RI.Typed.ElementTy = ElementTy;
109 RI.Typed.ElementCount = ElementCount;
110 RI.MultiSample.Count = SampleCount;
111 return RI;
112}
113
116 bool GloballyCoherent, bool IsROV,
117 ResourceKind Kind) {
118 ResourceInfo RI(ResourceClass::UAV, Kind, Symbol, Name);
119 assert(RI.isTyped() && !(RI.isStruct() || RI.isMultiSample()) &&
120 "Invalid ResourceKind for UAV constructor.");
121 RI.Typed.ElementTy = ElementTy;
122 RI.Typed.ElementCount = ElementCount;
123 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
124 RI.UAVFlags.IsROV = IsROV;
125 RI.UAVFlags.HasCounter = false;
126 return RI;
127}
128
130 bool GloballyCoherent, bool IsROV) {
132 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
133 RI.UAVFlags.IsROV = IsROV;
134 RI.UAVFlags.HasCounter = false;
135 return RI;
136}
137
139 uint32_t Stride, Align Alignment,
140 bool GloballyCoherent, bool IsROV,
141 bool HasCounter) {
143 Name);
144 RI.Struct.Stride = Stride;
145 RI.Struct.Alignment = Alignment;
146 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
147 RI.UAVFlags.IsROV = IsROV;
148 RI.UAVFlags.HasCounter = HasCounter;
149 return RI;
150}
151
153 ElementType ElementTy,
155 uint32_t SampleCount,
156 bool GloballyCoherent) {
158 RI.Typed.ElementTy = ElementTy;
159 RI.Typed.ElementCount = ElementCount;
160 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
161 RI.UAVFlags.IsROV = false;
162 RI.UAVFlags.HasCounter = false;
163 RI.MultiSample.Count = SampleCount;
164 return RI;
165}
166
168 ElementType ElementTy,
170 uint32_t SampleCount,
171 bool GloballyCoherent) {
173 Name);
174 RI.Typed.ElementTy = ElementTy;
175 RI.Typed.ElementCount = ElementCount;
176 RI.UAVFlags.GloballyCoherent = GloballyCoherent;
177 RI.UAVFlags.IsROV = false;
178 RI.UAVFlags.HasCounter = false;
179 RI.MultiSample.Count = SampleCount;
180 return RI;
181}
182
184 SamplerFeedbackType FeedbackTy) {
186 Name);
187 RI.UAVFlags.GloballyCoherent = false;
188 RI.UAVFlags.IsROV = false;
189 RI.UAVFlags.HasCounter = false;
190 RI.Feedback.Type = FeedbackTy;
191 return RI;
192}
193
196 SamplerFeedbackType FeedbackTy) {
198 Symbol, Name);
199 RI.UAVFlags.GloballyCoherent = false;
200 RI.UAVFlags.IsROV = false;
201 RI.UAVFlags.HasCounter = false;
202 RI.Feedback.Type = FeedbackTy;
203 return RI;
204}
205
207 uint32_t Size) {
209 RI.CBufferSize = Size;
210 return RI;
211}
212
214 SamplerType SamplerTy) {
216 RI.SamplerTy = SamplerTy;
217 return RI;
218}
219
221 if (std::tie(Symbol, Name, Binding, RC, Kind) !=
222 std::tie(RHS.Symbol, RHS.Name, RHS.Binding, RHS.RC, RHS.Kind))
223 return false;
224 if (isCBuffer())
225 return CBufferSize == RHS.CBufferSize;
226 if (isSampler())
227 return SamplerTy == RHS.SamplerTy;
228 if (isUAV() && UAVFlags != RHS.UAVFlags)
229 return false;
230
231 if (isStruct())
232 return Struct == RHS.Struct;
233 if (isFeedback())
234 return Feedback == RHS.Feedback;
235 if (isTyped() && Typed != RHS.Typed)
236 return false;
237
238 if (isMultiSample())
239 return MultiSample == RHS.MultiSample;
240
241 assert((Kind == ResourceKind::RawBuffer) && "Unhandled resource kind");
242 return true;
243}
244
247
248 Type *I32Ty = Type::getInt32Ty(Ctx);
249 Type *I1Ty = Type::getInt1Ty(Ctx);
250 auto getIntMD = [&I32Ty](uint32_t V) {
252 Constant::getIntegerValue(I32Ty, APInt(32, V)));
253 };
254 auto getBoolMD = [&I1Ty](uint32_t V) {
256 Constant::getIntegerValue(I1Ty, APInt(1, V)));
257 };
258
259 MDVals.push_back(getIntMD(Binding.UniqueID));
260 MDVals.push_back(ValueAsMetadata::get(Symbol));
261 MDVals.push_back(MDString::get(Ctx, Name));
262 MDVals.push_back(getIntMD(Binding.Space));
263 MDVals.push_back(getIntMD(Binding.LowerBound));
264 MDVals.push_back(getIntMD(Binding.Size));
265
266 if (isCBuffer()) {
267 MDVals.push_back(getIntMD(CBufferSize));
268 MDVals.push_back(nullptr);
269 } else if (isSampler()) {
270 MDVals.push_back(getIntMD(llvm::to_underlying(SamplerTy)));
271 MDVals.push_back(nullptr);
272 } else {
273 MDVals.push_back(getIntMD(llvm::to_underlying(Kind)));
274
275 if (isUAV()) {
276 MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
277 MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
278 MDVals.push_back(getBoolMD(UAVFlags.IsROV));
279 } else {
280 // All SRVs include sample count in the metadata, but it's only meaningful
281 // for multi-sampled textured. Also, UAVs can be multisampled in SM6.7+,
282 // but this just isn't reflected in the metadata at all.
283 uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
284 MDVals.push_back(getIntMD(SampleCount));
285 }
286
287 // Further properties are attached to a metadata list of tag-value pairs.
289 if (isStruct()) {
290 Tags.push_back(
292 Tags.push_back(getIntMD(Struct.Stride));
293 } else if (isTyped()) {
295 Tags.push_back(getIntMD(llvm::to_underlying(Typed.ElementTy)));
296 } else if (isFeedback()) {
297 Tags.push_back(
299 Tags.push_back(getIntMD(llvm::to_underlying(Feedback.Type)));
300 }
301 MDVals.push_back(Tags.empty() ? nullptr : MDNode::get(Ctx, Tags));
302 }
303
304 return MDNode::get(Ctx, MDVals);
305}
306
307std::pair<uint32_t, uint32_t> ResourceInfo::getAnnotateProps() const {
309 uint32_t AlignLog2 = isStruct() ? Log2(Struct.Alignment) : 0;
310 bool IsUAV = isUAV();
311 bool IsROV = IsUAV && UAVFlags.IsROV;
312 bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent;
313 uint8_t SamplerCmpOrHasCounter = 0;
314 if (IsUAV)
315 SamplerCmpOrHasCounter = UAVFlags.HasCounter;
316 else if (isSampler())
317 SamplerCmpOrHasCounter = SamplerTy == SamplerType::Comparison;
318
319 // TODO: Document this format. Currently the only reference is the
320 // implementation of dxc's DxilResourceProperties struct.
321 uint32_t Word0 = 0;
322 Word0 |= ResourceKind & 0xFF;
323 Word0 |= (AlignLog2 & 0xF) << 8;
324 Word0 |= (IsUAV & 1) << 12;
325 Word0 |= (IsROV & 1) << 13;
326 Word0 |= (IsGloballyCoherent & 1) << 14;
327 Word0 |= (SamplerCmpOrHasCounter & 1) << 15;
328
329 uint32_t Word1 = 0;
330 if (isStruct())
331 Word1 = Struct.Stride;
332 else if (isCBuffer())
333 Word1 = CBufferSize;
334 else if (isFeedback())
335 Word1 = llvm::to_underlying(Feedback.Type);
336 else if (isTyped()) {
337 uint32_t CompType = llvm::to_underlying(Typed.ElementTy);
338 uint32_t CompCount = Typed.ElementCount;
339 uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
340
341 Word1 |= (CompType & 0xFF) << 0;
342 Word1 |= (CompCount & 0xFF) << 8;
343 Word1 |= (SampleCount & 0xFF) << 16;
344 }
345
346 return {Word0, Word1};
347}
348
349#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
This file contains the declarations for metadata subclasses.
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:1543
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:600
Tuple of metadata.
Definition: Metadata.h:1472
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 Texture2DMSArray(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount)
static ResourceInfo RawBuffer(Value *Symbol, StringRef Name)
static ResourceInfo FeedbackTexture2D(Value *Symbol, StringRef Name, dxil::SamplerFeedbackType FeedbackTy)
static ResourceInfo Texture2DMS(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount)
static ResourceInfo RWTexture2DMS(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount, bool GloballyCoherent)
static ResourceInfo RWStructuredBuffer(Value *Symbol, StringRef Name, uint32_t Stride, Align Alignment, bool GloballyCoherent, bool IsROV, bool HasCounter)
std::pair< uint32_t, uint32_t > getAnnotateProps() const
static ResourceInfo Sampler(Value *Symbol, StringRef Name, dxil::SamplerType SamplerTy)
static ResourceInfo UAV(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, bool GloballyCoherent, bool IsROV, dxil::ResourceKind Kind)
static ResourceInfo RWRawBuffer(Value *Symbol, StringRef Name, bool GloballyCoherent, bool IsROV)
dxil::SamplerType SamplerTy
Definition: DXILResource.h:97
static ResourceInfo SRV(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, dxil::ResourceKind Kind)
bool operator==(const ResourceInfo &RHS) const
static ResourceInfo FeedbackTexture2DArray(Value *Symbol, StringRef Name, dxil::SamplerFeedbackType FeedbackTy)
static ResourceInfo StructuredBuffer(Value *Symbol, StringRef Name, uint32_t Stride, Align Alignment)
static ResourceInfo RWTexture2DMSArray(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount, bool GloballyCoherent)
MDTuple * getAsMetadata(LLVMContext &Ctx) const
static ResourceInfo CBuffer(Value *Symbol, StringRef Name, uint32_t Size)
#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