[llvm] [HLSL] Move Resouce Instance Properties from TypeInfo (PR #135259)
Ashley Coleman via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 11 09:10:34 PDT 2025
https://github.com/V-FEXrt updated https://github.com/llvm/llvm-project/pull/135259
>From a7998f34a897cbcdefb836e394983830610957c5 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Thu, 10 Apr 2025 14:55:56 -0600
Subject: [PATCH 1/2] [HLSL] Move Resouce Instance Properties from TypeInfo
---
llvm/include/llvm/Analysis/DXILResource.h | 41 +++++++-----------
llvm/lib/Analysis/DXILResource.cpp | 28 ++++++-------
.../lib/Target/DirectX/DXContainerGlobals.cpp | 2 +-
llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 4 +-
.../DXILResource/buffer-frombinding.ll | 30 ++++++-------
llvm/unittests/Analysis/DXILResourceTest.cpp | 42 +++++++++----------
6 files changed, 66 insertions(+), 81 deletions(-)
diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index ff7961c9ad51c..6ff4e2fb56006 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -222,19 +222,11 @@ class LayoutExtType : public TargetExtType {
class ResourceTypeInfo {
public:
struct UAVInfo {
- bool GloballyCoherent;
- bool HasCounter;
bool IsROV;
- bool operator==(const UAVInfo &RHS) const {
- return std::tie(GloballyCoherent, HasCounter, IsROV) ==
- std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
- }
+ bool operator==(const UAVInfo &RHS) const { return IsROV == RHS.IsROV; }
bool operator!=(const UAVInfo &RHS) const { return !(*this == RHS); }
- bool operator<(const UAVInfo &RHS) const {
- return std::tie(GloballyCoherent, HasCounter, IsROV) <
- std::tie(RHS.GloballyCoherent, RHS.HasCounter, RHS.IsROV);
- }
+ bool operator<(const UAVInfo &RHS) const { return IsROV < RHS.IsROV; }
};
struct StructInfo {
@@ -272,23 +264,14 @@ class ResourceTypeInfo {
private:
TargetExtType *HandleTy;
- // GloballyCoherent and HasCounter aren't really part of the type and need to
- // be determined by analysis, so they're just provided directly by the
- // DXILResourceTypeMap when we construct these.
- bool GloballyCoherent;
- bool HasCounter;
-
dxil::ResourceClass RC;
dxil::ResourceKind Kind;
public:
ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC,
- const dxil::ResourceKind Kind, bool GloballyCoherent = false,
- bool HasCounter = false);
- ResourceTypeInfo(TargetExtType *HandleTy, bool GloballyCoherent = false,
- bool HasCounter = false)
- : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid,
- GloballyCoherent, HasCounter) {}
+ const dxil::ResourceKind Kind);
+ ResourceTypeInfo(TargetExtType *HandleTy)
+ : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid) {}
TargetExtType *getHandleTy() const { return HandleTy; }
StructType *createElementStruct();
@@ -314,9 +297,6 @@ class ResourceTypeInfo {
dxil::ResourceClass getResourceClass() const { return RC; }
dxil::ResourceKind getResourceKind() const { return Kind; }
- void setGloballyCoherent(bool V) { GloballyCoherent = V; }
- void setHasCounter(bool V) { HasCounter = V; }
-
bool operator==(const ResourceTypeInfo &RHS) const;
bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); }
bool operator<(const ResourceTypeInfo &RHS) const;
@@ -353,13 +333,20 @@ class ResourceInfo {
GlobalVariable *Symbol = nullptr;
public:
+ bool GloballyCoherent;
+ bool HasCounter;
+
ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
uint32_t Size, TargetExtType *HandleTy,
- GlobalVariable *Symbol = nullptr)
+ GlobalVariable *Symbol = nullptr, bool GloballyCoherent = false,
+ bool HasCounter = false)
: Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy),
- Symbol(Symbol) {}
+ Symbol(Symbol), GloballyCoherent(GloballyCoherent),
+ HasCounter(HasCounter) {}
void setBindingID(unsigned ID) { Binding.RecordID = ID; }
+ void setGloballyCoherent(bool V) { GloballyCoherent = V; }
+ void setHasCounter(bool V) { HasCounter = V; }
const ResourceBinding &getBinding() const { return Binding; }
TargetExtType *getHandleTy() const { return HandleTy; }
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index b4bd43206b6e4..d4f0127a931dc 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -179,10 +179,8 @@ static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned) {
ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
const dxil::ResourceClass RC_,
- const dxil::ResourceKind Kind_,
- bool GloballyCoherent, bool HasCounter)
- : HandleTy(HandleTy), GloballyCoherent(GloballyCoherent),
- HasCounter(HasCounter) {
+ const dxil::ResourceKind Kind_)
+ : HandleTy(HandleTy) {
// If we're provided a resource class and kind, trust them.
if (Kind_ != dxil::ResourceKind::Invalid) {
RC = RC_;
@@ -377,7 +375,7 @@ static bool isROV(dxil::ResourceKind Kind, TargetExtType *Ty) {
ResourceTypeInfo::UAVInfo ResourceTypeInfo::getUAV() const {
assert(isUAV() && "Not a UAV");
- return {GloballyCoherent, HasCounter, isROV(Kind, HandleTy)};
+ return {isROV(Kind, HandleTy)};
}
uint32_t ResourceTypeInfo::getCBufferSize(const DataLayout &DL) const {
@@ -469,8 +467,7 @@ uint32_t ResourceTypeInfo::getMultiSampleCount() const {
}
bool ResourceTypeInfo::operator==(const ResourceTypeInfo &RHS) const {
- return std::tie(HandleTy, GloballyCoherent, HasCounter) ==
- std::tie(RHS.HandleTy, RHS.GloballyCoherent, RHS.HasCounter);
+ return std::tie(HandleTy) == std::tie(RHS.HandleTy);
}
bool ResourceTypeInfo::operator<(const ResourceTypeInfo &RHS) const {
@@ -510,9 +507,7 @@ void ResourceTypeInfo::print(raw_ostream &OS, const DataLayout &DL) const {
} else {
if (isUAV()) {
UAVInfo UAVFlags = getUAV();
- OS << " Globally Coherent: " << UAVFlags.GloballyCoherent << "\n"
- << " HasCounter: " << UAVFlags.HasCounter << "\n"
- << " IsROV: " << UAVFlags.IsROV << "\n";
+ OS << " IsROV: " << UAVFlags.IsROV << "\n";
}
if (isMultiSample())
OS << " Sample Count: " << getMultiSampleCount() << "\n";
@@ -577,8 +572,8 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M,
if (RTI.isUAV()) {
ResourceTypeInfo::UAVInfo UAVFlags = RTI.getUAV();
- MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent));
- MDVals.push_back(getBoolMD(UAVFlags.HasCounter));
+ MDVals.push_back(getBoolMD(GloballyCoherent));
+ MDVals.push_back(getBoolMD(HasCounter));
MDVals.push_back(getBoolMD(UAVFlags.IsROV));
} else {
// All SRVs include sample count in the metadata, but it's only meaningful
@@ -619,10 +614,10 @@ ResourceInfo::getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const {
ResourceTypeInfo::UAVInfo UAVFlags =
IsUAV ? RTI.getUAV() : ResourceTypeInfo::UAVInfo{};
bool IsROV = IsUAV && UAVFlags.IsROV;
- bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent;
+ bool IsGloballyCoherent = IsUAV && GloballyCoherent;
uint8_t SamplerCmpOrHasCounter = 0;
if (IsUAV)
- SamplerCmpOrHasCounter = UAVFlags.HasCounter;
+ SamplerCmpOrHasCounter = HasCounter;
else if (RTI.isSampler())
SamplerCmpOrHasCounter = RTI.getSamplerType() == SamplerType::Comparison;
@@ -671,6 +666,9 @@ void ResourceInfo::print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI,
<< " Lower Bound: " << Binding.LowerBound << "\n"
<< " Size: " << Binding.Size << "\n";
+ OS << " Globally Coherent: " << GloballyCoherent << "\n";
+ OS << " HasCounter: " << HasCounter << "\n";
+
RTI.print(OS, DL);
}
@@ -767,7 +765,7 @@ void DXILResourceMap::populate(Module &M, DXILResourceTypeMap &DRTM) {
void DXILResourceMap::print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
const DataLayout &DL) const {
for (unsigned I = 0, E = Infos.size(); I != E; ++I) {
- OS << "Binding " << I << ":\n";
+ OS << "Resource " << I << ":\n";
const dxil::ResourceInfo &RI = Infos[I];
RI.print(OS, DRTM[RI.getHandleTy()], DL);
OS << "\n";
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 27451074581ee..9576dd4a5e27b 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -229,7 +229,7 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) {
dxil::ResourceTypeInfo &TypeInfo = DRTM[RI.getHandleTy()];
dxbc::PSV::ResourceType ResType;
- if (TypeInfo.getUAV().HasCounter)
+ if (RI.HasCounter)
ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter;
else if (TypeInfo.isStruct())
ResType = dxbc::PSV::ResourceType::UAVStructured;
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index 88e23479cba2a..095e79832f39f 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -155,8 +155,8 @@ struct FormatResourceDimension
case dxil::ResourceKind::StructuredBuffer:
if (!Item.isUAV())
OS << "r/o";
- else if (Item.getUAV().HasCounter)
- OS << "r/w+cnt";
+ // else if (Item.getUAV().HasCounter)
+ // OS << "r/w+cnt";
else
OS << "r/w";
break;
diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
index 9b4d7722b72ac..b8f092ab4e514 100644
--- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
+++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
@@ -7,7 +7,7 @@ define void @test_typedbuffer() {
%srv0 = call target("dx.RawBuffer", void, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
i32 1, i32 8, i32 1, i32 0, i1 false)
- ; CHECK: Binding [[SRV0:[0-9]+]]:
+ ; CHECK: Resource [[SRV0:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 0
; CHECK: Space: 1
@@ -21,7 +21,7 @@ define void @test_typedbuffer() {
%srv1 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
i32 4, i32 2, i32 1, i32 0, i1 false)
- ; CHECK: Binding [[SRV1:[0-9]+]]:
+ ; CHECK: Resource [[SRV1:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 1
; CHECK: Space: 4
@@ -36,7 +36,7 @@ define void @test_typedbuffer() {
%srv2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_0_0t(
i32 5, i32 3, i32 24, i32 0, i1 false)
- ; CHECK: Binding [[SRV2:[0-9]+]]:
+ ; CHECK: Resource [[SRV2:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 2
; CHECK: Space: 5
@@ -51,16 +51,16 @@ define void @test_typedbuffer() {
%uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_1_0t(
i32 2, i32 7, i32 1, i32 0, i1 false)
- ; CHECK: Binding [[UAV0:[0-9]+]]:
+ ; CHECK: Resource [[UAV0:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 0
; CHECK: Space: 2
; CHECK: Lower Bound: 7
; CHECK: Size: 1
- ; CHECK: Class: UAV
- ; CHECK: Kind: TypedBuffer
; CHECK: Globally Coherent: 0
; CHECK: HasCounter: 0
+ ; CHECK: Class: UAV
+ ; CHECK: Kind: TypedBuffer
; CHECK: IsROV: 0
; CHECK: Element Type: i32
; CHECK: Element Count: 1
@@ -69,16 +69,16 @@ define void @test_typedbuffer() {
%uav1 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
i32 3, i32 5, i32 1, i32 0, i1 false)
- ; CHECK: Binding [[UAV1:[0-9]+]]:
+ ; CHECK: Resource [[UAV1:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 1
; CHECK: Space: 3
; CHECK: Lower Bound: 5
; CHECK: Size: 1
- ; CHECK: Class: UAV
- ; CHECK: Kind: TypedBuffer
; CHECK: Globally Coherent: 0
; CHECK: HasCounter: 0
+ ; CHECK: Class: UAV
+ ; CHECK: Kind: TypedBuffer
; CHECK: IsROV: 0
; CHECK: Element Type: f32
; CHECK: Element Count: 4
@@ -92,23 +92,23 @@ define void @test_typedbuffer() {
%uav2_2 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0(
i32 4, i32 0, i32 10, i32 5, i1 false)
- ; CHECK: Binding [[UAV2:[0-9]+]]:
+ ; CHECK: Resource [[UAV2:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 2
; CHECK: Space: 4
; CHECK: Lower Bound: 0
; CHECK: Size: 10
- ; CHECK: Class: UAV
- ; CHECK: Kind: TypedBuffer
; CHECK: Globally Coherent: 0
; CHECK: HasCounter: 0
+ ; CHECK: Class: UAV
+ ; CHECK: Kind: TypedBuffer
; CHECK: IsROV: 0
; CHECK: Element Type: f32
; CHECK: Element Count: 4
%cb0 = call target("dx.CBuffer", {float})
@llvm.dx.resource.handlefrombinding(i32 1, i32 0, i32 1, i32 0, i1 false)
- ; CHECK: Binding [[CB0:[0-9]+]]:
+ ; CHECK: Resource [[CB0:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 0
; CHECK: Space: 1
@@ -120,7 +120,7 @@ define void @test_typedbuffer() {
%cb1 = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
@llvm.dx.resource.handlefrombinding(i32 1, i32 8, i32 1, i32 0, i1 false)
- ; CHECK: Binding [[CB1:[0-9]+]]:
+ ; CHECK: Resource [[CB1:[0-9]+]]:
; CHECK: Binding:
; CHECK: Record ID: 1
; CHECK: Space: 1
@@ -130,7 +130,7 @@ define void @test_typedbuffer() {
; CHECK: Kind: CBuffer
; CHECK: CBuffer size: 4
- ; CHECK-NOT: Binding {{[0-9]+}}:
+ ; CHECK-NOT: Resource {{[0-9]+}}:
ret void
}
diff --git a/llvm/unittests/Analysis/DXILResourceTest.cpp b/llvm/unittests/Analysis/DXILResourceTest.cpp
index 6f25983801fc3..3a7c7ab6efd92 100644
--- a/llvm/unittests/Analysis/DXILResourceTest.cpp
+++ b/llvm/unittests/Analysis/DXILResourceTest.cpp
@@ -114,8 +114,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
ResourceTypeInfo RTI(llvm::TargetExtType::get(
Context, "dx.RawBuffer", Int8Ty, {/*IsWriteable=*/1, /*IsROV=*/0}));
EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
- EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
- EXPECT_EQ(RTI.getUAV().HasCounter, false);
EXPECT_EQ(RTI.getUAV().IsROV, false);
EXPECT_EQ(RTI.getResourceKind(), ResourceKind::RawBuffer);
@@ -128,6 +126,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
TestMD.get(1, GV, "BufferOut", 2, 3, 1, 11, false, false, false,
nullptr));
+ EXPECT_EQ(RI.GloballyCoherent, false);
+ EXPECT_EQ(RI.HasCounter, false);
}
// struct BufType0 { int i; float f; double d; };
@@ -268,27 +268,28 @@ TEST(DXILResource, AnnotationsAndMetadata) {
// globallycoherent RWTexture2D<int2> OutputTexture : register(u0, space2);
{
ResourceTypeInfo RTI(llvm::TargetExtType::get(
- Context, "dx.Texture", Int32x2Ty,
- {/*IsWriteable=*/1,
- /*IsROV=*/0, /*IsSigned=*/1,
- llvm::to_underlying(ResourceKind::Texture2D)}),
- /*GloballyCoherent=*/true, /*HasCounter=*/false);
+ Context, "dx.Texture", Int32x2Ty,
+ {/*IsWriteable=*/1,
+ /*IsROV=*/0, /*IsSigned=*/1,
+ llvm::to_underlying(ResourceKind::Texture2D)}));
EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
- EXPECT_EQ(RTI.getUAV().GloballyCoherent, true);
- EXPECT_EQ(RTI.getUAV().HasCounter, false);
EXPECT_EQ(RTI.getUAV().IsROV, false);
EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Texture2D);
ResourceInfo RI(
/*RecordID=*/0, /*Space=*/2, /*LowerBound=*/0, /*Size=*/1,
- RTI.getHandleTy());
+ RTI.getHandleTy(),
+ /*Symbol=*/nullptr, /*GloballyCoherent=*/true, /*HasCounter=*/false);
GlobalVariable *GV =
RI.createSymbol(M, RTI.createElementStruct(), "OutputTexture");
EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x00005002U, 0x00000204U);
EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
TestMD.get(0, GV, "OutputTexture", 2, 0, 1, 2, true, false,
false, TestMD.get(0, 4)));
+
+ EXPECT_EQ(RI.GloballyCoherent, true);
+ EXPECT_EQ(RI.HasCounter, false);
}
// RasterizerOrderedBuffer<float4> ROB;
@@ -297,8 +298,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
Context, "dx.TypedBuffer", Floatx4Ty,
{/*IsWriteable=*/1, /*IsROV=*/1, /*IsSigned=*/0}));
EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
- EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
- EXPECT_EQ(RTI.getUAV().HasCounter, false);
EXPECT_EQ(RTI.getUAV().IsROV, true);
ASSERT_EQ(RTI.isTyped(), true);
EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::F32);
@@ -313,19 +312,17 @@ TEST(DXILResource, AnnotationsAndMetadata) {
EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
TestMD.get(0, GV, "ROB", 0, 0, 1, 10, false, false, true,
TestMD.get(0, 9)));
+ EXPECT_EQ(RI.GloballyCoherent, false);
+ EXPECT_EQ(RI.HasCounter, false);
}
// RWStructuredBuffer<ParticleMotion> g_OutputBuffer : register(u2);
{
StructType *BufType1 = StructType::create(
Context, {Floatx3Ty, FloatTy, Int32Ty}, "ParticleMotion");
- ResourceTypeInfo RTI(
- llvm::TargetExtType::get(Context, "dx.RawBuffer", BufType1,
- {/*IsWriteable=*/1, /*IsROV=*/0}),
- /*GloballyCoherent=*/false, /*HasCounter=*/true);
+ ResourceTypeInfo RTI(llvm::TargetExtType::get(
+ Context, "dx.RawBuffer", BufType1, {/*IsWriteable=*/1, /*IsROV=*/0}));
EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
- EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
- EXPECT_EQ(RTI.getUAV().HasCounter, true);
EXPECT_EQ(RTI.getUAV().IsROV, false);
ASSERT_EQ(RTI.isStruct(), true);
EXPECT_EQ(RTI.getStruct(DL).Stride, 20u);
@@ -334,13 +331,16 @@ TEST(DXILResource, AnnotationsAndMetadata) {
ResourceInfo RI(
/*RecordID=*/0, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1,
- RTI.getHandleTy());
+ RTI.getHandleTy(),
+ /*Symbol=*/nullptr, /*GloballyCoherent=*/false, /*HasCounter=*/true);
GlobalVariable *GV =
RI.createSymbol(M, RTI.createElementStruct(), "g_OutputBuffer");
EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x0000920cU, 0x00000014U);
EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
TestMD.get(0, GV, "g_OutputBuffer", 0, 2, 1, 12, false, true,
false, TestMD.get(1, 20)));
+ EXPECT_EQ(RI.GloballyCoherent, false);
+ EXPECT_EQ(RI.HasCounter, true);
}
// RWTexture2DMSArray<uint, 8> g_rw_t2dmsa;
@@ -350,8 +350,6 @@ TEST(DXILResource, AnnotationsAndMetadata) {
{/*IsWriteable=*/1, /*SampleCount=*/8, /*IsSigned=*/0,
llvm::to_underlying(ResourceKind::Texture2DMSArray)}));
EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV);
- EXPECT_EQ(RTI.getUAV().GloballyCoherent, false);
- EXPECT_EQ(RTI.getUAV().HasCounter, false);
EXPECT_EQ(RTI.getUAV().IsROV, false);
ASSERT_EQ(RTI.isTyped(), true);
EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::U32);
@@ -369,6 +367,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
EXPECT_MDEQ(RI.getAsMetadata(M, RTI),
TestMD.get(0, GV, "g_rw_t2dmsa", 0, 0, 1, 8, false, false,
false, TestMD.get(0, 5)));
+ EXPECT_EQ(RI.GloballyCoherent, false);
+ EXPECT_EQ(RI.HasCounter, false);
}
// cbuffer cb0 { float4 g_X; float4 g_Y; }
>From 8c8a560dfc596bf9f87ed1f9f3042b17b0605a01 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Fri, 11 Apr 2025 10:10:00 -0600
Subject: [PATCH 2/2] Address Comments
---
llvm/include/llvm/Analysis/DXILResource.h | 23 +++++++++++++------
llvm/lib/Analysis/DXILResource.cpp | 21 ++++++++++++++---
.../lib/Target/DirectX/DXContainerGlobals.cpp | 2 +-
.../DXILResource/buffer-frombinding.ll | 6 ++---
llvm/unittests/Analysis/DXILResourceTest.cpp | 23 +++++++++++--------
5 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index 6ff4e2fb56006..e9b746d8096ee 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -306,6 +306,13 @@ class ResourceTypeInfo {
//===----------------------------------------------------------------------===//
+enum class ResourceCounterDirection {
+ Increment,
+ Decrement,
+ Unknown,
+ Invalid,
+};
+
class ResourceInfo {
public:
struct ResourceBinding {
@@ -333,20 +340,22 @@ class ResourceInfo {
GlobalVariable *Symbol = nullptr;
public:
- bool GloballyCoherent;
- bool HasCounter;
+ bool GloballyCoherent = false;
+ ResourceCounterDirection CounterDirection = ResourceCounterDirection::Unknown;
ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
uint32_t Size, TargetExtType *HandleTy,
- GlobalVariable *Symbol = nullptr, bool GloballyCoherent = false,
- bool HasCounter = false)
+ GlobalVariable *Symbol = nullptr)
: Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy),
- Symbol(Symbol), GloballyCoherent(GloballyCoherent),
- HasCounter(HasCounter) {}
+ Symbol(Symbol) {}
void setBindingID(unsigned ID) { Binding.RecordID = ID; }
void setGloballyCoherent(bool V) { GloballyCoherent = V; }
- void setHasCounter(bool V) { HasCounter = V; }
+ void setCounterDirection(ResourceCounterDirection V) { CounterDirection = V; }
+
+ bool hasCounter() const {
+ return CounterDirection != ResourceCounterDirection::Unknown;
+ }
const ResourceBinding &getBinding() const { return Binding; }
TargetExtType *getHandleTy() const { return HandleTy; }
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index d4f0127a931dc..7777e16ea9768 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -573,7 +573,7 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M,
if (RTI.isUAV()) {
ResourceTypeInfo::UAVInfo UAVFlags = RTI.getUAV();
MDVals.push_back(getBoolMD(GloballyCoherent));
- MDVals.push_back(getBoolMD(HasCounter));
+ MDVals.push_back(getBoolMD(hasCounter()));
MDVals.push_back(getBoolMD(UAVFlags.IsROV));
} else {
// All SRVs include sample count in the metadata, but it's only meaningful
@@ -617,7 +617,7 @@ ResourceInfo::getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const {
bool IsGloballyCoherent = IsUAV && GloballyCoherent;
uint8_t SamplerCmpOrHasCounter = 0;
if (IsUAV)
- SamplerCmpOrHasCounter = HasCounter;
+ SamplerCmpOrHasCounter = hasCounter();
else if (RTI.isSampler())
SamplerCmpOrHasCounter = RTI.getSamplerType() == SamplerType::Comparison;
@@ -667,7 +667,22 @@ void ResourceInfo::print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI,
<< " Size: " << Binding.Size << "\n";
OS << " Globally Coherent: " << GloballyCoherent << "\n";
- OS << " HasCounter: " << HasCounter << "\n";
+ OS << " Counter Direction: ";
+
+ switch (CounterDirection) {
+ case ResourceCounterDirection::Increment:
+ OS << "Increment\n";
+ break;
+ case ResourceCounterDirection::Decrement:
+ OS << "Decrement\n";
+ break;
+ case ResourceCounterDirection::Unknown:
+ OS << "Unknown\n";
+ break;
+ case ResourceCounterDirection::Invalid:
+ OS << "Invalid\n";
+ break;
+ }
RTI.print(OS, DL);
}
diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
index 9576dd4a5e27b..0aa6516db636c 100644
--- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
+++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp
@@ -229,7 +229,7 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) {
dxil::ResourceTypeInfo &TypeInfo = DRTM[RI.getHandleTy()];
dxbc::PSV::ResourceType ResType;
- if (RI.HasCounter)
+ if (RI.hasCounter())
ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter;
else if (TypeInfo.isStruct())
ResType = dxbc::PSV::ResourceType::UAVStructured;
diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
index b8f092ab4e514..81c8b5530afb6 100644
--- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
+++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
@@ -58,7 +58,7 @@ define void @test_typedbuffer() {
; CHECK: Lower Bound: 7
; CHECK: Size: 1
; CHECK: Globally Coherent: 0
- ; CHECK: HasCounter: 0
+ ; CHECK: Counter Direction: Unknown
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: IsROV: 0
@@ -76,7 +76,7 @@ define void @test_typedbuffer() {
; CHECK: Lower Bound: 5
; CHECK: Size: 1
; CHECK: Globally Coherent: 0
- ; CHECK: HasCounter: 0
+ ; CHECK: Counter Direction: Unknown
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: IsROV: 0
@@ -99,7 +99,7 @@ define void @test_typedbuffer() {
; CHECK: Lower Bound: 0
; CHECK: Size: 10
; CHECK: Globally Coherent: 0
- ; CHECK: HasCounter: 0
+ ; CHECK: Counter Direction: Unknown
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: IsROV: 0
diff --git a/llvm/unittests/Analysis/DXILResourceTest.cpp b/llvm/unittests/Analysis/DXILResourceTest.cpp
index 3a7c7ab6efd92..ed82a1ba0730a 100644
--- a/llvm/unittests/Analysis/DXILResourceTest.cpp
+++ b/llvm/unittests/Analysis/DXILResourceTest.cpp
@@ -127,7 +127,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
TestMD.get(1, GV, "BufferOut", 2, 3, 1, 11, false, false, false,
nullptr));
EXPECT_EQ(RI.GloballyCoherent, false);
- EXPECT_EQ(RI.HasCounter, false);
+ EXPECT_EQ(RI.hasCounter(), false);
+ EXPECT_EQ(RI.CounterDirection, ResourceCounterDirection::Unknown);
}
// struct BufType0 { int i; float f; double d; };
@@ -279,8 +280,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
ResourceInfo RI(
/*RecordID=*/0, /*Space=*/2, /*LowerBound=*/0, /*Size=*/1,
- RTI.getHandleTy(),
- /*Symbol=*/nullptr, /*GloballyCoherent=*/true, /*HasCounter=*/false);
+ RTI.getHandleTy());
+ RI.setGloballyCoherent(true);
GlobalVariable *GV =
RI.createSymbol(M, RTI.createElementStruct(), "OutputTexture");
EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x00005002U, 0x00000204U);
@@ -289,7 +290,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
false, TestMD.get(0, 4)));
EXPECT_EQ(RI.GloballyCoherent, true);
- EXPECT_EQ(RI.HasCounter, false);
+ EXPECT_EQ(RI.hasCounter(), false);
+ EXPECT_EQ(RI.CounterDirection, ResourceCounterDirection::Unknown);
}
// RasterizerOrderedBuffer<float4> ROB;
@@ -313,7 +315,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
TestMD.get(0, GV, "ROB", 0, 0, 1, 10, false, false, true,
TestMD.get(0, 9)));
EXPECT_EQ(RI.GloballyCoherent, false);
- EXPECT_EQ(RI.HasCounter, false);
+ EXPECT_EQ(RI.hasCounter(), false);
+ EXPECT_EQ(RI.CounterDirection, ResourceCounterDirection::Unknown);
}
// RWStructuredBuffer<ParticleMotion> g_OutputBuffer : register(u2);
@@ -331,8 +334,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
ResourceInfo RI(
/*RecordID=*/0, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1,
- RTI.getHandleTy(),
- /*Symbol=*/nullptr, /*GloballyCoherent=*/false, /*HasCounter=*/true);
+ RTI.getHandleTy());
+ RI.setCounterDirection(ResourceCounterDirection::Increment);
GlobalVariable *GV =
RI.createSymbol(M, RTI.createElementStruct(), "g_OutputBuffer");
EXPECT_PROPS_EQ(RI.getAnnotateProps(M, RTI), 0x0000920cU, 0x00000014U);
@@ -340,7 +343,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
TestMD.get(0, GV, "g_OutputBuffer", 0, 2, 1, 12, false, true,
false, TestMD.get(1, 20)));
EXPECT_EQ(RI.GloballyCoherent, false);
- EXPECT_EQ(RI.HasCounter, true);
+ EXPECT_EQ(RI.hasCounter(), true);
+ EXPECT_EQ(RI.CounterDirection, ResourceCounterDirection::Increment);
}
// RWTexture2DMSArray<uint, 8> g_rw_t2dmsa;
@@ -368,7 +372,8 @@ TEST(DXILResource, AnnotationsAndMetadata) {
TestMD.get(0, GV, "g_rw_t2dmsa", 0, 0, 1, 8, false, false,
false, TestMD.get(0, 5)));
EXPECT_EQ(RI.GloballyCoherent, false);
- EXPECT_EQ(RI.HasCounter, false);
+ EXPECT_EQ(RI.hasCounter(), false);
+ EXPECT_EQ(RI.CounterDirection, ResourceCounterDirection::Unknown);
}
// cbuffer cb0 { float4 g_X; float4 g_Y; }
More information about the llvm-commits
mailing list