From 31799cae05e621521e06a6d7f840a0d490c439af Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sun, 29 Oct 2023 21:01:58 -0400 Subject: [PATCH] Some code cleaup of the renderer file --- examples/testbed/src/main.rs | 2 +- src/render/mod.rs | 3 +- src/render/renderer.rs | 108 ++----------------------- src/render/transform_buffer_storage.rs | 103 +++++++++++++++++++++++ 4 files changed, 111 insertions(+), 105 deletions(-) create mode 100644 src/render/transform_buffer_storage.rs diff --git a/examples/testbed/src/main.rs b/examples/testbed/src/main.rs index af37fa4..6324c05 100644 --- a/examples/testbed/src/main.rs +++ b/examples/testbed/src/main.rs @@ -120,7 +120,7 @@ async fn main() { game.world().insert_resource(TpsAccumulator(0.0)); let mut sys = BatchedSystem::new(); - sys.with_criteria(FixedTimestep::new(60)); + sys.with_criteria(FixedTimestep::new(30)); sys.with_system(spin_system); sys.with_system(fps_system); diff --git a/src/render/mod.rs b/src/render/mod.rs index 881372a..e6fe716 100755 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -9,4 +9,5 @@ pub mod texture; pub mod shader_loader; pub mod material; pub mod camera; -pub mod window; \ No newline at end of file +pub mod window; +pub mod transform_buffer_storage; \ No newline at end of file diff --git a/src/render/renderer.rs b/src/render/renderer.rs index 6092997..5d67f97 100755 --- a/src/render/renderer.rs +++ b/src/render/renderer.rs @@ -20,6 +20,7 @@ use crate::math::Transform; use super::camera::RenderCamera; use super::desc_buf_lay::DescVertexBufferLayout; use super::texture::RenderTexture; +use super::transform_buffer_storage::{TransformBufferIndices, TransformBuffers}; use super::vertex::Vertex; use super::{render_pipeline::FullRenderPipeline, render_buffer::BufferStorage, render_job::RenderJob}; @@ -34,7 +35,7 @@ pub trait Renderer { fn add_render_pipeline(&mut self, shader_id: u64, pipeline: Arc); } -struct RenderBufferStorage { +struct MeshBufferStorage { buffer_vertex: BufferStorage, buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>, @@ -47,105 +48,6 @@ struct RenderBufferStorage { transform_index: TransformBufferIndices, } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -struct TransformBufferIndices { - buffer_index: usize, - transform_index: usize, -} - -struct TransformBuffers { - //transform_layout: wgpu::BindGroupLayout, - /// A vector storing the EntityId and - just_updated: HashMap, - not_updated: HashMap, - dead_indices: VecDeque, - next_indices: TransformBufferIndices, - /// (transform count, buffer, bindgroup) - buffer_bindgroups: Vec<(usize, wgpu::Buffer, wgpu::BindGroup)>, - /// The max amount of transforms in a buffer - max_transform_count: usize, -} - -impl TransformBuffers { - /// Update an entity's buffer with the new transform. Will panic if the entity isn't stored - fn update_entity(&mut self, queue: &wgpu::Queue, limits: &Limits, entity: EntityId, transform: glam::Mat4) -> TransformBufferIndices { - let indices = self.not_updated.remove(&entity) - .or_else(|| self.just_updated.remove(&entity)) - .expect("Use 'insert_entity' for new entities"); - self.just_updated.insert(entity, indices); - - let (_, buffer, _) = self.buffer_bindgroups.get(indices.buffer_index).unwrap(); - queue.write_buffer(buffer, indices.transform_index as u64 * limits.min_uniform_buffer_offset_alignment as u64, bytemuck::bytes_of(&transform)); - indices - } - - /// Insert a new entity into the buffer, returns where it was stored. - fn insert_entity(&mut self, queue: &wgpu::Queue, limits: &Limits, entity: EntityId, transform: glam::Mat4) -> TransformBufferIndices { - // get a dead index, or create a new one - let (indices, buffer) = if let Some(index) = self.dead_indices.pop_front() { - let (_, buffer, _) = self.buffer_bindgroups.get(index.buffer_index).unwrap(); - (index, buffer) - } else { - let indices = &mut self.next_indices; - let this_idx = *indices; - let (count, buffer, _) = self.buffer_bindgroups.get_mut(indices.buffer_index).unwrap(); - - if *count >= self.max_transform_count { - panic!("Transform buffer is filled and 'next_indices' was not incremented! Was a new buffer created?"); - } - - *count += 1; - indices.transform_index += 1; - - (this_idx, &*buffer) - }; - - queue.write_buffer(buffer, Self::get_offset_for(limits, indices), bytemuck::bytes_of(&transform)); - - self.just_updated.insert(entity, indices); - indices - } - - /// Update or insert an entities transform - fn update_or_insert(&mut self, queue: &wgpu::Queue, limits: &Limits, entity: EntityId, transform_fn: TFn) -> TransformBufferIndices - where TFn: Fn() -> glam::Mat4 - { - if self.contains(entity) { - self.update_entity(queue, limits, entity, transform_fn()) - } else { - self.insert_entity(queue, limits, entity, transform_fn()) - } - } - - /// Returns true if the entity's transform is stored (does not mean its up-to-date). - fn contains(&self, entity: EntityId) -> bool { - self.not_updated.contains_key(&entity) || self.just_updated.contains_key(&entity) - } - - /// Collect the dead entities, mark entities and not updated for next updates. - fn tick(&mut self) { - // take the dead entities, these were ones that were not updated this tick - let dead: VecDeque = self.not_updated.values().copied().collect(); - self.dead_indices = dead; - - self.not_updated = self.just_updated.clone(); - self.just_updated.clear(); - } - - fn get_offset_for(limits: &Limits, indices: TransformBufferIndices) -> u64 { - indices.transform_index as u64 * limits.min_uniform_buffer_offset_alignment as u64 - } - - /// Returns whether or not the transform buffers should be expanded - fn should_expand(&self) -> bool { - if let Some(( count, _, _ )) = self.buffer_bindgroups.last() { - *count >= self.max_transform_count - } else { - true - } - } -} - pub struct BasicRenderer { pub surface: wgpu::Surface, pub device: wgpu::Device, @@ -159,7 +61,7 @@ pub struct BasicRenderer { pub render_pipelines: HashMap>, pub render_jobs: VecDeque, - mesh_buffers: HashMap, // TODO: clean up left over buffers from deleted entities/components + mesh_buffers: HashMap, // TODO: clean up left over buffers from deleted entities/components entity_meshes: HashMap, transform_buffers: TransformBuffers, @@ -506,7 +408,7 @@ impl BasicRenderer { ( vertex_buffer, indices ) } - fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> RenderBufferStorage { + fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> MeshBufferStorage { let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh); let diffuse_bindgroup = if let Some(model_texture) = &mesh.material().base_color_texture { @@ -535,7 +437,7 @@ impl BasicRenderer { None }; - RenderBufferStorage { + MeshBufferStorage { buffer_vertex: vertex_buffer, buffer_indices, render_texture: None, diff --git a/src/render/transform_buffer_storage.rs b/src/render/transform_buffer_storage.rs new file mode 100644 index 0000000..1156bfd --- /dev/null +++ b/src/render/transform_buffer_storage.rs @@ -0,0 +1,103 @@ +use std::collections::{VecDeque, HashMap}; + +use edict::EntityId; +use wgpu::Limits; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub(crate) struct TransformBufferIndices { + pub buffer_index: usize, + pub transform_index: usize, +} + +pub(crate) struct TransformBuffers { + //transform_layout: wgpu::BindGroupLayout, + /// A vector storing the EntityId and + pub just_updated: HashMap, + pub not_updated: HashMap, + pub dead_indices: VecDeque, + pub next_indices: TransformBufferIndices, + /// (transform count, buffer, bindgroup) + pub buffer_bindgroups: Vec<(usize, wgpu::Buffer, wgpu::BindGroup)>, + /// The max amount of transforms in a buffer + pub max_transform_count: usize, +} + +impl TransformBuffers { + /// Update an entity's buffer with the new transform. Will panic if the entity isn't stored + pub fn update_entity(&mut self, queue: &wgpu::Queue, limits: &Limits, entity: EntityId, transform: glam::Mat4) -> TransformBufferIndices { + let indices = self.not_updated.remove(&entity) + .or_else(|| self.just_updated.remove(&entity)) + .expect("Use 'insert_entity' for new entities"); + self.just_updated.insert(entity, indices); + + let (_, buffer, _) = self.buffer_bindgroups.get(indices.buffer_index).unwrap(); + queue.write_buffer(buffer, indices.transform_index as u64 * limits.min_uniform_buffer_offset_alignment as u64, bytemuck::bytes_of(&transform)); + indices + } + + /// Insert a new entity into the buffer, returns where it was stored. + pub fn insert_entity(&mut self, queue: &wgpu::Queue, limits: &Limits, entity: EntityId, transform: glam::Mat4) -> TransformBufferIndices { + // get a dead index, or create a new one + let (indices, buffer) = if let Some(index) = self.dead_indices.pop_front() { + let (_, buffer, _) = self.buffer_bindgroups.get(index.buffer_index).unwrap(); + (index, buffer) + } else { + let indices = &mut self.next_indices; + let this_idx = *indices; + let (count, buffer, _) = self.buffer_bindgroups.get_mut(indices.buffer_index).unwrap(); + + if *count >= self.max_transform_count { + panic!("Transform buffer is filled and 'next_indices' was not incremented! Was a new buffer created?"); + } + + *count += 1; + indices.transform_index += 1; + + (this_idx, &*buffer) + }; + + queue.write_buffer(buffer, Self::get_offset_for(limits, indices), bytemuck::bytes_of(&transform)); + + self.just_updated.insert(entity, indices); + indices + } + + /// Update or insert an entities transform + pub fn update_or_insert(&mut self, queue: &wgpu::Queue, limits: &Limits, entity: EntityId, transform_fn: TFn) -> TransformBufferIndices + where TFn: Fn() -> glam::Mat4 + { + if self.contains(entity) { + self.update_entity(queue, limits, entity, transform_fn()) + } else { + self.insert_entity(queue, limits, entity, transform_fn()) + } + } + + /// Returns true if the entity's transform is stored (does not mean its up-to-date). + pub fn contains(&self, entity: EntityId) -> bool { + self.not_updated.contains_key(&entity) || self.just_updated.contains_key(&entity) + } + + /// Collect the dead entities, mark entities and not updated for next updates. + pub fn tick(&mut self) { + // take the dead entities, these were ones that were not updated this tick + let dead: VecDeque = self.not_updated.values().copied().collect(); + self.dead_indices = dead; + + self.not_updated = self.just_updated.clone(); + self.just_updated.clear(); + } + + pub fn get_offset_for(limits: &Limits, indices: TransformBufferIndices) -> u64 { + indices.transform_index as u64 * limits.min_uniform_buffer_offset_alignment as u64 + } + + /// Returns whether or not the transform buffers should be expanded + pub fn should_expand(&self) -> bool { + if let Some(( count, _, _ )) = self.buffer_bindgroups.last() { + *count >= self.max_transform_count + } else { + true + } + } +} \ No newline at end of file