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
24 return Kind == ResourceKind::StructuredBuffer;
25}
26
28 switch (Kind) {
39 return true;
48 return false;
51 llvm_unreachable("Invalid resource kind");
52 }
53 llvm_unreachable("Unhandled ResourceKind enum");
54}
55
57 return Kind == ResourceKind::FeedbackTexture2D ||
59}
60
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.setTyped(ElementTy, ElementCount);
73 return RI;
74}
75
78 return RI;
79}
80
82 uint32_t Stride,
83 MaybeAlign Alignment) {
85 Name);
86 RI.setStruct(Stride, Alignment);
87 return RI;
88}
89
91 ElementType ElementTy,
93 uint32_t SampleCount) {
95 RI.setTyped(ElementTy, ElementCount);
96 RI.setMultiSample(SampleCount);
97 return RI;
98}
99
101 ElementType ElementTy,
103 uint32_t SampleCount) {
105 Name);
106 RI.setTyped(ElementTy, ElementCount);
107 RI.setMultiSample(SampleCount);
108 return RI;
109}
110
113 bool GloballyCoherent, bool IsROV,
114 ResourceKind Kind) {
115 ResourceInfo RI(ResourceClass::UAV, Kind, Symbol, Name);
116 assert(RI.isTyped() && !(RI.isStruct() || RI.isMultiSample()) &&
117 "Invalid ResourceKind for UAV constructor.");
118 RI.setTyped(ElementTy, ElementCount);
119 RI.setUAV(GloballyCoherent, /*HasCounter=*/false, IsROV);
120 return RI;
121}
122
124 bool GloballyCoherent, bool IsROV) {
126 RI.setUAV(GloballyCoherent, /*HasCounter=*/false, IsROV);
127 return RI;
128}
129
131 uint32_t Stride,
132 MaybeAlign Alignment,
133 bool GloballyCoherent, bool IsROV,
134 bool HasCounter) {
136 Name);
137 RI.setStruct(Stride, Alignment);
138 RI.setUAV(GloballyCoherent, HasCounter, IsROV);
139 return RI;
140}
141
143 ElementType ElementTy,
145 uint32_t SampleCount,
146 bool GloballyCoherent) {
148 RI.setTyped(ElementTy, ElementCount);
149 RI.setUAV(GloballyCoherent, /*HasCounter=*/false, /*IsROV=*/false);
150 RI.setMultiSample(SampleCount);
151 return RI;
152}
153
155 ElementType ElementTy,
157 uint32_t SampleCount,
158 bool GloballyCoherent) {
160 Name);
161 RI.setTyped(ElementTy, ElementCount);
162 RI.setUAV(GloballyCoherent, /*HasCounter=*/false, /*IsROV=*/false);
163 RI.setMultiSample(SampleCount);
164 return RI;
165}
166
168 SamplerFeedbackType FeedbackTy) {
170 Name);
171 RI.setUAV(/*GloballyCoherent=*/false, /*HasCounter=*/false, /*IsROV=*/false);
172 RI.setFeedback(FeedbackTy);
173 return RI;
174}
175
178 SamplerFeedbackType FeedbackTy) {
180 Symbol, Name);
181 RI.setUAV(/*GloballyCoherent=*/false, /*HasCounter=*/false, /*IsROV=*/false);
182 RI.setFeedback(FeedbackTy);
183 return RI;
184}
185
187 uint32_t Size) {
189 RI.setCBuffer(Size);
190 return RI;
191}
192
194 SamplerType SamplerTy) {
197 return RI;
198}
199
201 if (std::tie(Symbol, Name, Binding, RC, Kind) !=
202 std::tie(RHS.Symbol, RHS.Name, RHS.Binding, RHS.RC, RHS.Kind))
203 return false;
204 if (isCBuffer())
205 return CBufferSize == RHS.CBufferSize;
206 if (isSampler())
207 return SamplerTy == RHS.SamplerTy;
208 if (isUAV() && UAVFlags != RHS.UAVFlags)
209 return false;
210
211 if (isStruct())
212 return Struct == RHS.Struct;
213 if (isFeedback())
214 return Feedback == RHS.Feedback;
215 if (isTyped() && Typed != RHS.Typed)
216 return false;
217
218 if (isMultiSample())
219 return MultiSample == RHS.MultiSample;
220
221 assert((Kind == ResourceKind::RawBuffer) && "Unhandled resource kind");
222 return true;
223}
224
227
228 Type *I32Ty = Type::getInt32Ty(Ctx);
229 Type *I1Ty = Type::getInt1Ty(Ctx);
230 auto getIntMD = [&I32Ty](uint32_t V) {
232 Constant::getIntegerValue(I32Ty, APInt(32, V)));
233 };
234 auto getBoolMD = [&I1Ty](uint32_t V) {
236 Constant::getIntegerValue(I1Ty, APInt(1, V)));
237 };
238
239 MDVals.push_back(getIntMD(Binding.UniqueID));
240 MDVals.push_back(ValueAsMetadata::get(Symbol));
241 MDVals.push_back(MDString::get(Ctx, Name));
242 MDVals.push_back(getIntMD(Binding.Space));
243 MDVals.push_back(getIntMD(Binding.LowerBound));
244 MDVals.push_back(getIntMD(Binding.Size));
245
246 if (isCBuffer()) {
247 MDVals.push_back(getIntMD(CBufferSize));
248 MDVals.push_back(nullptr);
249 } else if (isSampler()) {
250 MDVals.push_back(getIntMD(llvm::to_underlying(SamplerTy)));
251 MDVals.push_back(nullptr);
252 } else {
253 MDVals.push_back(getIntMD(llvm::to_underlying(Kind)));
254
255 if (isUAV()) {
256 MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
257 MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
258 MDVals.push_back(getBoolMD(UAVFlags.IsROV));
259 } else {
260 // All SRVs include sample count in the metadata, but it's only meaningful
261 // for multi-sampled textured. Also, UAVs can be multisampled in SM6.7+,
262 // but this just isn't reflected in the metadata at all.
263 uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
264 MDVals.push_back(getIntMD(SampleCount));
265 }
266
267 // Further properties are attached to a metadata list of tag-value pairs.
269 if (isStruct()) {
270 Tags.push_back(
272 Tags.push_back(getIntMD(Struct.Stride));
273 } else if (isTyped()) {
275 Tags.push_back(getIntMD(llvm::to_underlying(Typed.ElementTy)));
276 } else if (isFeedback()) {
277 Tags.push_back(
279 Tags.push_back(getIntMD(llvm::to_underlying(Feedback.Type)));
280 }
281 MDVals.push_back(Tags.empty() ? nullptr : MDNode::get(Ctx, Tags));
282 }
283
284 return MDNode::get(Ctx, MDVals);
285}
286
287std::pair<uint32_t, uint32_t> ResourceInfo::getAnnotateProps() const {
289 uint32_t AlignLog2 = isStruct() ? Struct.AlignLog2 : 0;
290 bool IsUAV = isUAV();
291 bool IsROV = IsUAV && UAVFlags.IsROV;
292 bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent;
293 uint8_t SamplerCmpOrHasCounter = 0;
294 if (IsUAV)
295 SamplerCmpOrHasCounter = UAVFlags.HasCounter;
296 else if (isSampler())
297 SamplerCmpOrHasCounter = SamplerTy == SamplerType::Comparison;
298
299 // TODO: Document this format. Currently the only reference is the
300 // implementation of dxc's DxilResourceProperties struct.
301 uint32_t Word0 = 0;
302 Word0 |= ResourceKind & 0xFF;
303 Word0 |= (AlignLog2 & 0xF) << 8;
304 Word0 |= (IsUAV & 1) << 12;
305 Word0 |= (IsROV & 1) << 13;
306 Word0 |= (IsGloballyCoherent & 1) << 14;
307 Word0 |= (SamplerCmpOrHasCounter & 1) << 15;
308
309 uint32_t Word1 = 0;
310 if (isStruct())
311 Word1 = Struct.Stride;
312 else if (isCBuffer())
313 Word1 = CBufferSize;
314 else if (isFeedback())
315 Word1 = llvm::to_underlying(Feedback.Type);
316 else if (isTyped()) {
317 uint32_t CompType = llvm::to_underlying(Typed.ElementTy);
318 uint32_t CompCount = Typed.ElementCount;
319 uint32_t SampleCount = isMultiSample() ? MultiSample.Count : 0;
320
321 Word1 |= (CompType & 0xFF) << 0;
322 Word1 |= (CompCount & 0xFF) << 8;
323 Word1 |= (SampleCount & 0xFF) << 16;
324 }
325
326 return {Word0, Word1};
327}
328
329#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:1542
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:606
Tuple of metadata.
Definition: Metadata.h:1472
bool empty() const
Definition: SmallVector.h:95
void push_back(const T &Elt)
Definition: SmallVector.h:427
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1210
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:501
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)
void setUAV(bool GloballyCoherent, bool HasCounter, bool IsROV)
Definition: DXILResource.h:134
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)
std::pair< uint32_t, uint32_t > getAnnotateProps() const
static ResourceInfo Sampler(Value *Symbol, StringRef Name, dxil::SamplerType SamplerTy)
void setCBuffer(uint32_t Size)
Definition: DXILResource.h:140
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:101
static ResourceInfo SRV(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, dxil::ResourceKind Kind)
void setTyped(dxil::ElementType ElementTy, uint32_t ElementCount)
Definition: DXILResource.h:150
bool operator==(const ResourceInfo &RHS) const
void setMultiSample(uint32_t Count)
Definition: DXILResource.h:159
void setSampler(dxil::SamplerType Ty)
Definition: DXILResource.h:144
void setStruct(uint32_t Stride, MaybeAlign Alignment)
Definition: DXILResource.h:145
static ResourceInfo FeedbackTexture2DArray(Value *Symbol, StringRef Name, dxil::SamplerFeedbackType FeedbackTy)
static ResourceInfo RWTexture2DMSArray(Value *Symbol, StringRef Name, dxil::ElementType ElementTy, uint32_t ElementCount, uint32_t SampleCount, bool GloballyCoherent)
MDTuple * getAsMetadata(LLVMContext &Ctx) const
void setFeedback(dxil::SamplerFeedbackType Type)
Definition: DXILResource.h:155
static ResourceInfo StructuredBuffer(Value *Symbol, StringRef Name, uint32_t Stride, MaybeAlign Alignment)
static ResourceInfo CBuffer(Value *Symbol, StringRef Name, uint32_t Size)
static ResourceInfo RWStructuredBuffer(Value *Symbol, StringRef Name, uint32_t Stride, MaybeAlign Alignment, bool GloballyCoherent, bool IsROV, bool HasCounter)
#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.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117