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 "%float = OpTypeFloat 32",
53 "%vec2 = OpTypeVector %float 2",
54 "%result = OpExtInst %vec2 %glsl 62 {int}",
56 "OpStore {result} %result",
57 int = in(reg) int,
58 result = in(reg) &mut result,
59 );
60 }
61 result
62}
63
64#[cfg_attr(target_arch = "spirv", repr(simd))]
67#[allow(dead_code)]
69#[derive(Default)]
70struct F32x2 {
71 x: f32,
72 y: f32,
73}
74unsafe impl Vector<f32, 2> for F32x2 {}
75
76#[spirv_std_macros::gpu_only]
79pub fn f32_to_f16(float: f32) -> u32 {
80 vec2_to_f16x2(F32x2 { x: float, y: 0.0 })
81}
82
83#[spirv_std_macros::gpu_only]
86pub fn f16_to_f32(packed: u32) -> f32 {
87 f16x2_to_vec2::<F32x2>(packed).x
88}
89
90#[spirv_std_macros::gpu_only]
94pub fn vec4_to_u8x4_snorm(vec: impl Vector<f32, 4>) -> u32 {
95 let result;
96 unsafe {
97 asm!(
98 "%glsl = OpExtInstImport \"GLSL.std.450\"",
99 "%uint = OpTypeInt 32 0",
100 "%vec = OpLoad _ {vec}",
101 "{result} = OpExtInst %uint %glsl 54 %vec",
103 vec = in(reg) &vec,
104 result = out(reg) result,
105 );
106 }
107 result
108}
109
110#[spirv_std_macros::gpu_only]
114pub fn vec4_to_u8x4_unorm(vec: impl Vector<f32, 4>) -> u32 {
115 let result;
116 unsafe {
117 asm!(
118 "%glsl = OpExtInstImport \"GLSL.std.450\"",
119 "%uint = OpTypeInt 32 0",
120 "%vec = OpLoad _ {vec}",
121 "{result} = OpExtInst %uint %glsl 55 %vec",
123 vec = in(reg) &vec,
124 result = out(reg) result,
125 );
126 }
127 result
128}
129
130#[spirv_std_macros::gpu_only]
134pub fn vec2_to_u16x2_snorm(vec: impl Vector<f32, 2>) -> u32 {
135 let result;
136 unsafe {
137 asm!(
138 "%glsl = OpExtInstImport \"GLSL.std.450\"",
139 "%uint = OpTypeInt 32 0",
140 "%vec = OpLoad _ {vec}",
141 "{result} = OpExtInst %uint %glsl 56 %vec",
143 vec = in(reg) &vec,
144 result = out(reg) result,
145 );
146 }
147 result
148}
149
150#[spirv_std_macros::gpu_only]
154pub fn vec2_to_u16x2_unorm(vec: impl Vector<f32, 2>) -> u32 {
155 let result;
156 unsafe {
157 asm!(
158 "%glsl = OpExtInstImport \"GLSL.std.450\"",
159 "%uint = OpTypeInt 32 0",
160 "%vec = OpLoad _ {vec}",
161 "{result} = OpExtInst %uint %glsl 57 %vec",
163 vec = in(reg) &vec,
164 result = out(reg) result,
165 );
166 }
167 result
168}
169
170#[spirv_std_macros::gpu_only]
174pub fn u8x4_to_vec4_snorm<V: Vector<f32, 4>>(int: u32) -> V {
175 let mut result = Default::default();
176 unsafe {
177 asm!(
178 "%glsl = OpExtInstImport \"GLSL.std.450\"",
179 "%float = OpTypeFloat 32",
180 "%vec4 = OpTypeVector %float 4",
181 "%result = OpExtInst %vec4 %glsl 63 {int}",
183 "OpStore {result} %result",
184 int = in(reg) int,
185 result = in(reg) &mut result,
186 );
187 }
188 result
189}
190
191#[spirv_std_macros::gpu_only]
195pub fn u8x4_to_vec4_unorm<V: Vector<f32, 4>>(int: u32) -> V {
196 let mut result = Default::default();
197 unsafe {
198 asm!(
199 "%glsl = OpExtInstImport \"GLSL.std.450\"",
200 "%float = OpTypeFloat 32",
201 "%vec4 = OpTypeVector %float 4",
202 "%result = OpExtInst %vec4 %glsl 64 {int}",
204 "OpStore {result} %result",
205 int = in(reg) int,
206 result = in(reg) &mut result,
207 );
208 }
209 result
210}
211
212#[spirv_std_macros::gpu_only]
216pub fn u16x2_to_vec2_snorm<V: Vector<f32, 2>>(int: u32) -> V {
217 let mut result = Default::default();
218 unsafe {
219 asm!(
220 "%glsl = OpExtInstImport \"GLSL.std.450\"",
221 "%float = OpTypeFloat 32",
222 "%vec2 = OpTypeVector %float 2",
223 "%result = OpExtInst %vec2 %glsl 60 {int}",
225 "OpStore {result} %result",
226 int = in(reg) int,
227 result = in(reg) &mut result,
228 );
229 }
230 result
231}
232
233#[spirv_std_macros::gpu_only]
237pub fn u16x2_to_vec2_unorm<V: Vector<f32, 2>>(int: u32) -> V {
238 let mut result = Default::default();
239 unsafe {
240 asm!(
241 "%glsl = OpExtInstImport \"GLSL.std.450\"",
242 "%float = OpTypeFloat 32",
243 "%vec2 = OpTypeVector %float 2",
244 "%result = OpExtInst %vec2 %glsl 61 {int}",
246 "OpStore {result} %result",
247 int = in(reg) int,
248 result = in(reg) &mut result,
249 );
250 }
251 result
252}