Skip to content

Commit 1df2855

Browse files
[HLSL] Add ByteAddressBuffer, RWByteAddressBuffer and RasterizerOrderedByteAddressBuffer definitions to HLSLExternalSemaSource #113477 (#116699)
This is the first one in a series of PRs adding the requirements for #58654 This PR adds `ByteAddressBuffer`, `RWByteAddressBuffer ` and `RasterizerOrderedByteAddressBuffer ` definitions as well as their handle lowering to `dx.RawBuffer`. closes #58654 --------- Co-authored-by: Joao Saffran <[email protected]>
1 parent c5e4e8f commit 1df2855

File tree

3 files changed

+130
-11
lines changed

3 files changed

+130
-11
lines changed

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ namespace {
3535

3636
struct TemplateParameterListBuilder;
3737

38-
struct BuiltinTypeDeclBuilder {
39-
Sema &SemaRef;
40-
CXXRecordDecl *Record = nullptr;
38+
class BuiltinTypeDeclBuilder {
4139
ClassTemplateDecl *Template = nullptr;
4240
ClassTemplateDecl *PrevTemplate = nullptr;
4341
NamespaceDecl *HLSLNamespace = nullptr;
4442
llvm::StringMap<FieldDecl *> Fields;
4543

44+
public:
45+
Sema &SemaRef;
46+
CXXRecordDecl *Record = nullptr;
47+
friend struct TemplateParameterListBuilder;
48+
4649
BuiltinTypeDeclBuilder(Sema &SemaRef, CXXRecordDecl *R)
4750
: SemaRef(SemaRef), Record(R) {
4851
Record->startDefinition();
@@ -51,7 +54,7 @@ struct BuiltinTypeDeclBuilder {
5154

5255
BuiltinTypeDeclBuilder(Sema &SemaRef, NamespaceDecl *Namespace,
5356
StringRef Name)
54-
: SemaRef(SemaRef), HLSLNamespace(Namespace) {
57+
: HLSLNamespace(Namespace), SemaRef(SemaRef) {
5558
ASTContext &AST = SemaRef.getASTContext();
5659
IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
5760

@@ -91,6 +94,18 @@ struct BuiltinTypeDeclBuilder {
9194
HLSLNamespace->addDecl(Record);
9295
}
9396

97+
CXXRecordDecl *finalizeForwardDeclaration() {
98+
// Force the QualType to be generated for the record declaration. In most
99+
// cases this will happen naturally when something uses the type the
100+
// QualType gets lazily created. Unfortunately, with our injected types if a
101+
// type isn't used in a translation unit the QualType may not get
102+
// automatically generated before a PCH is generated. To resolve this we
103+
// just force that the QualType is generated after we create a forward
104+
// declaration.
105+
(void)Record->getASTContext().getRecordType(Record);
106+
return Record;
107+
}
108+
94109
BuiltinTypeDeclBuilder &
95110
addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef<Attr *> Attrs,
96111
AccessSpecifier Access = AccessSpecifier::AS_private) {
@@ -849,7 +864,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
849864
constructTypedBufferConceptDecl(*SemaPtr, HLSLNamespace);
850865
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer")
851866
.addSimpleTemplateParams({"element_type"}, TypedBufferConcept)
852-
.Record;
867+
.finalizeForwardDeclaration();
853868

854869
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
855870
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
@@ -862,7 +877,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
862877
Decl =
863878
BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer")
864879
.addSimpleTemplateParams({"element_type"})
865-
.Record;
880+
.finalizeForwardDeclaration();
866881
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
867882
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
868883
ResourceKind::TypedBuffer, /*IsROV=*/true,
@@ -873,7 +888,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
873888

874889
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "StructuredBuffer")
875890
.addSimpleTemplateParams({"element_type"})
876-
.Record;
891+
.finalizeForwardDeclaration();
877892
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
878893
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
879894
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -883,7 +898,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
883898

884899
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWStructuredBuffer")
885900
.addSimpleTemplateParams({"element_type"})
886-
.Record;
901+
.finalizeForwardDeclaration();
887902
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
888903
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
889904
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -896,7 +911,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
896911
Decl =
897912
BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "AppendStructuredBuffer")
898913
.addSimpleTemplateParams({"element_type"})
899-
.Record;
914+
.finalizeForwardDeclaration();
900915
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
901916
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
902917
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -906,7 +921,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
906921
Decl =
907922
BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ConsumeStructuredBuffer")
908923
.addSimpleTemplateParams({"element_type"})
909-
.Record;
924+
.finalizeForwardDeclaration();
910925
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
911926
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
912927
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -916,7 +931,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
916931
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
917932
"RasterizerOrderedStructuredBuffer")
918933
.addSimpleTemplateParams({"element_type"})
919-
.Record;
934+
.finalizeForwardDeclaration();
920935
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
921936
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
922937
/*IsROV=*/true, /*RawBuffer=*/true)
@@ -925,6 +940,32 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
925940
.addDecrementCounterMethod()
926941
.completeDefinition();
927942
});
943+
944+
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ByteAddressBuffer")
945+
.finalizeForwardDeclaration();
946+
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
947+
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
948+
/*IsROV=*/false,
949+
/*RawBuffer=*/true)
950+
.completeDefinition();
951+
});
952+
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
953+
.finalizeForwardDeclaration();
954+
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
955+
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
956+
/*IsROV=*/false,
957+
/*RawBuffer=*/true)
958+
.completeDefinition();
959+
});
960+
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
961+
"RasterizerOrderedByteAddressBuffer")
962+
.finalizeForwardDeclaration();
963+
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
964+
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
965+
/*IsROV=*/true,
966+
/*RawBuffer=*/true)
967+
.completeDefinition();
968+
});
928969
}
929970

