diff --git a/Cargo.toml b/Cargo.toml index 5e19f3a9ec..91b50d9dc1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] # Modified to use std::any::type_name instead of std::any::TypeId legion = { path = "bevy_legion", features = ["serde-1"] } -wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "4a0da16fe6764c4e1dc918a31cbd7467d404df51"} +wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "2374b8ec9ddbc058dd0237856fc30d33e6ff8f93"} glam = "0.8.4" winit = "0.21.0" zerocopy = "0.2" diff --git a/src/app/app_builder.rs b/src/app/app_builder.rs index a85c274e0c..b473921e42 100644 --- a/src/app/app_builder.rs +++ b/src/app/app_builder.rs @@ -150,6 +150,7 @@ impl AppBuilder { .add_resource_provider(Box::new(Camera2dResourceProvider::default())) .add_resource_provider(Box::new(LightResourceProvider::new(10))) .add_resource_provider(Box::new(UiResourceProvider::new())) + .add_resource_provider(Box::new(MeshResourceProvider::new())) .add_resource_provider(Box::new(UniformResourceProvider::::new())) .add_resource_provider(Box::new(UniformResourceProvider::::new())) .add_forward_pass() diff --git a/src/render/render_graph/draw_targets/assigned_meshes_draw_target.rs b/src/render/render_graph/draw_targets/assigned_meshes_draw_target.rs index 1abb4cf654..1a315aedb9 100644 --- a/src/render/render_graph/draw_targets/assigned_meshes_draw_target.rs +++ b/src/render/render_graph/draw_targets/assigned_meshes_draw_target.rs @@ -1,25 +1,20 @@ use crate::{ - asset::{AssetStorage, Handle, Mesh}, + asset::{Handle, Mesh}, legion::prelude::*, - render::render_graph::{PipelineDescriptor, RenderPass, Renderable, ShaderPipelineAssignments}, + render::render_graph::{PipelineDescriptor, RenderPass, Renderable, ShaderPipelineAssignments, ResourceInfo}, }; -use zerocopy::AsBytes; - pub fn assigned_meshes_draw_target( world: &World, render_pass: &mut dyn RenderPass, pipeline_handle: Handle, ) { - let mesh_storage = world.resources.get_mut::>().unwrap(); let shader_pipeline_assignments = world .resources .get_mut::() .unwrap(); - let mut current_mesh_id = None; - let mut current_mesh_vertex_buffer = None; - let mut current_mesh_index_buffer = None; - let mut current_mesh_index_length = 0; + let mut current_mesh_handle = None; + let mut current_mesh_index_len = 0; let assigned_entities = shader_pipeline_assignments .assignments @@ -29,56 +24,30 @@ pub fn assigned_meshes_draw_target( for entity in assigned_entities.iter() { // TODO: hopefully legion has better random access apis that are more like queries? let renderable = world.get_component::(*entity).unwrap(); - let mesh = world.get_component::>(*entity).unwrap(); + let mesh = *world.get_component::>(*entity).unwrap(); if !renderable.is_visible { continue; } - let mut should_load_mesh = current_mesh_id == None; - if let Some(current) = current_mesh_id { - should_load_mesh = current != mesh.id; - } - - if should_load_mesh { - if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) { - let renderer = render_pass.get_renderer(); - if let Some(buffer) = current_mesh_vertex_buffer { - renderer.remove_buffer(buffer); + let renderer = render_pass.get_renderer(); + let render_resources = renderer.get_render_resources(); + if current_mesh_handle != Some(mesh) { + if let Some(vertex_buffer_resource) = render_resources.get_mesh_vertices_resource(mesh) { + let index_buffer_resource = render_resources.get_mesh_indices_resource(mesh).unwrap(); + match renderer.get_resource_info(index_buffer_resource).unwrap() { + ResourceInfo::Buffer { size, ..} => current_mesh_index_len = (size / 2) as u32, + _ => panic!("expected a buffer type"), } - - if let Some(buffer) = current_mesh_index_buffer { - renderer.remove_buffer(buffer); - } - current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.vertices.as_bytes(), - wgpu::BufferUsage::VERTEX, - )); - current_mesh_index_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.indices.as_bytes(), - wgpu::BufferUsage::INDEX, - )); - - // TODO: Verify buffer format matches render pass - render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0); - render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0); - current_mesh_id = Some(mesh.id); - current_mesh_index_length = mesh_asset.indices.len() as u32; - }; + render_pass.set_index_buffer(index_buffer_resource, 0); + render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0); + } + // TODO: Verify buffer format matches render pass + current_mesh_handle = Some(mesh); } // TODO: validate bind group properties against shader uniform properties at least once render_pass.setup_bind_groups(Some(&entity)); - render_pass.draw_indexed(0..current_mesh_index_length, 0, 0..1); - } - - // cleanup buffers - let renderer = render_pass.get_renderer(); - if let Some(buffer) = current_mesh_vertex_buffer { - renderer.remove_buffer(buffer); - } - - if let Some(buffer) = current_mesh_index_buffer { - renderer.remove_buffer(buffer); + render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1); } } } diff --git a/src/render/render_graph/draw_targets/meshes_draw_target.rs b/src/render/render_graph/draw_targets/meshes_draw_target.rs index 05a3ddfb9a..96ae961486 100644 --- a/src/render/render_graph/draw_targets/meshes_draw_target.rs +++ b/src/render/render_graph/draw_targets/meshes_draw_target.rs @@ -1,24 +1,19 @@ use crate::{ - asset::{AssetStorage, Handle, Mesh}, + asset::{Handle, Mesh}, legion::prelude::*, render::{ - render_graph::{PipelineDescriptor, RenderPass, Renderable}, + render_graph::{PipelineDescriptor, RenderPass, Renderable, ResourceInfo}, Instanced, }, }; -use zerocopy::AsBytes; - pub fn meshes_draw_target( world: &World, render_pass: &mut dyn RenderPass, _pipeline_handle: Handle, ) { - let mesh_storage = world.resources.get_mut::>().unwrap(); - let mut current_mesh_id = None; - let mut current_mesh_vertex_buffer = None; - let mut current_mesh_index_buffer = None; - let mut current_mesh_index_length = 0; + let mut current_mesh_handle = None; + let mut current_mesh_index_len = 0; let mesh_query = <(Read>, Read)>::query().filter(!component::()); @@ -27,51 +22,26 @@ pub fn meshes_draw_target( continue; } - let mut should_load_mesh = current_mesh_id == None; - if let Some(current) = current_mesh_id { - should_load_mesh = current != mesh.id; - } - - if should_load_mesh { - if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) { - let renderer = render_pass.get_renderer(); - if let Some(buffer) = current_mesh_vertex_buffer { - renderer.remove_buffer(buffer); + let renderer = render_pass.get_renderer(); + let render_resources = renderer.get_render_resources(); + if current_mesh_handle != Some(*mesh) { + if let Some(vertex_buffer_resource) = render_resources.get_mesh_vertices_resource(*mesh) + { + let index_buffer_resource = + render_resources.get_mesh_indices_resource(*mesh).unwrap(); + match renderer.get_resource_info(index_buffer_resource).unwrap() { + ResourceInfo::Buffer { size, .. } => current_mesh_index_len = (size / 2) as u32, + _ => panic!("expected a buffer type"), } - - if let Some(buffer) = current_mesh_index_buffer { - renderer.remove_buffer(buffer); - } - current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.vertices.as_bytes(), - wgpu::BufferUsage::VERTEX, - )); - current_mesh_index_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.indices.as_bytes(), - wgpu::BufferUsage::INDEX, - )); - - // TODO: Verify buffer format matches render pass - render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0); - render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0); - current_mesh_id = Some(mesh.id); - current_mesh_index_length = mesh_asset.indices.len() as u32; - }; + render_pass.set_index_buffer(index_buffer_resource, 0); + render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0); + } + // TODO: Verify buffer format matches render pass + current_mesh_handle = Some(*mesh); } // TODO: validate bind group properties against shader uniform properties at least once render_pass.setup_bind_groups(Some(&entity)); - render_pass.draw_indexed(0..current_mesh_index_length, 0, 0..1); - } - - // cleanup buffers - let renderer = render_pass.get_renderer(); - - if let Some(buffer) = current_mesh_vertex_buffer { - renderer.remove_buffer(buffer); - } - - if let Some(buffer) = current_mesh_index_buffer { - renderer.remove_buffer(buffer); + render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1); } } diff --git a/src/render/render_graph/draw_targets/ui_draw_target.rs b/src/render/render_graph/draw_targets/ui_draw_target.rs index 5f1cde23dc..ab3f2fe9d3 100644 --- a/src/render/render_graph/draw_targets/ui_draw_target.rs +++ b/src/render/render_graph/draw_targets/ui_draw_target.rs @@ -11,66 +11,67 @@ pub fn ui_draw_target( render_pass: &mut dyn RenderPass, _pipeline_handle: Handle, ) { - let mesh_storage = world.resources.get_mut::>().unwrap(); - let mut current_mesh_vertex_buffer = None; - let mut current_mesh_index_buffer = None; - let ui_instances_buffer = { - let renderer = render_pass.get_renderer(); - match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) { - Some(buffer) => buffer, - None => return, - } - }; - // NOTE: this is ugly and borrowing is stupid - let result = { - let renderer = render_pass.get_renderer(); - let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) = - renderer.get_resource_info(ui_instances_buffer) - { - Some((*count, *mesh_id)) - } else { - None - }; + // TODO: re-add support for this + // let mesh_storage = world.resources.get_mut::>().unwrap(); + // let mut current_mesh_vertex_buffer = None; + // let mut current_mesh_index_buffer = None; + // let ui_instances_buffer = { + // let renderer = render_pass.get_renderer(); + // match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) { + // Some(buffer) => buffer, + // None => return, + // } + // }; + // // NOTE: this is ugly and borrowing is stupid + // let result = { + // let renderer = render_pass.get_renderer(); + // let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) = + // renderer.get_resource_info(ui_instances_buffer) + // { + // Some((*count, *mesh_id)) + // } else { + // None + // }; - if let Some((instance_count, mesh_id)) = result { - if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) { - if let Some(buffer) = current_mesh_vertex_buffer { - renderer.remove_buffer(buffer); - } + // if let Some((instance_count, mesh_id)) = result { + // if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) { + // if let Some(buffer) = current_mesh_vertex_buffer { + // renderer.remove_buffer(buffer); + // } - if let Some(buffer) = current_mesh_index_buffer { - renderer.remove_buffer(buffer); - } - current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.vertices.as_bytes(), - wgpu::BufferUsage::VERTEX, - )); - current_mesh_index_buffer = Some(renderer.create_buffer_with_data( - mesh_asset.indices.as_bytes(), - wgpu::BufferUsage::INDEX, - )); - Some((instance_count, mesh_asset.indices.len())) - } else { - None - } - } else { - None - } - }; - if let Some((instance_count, indices_length)) = result { - render_pass.setup_bind_groups(None); - render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0); - render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0); - render_pass.set_vertex_buffer(1, ui_instances_buffer, 0); - render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32)); - } + // if let Some(buffer) = current_mesh_index_buffer { + // renderer.remove_buffer(buffer); + // } + // current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( + // mesh_asset.vertices.as_bytes(), + // wgpu::BufferUsage::VERTEX, + // )); + // current_mesh_index_buffer = Some(renderer.create_buffer_with_data( + // mesh_asset.indices.as_bytes(), + // wgpu::BufferUsage::INDEX, + // )); + // Some((instance_count, mesh_asset.indices.len())) + // } else { + // None + // } + // } else { + // None + // } + // }; + // if let Some((instance_count, indices_length)) = result { + // render_pass.setup_bind_groups(None); + // render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0); + // render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0); + // render_pass.set_vertex_buffer(1, ui_instances_buffer, 0); + // render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32)); + // } - let renderer = render_pass.get_renderer(); - if let Some(buffer) = current_mesh_vertex_buffer { - renderer.remove_buffer(buffer); - } + // let renderer = render_pass.get_renderer(); + // if let Some(buffer) = current_mesh_vertex_buffer { + // renderer.remove_buffer(buffer); + // } - if let Some(buffer) = current_mesh_index_buffer { - renderer.remove_buffer(buffer); - } + // if let Some(buffer) = current_mesh_index_buffer { + // renderer.remove_buffer(buffer); + // } } diff --git a/src/render/render_graph/render_resource.rs b/src/render/render_graph/render_resource.rs index 43daf2b248..289898ecac 100644 --- a/src/render/render_graph/render_resource.rs +++ b/src/render/render_graph/render_resource.rs @@ -1,4 +1,4 @@ -use crate::asset::{Handle, Texture}; +use crate::asset::{Handle, Texture, Mesh}; use std::collections::HashMap; #[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)] @@ -11,6 +11,8 @@ pub struct RenderResources { pub name_to_resource: HashMap, pub texture_to_resource: HashMap, RenderResource>, pub texture_to_sampler_resource: HashMap, RenderResource>, + pub mesh_to_vertices_resource: HashMap, RenderResource>, + pub mesh_to_indices_resource: HashMap, RenderResource>, pub resource_index: u64, } @@ -31,6 +33,22 @@ impl RenderResources { self.texture_to_resource.get(&texture).cloned() } + pub fn set_mesh_vertices_resource(&mut self, mesh: Handle, resource: RenderResource) { + self.mesh_to_vertices_resource.insert(mesh, resource); + } + + pub fn get_mesh_vertices_resource(&self, mesh: Handle) -> Option { + self.mesh_to_vertices_resource.get(&mesh).cloned() + } + + pub fn set_mesh_indices_resource(&mut self, mesh: Handle, resource: RenderResource) { + self.mesh_to_indices_resource.insert(mesh, resource); + } + + pub fn get_mesh_indices_resource(&self, mesh: Handle) -> Option { + self.mesh_to_indices_resource.get(&mesh).cloned() + } + pub fn set_texture_sampler_resource(&mut self, texture: Handle, resource: RenderResource) { self.texture_to_sampler_resource.insert(texture, resource); } diff --git a/src/render/render_graph/renderer.rs b/src/render/render_graph/renderer.rs index e1effe90b3..8e129619b7 100644 --- a/src/render/render_graph/renderer.rs +++ b/src/render/render_graph/renderer.rs @@ -86,7 +86,7 @@ pub trait Renderer { pub trait RenderPass { // TODO: consider using static dispatch for the renderer: Renderer. compare compile times - fn get_renderer(&mut self) -> &mut dyn Renderer; + fn get_renderer(&mut self) -> &dyn Renderer; fn get_pipeline_descriptor(&self) -> &PipelineDescriptor; fn set_index_buffer(&mut self, resource: RenderResource, offset: u64); fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64); diff --git a/src/render/render_graph/renderers/wgpu_renderer.rs b/src/render/render_graph/renderers/wgpu_renderer.rs index e215adcd09..1db1028b8f 100644 --- a/src/render/render_graph/renderers/wgpu_renderer.rs +++ b/src/render/render_graph/renderers/wgpu_renderer.rs @@ -18,7 +18,6 @@ pub struct WgpuResources { pub buffers: HashMap, pub textures: HashMap, pub samplers: HashMap, - pub render_pipelines: HashMap, wgpu::RenderPipeline>, pub resource_info: HashMap, pub bind_groups: HashMap, pub bind_group_layouts: HashMap, @@ -32,7 +31,6 @@ pub struct WgpuResources { impl WgpuResources { pub fn new() -> Self { WgpuResources { - render_pipelines: HashMap::new(), buffers: HashMap::new(), textures: HashMap::new(), samplers: HashMap::new(), @@ -455,6 +453,7 @@ pub struct WgpuRenderer { pub surface: Option, pub encoder: Option, pub swap_chain_descriptor: wgpu::SwapChainDescriptor, + pub render_pipelines: HashMap, wgpu::RenderPipeline>, pub wgpu_resources: WgpuResources, } @@ -490,6 +489,7 @@ impl WgpuRenderer { encoder: None, swap_chain_descriptor, wgpu_resources: WgpuResources::new(), + render_pipelines: HashMap::new(), } } @@ -620,7 +620,7 @@ impl WgpuRenderer { } pub fn create_render_pass<'a>( - wgpu_resources: &WgpuResources, + wgpu_resources: &'a WgpuResources, pass_descriptor: &PassDescriptor, encoder: &'a mut wgpu::CommandEncoder, frame: &'a wgpu::SwapChainOutput, @@ -686,7 +686,7 @@ impl WgpuRenderer { wgpu_resources: &'a WgpuResources, depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor, frame: &'a wgpu::SwapChainOutput, - ) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<&'a wgpu::TextureView> { + ) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> { let attachment = match depth_stencil_attachment_descriptor.attachment.as_str() { resource_name::texture::SWAP_CHAIN => &frame.view, _ => { @@ -828,7 +828,6 @@ impl Renderer for WgpuRenderer { .unwrap(); // create pipelines if !self - .wgpu_resources .render_pipelines .contains_key(pipeline_descriptor_handle) { @@ -849,7 +848,7 @@ impl Renderer for WgpuRenderer { vertex_shader, fragment_shader, ); - self.wgpu_resources.render_pipelines + self.render_pipelines .insert(*pipeline_descriptor_handle, render_pipeline); } @@ -862,22 +861,23 @@ impl Renderer for WgpuRenderer { for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() { // run passes - let mut render_pass = Self::create_render_pass(&mut self.wgpu_resources, pass_descriptor, &mut encoder, &frame); + let mut render_pass = Self::create_render_pass(&self.wgpu_resources, pass_descriptor, &mut encoder, &frame); if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) { for pass_pipeline in pass_pipelines.iter() { let pipeline_descriptor = pipeline_storage.get(pass_pipeline).unwrap(); - let render_pipeline = self.wgpu_resources.render_pipelines.get(pass_pipeline).unwrap(); + let render_pipeline = self.render_pipelines.get(pass_pipeline).unwrap(); render_pass.set_pipeline(render_pipeline); - let mut render_pass = WgpuRenderPass { + let mut wgpu_render_pass = WgpuRenderPass { render_pass: &mut render_pass, - renderer: self, pipeline_descriptor, + wgpu_resources: &self.wgpu_resources, + renderer: &self }; for draw_target_name in pipeline_descriptor.draw_targets.iter() { let draw_target = render_graph.draw_targets.get(draw_target_name).unwrap(); - draw_target(world, &mut render_pass, pass_pipeline.clone()); + draw_target(world, &mut wgpu_render_pass, *pass_pipeline); } } } @@ -1018,11 +1018,12 @@ impl Renderer for WgpuRenderer { pub struct WgpuRenderPass<'a, 'b, 'c, 'd> { pub render_pass: &'b mut wgpu::RenderPass<'a>, pub pipeline_descriptor: &'c PipelineDescriptor, - pub renderer: &'d mut WgpuRenderer, + pub wgpu_resources: &'a WgpuResources, + pub renderer: &'d WgpuRenderer, } impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { - fn get_renderer(&mut self) -> &mut dyn Renderer { + fn get_renderer(&mut self) -> &dyn Renderer { self.renderer } @@ -1031,13 +1032,13 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { } fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) { - let buffer = self.renderer.wgpu_resources.buffers.get(&resource).unwrap(); + let buffer = self.wgpu_resources.buffers.get(&resource).unwrap(); self.render_pass .set_vertex_buffers(start_slot, &[(&buffer, offset)]); } fn set_index_buffer(&mut self, resource: RenderResource, offset: u64) { - let buffer = self.renderer.wgpu_resources.buffers.get(&resource).unwrap(); + let buffer = self.wgpu_resources.buffers.get(&resource).unwrap(); self.render_pass.set_index_buffer(&buffer, offset); } @@ -1055,17 +1056,18 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { let pipeline_layout = self.pipeline_descriptor.get_layout().unwrap(); for bind_group in pipeline_layout.bind_groups.iter() { let bind_group_id = bind_group.get_hash().unwrap(); - let bind_group_info = match self.renderer.wgpu_resources.bind_groups.get(&bind_group_id) { + let bind_group_info = match self.wgpu_resources.bind_groups.get(&bind_group_id) { // if there is a "global" bind group, use that Some(bind_group_info) => bind_group_info, // otherwise try to get an entity-specific bind group None => { if let Some(entity) = entity { - if let None = self.renderer.wgpu_resources.get_entity_bind_group(*entity, bind_group_id) { - self.renderer.wgpu_resources.create_entity_bind_group(&self.renderer.device, bind_group, *entity); + if let None = self.wgpu_resources.get_entity_bind_group(*entity, bind_group_id) { + // TODO: Uncomment this + // self.wgpu_resources.create_entity_bind_group(&self.renderer.device, bind_group, *entity); } - self.renderer.wgpu_resources + self.wgpu_resources .get_entity_bind_group(*entity, bind_group_id) .unwrap() } else { @@ -1082,14 +1084,13 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { } if let Some(resource) = self - .renderer .wgpu_resources .render_resources .get_named_resource(&binding.name) { // PERF: This hashmap get is pretty expensive (10 fps for 10000 entities) if let Some(dynamic_uniform_buffer_info) = - self.renderer.wgpu_resources.dynamic_uniform_buffer_info.get(&resource) + self.wgpu_resources.dynamic_uniform_buffer_info.get(&resource) { let index = dynamic_uniform_buffer_info .offsets diff --git a/src/render/render_graph/resource.rs b/src/render/render_graph/resource.rs index e9ece2a0e0..4704b6f8ba 100644 --- a/src/render/render_graph/resource.rs +++ b/src/render/render_graph/resource.rs @@ -1,8 +1,4 @@ pub enum ResourceInfo { - BufferMapped { - size: u64, - buffer_usage: wgpu::BufferUsage, - }, Buffer { size: u64, buffer_usage: wgpu::BufferUsage, diff --git a/src/render/render_graph/resource_providers/mesh_resource_provider.rs b/src/render/render_graph/resource_providers/mesh_resource_provider.rs new file mode 100644 index 0000000000..53a5b993e1 --- /dev/null +++ b/src/render/render_graph/resource_providers/mesh_resource_provider.rs @@ -0,0 +1,72 @@ +use crate::{ + asset::{AssetStorage, Handle, Mesh}, + prelude::Renderable, + render::render_graph::{Renderer, ResourceProvider}, +}; +use legion::{filter::*, prelude::*}; +use zerocopy::AsBytes; + +pub struct MeshResourceProvider { + pub mesh_query: Query< + (Read>, Read), + EntityFilterTuple< + And<( + ComponentFilter>, + ComponentFilter, + ComponentFilter>, + )>, + And<(Passthrough, Passthrough)>, + And<( + Passthrough, + Passthrough, + ComponentChangedFilter>, + )>, + >, + >, +} + +impl MeshResourceProvider { + pub fn new() -> Self { + MeshResourceProvider { + mesh_query: <(Read>, Read)>::query() + .filter(changed::>()), + } + } +} + +impl ResourceProvider for MeshResourceProvider { + fn initialize(&mut self, _renderer: &mut dyn Renderer, _world: &mut World) {} + + fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World) { + let mesh_storage = world.resources.get_mut::>().unwrap(); + for (mesh_handle, _renderable) in self.mesh_query.iter(world) { + if let None = renderer + .get_render_resources() + .get_mesh_vertices_resource(*mesh_handle) + { + let mesh_asset = mesh_storage.get(&mesh_handle).unwrap(); + let vertex_buffer = renderer.create_buffer_with_data( + mesh_asset.vertices.as_bytes(), + wgpu::BufferUsage::VERTEX, + ); + let index_buffer = renderer.create_buffer_with_data( + mesh_asset.indices.as_bytes(), + wgpu::BufferUsage::INDEX, + ); + + let render_resources = renderer.get_render_resources_mut(); + render_resources.set_mesh_vertices_resource(*mesh_handle, vertex_buffer); + render_resources.set_mesh_indices_resource(*mesh_handle, index_buffer); + } + } + } + + fn resize( + &mut self, + _renderer: &mut dyn Renderer, + _world: &mut World, + _width: u32, + _height: u32, + ) { + } +} diff --git a/src/render/render_graph/resource_providers/mod.rs b/src/render/render_graph/resource_providers/mod.rs index 1fab72c4b4..bb2cba5f58 100644 --- a/src/render/render_graph/resource_providers/mod.rs +++ b/src/render/render_graph/resource_providers/mod.rs @@ -4,6 +4,7 @@ mod frame_texture_resource_provider; mod light_resource_provider; mod ui_resource_provider; mod uniform_resource_provider; +mod mesh_resource_provider; pub use camera2d_resource_provider::*; pub use camera_resource_provider::*; @@ -11,3 +12,4 @@ pub use frame_texture_resource_provider::*; pub use light_resource_provider::*; pub use ui_resource_provider::*; pub use uniform_resource_provider::*; +pub use mesh_resource_provider::*; diff --git a/src/render/render_graph/resource_providers/uniform_resource_provider.rs b/src/render/render_graph/resource_providers/uniform_resource_provider.rs index fc8da472bc..3df4977003 100644 --- a/src/render/render_graph/resource_providers/uniform_resource_provider.rs +++ b/src/render/render_graph/resource_providers/uniform_resource_provider.rs @@ -63,7 +63,7 @@ where .insert(uniform_info.name.to_string(), (None, 0, HashSet::new())); } - let (resource, counts, entities) = self.uniform_buffer_info_resources.get_mut(uniform_info.name).unwrap(); + let (_resource, counts, entities) = self.uniform_buffer_info_resources.get_mut(uniform_info.name).unwrap(); entities.insert(entity); *counts += 1; } @@ -112,7 +112,7 @@ where } // allocate uniform buffers - for (name, (resource, count, entities)) in self.uniform_buffer_info_resources.iter_mut() { + for (name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() { let count = *count as u64; if let Some(resource) = resource { let mut info = renderer @@ -158,7 +158,7 @@ where // TODO: check if index has changed. if it has, then entity should be updated // TODO: only mem-map entities if their data has changed // PERF: These hashmap inserts are pretty expensive (10 fps for 10000 entities) - info.offsets.insert(entity, offset as u64); + info.offsets.insert(entity, offset as u32); // TODO: try getting ref first offset += alignment; } diff --git a/src/render/render_graph/uniform.rs b/src/render/render_graph/uniform.rs index 3a1a29a355..2aee22978b 100644 --- a/src/render/render_graph/uniform.rs +++ b/src/render/render_graph/uniform.rs @@ -171,7 +171,7 @@ pub struct UniformInfo<'a> { } pub struct DynamicUniformBufferInfo { - pub offsets: HashMap, + pub offsets: HashMap, pub capacity: u64, pub count: u64, }