[clang] 1df2855 - [HLSL] Add ByteAddressBuffer, RWByteAddressBuffer and RasterizerOrderedByteAddressBuffer definitions to HLSLExternalSemaSource #113477 (#116699)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 6 12:19:43 PST 2024
Author: joaosaffran
Date: 2024-12-06T12:19:39-08:00
New Revision: 1df28554bd6264d44aa2ce12e5a2fc29f61bb027
URL: https://github.com/llvm/llvm-project/commit/1df28554bd6264d44aa2ce12e5a2fc29f61bb027
DIFF: https://github.com/llvm/llvm-project/commit/1df28554bd6264d44aa2ce12e5a2fc29f61bb027.diff
LOG: [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 <jderezende at microsoft.com>
Added:
clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl
Modified:
clang/lib/Sema/HLSLExternalSemaSource.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index f849e841de190a..8e57123c503cba 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -35,14 +35,17 @@ namespace {
struct TemplateParameterListBuilder;
-struct BuiltinTypeDeclBuilder {
- Sema &SemaRef;
- CXXRecordDecl *Record = nullptr;
+class BuiltinTypeDeclBuilder {
ClassTemplateDecl *Template = nullptr;
ClassTemplateDecl *PrevTemplate = nullptr;
NamespaceDecl *HLSLNamespace = nullptr;
llvm::StringMap<FieldDecl *> Fields;
+public:
+ Sema &SemaRef;
+ CXXRecordDecl *Record = nullptr;
+ friend struct TemplateParameterListBuilder;
+
BuiltinTypeDeclBuilder(Sema &SemaRef, CXXRecordDecl *R)
: SemaRef(SemaRef), Record(R) {
Record->startDefinition();
@@ -51,7 +54,7 @@ struct BuiltinTypeDeclBuilder {
BuiltinTypeDeclBuilder(Sema &SemaRef, NamespaceDecl *Namespace,
StringRef Name)
- : SemaRef(SemaRef), HLSLNamespace(Namespace) {
+ : HLSLNamespace(Namespace), SemaRef(SemaRef) {
ASTContext &AST = SemaRef.getASTContext();
IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
@@ -91,6 +94,18 @@ struct BuiltinTypeDeclBuilder {
HLSLNamespace->addDecl(Record);
}
+ CXXRecordDecl *finalizeForwardDeclaration() {
+ // Force the QualType to be generated for the record declaration. In most
+ // cases this will happen naturally when something uses the type the
+ // QualType gets lazily created. Unfortunately, with our injected types if a
+ // type isn't used in a translation unit the QualType may not get
+ // automatically generated before a PCH is generated. To resolve this we
+ // just force that the QualType is generated after we create a forward
+ // declaration.
+ (void)Record->getASTContext().getRecordType(Record);
+ return Record;
+ }
+
BuiltinTypeDeclBuilder &
addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef<Attr *> Attrs,
AccessSpecifier Access = AccessSpecifier::AS_private) {
@@ -849,7 +864,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
constructTypedBufferConceptDecl(*SemaPtr, HLSLNamespace);
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer")
.addSimpleTemplateParams({"element_type"}, TypedBufferConcept)
- .Record;
+ .finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
@@ -862,7 +877,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Decl =
BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer")
.addSimpleTemplateParams({"element_type"})
- .Record;
+ .finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
ResourceKind::TypedBuffer, /*IsROV=*/true,
@@ -873,7 +888,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "StructuredBuffer")
.addSimpleTemplateParams({"element_type"})
- .Record;
+ .finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -883,7 +898,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWStructuredBuffer")
.addSimpleTemplateParams({"element_type"})
- .Record;
+ .finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -896,7 +911,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Decl =
BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "AppendStructuredBuffer")
.addSimpleTemplateParams({"element_type"})
- .Record;
+ .finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -906,7 +921,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Decl =
BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ConsumeStructuredBuffer")
.addSimpleTemplateParams({"element_type"})
- .Record;
+ .finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/false, /*RawBuffer=*/true)
@@ -916,7 +931,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
"RasterizerOrderedStructuredBuffer")
.addSimpleTemplateParams({"element_type"})
- .Record;
+ .finalizeForwardDeclaration();
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
/*IsROV=*/true, /*RawBuffer=*/true)
@@ -925,6 +940,32 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
.addDecrementCounterMethod()
.completeDefinition();
});
+
+ Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ByteAddressBuffer")
+ .finalizeForwardDeclaration();
+ onCompletion(Decl, [this](CXXRecordDecl *Decl) {
+ setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
+ /*IsROV=*/false,
+ /*RawBuffer=*/true)
+ .completeDefinition();
+ });
+ Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
+ .finalizeForwardDeclaration();
+ onCompletion(Decl, [this](CXXRecordDecl *Decl) {
+ setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
+ /*IsROV=*/false,
+ /*RawBuffer=*/true)
+ .completeDefinition();
+ });
+ Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
+ "RasterizerOrderedByteAddressBuffer")
+ .finalizeForwardDeclaration();
+ onCompletion(Decl, [this](CXXRecordDecl *Decl) {
+ setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
+ /*IsROV=*/true,
+ /*RawBuffer=*/true)
+ .completeDefinition();
+ });
}
void HLSLExternalSemaSource::onCompletion(CXXRecordDecl *Record,
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
new file mode 100644
index 00000000000000..909cce17e344c1
--- /dev/null
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
+// RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \
+// RUN: -check-prefix=EMPTY %s
+//
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
+// RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \
+// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-NOSUBSCRIPT %s
+//
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
+// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \
+// RUN: -check-prefix=EMPTY %s
+//
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
+// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \
+// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s
+//
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
+// RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \
+// RUN: -check-prefix=EMPTY %s
+//
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
+// RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \
+// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s
+
+// EMPTY: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class [[RESOURCE]]
+// EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
+
+// There should be no more occurrences of RESOURCE
+// EMPTY-NOT: {{[^[:alnum:]]}}[[RESOURCE]]
+
+#ifndef EMPTY
+
+RESOURCE Buffer;
+
+#endif
+
+// CHECK: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced <undeserialized declarations> class [[RESOURCE]] definition
+
+
+// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
+// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit __handle '__hlsl_resource_t
+// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
+// CHECK-SAME{LITERAL}: [[hlsl::contained_type(char8_t)]]
+// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit RawBuffer
+
+// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'const element_type &(unsigned int) const'
+// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &(unsigned int)'
diff --git a/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl
new file mode 100644
index 00000000000000..45e135427ba9c3
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl
@@ -0,0 +1,29 @@
+// 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
+// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
+
+// NOTE: SPIRV codegen for resource types is not yet implemented
+
+ByteAddressBuffer Buffer0: register(t0);
+RWByteAddressBuffer Buffer1: register(u1, space2);
+RasterizerOrderedByteAddressBuffer Buffer2: register(u3, space4);
+
+// CHECK: "class.hlsl::ByteAddressBuffer" = type { target("dx.RawBuffer", i8, 0, 0) }
+// CHECK: "class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) }
+// CHECK: "class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) }
+
+// CHECK: @Buffer0 = global %"class.hlsl::ByteAddressBuffer" zeroinitializer, align 4
+// CHECK: @Buffer1 = global %"class.hlsl::RWByteAddressBuffer" zeroinitializer, align 4
+// CHECK: @Buffer2 = global %"class.hlsl::RasterizerOrderedByteAddressBuffer" zeroinitializer, align 4
+
+// CHECK: define internal void @_GLOBAL__sub_I_ByteAddressBuffers_constructors.hlsl()
+// CHECK: entry:
+// CHECK: call void @_init_resource_bindings()
+
+// CHECK: define internal void @_init_resource_bindings() {
+// CHECK-NEXT: entry:
+// 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)
+// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %Buffer0_h, ptr @Buffer0, align 4
+// 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)
+// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 0) %Buffer1_h, ptr @Buffer1, align 4
+// 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)
+// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 1) %Buffer2_h, ptr @Buffer2, align 4
More information about the cfe-commits
mailing list