Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/DXILResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ class ResourceTypeInfo {
: ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid) {}

TargetExtType *getHandleTy() const { return HandleTy; }
LLVM_ABI StructType *createElementStruct();
LLVM_ABI StructType *createElementStruct(StringRef CBufferName = "");

// Conditions to check before accessing specific views.
LLVM_ABI bool isUAV() const;
Expand Down
122 changes: 101 additions & 21 deletions llvm/lib/Analysis/DXILResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static StringRef getResourceKindName(ResourceKind RK) {
case ResourceKind::TextureCubeArray:
return "TextureCubeArray";
case ResourceKind::TypedBuffer:
return "TypedBuffer";
return "Buffer";
case ResourceKind::RawBuffer:
return "RawBuffer";
case ResourceKind::StructuredBuffer:
Expand Down Expand Up @@ -132,6 +132,44 @@ static StringRef getElementTypeName(ElementType ET) {
llvm_unreachable("Unhandled ElementType");
}

static StringRef getElementTypeNameForTemplate(ElementType ET) {
switch (ET) {
case ElementType::I1:
return "bool";
case ElementType::I16:
return "int16_t";
case ElementType::U16:
return "uint16_t";
case ElementType::I32:
return "int32_t";
case ElementType::U32:
return "uint32_t";
case ElementType::I64:
return "int64_t";
case ElementType::U64:
return "uint32_t";
case ElementType::F16:
case ElementType::SNormF16:
case ElementType::UNormF16:
return "half";
case ElementType::F32:
case ElementType::SNormF32:
case ElementType::UNormF32:
return "float";
case ElementType::F64:
case ElementType::SNormF64:
case ElementType::UNormF64:
return "double";
case ElementType::PackedS8x32:
return "int8_t4_packed";
case ElementType::PackedU8x32:
return "uint8_t4_packed";
case ElementType::Invalid:
return "<invalid>";
}
llvm_unreachable("Unhandled ElementType");
}

static StringRef getSamplerTypeName(SamplerType ST) {
switch (ST) {
case SamplerType::Default:
Expand Down Expand Up @@ -219,12 +257,44 @@ ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
}

static void formatTypeName(SmallString<64> &Dest, StringRef Name,
bool isWriteable, bool isROV) {
Dest = isWriteable ? (isROV ? "RasterizerOrdered" : "RW") : "";
Dest += Name;
bool IsWriteable, bool IsROV,
Type *ContainedType = nullptr,
bool IsSigned = true) {
raw_svector_ostream DestStream(Dest);
if (IsWriteable)
DestStream << (IsROV ? "RasterizerOrdered" : "RW");
DestStream << Name;

if (!ContainedType)
return;

StringRef ElementName;
ElementType ET = toDXILElementType(ContainedType, IsSigned);
if (ET != ElementType::Invalid) {
Copy link
Contributor

@V-FEXrt V-FEXrt May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you have a test covering both branches here? I'm not exactly sure what's happening when ET isn't invalid or what the nominal flow is

ElementName = getElementTypeNameForTemplate(ET);
} else {
assert(isa<StructType>(ContainedType) &&
"invalid element type for raw buffer");
StructType *ST = cast<StructType>(ContainedType);
if (!ST->hasName())
return;
ElementName = ST->getStructName();
}

DestStream << "<" << ElementName;
if (const FixedVectorType *VTy = dyn_cast<FixedVectorType>(ContainedType))
DestStream << VTy->getNumElements();
DestStream << ">";
}

static StructType *getOrCreateElementStruct(Type *ElemType, StringRef Name) {
StructType *Ty = StructType::getTypeByName(ElemType->getContext(), Name);
if (Ty && Ty->getNumElements() == 1 && Ty->getElementType(0) == ElemType)
return Ty;
return StructType::create(ElemType, Name);
}

StructType *ResourceTypeInfo::createElementStruct() {
StructType *ResourceTypeInfo::createElementStruct(StringRef CBufferName) {
SmallString<64> TypeName;

switch (Kind) {
Expand All @@ -237,51 +307,61 @@ StructType *ResourceTypeInfo::createElementStruct() {
case ResourceKind::TextureCubeArray: {
auto *RTy = cast<TextureExtType>(HandleTy);
formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
RTy->isROV());
return StructType::create(RTy->getResourceType(), TypeName);
RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
}
case ResourceKind::Texture2DMS:
case ResourceKind::Texture2DMSArray: {
auto *RTy = cast<MSTextureExtType>(HandleTy);
formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
/*IsROV=*/false);
return StructType::create(RTy->getResourceType(), TypeName);
/*IsROV=*/false, RTy->getResourceType(), RTy->isSigned());
return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
}
case ResourceKind::TypedBuffer: {
auto *RTy = cast<TypedBufferExtType>(HandleTy);
formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
RTy->isROV());
return StructType::create(RTy->getResourceType(), TypeName);
RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
}
case ResourceKind::RawBuffer: {
auto *RTy = cast<RawBufferExtType>(HandleTy);
formatTypeName(TypeName, "ByteAddressBuffer", RTy->isWriteable(),
RTy->isROV());
return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
TypeName);
return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
TypeName);
}
case ResourceKind::StructuredBuffer: {
auto *RTy = cast<RawBufferExtType>(HandleTy);
Type *Ty = RTy->getResourceType();
formatTypeName(TypeName, "StructuredBuffer", RTy->isWriteable(),
RTy->isROV());
return StructType::create(RTy->getResourceType(), TypeName);
RTy->isROV(), RTy->getResourceType(), true);
return getOrCreateElementStruct(Ty, TypeName);
}
case ResourceKind::FeedbackTexture2D:
case ResourceKind::FeedbackTexture2DArray: {
auto *RTy = cast<FeedbackTextureExtType>(HandleTy);
TypeName = formatv("{0}<{1}>", getResourceKindName(Kind),
llvm::to_underlying(RTy->getFeedbackType()));
return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
TypeName);
return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
TypeName);
}
case ResourceKind::CBuffer: {
auto *RTy = cast<CBufferExtType>(HandleTy);
LayoutExtType *LayoutType = cast<LayoutExtType>(RTy->getResourceType());
StructType *Ty = cast<StructType>(LayoutType->getWrappedType());
SmallString<64> Name = getResourceKindName(Kind);
if (!CBufferName.empty()) {
Name.append(".");
Name.append(CBufferName);
}
return StructType::create(Ty->elements(), Name);
}
case ResourceKind::CBuffer:
return StructType::create(HandleTy->getContext(), "cbuffer");
case ResourceKind::Sampler: {
auto *RTy = cast<SamplerExtType>(HandleTy);
TypeName = formatv("SamplerState<{0}>",
llvm::to_underlying(RTy->getSamplerType()));
return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
TypeName);
return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
TypeName);
}
case ResourceKind::TBuffer:
case ResourceKind::RTAccelerationStructure:
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ static NamedMDNode *emitResourceMetadata(Module &M, DXILResourceMap &DRM,

for (ResourceInfo &RI : DRM)
if (!RI.hasSymbol())
RI.createSymbol(M, DRTM[RI.getHandleTy()].createElementStruct());
RI.createSymbol(M,
DRTM[RI.getHandleTy()].createElementStruct(RI.getName()));

SmallVector<Metadata *> SRVs, UAVs, CBufs, Smps;
for (const ResourceInfo &RI : DRM.srvs())
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Analysis/DXILResource/buffer-frombinding.ll
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ define void @test_typedbuffer() {
; CHECK: Lower Bound: 3
; CHECK: Size: 24
; CHECK: Class: SRV
; CHECK: Kind: TypedBuffer
; CHECK: Kind: Buffer
; CHECK: Element Type: u32
; CHECK: Element Count: 4

Expand All @@ -70,7 +70,7 @@ define void @test_typedbuffer() {
; CHECK: Globally Coherent: 0
; CHECK: Counter Direction: Unknown
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: Kind: Buffer
; CHECK: IsROV: 0
; CHECK: Element Type: i32
; CHECK: Element Count: 1
Expand All @@ -89,7 +89,7 @@ define void @test_typedbuffer() {
; CHECK: Globally Coherent: 0
; CHECK: Counter Direction: Decrement
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: Kind: Buffer
; CHECK: IsROV: 0
; CHECK: Element Type: f32
; CHECK: Element Count: 4
Expand All @@ -112,7 +112,7 @@ define void @test_typedbuffer() {
; CHECK: Globally Coherent: 0
; CHECK: Counter Direction: Increment
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: Kind: Buffer
; CHECK: IsROV: 0
; CHECK: Element Type: f32
; CHECK: Element Count: 4
Expand All @@ -132,7 +132,7 @@ define void @test_typedbuffer() {
; CHECK: Globally Coherent: 0
; CHECK: Counter Direction: Invalid
; CHECK: Class: UAV
; CHECK: Kind: TypedBuffer
; CHECK: Kind: Buffer
; CHECK: IsROV: 0
; CHECK: Element Type: f32
; CHECK: Element Count: 4
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/DirectX/Metadata/cbuffer-only.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ target triple = "dxil-pc-shadermodel6.6-compute"
define void @cbuffer_is_only_binding() {
%cbuf = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
@llvm.dx.resource.handlefrombinding(i32 1, i32 8, i32 1, i32 0, i1 false, ptr null)
; CHECK: %cbuffer = type
; CHECK: %CBuffer = type { float }

ret void
}

; CHECK: @[[CB0:.*]] = external constant %cbuffer
; CHECK: @[[CB0:.*]] = external constant %CBuffer

; CHECK: !{i32 0, ptr @[[CB0]], !""
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ define void @test() #0 {

attributes #0 = { noinline nounwind "hlsl.shader"="compute" }

; CHECK: @CB1 = external constant %cbuffer
; CHECK: @CB2 = external constant %cbuffer.0
; CHECK: @MyConstants = external constant %cbuffer.1
; CHECK: @CB1 = external constant %CBuffer.CB1
; CHECK: @CB2 = external constant %CBuffer.CB2
; CHECK: @MyConstants = external constant %CBuffer.MyConstants

; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}

Expand Down
16 changes: 8 additions & 8 deletions llvm/test/CodeGen/DirectX/Metadata/resource-symbols.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ define void @test() {
; Buffer<float4>
%float4 = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr @A.str)
; CHECK: %TypedBuffer = type { <4 x float> }
; CHECK: %"Buffer<float4>" = type { <4 x float> }

; Buffer<int>
%int = call target("dx.TypedBuffer", i32, 0, 0, 1)
@llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
; CHECK: %TypedBuffer.0 = type { i32 }
; CHECK: %"Buffer<int32_t>" = type { i32 }

; Buffer<uint3>
%uint3 = call target("dx.TypedBuffer", <3 x i32>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr null)
; CHECK: %TypedBuffer.1 = type { <3 x i32> }
; CHECK: %"Buffer<uint32_t3>" = type { <3 x i32> }

; StructuredBuffer<S>
%struct0 = call target("dx.RawBuffer", %struct.S, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 10, i32 1, i32 0, i1 true, ptr @SB.str)
; CHECK: %StructuredBuffer = type { %struct.S }
; CHECK: %"StructuredBuffer<struct.S>" = type { %struct.S }

; ByteAddressBuffer
%byteaddr = call target("dx.RawBuffer", i8, 0, 0)
Expand All @@ -36,10 +36,10 @@ define void @test() {
ret void
}

; CHECK: @[[T0:.*]] = external constant %TypedBuffer
; CHECK-NEXT: @[[T1:.*]] = external constant %TypedBuffer.0
; CHECK-NEXT: @[[T2:.*]] = external constant %TypedBuffer.1
; CHECK-NEXT: @[[S0:.*]] = external constant %StructuredBuffer
; CHECK: @[[T0:.*]] = external constant %"Buffer<float4>"
; CHECK-NEXT: @[[T1:.*]] = external constant %"Buffer<int32_t>"
; CHECK-NEXT: @[[T2:.*]] = external constant %"Buffer<uint32_t3>"
; CHECK-NEXT: @[[S0:.*]] = external constant %"StructuredBuffer<struct.S>"
; CHECK-NEXT: @[[B0:.*]] = external constant %ByteAddressBuffer

; CHECK: !{i32 0, ptr @[[T0]], !"A"
Expand Down
33 changes: 16 additions & 17 deletions llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
Original file line number Diff line number Diff line change
Expand Up @@ -78,25 +78,24 @@ define void @test() #0 {

attributes #0 = { noinline nounwind "hlsl.shader"="compute" }

; CHECK: %TypedBuffer = type { <4 x half> }
; CHECK: %TypedBuffer.0 = type { <2 x float> }
; CHECK: %TypedBuffer.1 = type { double }
; CHECK: %TypedBuffer.2 = type { <4 x i32> }
; CHECK: %"Buffer<half4>" = type { <4 x half> }
; CHECK: %"Buffer<float2>" = type { <2 x float> }
; CHECK: %"Buffer<double>" = type { double }
; CHECK: %"Buffer<int32_t4>" = type { <4 x i32> }
; CHECK: %ByteAddressBuffer = type { i32 }
; CHECK: %StructuredBuffer = type { i16 }
; CHECK: %TypedBuffer.3 = type { i64 }
; CHECK: %TypedBuffer.4 = type { <4 x float> }
; CHECK: %TypedBuffer.5 = type { i64 }

; CHECK: @Zero = external constant %TypedBuffer
; CHECK: @One = external constant %TypedBuffer.0
; CHECK: @Two = external constant %TypedBuffer.1
; CHECK: @Three = external constant %TypedBuffer.2
; CHECK: %"StructuredBuffer<int16_t>" = type { i16 }
; CHECK: %"Buffer<uint32_t>" = type { i64 }
; CHECK: %"Buffer<float4>" = type { <4 x float> }

; CHECK: @Zero = external constant %"Buffer<half4>"
; CHECK: @One = external constant %"Buffer<float2>"
; CHECK: @Two = external constant %"Buffer<double>"
; CHECK: @Three = external constant %"Buffer<int32_t4>"
; CHECK: @Four = external constant %ByteAddressBuffer
; CHECK: @Five = external constant %StructuredBuffer
; CHECK: @Six = external constant %TypedBuffer.3
; CHECK: @Array = external constant %TypedBuffer.4
; CHECK: @Seven = external constant %TypedBuffer.5
; CHECK: @Five = external constant %"StructuredBuffer<int16_t>"
; CHECK: @Six = external constant %"Buffer<uint32_t>"
; CHECK: @Array = external constant %"Buffer<float4>"
; CHECK: @Seven = external constant %"Buffer<uint32_t>"

; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}

Expand Down
Loading
Loading