spirv_std/
typed_buffer.rs1#[cfg(target_arch = "spirv")]
2use core::arch::asm;
3use core::marker::PhantomData;
4use core::ops::{Deref, DerefMut};
5
6#[spirv(typed_buffer)]
15#[repr(C)]
17#[allow(dead_code)]
19pub struct TypedBuffer<T: ?Sized> {
20 _anti_zst_padding: core::mem::MaybeUninit<u32>,
23 _phantom: PhantomData<T>,
24}
25
26impl<T> Deref for TypedBuffer<T> {
27 type Target = T;
28 #[spirv_std_macros::gpu_only]
29 fn deref(&self) -> &T {
30 unsafe {
31 let mut result_slot = core::mem::MaybeUninit::uninit();
32 asm! {
33 "%uint = OpTypeInt 32 0",
34 "%uint_0 = OpConstant %uint 0",
35 "%result = OpAccessChain _ {buffer} %uint_0",
36 "OpStore {result_slot} %result",
37 buffer = in(reg) self,
38 result_slot = in(reg) result_slot.as_mut_ptr(),
39 }
40 result_slot.assume_init()
41 }
42 }
43}
44
45impl<T> DerefMut for TypedBuffer<T> {
46 #[spirv_std_macros::gpu_only]
47 fn deref_mut(&mut self) -> &mut T {
48 unsafe {
49 let mut result_slot = core::mem::MaybeUninit::uninit();
50 asm! {
51 "%uint = OpTypeInt 32 0",
52 "%uint_0 = OpConstant %uint 0",
53 "%result = OpAccessChain _ {buffer} %uint_0",
54 "OpStore {result_slot} %result",
55 buffer = in(reg) self,
56 result_slot = in(reg) result_slot.as_mut_ptr(),
57 }
58 result_slot.assume_init()
59 }
60 }
61}
62
63impl<T> Deref for TypedBuffer<[T]> {
64 type Target = [T];
65 #[spirv_std_macros::gpu_only]
66 fn deref(&self) -> &[T] {
67 unsafe {
68 let mut result_slot = core::mem::MaybeUninit::uninit();
69 asm! {
70 "%uint = OpTypeInt 32 0",
71 "%uint_0 = OpConstant %uint 0",
72 "%inner_ptr = OpAccessChain _ {buffer} %uint_0",
73 "%inner_len = OpArrayLength %uint {buffer} 0",
74 "%result = OpCompositeConstruct typeof*{result_slot} %inner_ptr %inner_len",
75 "OpStore {result_slot} %result",
76 buffer = in(reg) self,
77 result_slot = in(reg) result_slot.as_mut_ptr(),
78 }
79 result_slot.assume_init()
80 }
81 }
82}
83
84impl<T> DerefMut for TypedBuffer<[T]> {
85 #[spirv_std_macros::gpu_only]
86 fn deref_mut(&mut self) -> &mut Self::Target {
87 unsafe {
88 let mut result_slot = core::mem::MaybeUninit::uninit();
89 asm! {
90 "%uint = OpTypeInt 32 0",
91 "%uint_0 = OpConstant %uint 0",
92 "%inner_ptr = OpAccessChain _ {buffer} %uint_0",
93 "%inner_len = OpArrayLength %uint {buffer} 0",
94 "%result = OpCompositeConstruct typeof*{result_slot} %inner_ptr %inner_len",
95 "OpStore {result_slot} %result",
96 buffer = in(reg) self,
97 result_slot = in(reg) result_slot.as_mut_ptr(),
98 }
99 result_slot.assume_init()
100 }
101 }
102}