Skip to content

Commit

Permalink
[DirectX] Update CBuffer to refer to a dx.Layout type (llvm#128697)
Browse files Browse the repository at this point in the history
This adds support cbuffers based on llvm/wg-hlsl#171 - the type argument
of the CBuffer TargetExtType is either a `dx.Layout` type which reports
its own size, or it's a normal type and we can simply refer to
DataLayout.
  • Loading branch information
bogner authored Feb 25, 2025
1 parent 6a5dd04 commit c79e867
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
22 changes: 21 additions & 1 deletion llvm/include/llvm/Analysis/DXILResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ class CBufferExtType : public TargetExtType {
CBufferExtType &operator=(const CBufferExtType &) = delete;

Type *getResourceType() const { return getTypeParameter(0); }
uint32_t getCBufferSize() const { return getIntParameter(0); }

static bool classof(const TargetExtType *T) {
return T->getName() == "dx.CBuffer";
Expand Down Expand Up @@ -197,6 +196,27 @@ class SamplerExtType : public TargetExtType {
}
};

/// The dx.Layout target extension type
///
/// `target("dx.Layout", <Type>, <size>, [offsets...])`
class LayoutExtType : public TargetExtType {
public:
LayoutExtType() = delete;
LayoutExtType(const LayoutExtType &) = delete;
LayoutExtType &operator=(const LayoutExtType &) = delete;

Type *getWrappedType() const { return getTypeParameter(0); }
uint32_t getSize() const { return getIntParameter(0); }
uint32_t getOffsetOfElement(int I) const { return getIntParameter(I + 1); }

static bool classof(const TargetExtType *T) {
return T->getName() == "dx.Layout";
}
static bool classof(const Type *T) {
return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
}
};

//===----------------------------------------------------------------------===//

class ResourceTypeInfo {
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/Analysis/DXILResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,14 @@ ResourceTypeInfo::UAVInfo ResourceTypeInfo::getUAV() const {

uint32_t ResourceTypeInfo::getCBufferSize(const DataLayout &DL) const {
assert(isCBuffer() && "Not a CBuffer");
return cast<CBufferExtType>(HandleTy)->getCBufferSize();

Type *ElTy = cast<CBufferExtType>(HandleTy)->getResourceType();

if (auto *LayoutTy = dyn_cast<LayoutExtType>(ElTy))
return LayoutTy->getSize();

// TODO: What should we do with unannotated arrays?
return DL.getTypeAllocSize(ElTy);
}

dxil::SamplerType ResourceTypeInfo::getSamplerType() const {
Expand Down
26 changes: 26 additions & 0 deletions llvm/test/Analysis/DXILResource/buffer-frombinding.ll
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,30 @@ define void @test_typedbuffer() {
; 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: Binding:
; CHECK: Record ID: 0
; CHECK: Space: 1
; CHECK: Lower Bound: 0
; CHECK: Size: 1
; CHECK: Class: CBuffer
; CHECK: Kind: CBuffer
; CHECK: CBuffer size: 4

%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: Binding:
; CHECK: Record ID: 1
; CHECK: Space: 1
; CHECK: Lower Bound: 8
; CHECK: Size: 1
; CHECK: Class: CBuffer
; CHECK: Kind: CBuffer
; CHECK: CBuffer size: 4

; CHECK-NOT: Binding {{[0-9]+}}:

ret void
Expand All @@ -118,5 +142,7 @@ define void @test_typedbuffer() {
; CHECK-DAG: Call bound to [[UAV1]]: %uav1 =
; CHECK-DAG: Call bound to [[UAV2]]: %uav2_1 =
; CHECK-DAG: Call bound to [[UAV2]]: %uav2_2 =
; CHECK-DAG: Call bound to [[CB0]]: %cb0 =
; CHECK-DAG: Call bound to [[CB1]]: %cb1 =

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

0 comments on commit c79e867

Please sign in to comment.