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#[spirv_std_macros::gpu_only]
67pub fn f32_to_f16(float: f32) -> u32 {
68 vec2_to_f16x2(glam::Vec2::new(float, 0.))
69}
70
71#[spirv_std_macros::gpu_only]
74pub fn f16_to_f32(packed: u32) -> f32 {
75 f16x2_to_vec2::<glam::Vec2>(packed).x
76}
77
78#[spirv_std_macros::gpu_only]
82pub fn vec4_to_u8x4_snorm(vec: impl Vector<f32, 4>) -> u32 {
83 let result;
84 unsafe {
85 asm!(
86 "%glsl = OpExtInstImport \"GLSL.std.450\"",
87 "%uint = OpTypeInt 32 0",
88 "%vec = OpLoad _ {vec}",
89 "{result} = OpExtInst %uint %glsl 54 %vec",
91 vec = in(reg) &vec,
92 result = out(reg) result,
93 );
94 }
95 result
96}
97
98#[spirv_std_macros::gpu_only]
102pub fn vec4_to_u8x4_unorm(vec: impl Vector<f32, 4>) -> u32 {
103 let result;
104 unsafe {
105 asm!(
106 "%glsl = OpExtInstImport \"GLSL.std.450\"",
107 "%uint = OpTypeInt 32 0",
108 "%vec = OpLoad _ {vec}",
109 "{result} = OpExtInst %uint %glsl 55 %vec",
111 vec = in(reg) &vec,
112 result = out(reg) result,
113 );
114 }
115 result
116}
117
118#[spirv_std_macros::gpu_only]
122pub fn vec2_to_u16x2_snorm(vec: impl Vector<f32, 2>) -> u32 {
123 let result;
124 unsafe {
125 asm!(
126 "%glsl = OpExtInstImport \"GLSL.std.450\"",
127 "%uint = OpTypeInt 32 0",
128 "%vec = OpLoad _ {vec}",
129 "{result} = OpExtInst %uint %glsl 56 %vec",
131 vec = in(reg) &vec,
132 result = out(reg) result,
133 );
134 }
135 result
136}
137
138#[spirv_std_macros::gpu_only]
142pub fn vec2_to_u16x2_unorm(vec: impl Vector<f32, 2>) -> u32 {
143 let result;
144 unsafe {
145 asm!(
146 "%glsl = OpExtInstImport \"GLSL.std.450\"",
147 "%uint = OpTypeInt 32 0",
148 "%vec = OpLoad _ {vec}",
149 "{result} = OpExtInst %uint %glsl 57 %vec",
151 vec = in(reg) &vec,
152 result = out(reg) result,
153 );
154 }
155 result
156}
157
158#[spirv_std_macros::gpu_only]
162pub fn u8x4_to_vec4_snorm<V: Vector<f32, 4>>(int: u32) -> V {
163 let mut result = Default::default();
164 unsafe {
165 asm!(
166 "%glsl = OpExtInstImport \"GLSL.std.450\"",
167 "%float = OpTypeFloat 32",
168 "%vec4 = OpTypeVector %float 4",
169 "%result = OpExtInst %vec4 %glsl 63 {int}",
171 "OpStore {result} %result",
172 int = in(reg) int,
173 result = in(reg) &mut result,
174 );
175 }
176 result
177}
178
179#[spirv_std_macros::gpu_only]
183pub fn u8x4_to_vec4_unorm<V: Vector<f32, 4>>(int: u32) -> V {
184 let mut result = Default::default();
185 unsafe {
186 asm!(
187 "%glsl = OpExtInstImport \"GLSL.std.450\"",
188 "%float = OpTypeFloat 32",
189 "%vec4 = OpTypeVector %float 4",
190 "%result = OpExtInst %vec4 %glsl 64 {int}",
192 "OpStore {result} %result",
193 int = in(reg) int,
194 result = in(reg) &mut result,
195 );
196 }
197 result
198}
199
200#[spirv_std_macros::gpu_only]
204pub fn u16x2_to_vec2_snorm<V: Vector<f32, 2>>(int: u32) -> V {
205 let mut result = Default::default();
206 unsafe {
207 asm!(
208 "%glsl = OpExtInstImport \"GLSL.std.450\"",
209 "%float = OpTypeFloat 32",
210 "%vec2 = OpTypeVector %float 2",
211 "%result = OpExtInst %vec2 %glsl 60 {int}",
213 "OpStore {result} %result",
214 int = in(reg) int,
215 result = in(reg) &mut result,
216 );
217 }
218 result
219}
220
221#[spirv_std_macros::gpu_only]
225pub fn u16x2_to_vec2_unorm<V: Vector<f32, 2>>(int: u32) -> V {
226 let mut result = Default::default();
227 unsafe {
228 asm!(
229 "%glsl = OpExtInstImport \"GLSL.std.450\"",
230 "%float = OpTypeFloat 32",
231 "%vec2 = OpTypeVector %float 2",
232 "%result = OpExtInst %vec2 %glsl 61 {int}",
234 "OpStore {result} %result",
235 int = in(reg) int,
236 result = in(reg) &mut result,
237 );
238 }
239 result
240}