https://github.com/s-perron created https://github.com/llvm/llvm-project/pull/132027
This PR adds the target type that should be used for RWStructuredBuffers. It does not handle ByteAddressBuffers yet. For now all structs will be laid out using the standard C/C++ layout rules. Other layout rules will be implemented later. >From bca59dea277747dc165eb242b740468712a839b3 Mon Sep 17 00:00:00 2001 From: Steven Perron <stevenper...@google.com> Date: Fri, 24 Jan 2025 13:04:29 -0500 Subject: [PATCH] [HLSL] Add SPIR-V target type for RWStructuredBuffers This PR adds the target type that should be used for RWStructuredBuffers. It does not handle ByteAddressBuffers yet. For now all structs will be laid out using the standard C/C++ layout rules. Other layout rules will be implemented later. --- clang/lib/CodeGen/Targets/SPIR.cpp | 23 ++++++- .../StructuredBuffers-constructors.hlsl | 68 +++++++++++-------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 43f511e572d37..5f5c10e291d89 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -386,13 +386,30 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType( if (ContainedTy.isNull()) return nullptr; - assert(!ResAttrs.RawBuffer && - "Raw buffers handles are not implemented for SPIR-V yet"); assert(!ResAttrs.IsROV && "Rasterizer order views not implemented for SPIR-V yet"); - // convert element type llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy); + if (ResAttrs.RawBuffer) { + // TODO: Handle types with layout information. + assert((ElemType->isIntegerTy() || ElemType->isFloatingPointTy() || + ElemType->isVectorTy()) && + "The element type for a SPIR-V resource must be a types that does " + "not require layout information."); + llvm::ArrayType *RuntimeArrayType = llvm::ArrayType::get(ElemType, 0); + + uint32_t StorageClass = /* StorageBuffer storage class */ 12; + bool IsWritable = + ResAttrs.ResourceClass == llvm::dxil::ResourceClass::UAV; + assert(!IsWritable && "Writable buffers require a corresponding counter " + "variable. Not implemented yet."); + bool IsRov = ResAttrs.IsROV; + return llvm::TargetExtType::get(Ctx, "spirv.VulkanBuffer", + {RuntimeArrayType}, + {StorageClass, IsWritable, IsRov}); + } + + // convert element type return getSPIRVImageTypeFromHLSLResource(ResAttrs, ElemType, Ctx); } case llvm::dxil::ResourceClass::CBuffer: diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl index 04534c5550252..74abf6b1340de 100644 --- a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl +++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl @@ -1,59 +1,67 @@ // 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 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -DSPIRV -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -// NOTE: SPIRV codegen for resource types is not yet implemented StructuredBuffer<float> Buf : register(t10); + +#ifndef SPIRV +// NOTE: SPIRV codegen for resource types with counter variable is not yet implemented RWStructuredBuffer<float> Buf2 : register(u5, space1); AppendStructuredBuffer<float> Buf3 : register(u3); ConsumeStructuredBuffer<float> Buf4 : register(u4); RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2); +#endif + +// CHECK-DXIL: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", float, 0, 0) } +// CHECK-DXIL: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } +// CHECK-DXIL: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } +// CHECK-DXIL: %"class.hlsl::ConsumeStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } +// CHECK-DXIL: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 1) } + +// CHECK-SPIRV: %"class.hlsl::StructuredBuffer" = type { target("spirv.VulkanBuffer", [0 x float], 12, 0, 0) } -// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", float, 0, 0) } -// CHECK: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } -// CHECK: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } -// CHECK: %"class.hlsl::ConsumeStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } -// CHECK: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 1) } -// CHECK: @_ZL3Buf = internal global %"class.hlsl::StructuredBuffer" poison, align 4 -// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4 -// CHECK: @_ZL4Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" poison, align 4 -// CHECK: @_ZL4Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" poison, align 4 -// CHECK: @_ZL4Buf5 = internal global %"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4 +// CHECK: @_ZL3Buf = internal global %"class.hlsl::StructuredBuffer" poison +// CHECK-DXIL: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4 +// CHECK-DXIL: @_ZL4Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" poison, align 4 +// CHECK-DXIL: @_ZL4Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" poison, align 4 +// CHECK-DXIL: @_ZL4Buf5 = internal global %"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4 // CHECK: define internal void @_init_resource__ZL3Buf() // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(i32 0, i32 10, i32 1, i32 0, i1 false) // CHECK-DXIL: store target("dx.RawBuffer", float, 0, 0) [[H]], ptr @_ZL3Buf, align 4 +// CHECK-SPIRV: [[H:%.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 0, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0f32_12_0_0t(i32 0, i32 10, i32 1, i32 0, i1 false) +// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 0, 0) [[H]], ptr @_ZL3Buf, align 8 -// CHECK: define internal void @_init_resource__ZL4Buf2() +// CHECK-DXIL: define internal void @_init_resource__ZL4Buf2() // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 1, i32 5, i32 1, i32 0, i1 false) // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf2, align 4 -// CHECK: define internal void @_init_resource__ZL4Buf3() +// CHECK-DXIL: define internal void @_init_resource__ZL4Buf3() // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false) // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf3, align 4 -// CHECK: define internal void @_init_resource__ZL4Buf4() +// CHECK-DXIL: define internal void @_init_resource__ZL4Buf4() // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 4, i32 1, i32 0, i1 false) // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf4, align 4 -// CHECK: define internal void @_init_resource__ZL4Buf5() +// CHECK-DXIL: define internal void @_init_resource__ZL4Buf5() // CHECK-DXIL: [[H:%.*]] = call target("dx.RawBuffer", float, 1, 1) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_1t(i32 2, i32 1, i32 1, i32 0, i1 false) // CHECK-DXIL: store target("dx.RawBuffer", float, 1, 1) [[H]], ptr @_ZL4Buf5, align 4 -// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) -// CHECK-NEXT: entry: -// CHECK: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) -// CHECK-NEXT: entry: -// CHECK: define linkonce_odr void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) -// CHECK-NEXT: entry: -// CHECK: define linkonce_odr void @_ZN4hlsl23ConsumeStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) -// CHECK: define linkonce_odr void @_ZN4hlsl33RasterizerOrderedStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2Ev(ptr noundef nonnull align {{[48]}} dereferenceable({{[48]}}) %this) // CHECK-NEXT: entry: +// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK-DXIL-NEXT: entry: +// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK-DXIL-NEXT: entry: +// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl23ConsumeStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl33RasterizerOrderedStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this) +// CHECK-DXIL-NEXT: entry: -// CHECK: define internal void @_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl() -// CHECK: call void @_init_resource__ZL3Buf() -// CHECK: call void @_init_resource__ZL4Buf2() -// CHECK: call void @_init_resource__ZL4Buf3() -// CHECK: call void @_init_resource__ZL4Buf4() -// CHECK: call void @_init_resource__ZL4Buf5() +// CHECK: define {{.*}} void @_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl() +// CHECK: call {{.*}} @_init_resource__ZL3Buf() +// CHECK-DXIL: call void @_init_resource__ZL4Buf2() +// CHECK-DXIL: call void @_init_resource__ZL4Buf3() +// CHECK-DXIL: call void @_init_resource__ZL4Buf4() +// CHECK-DXIL: call void @_init_resource__ZL4Buf5() _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits