Skip to content

Commit 1645c20

Browse files
committed
asm fn_ptr: compiletest with compute shader copying a buffer
1 parent 4256235 commit 1645c20

File tree

4 files changed

+199
-0
lines changed

4 files changed

+199
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// build-pass
2+
// compile-flags: -C llvm-args=--disassemble
3+
// normalize-stderr-test "OpSource .*\n" -> ""
4+
// normalize-stderr-test "OpLine .*\n" -> ""
5+
// normalize-stderr-test "%\d+ = OpString .*\n" -> ""
6+
// normalize-stderr-test "; .*\n" -> ""
7+
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
8+
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
9+
// ignore-spv1.0
10+
// ignore-spv1.1
11+
// ignore-spv1.2
12+
// ignore-spv1.3
13+
// ignore-vulkan1.0
14+
// ignore-vulkan1.1
15+
16+
use core::arch::asm;
17+
use spirv_std::TypedBuffer;
18+
use spirv_std::arch::IndexUnchecked;
19+
use spirv_std::glam::*;
20+
use spirv_std::spirv;
21+
22+
pub fn main(input: &TypedBuffer<[u32]>, output: &mut TypedBuffer<[u32]>, gid: UVec3) {
23+
unsafe {
24+
let gid = gid.x;
25+
*output.index_unchecked_mut(gid as usize) = *input.index_unchecked(gid as usize);
26+
}
27+
}
28+
29+
pub fn entry() {
30+
unsafe {
31+
let mut input_slot = core::mem::MaybeUninit::<&TypedBuffer<[u32]>>::uninit();
32+
asm!(
33+
"%var = OpVariable typeof*{result_slot} StorageBuffer",
34+
"OpDecorate %var DescriptorSet {descriptor_set}",
35+
"OpDecorate %var Binding {binding}",
36+
"OpDecorate %var NonWritable",
37+
"OpName %var \"input\"",
38+
"OpStore {result_slot} %var",
39+
descriptor_set = const 0,
40+
binding = const 0,
41+
result_slot = in(reg) input_slot.as_mut_ptr(),
42+
);
43+
let input = input_slot.assume_init();
44+
45+
let mut output_slot = core::mem::MaybeUninit::<&mut TypedBuffer<[u32]>>::uninit();
46+
asm!(
47+
"%var = OpVariable typeof*{result_slot} StorageBuffer",
48+
"OpDecorate %var DescriptorSet {descriptor_set}",
49+
"OpDecorate %var Binding {binding}",
50+
"OpName %var \"output\"",
51+
"OpStore {result_slot} %var",
52+
descriptor_set = const 0,
53+
binding = const 1,
54+
result_slot = in(reg) output_slot.as_mut_ptr(),
55+
);
56+
let output = output_slot.assume_init();
57+
58+
let gid = UVec3::default();
59+
asm! {
60+
"%builtin = OpVariable typeof{result} Input",
61+
"OpDecorate %builtin BuiltIn GlobalInvocationId",
62+
"OpName %builtin \"gid\"",
63+
"%result = OpLoad typeof*{result} %builtin",
64+
"OpStore {result} %result",
65+
result = in(reg) &gid,
66+
}
67+
68+
main(input, output, gid);
69+
}
70+
}
71+
72+
/// we don't support `global_asm!` yet
73+
pub fn non_global_asm() {
74+
unsafe {
75+
asm! {
76+
"OpEntryPoint GLCompute {entry} \"main\"",
77+
"OpExecutionMode {entry} LocalSize 32 1 1",
78+
entry = in(reg) entry,
79+
}
80+
}
81+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
OpCapability Shader
2+
OpMemoryModel Logical Simple
3+
OpEntryPoint GLCompute %1 "main" %2 %3 %4
4+
OpExecutionMode %1 LocalSize 32 1 1
5+
OpName %2 "gid"
6+
OpName %3 "input"
7+
OpName %4 "output"
8+
OpName %1 "entry3_global_asm::entry"
9+
OpDecorate %2 BuiltIn GlobalInvocationId
10+
OpDecorate %8 ArrayStride 4
11+
OpDecorate %9 Block
12+
OpMemberDecorate %9 0 Offset 0
13+
OpDecorate %3 NonWritable
14+
OpDecorate %3 Binding 0
15+
OpDecorate %3 DescriptorSet 0
16+
OpDecorate %4 Binding 1
17+
OpDecorate %4 DescriptorSet 0
18+
%10 = OpTypeVoid
19+
%11 = OpTypeFunction %10
20+
%12 = OpTypeInt 32 0
21+
%13 = OpTypeVector %12 3
22+
%14 = OpTypePointer Input %13
23+
%2 = OpVariable %14 Input
24+
%8 = OpTypeRuntimeArray %12
25+
%15 = OpTypePointer StorageBuffer %8
26+
%9 = OpTypeStruct %8
27+
%16 = OpTypePointer StorageBuffer %9
28+
%3 = OpVariable %16 StorageBuffer
29+
%17 = OpConstant %12 0
30+
%18 = OpTypePointer StorageBuffer %12
31+
%4 = OpVariable %16 StorageBuffer
32+
%1 = OpFunction %10 None %11
33+
%19 = OpLabel
34+
%20 = OpLoad %13 %2
35+
%21 = OpCompositeExtract %12 %20 0
36+
%22 = OpAccessChain %15 %3 %17
37+
%23 = OpAccessChain %18 %22 %21
38+
%24 = OpLoad %12 %23
39+
%25 = OpAccessChain %15 %4 %17
40+
%26 = OpAccessChain %18 %25 %21
41+
OpStore %26 %24
42+
OpNoLine
43+
OpReturn
44+
OpFunctionEnd
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// build-pass
2+
// compile-flags: -C llvm-args=--disassemble
3+
// normalize-stderr-test "OpSource .*\n" -> ""
4+
// normalize-stderr-test "OpLine .*\n" -> ""
5+
// normalize-stderr-test "%\d+ = OpString .*\n" -> ""
6+
// normalize-stderr-test "; .*\n" -> ""
7+
// normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> ""
8+
// normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple"
9+
// ignore-spv1.0
10+
// ignore-spv1.1
11+
// ignore-spv1.2
12+
// ignore-spv1.3
13+
// ignore-vulkan1.0
14+
// ignore-vulkan1.1
15+
16+
use spirv_std::TypedBuffer;
17+
use spirv_std::arch::IndexUnchecked;
18+
use spirv_std::glam::*;
19+
use spirv_std::spirv;
20+
21+
#[spirv(compute(threads(32)))]
22+
pub fn main(
23+
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] input: &TypedBuffer<[u32]>,
24+
#[spirv(descriptor_set = 0, binding = 1, storage_buffer)] output: &mut TypedBuffer<[u32]>,
25+
#[spirv(global_invocation_id)] gid: UVec3,
26+
) {
27+
unsafe {
28+
let gid = gid.x;
29+
*output.index_unchecked_mut(gid as usize) = *input.index_unchecked(gid as usize);
30+
}
31+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
OpCapability Shader
2+
OpMemoryModel Logical Simple
3+
OpEntryPoint GLCompute %1 "main" %2 %3 %4
4+
OpExecutionMode %1 LocalSize 32 1 1
5+
OpName %2 "gid"
6+
OpName %3 "input"
7+
OpName %4 "output"
8+
OpDecorate %8 ArrayStride 4
9+
OpDecorate %9 Block
10+
OpMemberDecorate %9 0 Offset 0
11+
OpDecorate %2 BuiltIn GlobalInvocationId
12+
OpDecorate %3 NonWritable
13+
OpDecorate %3 Binding 0
14+
OpDecorate %3 DescriptorSet 0
15+
OpDecorate %4 Binding 1
16+
OpDecorate %4 DescriptorSet 0
17+
%10 = OpTypeInt 32 0
18+
%8 = OpTypeRuntimeArray %10
19+
%9 = OpTypeStruct %8
20+
%11 = OpTypePointer StorageBuffer %9
21+
%12 = OpTypeVector %10 3
22+
%13 = OpTypePointer Input %12
23+
%14 = OpTypeVoid
24+
%15 = OpTypeFunction %14
25+
%2 = OpVariable %13 Input
26+
%16 = OpTypePointer StorageBuffer %8
27+
%3 = OpVariable %11 StorageBuffer
28+
%17 = OpConstant %10 0
29+
%18 = OpTypePointer StorageBuffer %10
30+
%4 = OpVariable %11 StorageBuffer
31+
%1 = OpFunction %14 None %15
32+
%19 = OpLabel
33+
%20 = OpLoad %12 %2
34+
%21 = OpCompositeExtract %10 %20 0
35+
%22 = OpAccessChain %16 %3 %17
36+
%23 = OpAccessChain %18 %22 %21
37+
%24 = OpLoad %10 %23
38+
%25 = OpAccessChain %16 %4 %17
39+
%26 = OpAccessChain %18 %25 %21
40+
OpStore %26 %24
41+
OpNoLine
42+
OpReturn
43+
OpFunctionEnd

0 commit comments

Comments
 (0)