Skip to content

Commit 7a4b3b4

Browse files
authored
[HLSL] Add Load(int) method on structured buffers (#120663)
Adds `T Load(int)` method on `StructuredBuffer`, `RWStructuredBuffer` and `RasterizerOrderedStructuredBuffer`. Uses the existing `addLoadMethods` in HLSLExternalSemalSource so most of this change is just tests. Fixes #112977
1 parent df8efbd commit 7a4b3b4

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
10271027
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
10281028
/*IsROV=*/false, /*RawBuffer=*/true)
10291029
.addArraySubscriptOperators()
1030+
.addLoadMethods()
10301031
.completeDefinition();
10311032
});
10321033

@@ -1037,6 +1038,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
10371038
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
10381039
/*IsROV=*/false, /*RawBuffer=*/true)
10391040
.addArraySubscriptOperators()
1041+
.addLoadMethods()
10401042
.addIncrementCounterMethod()
10411043
.addDecrementCounterMethod()
10421044
.completeDefinition();
@@ -1072,6 +1074,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
10721074
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
10731075
/*IsROV=*/true, /*RawBuffer=*/true)
10741076
.addArraySubscriptOperators()
1077+
.addLoadMethods()
10751078
.addIncrementCounterMethod()
10761079
.addDecrementCounterMethod()
10771080
.completeDefinition();

clang/test/AST/HLSL/StructuredBuffers-AST.hlsl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
//
55
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
66
// RUN: -DRESOURCE=StructuredBuffer %s | FileCheck -DRESOURCE=StructuredBuffer \
7-
// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-SUBSCRIPT %s
7+
// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-SUBSCRIPT,CHECK-LOAD %s
88
//
99
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
1010
// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \
1111
// RUN: -check-prefix=EMPTY %s
1212
//
1313
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
1414
// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \
15-
// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-COUNTER %s
15+
// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-COUNTER,CHECK-LOAD %s
1616
//
1717
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
1818
// RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \
@@ -36,7 +36,7 @@
3636
//
3737
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
3838
// RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \
39-
// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT %s
39+
// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT,CHECK-LOAD %s
4040

4141
// This test tests two different AST generations for each structured buffer.
4242
// The "EMPTY" test mode verifies the AST generated by forward declaration
@@ -125,6 +125,21 @@ RESOURCE<float> Buffer;
125125
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'const element_type &(unsigned int) const'
126126
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &(unsigned int)'
127127

128+
// CHECK-LOAD: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Load 'element_type (unsigned int)'
129+
// CHECK-LOAD-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Index 'unsigned int'
130+
// CHECK-LOAD-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
131+
// CHECK-LOAD-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
132+
// CHECK-LOAD-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
133+
// CHECK-LOAD-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
134+
// CHECK-LOAD-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
135+
// CHECK-LOAD-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
136+
// CHECK-LOAD-SAME{LITERAL}: [[hlsl::resource_class(
137+
// CHECK-LOAD-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
138+
// CHECK-LOAD-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
139+
// CHECK-LOAD-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '[[RESOURCE]]<element_type>' lvalue implicit this
140+
// CHECK-LOAD-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int'
141+
// CHECK-LOAD-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
142+
128143
// CHECK-COUNTER: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> IncrementCounter 'unsigned int ()'
129144
// CHECK-COUNTER-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
130145
// CHECK-COUNTER-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>

clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33

44
// NOTE: SPIRV codegen for resource methods is not yet implemented
55

6+
StructuredBuffer<float> SB1 : register(t0);
67
RWStructuredBuffer<float> RWSB1 : register(u0);
78
RWStructuredBuffer<float> RWSB2 : register(u1);
89
AppendStructuredBuffer<float> ASB : register(u2);
910
ConsumeStructuredBuffer<float> CSB : register(u3);
1011

12+
// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", float, 0, 0) }
1113
// CHECK: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
14+
// CHECK: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
15+
// CHECK: %"class.hlsl::ConsumeStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
1216

1317
export int TestIncrementCounter() {
1418
return RWSB1.IncrementCounter();
@@ -45,5 +49,16 @@ export float TestConsume() {
4549
// CHECK-DXIL: %[[VALUE:.*]] = load float, ptr %[[RESPTR]], align 4
4650
// CHECK-DXIL: ret float %[[VALUE]]
4751

52+
export float TestLoad() {
53+
return RWSB1.Load(1) + SB1.Load(2);
54+
}
55+
56+
// CHECK: define noundef float @_Z8TestLoadv()
57+
// CHECK: %[[PTR1:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i32 %{{[0-9]+}})
58+
// CHECK: %[[VALUE1:.*]] = load float, ptr %[[PTR1]]
59+
// CHECK: %[[PTR2:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0) %{{[0-9]+}}, i32 %{{[0-9]+}})
60+
// CHECK: %[[VALUE2:.*]] = load float, ptr %[[PTR2]]
61+
4862
// CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i8)
4963
// CHECK: declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32)
64+
// CHECK: declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0), i32)

clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-ps.hlsl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,14 @@ export void TestDecrementCounter() {
2424
ROSB2.DecrementCounter();
2525
}
2626

27-
// CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i8)
28-
// CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1), i8)
27+
export float TestLoad() {
28+
return ROSB1.Load(10);
29+
}
30+
31+
// CHECK: define noundef float @_Z8TestLoadv()
32+
// CHECK: %[[PTR1:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1) %{{[0-9]+}}, i32 %{{[0-9]+}})
33+
// CHECK: %[[VALUE1:.*]] = load float, ptr %[[PTR1]]
34+
35+
// CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i8) #3
36+
// CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1), i8) #3
37+
// CHECK: declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1), i32) #4

0 commit comments

Comments
 (0)