Skip to content

Commit

Permalink
Matrices in instance
Browse files Browse the repository at this point in the history
  • Loading branch information
nanoqsh committed Jan 16, 2024
1 parent f42ca21 commit be66fac
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 125 deletions.
10 changes: 5 additions & 5 deletions dunge/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use {
context::Context,
sl::{ReadInstance, Ret},
state::State,
types::{self, VectorType},
types::{self, ValueType, VectorType},
uniform::{self, Value},
Instance,
},
Expand All @@ -17,15 +17,15 @@ pub use dunge_shader::instance::Projection;
///
/// The trait is sealed because the derive macro relies on no new types being used.
pub trait MemberProjection: private::Sealed {
const TYPE: VectorType;
const TYPE: ValueType;
type Field;
fn member_projection(id: u32) -> Self::Field;
}

impl private::Sealed for Row<[f32; 2]> {}

impl MemberProjection for Row<[f32; 2]> {
const TYPE: VectorType = VectorType::Vec2f;
const TYPE: ValueType = ValueType::Vector(VectorType::Vec2f);
type Field = Ret<ReadInstance, types::Vec2<f32>>;

fn member_projection(id: u32) -> Self::Field {
Expand All @@ -36,7 +36,7 @@ impl MemberProjection for Row<[f32; 2]> {
impl private::Sealed for Row<[f32; 3]> {}

impl MemberProjection for Row<[f32; 3]> {
const TYPE: VectorType = VectorType::Vec3f;
const TYPE: ValueType = ValueType::Vector(VectorType::Vec3f);
type Field = Ret<ReadInstance, types::Vec3<f32>>;

fn member_projection(id: u32) -> Self::Field {
Expand All @@ -47,7 +47,7 @@ impl MemberProjection for Row<[f32; 3]> {
impl private::Sealed for Row<[f32; 4]> {}

impl MemberProjection for Row<[f32; 4]> {
const TYPE: VectorType = VectorType::Vec4f;
const TYPE: ValueType = ValueType::Vector(VectorType::Vec4f);
type Field = Ret<ReadInstance, types::Vec4<f32>>;

fn member_projection(id: u32) -> Self::Field {
Expand Down
127 changes: 73 additions & 54 deletions dunge/src/shader.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use {
crate::{
bind::TypedGroup,
sl::{InputInfo, InstInfo, IntoModule, Module, Stages, VertInfo},
sl::{InputInfo, IntoModule, Module, Stages},
state::State,
types::{MemberType, VectorType},
types::{MemberType, ScalarType, ValueType, VectorType},
},
std::{cell::Cell, marker::PhantomData},
wgpu::{
BufferAddress, PipelineLayout, ShaderModule, VertexAttribute, VertexBufferLayout,
VertexStepMode,
VertexFormat, VertexStepMode,
},
};

Expand Down Expand Up @@ -167,60 +167,28 @@ impl Inner {
state.device().create_pipeline_layout(&desc)
};

let to_format = |vecty| match vecty {
VectorType::Vec2f => VertexFormat::Float32x2,
VectorType::Vec3f => VertexFormat::Float32x3,
VectorType::Vec4f => VertexFormat::Float32x4,
VectorType::Vec2u => VertexFormat::Uint32x2,
VectorType::Vec3u => VertexFormat::Uint32x3,
VectorType::Vec4u => VertexFormat::Uint32x4,
VectorType::Vec2i => VertexFormat::Sint32x2,
VectorType::Vec3i => VertexFormat::Sint32x3,
VectorType::Vec4i => VertexFormat::Sint32x4,
let location = Cell::default();
let next_location = || {
let current = location.get();
location.set(current + 1);
current
};

let next_location = {
let location = Cell::default();
move || {
let current = location.get();
location.set(current + 1);
current
}
};

let vert = |info: VertInfo| {
let make_attr = || {
let mut offset = 0;
let attr = |vecty| {
let format = to_format(vecty);
let attr = VertexAttribute {
format,
offset,
shader_location: next_location(),
move |ty, attrs: &mut Vec<_>| {
let mut f = |format| {
let attr = VertexAttribute {
format,
offset,
shader_location: next_location(),
};

offset += format.size();
attrs.push(attr);
};

offset += format.size();
attr
};

Vertex {
array_stride: info.size as BufferAddress,
step_mode: VertexStepMode::Vertex,
attributes: info.def.into_iter().map(attr).collect(),
}
};

let inst = |info: InstInfo| {
let format = to_format(info.vecty);
let attr = VertexAttribute {
format,
offset: 0,
shader_location: next_location(),
};

Vertex {
array_stride: format.size(),
step_mode: VertexStepMode::Instance,
attributes: Box::from([attr]),
to_format(ty, &mut f);
}
};

Expand All @@ -235,15 +203,39 @@ impl Inner {
match input {
InputInfo::Vert(v) => {
slots.vertex = vertex.len() as u32;
vertex.push(vert(v));

let vert = {
let mut attr = make_attr();
let mut attrs = vec![];
for vecty in v.def {
attr(ValueType::Vector(vecty), &mut attrs);
}

Vertex {
array_stride: v.size as BufferAddress,
step_mode: VertexStepMode::Vertex,
attributes: attrs.into(),
}
};

vertex.push(vert);
}
InputInfo::Inst(i) => {
if set_instance {
slots.instance = vertex.len() as u32;
set_instance = false;
}

vertex.push(inst(i));
let mut attr = make_attr();
let mut attrs = vec![];
attr(i.ty, &mut attrs);
let vert = Vertex {
array_stride: attrs.iter().map(|attr| attr.format.size()).sum(),
step_mode: VertexStepMode::Instance,
attributes: attrs.into(),
};

vertex.push(vert);
}
InputInfo::Index => {}
}
Expand All @@ -259,3 +251,30 @@ impl Inner {
}
}
}

fn to_format<F>(ty: ValueType, f: &mut F)
where
F: FnMut(VertexFormat),
{
match ty {
ValueType::Scalar(ScalarType::Float) => f(VertexFormat::Float32),
ValueType::Scalar(ScalarType::Sint) => f(VertexFormat::Sint32),
ValueType::Scalar(ScalarType::Uint) | ValueType::Scalar(ScalarType::Bool) => {
f(VertexFormat::Uint32);
}
ValueType::Vector(VectorType::Vec2f) => f(VertexFormat::Float32x2),
ValueType::Vector(VectorType::Vec3f) => f(VertexFormat::Float32x3),
ValueType::Vector(VectorType::Vec4f) => f(VertexFormat::Float32x4),
ValueType::Vector(VectorType::Vec2u) => f(VertexFormat::Uint32x2),
ValueType::Vector(VectorType::Vec3u) => f(VertexFormat::Uint32x3),
ValueType::Vector(VectorType::Vec4u) => f(VertexFormat::Uint32x4),
ValueType::Vector(VectorType::Vec2i) => f(VertexFormat::Sint32x2),
ValueType::Vector(VectorType::Vec3i) => f(VertexFormat::Sint32x3),
ValueType::Vector(VectorType::Vec4i) => f(VertexFormat::Sint32x4),
ValueType::Matrix(mat) => {
for _ in 0..mat.dims() {
to_format(ValueType::Vector(mat.vector_type()), f);
}
}
}
}
6 changes: 3 additions & 3 deletions dunge_macros/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub(crate) fn derive(input: DeriveInput) -> TokenStream {
quote::quote! {
impl ::dunge::Instance for #name {
type Projection = #projection_name;
const DEF: ::dunge::sl::Define<::dunge::types::VectorType> = ::dunge::sl::Define::new(&[
const DEF: ::dunge::sl::Define<::dunge::types::ValueType> = ::dunge::sl::Define::new(&[
#(#instance_types),*,
]);
}
Expand Down Expand Up @@ -121,7 +121,7 @@ mod tests {
let expected = quote::quote! {
impl ::dunge::Instance for Transform {
type Projection = TransformProjection;
const DEF: ::dunge::sl::Define<::dunge::types::VectorType> = ::dunge::sl::Define::new(&[
const DEF: ::dunge::sl::Define<::dunge::types::ValueType> = ::dunge::sl::Define::new(&[
<Row<[f32; 2]> as ::dunge::instance::MemberProjection>::TYPE,
<Row<[f32; 3]> as ::dunge::instance::MemberProjection>::TYPE,
]);
Expand Down Expand Up @@ -163,7 +163,7 @@ mod tests {
let expected = quote::quote! {
impl ::dunge::Instance for Transform {
type Projection = TransformProjection;
const DEF: ::dunge::sl::Define<::dunge::types::VectorType> = ::dunge::sl::Define::new(&[
const DEF: ::dunge::sl::Define<::dunge::types::ValueType> = ::dunge::sl::Define::new(&[
<Row<[f32; 2]> as ::dunge::instance::MemberProjection>::TYPE,
<Row<[f32; 3]> as ::dunge::instance::MemberProjection>::TYPE,
]);
Expand Down
12 changes: 6 additions & 6 deletions dunge_shader/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use {
group::{self, Group},
instance::{self, Instance},
ret::Ret,
types::{MemberType, VectorType},
types::{MemberType, ValueType, VectorType},
vertex::{self, Vertex},
},
std::{any::TypeId, mem, ops},
Expand Down Expand Up @@ -51,7 +51,7 @@ pub struct VertInfo {
#[doc(hidden)]
#[derive(Clone, Copy)]
pub struct InstInfo {
pub vecty: VectorType,
pub ty: ValueType,
}

pub(crate) struct GroupEntry {
Expand Down Expand Up @@ -115,10 +115,10 @@ impl Context {
id
}

fn add_instance(&mut self, vec: VectorType) -> u32 {
fn add_instance(&mut self, ty: ValueType) -> u32 {
countdown(&mut self.limits.insts, "too many instances in the shader");
let id = self.inputs.len() as u32;
let info = InstInfo { vecty: vec };
let info = InstInfo { ty };
self.inputs.push(InputInfo::Inst(info));
id
}
Expand Down Expand Up @@ -230,8 +230,8 @@ where

fn from_context_input(cx: &mut Context) -> Self {
let mut id = None;
for vec in I::DEF {
id.get_or_insert(cx.add_instance(vec));
for ty in I::DEF {
id.get_or_insert(cx.add_instance(ty));
}

let id = id.expect("the instance must have at least one field");
Expand Down
Loading

0 comments on commit be66fac

Please sign in to comment.