Skip to content

Commit 00f5d28

Browse files
committed
asm fn_ptr: compiletest entry3 with generic fns
1 parent 1645c20 commit 00f5d28

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
#[inline]
23+
pub fn main(input: &TypedBuffer<[u32]>, output: &mut TypedBuffer<[u32]>, gid: UVec3) {
24+
unsafe {
25+
let gid = gid.x;
26+
*output.index_unchecked_mut(gid as usize) = *input.index_unchecked(gid as usize);
27+
}
28+
}
29+
30+
pub fn entry() {
31+
let input = decl_buffer::<0, 0, [u32]>();
32+
let output = decl_buffer_mut::<0, 1, [u32]>();
33+
let gid = global_invocation_id();
34+
main(input, output, gid);
35+
}
36+
37+
#[inline]
38+
pub fn decl_buffer<const DESCRIPTOR_SET: u32, const BINDING: u32, T: ?Sized>()
39+
-> &'static TypedBuffer<T> {
40+
unsafe {
41+
let mut slot = core::mem::MaybeUninit::<&TypedBuffer<T>>::uninit();
42+
asm!(
43+
"%var = OpVariable typeof*{slot} StorageBuffer",
44+
"OpDecorate %var DescriptorSet {descriptor_set}",
45+
"OpDecorate %var Binding {binding}",
46+
"OpDecorate %var NonWritable",
47+
"OpStore {slot} %var",
48+
descriptor_set = const DESCRIPTOR_SET,
49+
binding = const BINDING,
50+
slot = in(reg) slot.as_mut_ptr(),
51+
);
52+
slot.assume_init()
53+
}
54+
}
55+
56+
#[inline]
57+
pub fn decl_buffer_mut<const DESCRIPTOR_SET: u32, const BINDING: u32, T: ?Sized>()
58+
-> &'static mut TypedBuffer<T> {
59+
unsafe {
60+
let mut slot = core::mem::MaybeUninit::<&mut TypedBuffer<T>>::uninit();
61+
asm!(
62+
"%var = OpVariable typeof*{slot} StorageBuffer",
63+
"OpDecorate %var DescriptorSet {descriptor_set}",
64+
"OpDecorate %var Binding {binding}",
65+
"OpStore {slot} %var",
66+
descriptor_set = const DESCRIPTOR_SET,
67+
binding = const BINDING,
68+
slot = in(reg) slot.as_mut_ptr(),
69+
);
70+
slot.assume_init()
71+
}
72+
}
73+
74+
#[inline]
75+
pub fn global_invocation_id() -> UVec3 {
76+
unsafe {
77+
let gid = UVec3::default();
78+
asm! {
79+
"%builtin = OpVariable typeof{result} Input",
80+
"OpDecorate %builtin BuiltIn GlobalInvocationId",
81+
"%result = OpLoad typeof*{result} %builtin",
82+
"OpStore {result} %result",
83+
result = in(reg) &gid,
84+
}
85+
gid
86+
}
87+
}
88+
89+
/// we don't support `global_asm!` yet
90+
pub fn non_global_asm() {
91+
unsafe {
92+
asm! {
93+
"OpEntryPoint GLCompute {entry} \"main\"",
94+
"OpExecutionMode {entry} LocalSize 32 1 1",
95+
entry = in(reg) entry,
96+
}
97+
}
98+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
OpCapability Shader
2+
OpMemoryModel Logical Simple
3+
OpEntryPoint GLCompute %1 "main" %2 %3 %4
4+
OpExecutionMode %1 LocalSize 32 1 1
5+
OpName %1 "entry3_generic_asm::entry"
6+
OpDecorate %2 BuiltIn GlobalInvocationId
7+
OpDecorate %8 ArrayStride 4
8+
OpDecorate %9 Block
9+
OpMemberDecorate %9 0 Offset 0
10+
OpDecorate %3 NonWritable
11+
OpDecorate %3 Binding 0
12+
OpDecorate %3 DescriptorSet 0
13+
OpDecorate %4 Binding 1
14+
OpDecorate %4 DescriptorSet 0
15+
%10 = OpTypeVoid
16+
%11 = OpTypeFunction %10
17+
%12 = OpTypeInt 32 0
18+
%13 = OpTypeVector %12 3
19+
%14 = OpTypePointer Input %13
20+
%2 = OpVariable %14 Input
21+
%8 = OpTypeRuntimeArray %12
22+
%15 = OpTypePointer StorageBuffer %8
23+
%9 = OpTypeStruct %8
24+
%16 = OpTypePointer StorageBuffer %9
25+
%3 = OpVariable %16 StorageBuffer
26+
%17 = OpConstant %12 0
27+
%18 = OpTypePointer StorageBuffer %12
28+
%4 = OpVariable %16 StorageBuffer
29+
%1 = OpFunction %10 None %11
30+
%19 = OpLabel
31+
%20 = OpLoad %13 %2
32+
%21 = OpCompositeExtract %12 %20 0
33+
%22 = OpAccessChain %15 %3 %17
34+
%23 = OpAccessChain %18 %22 %21
35+
%24 = OpLoad %12 %23
36+
%25 = OpAccessChain %15 %4 %17
37+
%26 = OpAccessChain %18 %25 %21
38+
OpStore %26 %24
39+
OpNoLine
40+
OpReturn
41+
OpFunctionEnd

0 commit comments

Comments
 (0)