diff --git a/dunge/src/shader.rs b/dunge/src/shader.rs index a679f38..6d85bf5 100644 --- a/dunge/src/shader.rs +++ b/dunge/src/shader.rs @@ -98,16 +98,18 @@ impl Inner { entries.clear(); for (binding, member) in iter::zip(0.., info.decl) { let entry = match member { - MemberType::Scalar(_) | MemberType::Vector(_) => BindGroupLayoutEntry { - binding, - visibility: visibility(info.stages), - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: None, - }, - count: None, - }, + MemberType::Scalar(_) | MemberType::Vector(_) | MemberType::Matrix(_) => { + BindGroupLayoutEntry { + binding, + visibility: visibility(info.stages), + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + } + } MemberType::Tx2df => BindGroupLayoutEntry { binding, visibility: visibility(info.stages), diff --git a/dunge_shader/src/eval.rs b/dunge_shader/src/eval.rs index 0b20fd0..af5de3c 100644 --- a/dunge_shader/src/eval.rs +++ b/dunge_shader/src/eval.rs @@ -4,7 +4,7 @@ use { group::DeclareGroup, module::{Module, Out, Output}, ret::Ret, - types::{self, IntoVector, ScalarType, Vector, VectorType}, + types::{self, ScalarType, VectorType}, }, naga::{ AddressSpace, Arena, BinaryOperator, Binding, Block, BuiltIn, EntryPoint, Expression, @@ -150,27 +150,6 @@ where } } -impl Eval for V -where - V: IntoVector, - ::Scalar: Eval, - E: GetEntry, -{ - type Out = V::Vector; - - fn eval(self, en: &mut E) -> Expr { - let mut components = Vec::with_capacity(V::Vector::TYPE.dims()); - self.into_vector(|scalar| { - let v = scalar.eval(en).get(); - components.push(v); - }); - - let en = en.get_entry(); - let ty = en.new_type(V::Vector::TYPE.ty()); - en.compose(ty, Exprs(components)) - } -} - #[derive(Clone, Copy)] pub struct ReadIndex { id: u32, diff --git a/dunge_shader/src/lib.rs b/dunge_shader/src/lib.rs index f87c1ae..3988edc 100644 --- a/dunge_shader/src/lib.rs +++ b/dunge_shader/src/lib.rs @@ -3,6 +3,7 @@ mod convert; mod eval; pub mod group; mod math; +mod matrix; mod module; mod ret; mod texture; diff --git a/dunge_shader/src/matrix.rs b/dunge_shader/src/matrix.rs new file mode 100644 index 0000000..1b07834 --- /dev/null +++ b/dunge_shader/src/matrix.rs @@ -0,0 +1,72 @@ +use crate::{ + eval::{Eval, Expr, Exprs, GetEntry}, + types::{self, Matrix}, +}; + +macro_rules! impl_eval_mat { + ($g:ty => $t:ty) => { + impl Eval for $g + where + E: GetEntry, + { + type Out = $t; + + fn eval(self, en: &mut E) -> Expr { + let mut components = Vec::with_capacity(<$t>::TYPE.dims()); + self.into_matrix(|vector| { + let v = vector.eval(en).get(); + components.push(v); + }); + + let en = en.get_entry(); + let ty = en.new_type(<$t>::TYPE.ty()); + en.compose(ty, Exprs(components)) + } + } + }; +} + +impl_eval_mat!(glam::Mat2 => types::Mat2); +impl_eval_mat!(glam::Mat3 => types::Mat3); +impl_eval_mat!(glam::Mat4 => types::Mat4); + +trait IntoMatrix { + type Vector; + + fn into_matrix(self, f: F) + where + F: FnMut(Self::Vector); +} + +impl IntoMatrix for glam::Mat2 { + type Vector = glam::Vec2; + + fn into_matrix(self, mut f: F) + where + F: FnMut(Self::Vector), + { + self.to_cols_array_2d().map(|v| f(Self::Vector::from(v))); + } +} + +impl IntoMatrix for glam::Mat3 { + type Vector = glam::Vec3; + + fn into_matrix(self, mut f: F) + where + F: FnMut(Self::Vector), + { + self.to_cols_array_2d().map(|v| f(Self::Vector::from(v))); + } +} + +impl IntoMatrix for glam::Mat4 { + type Vector = glam::Vec4; + + fn into_matrix(self, mut f: F) + where + F: FnMut(Self::Vector), + { + self.to_cols_array_2d().map(|v| f(Self::Vector::from(v))); + } +} diff --git a/dunge_shader/src/ret.rs b/dunge_shader/src/ret.rs index 1e7c001..b3f059a 100644 --- a/dunge_shader/src/ret.rs +++ b/dunge_shader/src/ret.rs @@ -69,7 +69,7 @@ macro_rules! impl_op { } impl ops::$o<$a> for Ret { - type Output = Ret, $b>, $r>; + type Output = Ret, $a>, $r>; fn $f(self, b: $a) -> Self::Output { Ret::new(Binary { @@ -110,62 +110,31 @@ impl_op!(Mul::mul(u32, u32) -> u32); impl_op!(Div::div(u32, u32) -> u32); impl_op!(Rem::rem(u32, u32) -> u32); -impl ops::Mul for Ret -where - O: types::Vector, -{ - type Output = Ret, O>; - - fn mul(self, b: f32) -> Self::Output { - Ret::new(Binary { - a: self, - b, - op: Op::Mul, - }) - } -} - -impl ops::Mul> for f32 -where - O: types::Vector, -{ - type Output = Ret>, O>; - - fn mul(self, b: Ret) -> Self::Output { - Ret::new(Binary { - a: self, - b, - op: Op::Mul, - }) - } -} - -impl ops::Add> for Ret -where - O: types::Vector, -{ - type Output = Ret>, O>; - - fn add(self, b: Ret) -> Self::Output { - Ret::new(Binary { - a: self, - b, - op: Op::Add, - }) - } -} - -impl ops::Sub> for Ret -where - O: types::Vector, -{ - type Output = Ret>, O>; - - fn sub(self, b: Ret) -> Self::Output { - Ret::new(Binary { - a: self, - b, - op: Op::Sub, - }) - } -} +impl_op!(Add::add(types::Vec2, types::Vec2) -> types::Vec2); +impl_op!(Add::add(types::Vec3, types::Vec3) -> types::Vec3); +impl_op!(Add::add(types::Vec4, types::Vec4) -> types::Vec4); +impl_op!(Sub::sub(types::Vec2, types::Vec2) -> types::Vec2); +impl_op!(Sub::sub(types::Vec3, types::Vec3) -> types::Vec3); +impl_op!(Sub::sub(types::Vec4, types::Vec4) -> types::Vec4); +impl_op!(Mul::mul(f32, types::Vec2) -> types::Vec2); +impl_op!(Mul::mul(types::Vec2, f32) -> types::Vec2); +impl_op!(Mul::mul(f32, types::Vec3) -> types::Vec3); +impl_op!(Mul::mul(types::Vec3, f32) -> types::Vec3); +impl_op!(Mul::mul(f32, types::Vec4) -> types::Vec4); +impl_op!(Mul::mul(types::Vec4, f32) -> types::Vec4); + +impl_op!(Add::add(types::Mat2, types::Mat2) -> types::Mat2); +impl_op!(Add::add(types::Mat3, types::Mat3) -> types::Mat3); +impl_op!(Add::add(types::Mat4, types::Mat4) -> types::Mat4); +impl_op!(Sub::sub(types::Mat2, types::Mat2) -> types::Mat2); +impl_op!(Sub::sub(types::Mat3, types::Mat3) -> types::Mat3); +impl_op!(Sub::sub(types::Mat4, types::Mat4) -> types::Mat4); +impl_op!(Mul::mul(types::Mat2, types::Mat2) -> types::Mat2); +impl_op!(Mul::mul(types::Mat3, types::Mat3) -> types::Mat3); +impl_op!(Mul::mul(types::Mat4, types::Mat4) -> types::Mat4); +impl_op!(Mul::mul(f32, types::Mat2) -> types::Mat2); +impl_op!(Mul::mul(f32, types::Mat3) -> types::Mat3); +impl_op!(Mul::mul(f32, types::Mat4) -> types::Mat4); +impl_op!(Mul::mul(types::Mat2, types::Vec2) -> types::Vec2); +impl_op!(Mul::mul(types::Mat3, types::Vec3) -> types::Vec3); +impl_op!(Mul::mul(types::Mat4, types::Vec4) -> types::Vec4); diff --git a/dunge_shader/src/types.rs b/dunge_shader/src/types.rs index d074129..19fb825 100644 --- a/dunge_shader/src/types.rs +++ b/dunge_shader/src/types.rs @@ -162,6 +162,66 @@ const fn vec(size: VectorSize, kind: ScalarKind) -> Type { } } +pub struct Mat2; +pub struct Mat3; +pub struct Mat4; + +#[derive(Clone, Copy)] +pub enum MatrixType { + Mat2, + Mat3, + Mat4, +} + +impl MatrixType { + pub(crate) const fn dims(self) -> usize { + match self { + Self::Mat2 => 2, + Self::Mat3 => 3, + Self::Mat4 => 4, + } + } + + pub(crate) const fn ty(self) -> Type { + match self { + Self::Mat2 => MAT2F, + Self::Mat3 => MAT3F, + Self::Mat4 => MAT4F, + } + } +} + +pub trait Matrix { + const TYPE: MatrixType; +} + +impl Matrix for Mat2 { + const TYPE: MatrixType = MatrixType::Mat2; +} + +impl Matrix for Mat3 { + const TYPE: MatrixType = MatrixType::Mat3; +} + +impl Matrix for Mat4 { + const TYPE: MatrixType = MatrixType::Mat4; +} + +const MAT2F: Type = mat(VectorSize::Bi); +const MAT3F: Type = mat(VectorSize::Tri); +const MAT4F: Type = mat(VectorSize::Quad); + +const fn mat(size: VectorSize) -> Type { + Type { + name: None, + inner: TypeInner::Matrix { + columns: size, + rows: size, + width: 4, + }, + } +} + pub struct Texture2d(PhantomData); const TEXTURE2DF: Type = texture(ImageDimension::D2, ScalarKind::Float); @@ -194,19 +254,21 @@ const SAMPLER: Type = Type { pub enum MemberType { Scalar(ScalarType), Vector(VectorType), + Matrix(MatrixType), Tx2df, Sampl, } impl MemberType { pub const fn is_value(self) -> bool { - matches!(self, Self::Scalar(_) | Self::Vector(_)) + matches!(self, Self::Scalar(_) | Self::Vector(_) | Self::Matrix(_)) } pub(crate) const fn ty(self) -> Type { match self { Self::Scalar(v) => v.ty(), Self::Vector(v) => v.ty(), + Self::Matrix(v) => v.ty(), Self::Tx2df => TEXTURE2DF, Self::Sampl => SAMPLER, } @@ -214,126 +276,8 @@ impl MemberType { pub(crate) const fn address_space(self) -> AddressSpace { match self { - Self::Scalar(_) | Self::Vector(_) => AddressSpace::Uniform, + Self::Scalar(_) | Self::Vector(_) | Self::Matrix(_) => AddressSpace::Uniform, Self::Tx2df | Self::Sampl => AddressSpace::Handle, } } } - -pub trait IntoVector { - type Vector: Vector; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar); -} - -impl IntoVector for glam::Vec2 { - type Vector = Vec2; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::Vec3 { - type Vector = Vec3; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::Vec3A { - type Vector = Vec3; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::Vec4 { - type Vector = Vec4; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::IVec2 { - type Vector = Vec2; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::IVec3 { - type Vector = Vec3; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::IVec4 { - type Vector = Vec4; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::UVec2 { - type Vector = Vec2; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::UVec3 { - type Vector = Vec3; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} - -impl IntoVector for glam::UVec4 { - type Vector = Vec4; - - fn into_vector(self, f: F) - where - F: FnMut(::Scalar), - { - self.to_array().map(f); - } -} diff --git a/dunge_shader/src/vector.rs b/dunge_shader/src/vector.rs index 4903638..884e112 100644 --- a/dunge_shader/src/vector.rs +++ b/dunge_shader/src/vector.rs @@ -4,6 +4,40 @@ use crate::{ types::{self, Scalar, Vector}, }; +macro_rules! impl_eval_vec { + ($g:ty => $t:ty) => { + impl Eval for $g + where + E: GetEntry, + { + type Out = $t; + + fn eval(self, en: &mut E) -> Expr { + let mut components = Vec::with_capacity(<$t>::TYPE.dims()); + self.into_vector(|scalar| { + let v = scalar.eval(en).get(); + components.push(v); + }); + + let en = en.get_entry(); + let ty = en.new_type(<$t>::TYPE.ty()); + en.compose(ty, Exprs(components)) + } + } + }; +} + +impl_eval_vec!(glam::Vec2 => types::Vec2); +impl_eval_vec!(glam::Vec3 => types::Vec3); +impl_eval_vec!(glam::Vec3A => types::Vec3); +impl_eval_vec!(glam::Vec4 => types::Vec4); +impl_eval_vec!(glam::IVec2 => types::Vec2); +impl_eval_vec!(glam::IVec3 => types::Vec3); +impl_eval_vec!(glam::IVec4 => types::Vec4); +impl_eval_vec!(glam::UVec2 => types::Vec2); +impl_eval_vec!(glam::UVec3 => types::Vec3); +impl_eval_vec!(glam::UVec4 => types::Vec4); + pub const fn splat_vec2(a: A) -> Ret, types::Vec2> where A: Eval, @@ -47,7 +81,7 @@ where } } -type Vector2 = Ret, types::Vec2>; +type Vector2 = Ret, types::Vec2>; pub const fn vec2(x: X, y: Y) -> Vector2 where @@ -55,10 +89,10 @@ where X::Out: Scalar, Y: Eval, { - Ret::new(New((x, y))) + Ret::new(NewVec((x, y))) } -type Vector3 = Ret, types::Vec3>; +type Vector3 = Ret, types::Vec3>; pub const fn vec3(x: X, y: Y, z: Z) -> Vector3 where @@ -67,10 +101,10 @@ where Y: Eval, Z: Eval, { - Ret::new(New((x, y, z))) + Ret::new(NewVec((x, y, z))) } -type Vector4 = Ret, types::Vec4>; +type Vector4 = Ret, types::Vec4>; pub const fn vec4(x: X, y: Y, z: Z, w: W) -> Vector4 where @@ -80,12 +114,12 @@ where Z: Eval, W: Eval, { - Ret::new(New((x, y, z, w))) + Ret::new(NewVec((x, y, z, w))) } -pub struct New(A); +pub struct NewVec(A); -impl Eval for Ret, O> +impl Eval for Ret, O> where A: EvalTuple, O: Vector, @@ -153,3 +187,121 @@ where en.compose(ty, Exprs(vec![x, y])) } } + +trait IntoVector { + type Scalar; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar); +} + +impl IntoVector for glam::Vec2 { + type Scalar = f32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::Vec3 { + type Scalar = f32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::Vec3A { + type Scalar = f32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::Vec4 { + type Scalar = f32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::IVec2 { + type Scalar = i32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::IVec3 { + type Scalar = i32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::IVec4 { + type Scalar = i32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::UVec2 { + type Scalar = u32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::UVec3 { + type Scalar = u32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +} + +impl IntoVector for glam::UVec4 { + type Scalar = u32; + + fn into_vector(self, f: F) + where + F: FnMut(Self::Scalar), + { + self.to_array().map(f); + } +}