Skip to content

Commit 16603d8

Browse files
authored
[HLSL] Add SPIR-V target type for RWStructuredBuffers (llvm#133468)
This PR adds the target type for main storage for HLSL raw buffer types. It does not handle the counter variables that are associated with those buffers. This is implementing part of https://github.com/llvm/wg-hlsl/blob/main/proposals/0018-spirv-resource-representation.md. We do not handle other HLSL raw buffer types.
1 parent bb179c4 commit 16603d8

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

clang/lib/CodeGen/Targets/SPIR.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -386,14 +386,21 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType(
386386
if (ContainedTy.isNull())
387387
return nullptr;
388388

389-
assert(!ResAttrs.RawBuffer &&
390-
"Raw buffers handles are not implemented for SPIR-V yet");
391389
assert(!ResAttrs.IsROV &&
392390
"Rasterizer order views not implemented for SPIR-V yet");
393391

394-
// convert element type
395392
llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy);
396-
return getSPIRVImageTypeFromHLSLResource(ResAttrs, ElemType, Ctx);
393+
if (!ResAttrs.RawBuffer) {
394+
// convert element type
395+
return getSPIRVImageTypeFromHLSLResource(ResAttrs, ElemType, Ctx);
396+
}
397+
398+
llvm::ArrayType *RuntimeArrayType = llvm::ArrayType::get(ElemType, 0);
399+
uint32_t StorageClass = /* StorageBuffer storage class */ 12;
400+
bool IsWritable = ResAttrs.ResourceClass == llvm::dxil::ResourceClass::UAV;
401+
return llvm::TargetExtType::get(Ctx, "spirv.VulkanBuffer",
402+
{RuntimeArrayType},
403+
{StorageClass, IsWritable});
397404
}
398405
case llvm::dxil::ResourceClass::CBuffer:
399406
llvm_unreachable("CBuffer handles are not implemented for SPIR-V yet");
Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,70 @@
11
// 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
2+
// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -DSPIRV -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
33

4-
// NOTE: SPIRV codegen for resource types is not yet implemented
54

65
StructuredBuffer<float> Buf : register(t10);
76
RWStructuredBuffer<float> Buf2 : register(u5, space1);
7+
8+
#ifndef SPIRV
9+
// NOTE: SPIRV codegen for these resource types is not implemented yet.
810
AppendStructuredBuffer<float> Buf3 : register(u3);
911
ConsumeStructuredBuffer<float> Buf4 : register(u4);
1012
RasterizerOrderedStructuredBuffer<float> Buf5 : register(u1, space2);
13+
#endif
14+
15+
// CHECK-DXIL: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", float, 0, 0) }
16+
// CHECK-DXIL: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
17+
// CHECK-DXIL: %"class.hlsl::AppendStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
18+
// CHECK-DXIL: %"class.hlsl::ConsumeStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) }
19+
// CHECK-DXIL: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 1) }
20+
21+
// CHECK-SPIRV: %"class.hlsl::StructuredBuffer" = type { target("spirv.VulkanBuffer", [0 x float], 12, 0) }
22+
// CHECK-SPIRV: %"class.hlsl::RWStructuredBuffer" = type { target("spirv.VulkanBuffer", [0 x float], 12, 1) }
1123

12-
// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", float, 0, 0) }
13-
// 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) }
16-
// CHECK: %"class.hlsl::RasterizerOrderedStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 1) }
1724

18-
// CHECK: @_ZL3Buf = internal global %"class.hlsl::StructuredBuffer" poison, align 4
19-
// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison, align 4
20-
// CHECK: @_ZL4Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" poison, align 4
21-
// CHECK: @_ZL4Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" poison, align 4
22-
// CHECK: @_ZL4Buf5 = internal global %"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4
25+
// CHECK: @_ZL3Buf = internal global %"class.hlsl::StructuredBuffer" poison
26+
// CHECK: @_ZL4Buf2 = internal global %"class.hlsl::RWStructuredBuffer" poison
27+
// CHECK-DXIL: @_ZL4Buf3 = internal global %"class.hlsl::AppendStructuredBuffer" poison, align 4
28+
// CHECK-DXIL: @_ZL4Buf4 = internal global %"class.hlsl::ConsumeStructuredBuffer" poison, align 4
29+
// CHECK-DXIL: @_ZL4Buf5 = internal global %"class.hlsl::RasterizerOrderedStructuredBuffer" poison, align 4
2330

