[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@microsoft.com>
This commit is contained in:
@@ -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,
|
||||
|
||||
49
clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
Normal file
49
clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
Normal file
@@ -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)'
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user