Skip to content

Commit

Permalink
Instance
Browse files Browse the repository at this point in the history
  • Loading branch information
nanoqsh committed Jan 13, 2024
1 parent 7e7d08c commit 02a7247
Show file tree
Hide file tree
Showing 16 changed files with 381 additions and 83 deletions.
10 changes: 9 additions & 1 deletion dunge/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ use {
shader::Shader,
sl::IntoModule,
state::{Render, State},
table::{self, Table},
texture::{
self, CopyBuffer, CopyBufferView, DrawTexture, Filter, Make, MapResult, Mapped, Sampler,
},
uniform::{Uniform, Value},
Vertex,
Instance, Vertex,
},
std::{error, fmt, future::IntoFuture, sync::Arc},
};
Expand Down Expand Up @@ -58,6 +59,13 @@ impl Context {
Mesh::new(&self.0, data)
}

pub fn make_table<I>(&self, data: table::Data<I>) -> Table<I>
where
I: Instance,
{
Table::new(&self.0, data)
}

pub fn make_texture<M>(&self, data: M) -> M::Out
where
M: Make,
Expand Down
3 changes: 1 addition & 2 deletions dunge/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ pub enum Format {
impl Format {
pub(crate) const fn bytes(self) -> u32 {
match self {
Self::RgbAlpha => 4,
Self::BgrAlpha => 4,
Self::RgbAlpha | Self::BgrAlpha => 4,
}
}

Expand Down
2 changes: 1 addition & 1 deletion dunge/src/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl<V> MemberProjection for &Uniform<V>
where
V: Value,
{
const TYPE: MemberType = V::TYPE;
const TYPE: MemberType = MemberType::from_value(V::TYPE);
type Field = Ret<ReadGlobal, V::Type>;

fn member_projection(id: u32, binding: u32, out: GlobalOut) -> Self::Field {
Expand Down
84 changes: 64 additions & 20 deletions dunge/src/layer.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
use crate::table::Table;

use {
crate::{bind::Binding, format::Format, mesh::Mesh, shader::Shader, state::State},
crate::{
bind::Binding,
format::Format,
mesh::Mesh,
shader::{Shader, Slots},
state::State,
},
std::{iter, marker::PhantomData},
wgpu::{RenderPass, RenderPipeline},
};

pub struct SetLayer<'p, V> {
pub struct SetLayer<'p, V, I> {
shader_id: usize,
no_bindings: bool,
slots: Slots,
pass: RenderPass<'p>,
vert: PhantomData<V>,
ty: PhantomData<(V, I)>,
}

impl<'p, V> SetLayer<'p, V> {
pub fn bind<B>(&mut self, bind: &'p B) -> BoundLayer<'_, 'p, V>
impl<'p, V, I> SetLayer<'p, V, I> {
pub fn bind<B>(&mut self, bind: &'p B) -> SetBinding<'_, 'p, V, I>
where
B: Binding,
{
let bind = bind.binding();

assert!(
self.shader_id == bind.shader_id,
"the binding doesn't belong to this shader",
Expand All @@ -27,42 +35,76 @@ impl<'p, V> SetLayer<'p, V> {
self.pass.set_bind_group(id, group, &[]);
}

BoundLayer::new(&mut self.pass)
SetBinding::new(self.slots, &mut self.pass)
}

pub fn bind_empty(&mut self) -> BoundLayer<'_, 'p, V> {
pub fn bind_empty(&mut self) -> SetBinding<'_, 'p, V, I> {
assert!(self.no_bindings, "ths shader has any bindings");
BoundLayer::new(&mut self.pass)
SetBinding::new(self.slots, &mut self.pass)
}
}

pub struct BoundLayer<'s, 'p, V> {
pub struct SetBinding<'s, 'p, V, I> {
slots: Slots,
pass: &'s mut RenderPass<'p>,
vert: PhantomData<V>,
ty: PhantomData<(V, I)>,
}

impl<'s, 'p, V> BoundLayer<'s, 'p, V> {
fn new(pass: &'s mut RenderPass<'p>) -> Self {
impl<'s, 'p, V, I> SetBinding<'s, 'p, V, I> {
fn new(slots: Slots, pass: &'s mut RenderPass<'p>) -> Self {
Self {
slots,
pass,
vert: PhantomData,
ty: PhantomData,
}
}

pub fn instance(&'s mut self, table: &'p Table<I>) -> SetInstance<'s, 'p, V> {
table.set(self.pass, self.slots.instance);
SetInstance {
count: table.count(),
slots: self.slots,
pass: self.pass,
ty: PhantomData,
}
}
}

impl<'p, V> SetBinding<'_, 'p, V, ()> {
pub fn draw(&mut self, mesh: &'p Mesh<V>) {
mesh.draw(self.pass, 1);
mesh.draw(self.pass, self.slots.vertex, 1);
}
}

impl BoundLayer<'_, '_, ()> {
pub fn draw_triangles(&mut self, n: u32) {
self.pass.draw(0..n * 3, 0..1);
impl SetBinding<'_, '_, (), ()> {
pub fn draw_triangles(&mut self, count: u32) {
self.pass.draw(0..count * 3, 0..1);
}
}

pub struct SetInstance<'s, 'p, V> {
count: u32,
slots: Slots,
pass: &'s mut RenderPass<'p>,
ty: PhantomData<V>,
}

impl<'p, V> SetInstance<'_, 'p, V> {
pub fn draw(&mut self, mesh: &'p Mesh<V>) {
mesh.draw(self.pass, self.slots.vertex, self.count);
}
}

impl SetInstance<'_, '_, ()> {
pub fn draw_triangles(&mut self, count: u32) {
self.pass.draw(0..count * 3, 0..self.count);
}
}

pub struct Layer<V, I> {
shader_id: usize,
no_bindings: bool,
slots: Slots,
format: Format,
render: RenderPipeline,
ty: PhantomData<(V, I)>,
Expand Down Expand Up @@ -111,6 +153,7 @@ impl<V, I> Layer<V, I> {
Self {
shader_id: shader.id(),
no_bindings: shader.groups().is_empty(),
slots: shader.slots(),
format,
render,
ty: PhantomData,
Expand All @@ -121,13 +164,14 @@ impl<V, I> Layer<V, I> {
self.format
}

pub(crate) fn set<'p>(&'p self, mut pass: RenderPass<'p>) -> SetLayer<'p, V> {
pub(crate) fn set<'p>(&'p self, mut pass: RenderPass<'p>) -> SetLayer<'p, V, I> {
pass.set_pipeline(&self.render);
SetLayer {
shader_id: self.shader_id,
no_bindings: self.no_bindings,
slots: self.slots,
pass,
vert: PhantomData,
ty: PhantomData,
}
}
}
7 changes: 6 additions & 1 deletion dunge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod layer;
pub mod mesh;
pub mod shader;
pub mod state;
pub mod table;
pub mod texture;
pub mod uniform;
pub mod vertex;
Expand All @@ -25,9 +26,13 @@ pub mod window;
pub use {
crate::{init::context, state::Frame},
dunge_macros::{Group, Vertex},
dunge_shader::{group::Group, sl, types, vertex::Vertex},
dunge_shader::{group::Group, instance::Instance, sl, types, vertex::Vertex},
glam,
};

pub mod instance {
pub use dunge_shader::instance::Projection;
}

#[cfg(feature = "winit")]
pub use {crate::init::window, el::Control};
12 changes: 6 additions & 6 deletions dunge/src/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl<V> Mesh<V> {
let desc = BufferInitDescriptor {
label: None,
contents: vertex::verts_as_bytes(data.verts),
usage: BufferUsages::VERTEX | BufferUsages::COPY_DST,
usage: BufferUsages::VERTEX,
};

device.create_buffer_init(&desc)
Expand All @@ -122,7 +122,7 @@ impl<V> Mesh<V> {
let desc = BufferInitDescriptor {
label: None,
contents: bytemuck::cast_slice(indxs),
usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
usage: BufferUsages::INDEX,
};

device.create_buffer_init(&desc)
Expand All @@ -135,19 +135,19 @@ impl<V> Mesh<V> {
}
}

pub(crate) fn draw<'a>(&'a self, pass: &mut RenderPass<'a>, n: u32) {
pub(crate) fn draw<'a>(&'a self, pass: &mut RenderPass<'a>, slot: u32, count: u32) {
use wgpu::IndexFormat;

pass.set_vertex_buffer(0, self.verts.slice(..));
pass.set_vertex_buffer(slot, self.verts.slice(..));
match &self.indxs {
Some(indxs) => {
pass.set_index_buffer(indxs.slice(..), IndexFormat::Uint16);
let len = indxs.size() as u32 / mem::size_of::<u16>() as u32;
pass.draw_indexed(0..len, 0, 0..n);
pass.draw_indexed(0..len, 0, 0..count);
}
None => {
let len = self.verts.size() as u32 / mem::size_of::<V>() as u32;
pass.draw(0..len, 0..n);
pass.draw(0..len, 0..count);
}
}
}
Expand Down
54 changes: 44 additions & 10 deletions dunge/src/shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use {
types::{MemberType, VectorType},
},
std::{cell::Cell, marker::PhantomData},
wgpu::{BufferAddress, PipelineLayout, ShaderModule, VertexAttribute, VertexBufferLayout},
wgpu::{
BufferAddress, PipelineLayout, ShaderModule, VertexAttribute, VertexBufferLayout,
VertexStepMode,
},
};

pub struct Shader<V, I> {
Expand Down Expand Up @@ -40,32 +43,44 @@ impl<V, I> Shader<V, I> {
pub(crate) fn buffers(&self) -> Box<[VertexBufferLayout]> {
use wgpu::*;

fn layout(Vertex { size, attributes }: &Vertex) -> VertexBufferLayout {
fn layout(vert: &Vertex) -> VertexBufferLayout {
VertexBufferLayout {
array_stride: *size,
step_mode: VertexStepMode::Vertex,
attributes,
array_stride: vert.array_stride,
step_mode: vert.step_mode,
attributes: &vert.attributes,
}
}

self.inner.vertex.iter().map(layout).collect()
}

pub(crate) fn slots(&self) -> Slots {
self.inner.slots
}

pub(crate) fn groups(&self) -> &[TypedGroup] {
&self.inner.groups
}
}

struct Vertex {
size: BufferAddress,
array_stride: BufferAddress,
step_mode: VertexStepMode,
attributes: Box<[VertexAttribute]>,
}

#[derive(Clone, Copy)]
pub(crate) struct Slots {
pub vertex: u32,
pub instance: u32,
}

struct Inner {
id: usize,
module: ShaderModule,
layout: PipelineLayout,
vertex: Box<[Vertex]>,
slots: Slots,
groups: Box<[TypedGroup]>,
}

Expand Down Expand Up @@ -188,7 +203,8 @@ impl Inner {
};

Vertex {
size: info.size as BufferAddress,
array_stride: info.size as BufferAddress,
step_mode: VertexStepMode::Vertex,
attributes: info.def.into_iter().map(attr).collect(),
}
};
Expand All @@ -202,16 +218,33 @@ impl Inner {
};

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

let mut set_instance = true;
let mut slots = Slots {
vertex: 0,
instance: 0,
};

let mut vertex = Vec::with_capacity(cx.count_input());
for input in cx.input() {
match input {
InputInfo::Vert(v) => vertex.push(vert(v)),
InputInfo::Inst(i) => vertex.push(inst(i)),
InputInfo::Vert(v) => {
slots.vertex = vertex.len() as u32;
vertex.push(vert(v));
}
InputInfo::Inst(i) => {
if set_instance {
slots.instance = vertex.len() as u32;
set_instance = false;
}

vertex.push(inst(i));
}
InputInfo::Index => {}
}
}
Expand All @@ -221,6 +254,7 @@ impl Inner {
module,
layout,
vertex: Box::from(vertex),
slots,
groups,
}
}
Expand Down
2 changes: 1 addition & 1 deletion dunge/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl Frame<'_, '_> {
self.encoders.make(self.device, view)
}

pub fn layer<'p, V, I, O>(&'p mut self, layer: &'p Layer<V, I>, opts: O) -> SetLayer<'p, V>
pub fn layer<'p, V, I, O>(&'p mut self, layer: &'p Layer<V, I>, opts: O) -> SetLayer<'p, V, I>
where
O: Into<Options>,
{
Expand Down
Loading

0 comments on commit 02a7247

Please sign in to comment.