2431
// CHECK: define internal void @_init_resource__ZL3Buf()
2532
// 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)
2633
// CHECK-DXIL: store target("dx.RawBuffer", float, 0, 0) [[H]], ptr @_ZL3Buf, align 4
34+
// CHECK-SPIRV: [[H:%.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 0) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0f32_12_0t(i32 0, i32 10, i32 1, i32 0, i1 false)
35+
// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 0) [[H]], ptr @_ZL3Buf, align 8
2736

2837
// CHECK: define internal void @_init_resource__ZL4Buf2()
2938
// 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)
3039
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf2, align 4
40+
// CHECK-SPIRV: [[H:%.*]] = call target("spirv.VulkanBuffer", [0 x float], 12, 1) @llvm.spv.resource.handlefrombinding.tspirv.VulkanBuffer_a0f32_12_1t(i32 1, i32 5, i32 1, i32 0, i1 false)
41+
// CHECK-SPIRV: store target("spirv.VulkanBuffer", [0 x float], 12, 1) [[H]], ptr @_ZL4Buf2, align 8
3142

32-
// CHECK: define internal void @_init_resource__ZL4Buf3()
43+
// CHECK-DXIL: define internal void @_init_resource__ZL4Buf3()
3344
// 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)
3445
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf3, align 4
3546

36-
// CHECK: define internal void @_init_resource__ZL4Buf4()
47+
// CHECK-DXIL: define internal void @_init_resource__ZL4Buf4()
3748
// 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)
3849
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) [[H]], ptr @_ZL4Buf4, align 4
3950

40-
// CHECK: define internal void @_init_resource__ZL4Buf5()
51+
// CHECK-DXIL: define internal void @_init_resource__ZL4Buf5()
4152
// 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)
4253
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 1) [[H]], ptr @_ZL4Buf5, align 4
4354

44-
// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
45-
// CHECK-NEXT: entry:
46-
// CHECK: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
47-
// CHECK-NEXT: entry:
48-
// CHECK: define linkonce_odr void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
49-
// CHECK-NEXT: entry:
50-
// CHECK: define linkonce_odr void @_ZN4hlsl23ConsumeStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
51-
// CHECK: define linkonce_odr void @_ZN4hlsl33RasterizerOrderedStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
55+
// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2Ev(ptr noundef nonnull align {{[48]}} dereferenceable({{[48]}}) %this)
5256
// CHECK-NEXT: entry:
57+
// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
58+
// CHECK-DXIL-NEXT: entry:
59+
// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl22AppendStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
60+
// CHECK-DXIL-NEXT: entry:
61+
// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl23ConsumeStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
62+
// CHECK-DXIL: define linkonce_odr void @_ZN4hlsl33RasterizerOrderedStructuredBufferIfEC2Ev(ptr noundef nonnull align 4 dereferenceable(4) %this)
63+
// CHECK-DXIL-NEXT: entry:
5364

54-
// CHECK: define internal void @_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl()
55-
// CHECK: call void @_init_resource__ZL3Buf()
56-
// CHECK: call void @_init_resource__ZL4Buf2()
57-
// CHECK: call void @_init_resource__ZL4Buf3()
58-
// CHECK: call void @_init_resource__ZL4Buf4()
59-
// CHECK: call void @_init_resource__ZL4Buf5()
65+
// CHECK: define {{.*}} void @_GLOBAL__sub_I_StructuredBuffers_constructors.hlsl()
66+
// CHECK: call {{.*}} @_init_resource__ZL3Buf()
67+
// CHECK: call {{.*}} @_init_resource__ZL4Buf2()
68+
// CHECK-DXIL: call void @_init_resource__ZL4Buf3()
69+
// CHECK-DXIL: call void @_init_resource__ZL4Buf4()
70+
// CHECK-DXIL: call void @_init_resource__ZL4Buf5()

0 commit comments

Comments
 (0)