930971
void HLSLExternalSemaSource::onCompletion(CXXRecordDecl *Record,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
2+
// RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \
3+
// RUN: -check-prefix=EMPTY %s
4+
//
5+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
6+
// RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \
7+
// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-NOSUBSCRIPT %s
8+
//
9+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
10+
// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \
11+
// RUN: -check-prefix=EMPTY %s
12+
//
13+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
14+
// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \
15+
// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s
16+
//
17+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
18+
// RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \
19+
// RUN: -check-prefix=EMPTY %s
20+
//
21+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
22+
// RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \
23+
// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s
24+
25+
// EMPTY: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class [[RESOURCE]]
26+
// EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
27+
28+
// There should be no more occurrences of RESOURCE
29+
// EMPTY-NOT: {{[^[:alnum:]]}}[[RESOURCE]]
30+
31+
#ifndef EMPTY
32+
33+
RESOURCE Buffer;
34+
35+
#endif
36+
37+
// CHECK: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced <undeserialized declarations> class [[RESOURCE]] definition
38+
39+
40+
// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
41+
// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit __handle '__hlsl_resource_t
42+
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
43+
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
44+
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
45+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(char8_t)]]
46+
// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit RawBuffer
47+
48+
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'const element_type &(unsigned int) const'
49+
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &(unsigned int)'
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
2+
// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
3+
4+
// NOTE: SPIRV codegen for resource types is not yet implemented
5+
6+
ByteAddressBuffer Buffer0: register(t0);
7+
RWByteAddressBuffer Buffer1: register(u1, space2);
8+
RasterizerOrderedByteAddressBuffer Buffer2: register(u3, space4);
9+
10+
// CHECK: "class.hlsl::ByteAddressBuffer" = type { target("dx.RawBuffer", i8, 0, 0) }
11+
// CHECK: "class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
12+
// CHECK: "class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) }
13+
14+
// CHECK: @Buffer0 = global %"class.hlsl::ByteAddressBuffer" zeroinitializer, align 4
15+
// CHECK: @Buffer1 = global %"class.hlsl::RWByteAddressBuffer" zeroinitializer, align 4
16+
// CHECK: @Buffer2 = global %"class.hlsl::RasterizerOrderedByteAddressBuffer" zeroinitializer, align 4
17+
18+
// CHECK: define internal void @_GLOBAL__sub_I_ByteAddressBuffers_constructors.hlsl()
19+
// CHECK: entry:
20+
// CHECK: call void @_init_resource_bindings()
21+
22+
// CHECK: define internal void @_init_resource_bindings() {
23+
// CHECK-NEXT: entry:
24+
// CHECK-DXIL-NEXT: %Buffer0_h = call target("dx.RawBuffer", i8, 0, 0) @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false)
25+
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %Buffer0_h, ptr @Buffer0, align 4
26+
// CHECK-DXIL-NEXT: %Buffer1_h = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_1_0t(i32 2, i32 1, i32 1, i32 0, i1 false)
27+
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 0) %Buffer1_h, ptr @Buffer1, align 4
28+
// CHECK-DXIL-NEXT: %Buffer2_h = call target("dx.RawBuffer", i8, 1, 1) @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_1_1t(i32 4, i32 3, i32 1, i32 0, i1 false)
29+
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 1) %Buffer2_h, ptr @Buffer2, align 4

0 commit comments

Comments
 (0)