use crate::vector::Vector;
#[cfg(target_arch = "spirv")]
use core::arch::asm;
pub unsafe trait Float: num_traits::Float + crate::scalar::Scalar + Default {
const WIDTH: usize;
}
unsafe impl Float for f32 {
const WIDTH: usize = 32;
}
unsafe impl Float for f64 {
const WIDTH: usize = 64;
}
#[spirv_std_macros::gpu_only]
pub fn vec2_to_f16x2(vec: impl Vector<f32, 2>) -> u32 {
let result;
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%uint = OpTypeInt 32 0",
"%vec = OpLoad _ {vec}",
"{result} = OpExtInst %uint %glsl 58 %vec",
vec = in(reg) &vec,
result = out(reg) result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn f16x2_to_vec2<V: Vector<f32, 2>>(int: u32) -> V {
let mut result = Default::default();
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%float = OpTypeFloat 32",
"%vec2 = OpTypeVector %float 2",
"%result = OpExtInst %vec2 %glsl 62 {int}",
"OpStore {result} %result",
int = in(reg) int,
result = in(reg) &mut result,
);
}
result
}
#[cfg_attr(target_arch = "spirv", repr(simd))]
#[allow(dead_code)]
#[derive(Default)]
struct F32x2 {
x: f32,
y: f32,
}
unsafe impl Vector<f32, 2> for F32x2 {}
#[spirv_std_macros::gpu_only]
pub fn f32_to_f16(float: f32) -> u32 {
vec2_to_f16x2(F32x2 { x: float, y: 0.0 })
}
#[spirv_std_macros::gpu_only]
pub fn f16_to_f32(packed: u32) -> f32 {
f16x2_to_vec2::<F32x2>(packed).x
}
#[spirv_std_macros::gpu_only]
pub fn vec4_to_u8x4_snorm(vec: impl Vector<f32, 4>) -> u32 {
let result;
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%uint = OpTypeInt 32 0",
"%vec = OpLoad _ {vec}",
"{result} = OpExtInst %uint %glsl 54 %vec",
vec = in(reg) &vec,
result = out(reg) result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn vec4_to_u8x4_unorm(vec: impl Vector<f32, 4>) -> u32 {
let result;
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%uint = OpTypeInt 32 0",
"%vec = OpLoad _ {vec}",
"{result} = OpExtInst %uint %glsl 55 %vec",
vec = in(reg) &vec,
result = out(reg) result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn vec2_to_u16x2_snorm(vec: impl Vector<f32, 2>) -> u32 {
let result;
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%uint = OpTypeInt 32 0",
"%vec = OpLoad _ {vec}",
"{result} = OpExtInst %uint %glsl 56 %vec",
vec = in(reg) &vec,
result = out(reg) result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn vec2_to_u16x2_unorm(vec: impl Vector<f32, 2>) -> u32 {
let result;
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%uint = OpTypeInt 32 0",
"%vec = OpLoad _ {vec}",
"{result} = OpExtInst %uint %glsl 57 %vec",
vec = in(reg) &vec,
result = out(reg) result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn u8x4_to_vec4_snorm<V: Vector<f32, 4>>(int: u32) -> V {
let mut result = Default::default();
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%float = OpTypeFloat 32",
"%vec4 = OpTypeVector %float 4",
"%result = OpExtInst %vec4 %glsl 63 {int}",
"OpStore {result} %result",
int = in(reg) int,
result = in(reg) &mut result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn u8x4_to_vec4_unorm<V: Vector<f32, 4>>(int: u32) -> V {
let mut result = Default::default();
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%float = OpTypeFloat 32",
"%vec4 = OpTypeVector %float 4",
"%result = OpExtInst %vec4 %glsl 64 {int}",
"OpStore {result} %result",
int = in(reg) int,
result = in(reg) &mut result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn u16x2_to_vec2_snorm<V: Vector<f32, 2>>(int: u32) -> V {
let mut result = Default::default();
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%float = OpTypeFloat 32",
"%vec2 = OpTypeVector %float 2",
"%result = OpExtInst %vec2 %glsl 60 {int}",
"OpStore {result} %result",
int = in(reg) int,
result = in(reg) &mut result,
);
}
result
}
#[spirv_std_macros::gpu_only]
pub fn u16x2_to_vec2_unorm<V: Vector<f32, 2>>(int: u32) -> V {
let mut result = Default::default();
unsafe {
asm!(
"%glsl = OpExtInstImport \"GLSL.std.450\"",
"%float = OpTypeFloat 32",
"%vec2 = OpTypeVector %float 2",
"%result = OpExtInst %vec2 %glsl 61 {int}",
"OpStore {result} %result",
int = in(reg) int,
result = in(reg) &mut result,
);
}
result
}