#![cfg_attr( target_arch = "spirv", feature(register_attr), register_attr(spirv), no_std )] #![feature(const_fn_floating_point_arithmetic)] extern crate spirv_std; use spirv_std::{glam, RuntimeArray}; #[cfg(not(target_arch = "spirv"))] use spirv_std::macros::spirv; mod adapt; mod support; use coremem_cross::mat::{Ferroxcube3R1MH, GenericMaterial, IsoConductorOr}; use coremem_cross::real::R32; use coremem_cross::step::SimMeta; use coremem_cross::vec::{Vec3, Vec3u}; type Iso3R1 = IsoConductorOr; fn glam_vec_to_internal(v: glam::UVec3) -> Vec3u { Vec3u::new(v.x, v.y, v.z) } mod private { pub trait Sealed {} } pub trait HasEntryPoints: private::Sealed { fn step_h() -> &'static str; fn step_e() -> &'static str; } macro_rules! steps { ($flt:ty, $mat:ty, $step_h:ident, $step_e:ident) => { impl private::Sealed for $mat { } impl HasEntryPoints<$flt> for $mat { fn step_h() -> &'static str { stringify!($step_h) } fn step_e() -> &'static str { stringify!($step_e) } } // LocalSize/numthreads #[spirv(compute(threads(4, 4, 4)))] pub fn $step_h( #[spirv(global_invocation_id)] id: glam::UVec3, #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] meta: &SimMeta<$flt>, // XXX: delete this input? #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] _unused_stimulus_e: &RuntimeArray>, #[spirv(storage_buffer, descriptor_set = 0, binding = 2)] stimulus_h: &RuntimeArray>, #[spirv(storage_buffer, descriptor_set = 0, binding = 3)] material: &RuntimeArray<$mat>, #[spirv(storage_buffer, descriptor_set = 0, binding = 4)] e: &RuntimeArray>, #[spirv(storage_buffer, descriptor_set = 0, binding = 5)] h: &mut RuntimeArray>, #[spirv(storage_buffer, descriptor_set = 0, binding = 6)] m: &mut RuntimeArray>, ) { adapt::step_h(glam_vec_to_internal(id), meta, stimulus_h, material, e, h, m) } #[spirv(compute(threads(4, 4, 4)))] pub fn $step_e( #[spirv(global_invocation_id)] id: glam::UVec3, #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] meta: &SimMeta<$flt>, #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] stimulus_e: &RuntimeArray>, // XXX: delete this input? #[spirv(storage_buffer, descriptor_set = 0, binding = 2)] _unused_stimulus_h: &RuntimeArray>, #[spirv(storage_buffer, descriptor_set = 0, binding = 3)] material: &RuntimeArray<$mat>, #[spirv(storage_buffer, descriptor_set = 0, binding = 4)] e: &mut RuntimeArray>, #[spirv(storage_buffer, descriptor_set = 0, binding = 5)] h: &RuntimeArray>, // XXX: can/should this m input be deleted? #[spirv(storage_buffer, descriptor_set = 0, binding = 6)] _unused_m: &RuntimeArray>, ) { adapt::step_e(glam_vec_to_internal(id), meta, stimulus_e, material, e, h) } }; } steps!(f32, GenericMaterial, step_h_generic_material_f32, step_e_generic_material_f32); steps!(f32, Iso3R1, step_h_iso_3r1_f32, step_e_iso_3r1_f32); steps!(R32, GenericMaterial, step_h_generic_material_r32, step_e_generic_material_r32); steps!(R32, Iso3R1, step_h_iso_3r1_r32, step_e_iso_3r1_r32); // these should work, but require OpCapability Float64 // we disable them for compatibility concerns: use the Cpu if you need f64 or temporarily uncomment // this and add the capability to the WgpuBackend driver. // steps!(f64, GenericMaterial, step_h_generic_material_f64, step_e_generic_material_f64); // steps!(f64, Iso3R1, step_h_iso_3r1_f64, step_e_iso_3r1_f64); // steps!(R64, GenericMaterial, step_h_generic_material_r64, step_e_generic_material_r64); // steps!(R64, Iso3R1, step_h_iso_3r1_r64, step_e_iso_3r1_r64);