plumb the R type parameter through spirv code

This commit is contained in:
2022-07-22 16:21:03 -07:00
parent ee2cf47b8d
commit 4a6a43fb31
4 changed files with 144 additions and 141 deletions

View File

@@ -2,25 +2,25 @@ use serde::de::Deserializer;
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
use crate::geom::{Index, Vec3, Vec3u};
// TODO: split out the re-exports (coremem_types) from the native types
use crate::mat::{
AnisomorphicConductor,
IsoConductorOr,
IsomorphicConductor,
Ferroxcube3R1MH,
FullyGenericMaterial,
MaterialExt as _,
MBFerromagnet,
MBPgram,
MHPgram,
Static
};
use crate::geom::{Index, Vec3, Vec3u};
/// hide the actual spirv backend structures inside a submodule to make their use/boundary clear.
mod ffi {
pub use spirv_backend::entry_points;
pub use spirv_backend::sim::SerializedSimMeta;
pub use spirv_backend::support::Optional;
// TODO: move this out of FFI
pub use coremem_types::mat::MBPgram;
}
@@ -35,29 +35,25 @@ pub trait IntoLib {
fn into_lib(self) -> Self::Lib;
}
macro_rules! identity {
($($param:ident,)* => $t:ty) => {
impl<$($param: IntoFfi),*> IntoFfi for $t {
type Ffi = $t;
fn into_ffi(self) -> Self::Ffi {
self
}
}
impl<$($param: IntoLib),*> IntoLib for $t {
type Lib = $t;
fn into_lib(self) -> Self::Lib {
self
}
}
};
pub trait Identity { }
impl<T: Identity> IntoFfi for T {
type Ffi = Self;
fn into_ffi(self) -> Self::Ffi {
self
}
}
impl<T: Identity> IntoLib for T {
type Lib = Self;
fn into_lib(self) -> Self::Lib {
self
}
}
// XXX: should work for any other lifetime, not just 'static
identity!(=> f32);
identity!(=> &'static str);
identity!(T0, T1, => (T0, T1));
identity!(=> Vec3u);
identity!(T, => Vec3<T>);
impl Identity for f32 {}
impl<'a> Identity for &'a str {}
impl<T0: Identity, T1: Identity> Identity for (T0, T1) {}
impl Identity for Vec3u {}
impl<T: Identity> Identity for Vec3<T> {}
impl<L: IntoFfi> IntoFfi for Option<L>
where L::Ffi: Default
@@ -96,10 +92,10 @@ impl IntoLib for ffi::MBPgram<f32> {
}
}
identity!( => MHPgram<f32>);
identity!( => Ferroxcube3R1MH);
identity!( => FullyGenericMaterial<f32>);
identity!(R, M, => IsoConductorOr<R, M>);
impl Identity for MHPgram<f32> {}
impl Identity for Ferroxcube3R1MH {}
impl Identity for FullyGenericMaterial<f32> {}
impl <R: Identity, M: Identity> Identity for IsoConductorOr<R, M> {}
// N.B.: this isn't fully correct, as Static also encodes the magnetic component
impl From<Static<f32>> for FullyGenericMaterial<f32> {
@@ -114,23 +110,24 @@ impl From<MBFerromagnet<f32>> for FullyGenericMaterial<f32> {
}
}
// TODO: if we lift this type out of the spirv crate we can derive serde based on a feature flag
// this is bitwise- and type-compatible with the spirv SimMeta, except we need serde traits
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct SimMeta {
pub struct SimMeta<R> {
pub(crate) dim: Index,
pub(crate) inv_feature_size: f32,
pub(crate) time_step: f32,
pub(crate) feature_size: f32,
pub(crate) inv_feature_size: R,
pub(crate) time_step: R,
pub(crate) feature_size: R,
}
impl IntoFfi for SimMeta {
type Ffi = ffi::SerializedSimMeta;
impl<R: IntoFfi> IntoFfi for SimMeta<R> {
type Ffi = ffi::SerializedSimMeta<R::Ffi>;
fn into_ffi(self) -> Self::Ffi {
Self::Ffi {
dim: self.dim.0.into_ffi(),
inv_feature_size: self.inv_feature_size,
time_step: self.time_step,
feature_size: self.feature_size,
inv_feature_size: self.inv_feature_size.into_ffi(),
time_step: self.time_step.into_ffi(),
feature_size: self.feature_size.into_ffi(),
}
}
}

View File

@@ -24,7 +24,8 @@ pub use bindings::{entry_points, IntoFfi, IntoLib, Remote, SimMeta};
pub struct SpirvSim<M=FullyGenericMaterial<f32>>
where M: IntoFfi,
{
meta: SimMeta,
// TODO: make this generic over R
meta: SimMeta<f32>,
e: Vec<Vec3<f32>>,
h: Vec<Vec3<f32>>,
m: Vec<Vec3<f32>>,