1use glamx::Vec2;
4
5#[inline(always)]
12pub fn unpack_half2x16(v: u32) -> Vec2 {
13 #[cfg(target_arch = "spirv")]
14 {
15 let v2 = spirv_std::float::f16x2_to_vec2(v);
16 Vec2::new(v2.x, v2.y)
17 }
18 #[cfg(not(target_arch = "spirv"))]
19 {
20 let lo = (v & 0xFFFF) as u16;
21 let hi = ((v >> 16) & 0xFFFF) as u16;
22 Vec2::new(f16_to_f32(lo), f16_to_f32(hi))
23 }
24}
25
26#[cfg(not(target_arch = "spirv"))]
28#[inline]
29fn f16_to_f32(bits: u16) -> f32 {
30 let sign = ((bits >> 15) as u32) << 31;
31 let exp = (bits >> 10) & 0x1F;
32 let mantissa = (bits & 0x3FF) as u32;
33
34 if exp == 0 {
35 if mantissa == 0 {
36 f32::from_bits(sign)
37 } else {
38 let mut m = mantissa;
40 let mut e: i32 = -14 + 127;
41 while m & 0x400 == 0 {
42 m <<= 1;
43 e -= 1;
44 }
45 m &= 0x3FF;
46 f32::from_bits(sign | ((e as u32) << 23) | (m << 13))
47 }
48 } else if exp == 31 {
49 f32::from_bits(sign | 0x7F800000 | (mantissa << 13))
51 } else {
52 let e = (exp as u32) + 112;
54 f32::from_bits(sign | (e << 23) | (mantissa << 13))
55 }
56}