1use crate::vector::Vector;
4#[cfg(target_arch = "spirv")]
5use core::arch::asm;
6
7pub unsafe trait Float: num_traits::Float + crate::scalar::Scalar + Default {
13 const WIDTH: usize;
15}
16
17unsafe impl Float for f32 {
18 const WIDTH: usize = 32;
19}
20
21unsafe impl Float for f64 {
22 const WIDTH: usize = 64;
23}
24
25#[spirv_std_macros::gpu_only]
28pub fn vec2_to_f16x2(vec: impl Vector<f32, 2>) -> u32 {
29 let result;
30 unsafe {
31 asm!(
32 "%glsl = OpExtInstImport \"GLSL.std.450\"",
33 "%uint = OpTypeInt 32 0",
34 "%vec = OpLoad _ {vec}",
35 "{result} = OpExtInst %uint %glsl 58 %vec",
37 vec = in(reg) &vec,
38 result = out(reg) result,
39 );
40 }
41 result
42}
43
44#[spirv_std_macros::gpu_only]
47pub fn f16x2_to_vec2<V: Vector<f32, 2>>(int: u32) -> V {
48 let mut result = Default::default();
49 unsafe {
50 asm!(
51 "%glsl = OpExtInstImport \"GLSL.std.450\"",
52 "%result = OpExtInst typeof*{result} %glsl 62 {int}",
54 "OpStore {result} %result",
55 int = in(reg) int,
56 result = in(reg) &mut result,
57 );
58 }
59 result
60}
61
62#[spirv_std_macros::gpu_only]
65pub fn f32_to_f16(float: f32) -> u32 {
66 vec2_to_f16x2(glam::Vec2::new(float, 0.))
67}
68
69#[spirv_std_macros::gpu_only]
72pub fn f16_to_f32(packed: u32) -> f32 {
73 f16x2_to_vec2::<glam::Vec2>(packed).x
74}
75
76#[spirv_std_macros::gpu_only]
80pub fn vec4_to_u8x4_snorm(vec: impl Vector<f32, 4>) -> u32 {
81 let result;
82 unsafe {
83 asm!(
84 "%glsl = OpExtInstImport \"GLSL.std.450\"",
85 "%uint = OpTypeInt 32 0",
86 "%vec = OpLoad _ {vec}",
87 "{result} = OpExtInst %uint %glsl 54 %vec",
89 vec = in(reg) &vec,
90 result = out(reg) result,
91 );
92 }
93 result
94}
95
96#[spirv_std_macros::gpu_only]
100pub fn vec4_to_u8x4_unorm(vec: impl Vector<f32, 4>) -> u32 {
101 let result;
102 unsafe {
103 asm!(
104 "%glsl = OpExtInstImport \"GLSL.std.450\"",
105 "%uint = OpTypeInt 32 0",
106 "%vec = OpLoad _ {vec}",
107 "{result} = OpExtInst %uint %glsl 55 %vec",
109 vec = in(reg) &vec,
110 result = out(reg) result,
111 );
112 }
113 result
114}
115
116#[spirv_std_macros::gpu_only]
120pub fn vec2_to_u16x2_snorm(vec: impl Vector<f32, 2>) -> u32 {
121 let result;
122 unsafe {
123 asm!(
124 "%glsl = OpExtInstImport \"GLSL.std.450\"",
125 "%uint = OpTypeInt 32 0",
126 "%vec = OpLoad _ {vec}",
127 "{result} = OpExtInst %uint %glsl 56 %vec",
129 vec = in(reg) &vec,
130 result = out(reg) result,
131 );
132 }
133 result
134}
135
136#[spirv_std_macros::gpu_only]
140pub fn vec2_to_u16x2_unorm(vec: impl Vector<f32, 2>) -> u32 {
141 let result;
142 unsafe {
143 asm!(
144 "%glsl = OpExtInstImport \"GLSL.std.450\"",
145 "%uint = OpTypeInt 32 0",
146 "%vec = OpLoad _ {vec}",
147 "{result} = OpExtInst %uint %glsl 57 %vec",
149 vec = in(reg) &vec,
150 result = out(reg) result,
151 );
152 }
153 result
154}
155
156#[spirv_std_macros::gpu_only]
160pub fn u8x4_to_vec4_snorm<V: Vector<f32, 4>>(int: u32) -> V {
161 let mut result = Default::default();
162 unsafe {
163 asm!(
164 "%glsl = OpExtInstImport \"GLSL.std.450\"",
165 "%result = OpExtInst typeof*{result} %glsl 63 {int}",
167 "OpStore {result} %result",
168 int = in(reg) int,
169 result = in(reg) &mut result,
170 );
171 }
172 result
173}
174
175#[spirv_std_macros::gpu_only]
179pub fn u8x4_to_vec4_unorm<V: Vector<f32, 4>>(int: u32) -> V {
180 let mut result = Default::default();
181 unsafe {
182 asm!(
183 "%glsl = OpExtInstImport \"GLSL.std.450\"",
184 "%result = OpExtInst typeof*{result} %glsl 64 {int}",
186 "OpStore {result} %result",
187 int = in(reg) int,
188 result = in(reg) &mut result,
189 );
190 }
191 result
192}
193
194#[spirv_std_macros::gpu_only]
198pub fn u16x2_to_vec2_snorm<V: Vector<f32, 2>>(int: u32) -> V {
199 let mut result = Default::default();
200 unsafe {
201 asm!(
202 "%glsl = OpExtInstImport \"GLSL.std.450\"",
203 "%result = OpExtInst typeof*{result} %glsl 60 {int}",
205 "OpStore {result} %result",
206 int = in(reg) int,
207 result = in(reg) &mut result,
208 );
209 }
210 result
211}
212
213#[spirv_std_macros::gpu_only]
217pub fn u16x2_to_vec2_unorm<V: Vector<f32, 2>>(int: u32) -> V {
218 let mut result = Default::default();
219 unsafe {
220 asm!(
221 "%glsl = OpExtInstImport \"GLSL.std.450\"",
222 "%result = OpExtInst typeof*{result} %glsl 61 {int}",
224 "OpStore {result} %result",
225 int = in(reg) int,
226 result = in(reg) &mut result,
227 );
228 }
229 result
230}