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