upgrade wgpu. work around new wgpu lifetimes (this was painful)
This commit is contained in:
		
							parent
							
								
									8beed27c0e
								
							
						
					
					
						commit
						85c880e754
					
				| @ -7,7 +7,7 @@ edition = "2018" | |||||||
| [dependencies] | [dependencies] | ||||||
| # Modified to use std::any::type_name instead of std::any::TypeId | # Modified to use std::any::type_name instead of std::any::TypeId | ||||||
| legion = { path = "bevy_legion", features = ["serde-1"] } | 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" | glam = "0.8.4" | ||||||
| winit = "0.21.0" | winit = "0.21.0" | ||||||
| zerocopy = "0.2" | zerocopy = "0.2" | ||||||
|  | |||||||
| @ -150,6 +150,7 @@ impl AppBuilder { | |||||||
|                 .add_resource_provider(Box::new(Camera2dResourceProvider::default())) |                 .add_resource_provider(Box::new(Camera2dResourceProvider::default())) | ||||||
|                 .add_resource_provider(Box::new(LightResourceProvider::new(10))) |                 .add_resource_provider(Box::new(LightResourceProvider::new(10))) | ||||||
|                 .add_resource_provider(Box::new(UiResourceProvider::new())) |                 .add_resource_provider(Box::new(UiResourceProvider::new())) | ||||||
|  |                 .add_resource_provider(Box::new(MeshResourceProvider::new())) | ||||||
|                 .add_resource_provider(Box::new(UniformResourceProvider::<StandardMaterial>::new())) |                 .add_resource_provider(Box::new(UniformResourceProvider::<StandardMaterial>::new())) | ||||||
|                 .add_resource_provider(Box::new(UniformResourceProvider::<LocalToWorld>::new())) |                 .add_resource_provider(Box::new(UniformResourceProvider::<LocalToWorld>::new())) | ||||||
|                 .add_forward_pass() |                 .add_forward_pass() | ||||||
|  | |||||||
| @ -1,25 +1,20 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{AssetStorage, Handle, Mesh}, |     asset::{Handle, Mesh}, | ||||||
|     legion::prelude::*, |     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( | pub fn assigned_meshes_draw_target( | ||||||
|     world: &World, |     world: &World, | ||||||
|     render_pass: &mut dyn RenderPass, |     render_pass: &mut dyn RenderPass, | ||||||
|     pipeline_handle: Handle<PipelineDescriptor>, |     pipeline_handle: Handle<PipelineDescriptor>, | ||||||
| ) { | ) { | ||||||
|     let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); |  | ||||||
|     let shader_pipeline_assignments = world |     let shader_pipeline_assignments = world | ||||||
|         .resources |         .resources | ||||||
|         .get_mut::<ShaderPipelineAssignments>() |         .get_mut::<ShaderPipelineAssignments>() | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
|     let mut current_mesh_id = None; |     let mut current_mesh_handle = None; | ||||||
|     let mut current_mesh_vertex_buffer = None; |     let mut current_mesh_index_len = 0; | ||||||
|     let mut current_mesh_index_buffer = None; |  | ||||||
|     let mut current_mesh_index_length = 0; |  | ||||||
| 
 | 
 | ||||||
|     let assigned_entities = shader_pipeline_assignments |     let assigned_entities = shader_pipeline_assignments | ||||||
|         .assignments |         .assignments | ||||||
| @ -29,56 +24,30 @@ pub fn assigned_meshes_draw_target( | |||||||
|         for entity in assigned_entities.iter() { |         for entity in assigned_entities.iter() { | ||||||
|             // TODO: hopefully legion has better random access apis that are more like queries?
 |             // TODO: hopefully legion has better random access apis that are more like queries?
 | ||||||
|             let renderable = world.get_component::<Renderable>(*entity).unwrap(); |             let renderable = world.get_component::<Renderable>(*entity).unwrap(); | ||||||
|             let mesh = world.get_component::<Handle<Mesh>>(*entity).unwrap(); |             let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap(); | ||||||
|             if !renderable.is_visible { |             if !renderable.is_visible { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             let mut should_load_mesh = current_mesh_id == None; |             let renderer = render_pass.get_renderer(); | ||||||
|             if let Some(current) = current_mesh_id { |             let render_resources = renderer.get_render_resources(); | ||||||
|                 should_load_mesh = current != mesh.id; |             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(); | ||||||
|             if should_load_mesh { |                     match renderer.get_resource_info(index_buffer_resource).unwrap() { | ||||||
|                 if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) { |                         ResourceInfo::Buffer { size, ..} => current_mesh_index_len = (size / 2) as u32, | ||||||
|                     let renderer = render_pass.get_renderer(); |                         _ => panic!("expected a buffer type"), | ||||||
|                     if let Some(buffer) = current_mesh_vertex_buffer { |  | ||||||
|                         renderer.remove_buffer(buffer); |  | ||||||
|                     } |                     } | ||||||
| 
 |                     render_pass.set_index_buffer(index_buffer_resource, 0); | ||||||
|                     if let Some(buffer) = current_mesh_index_buffer { |                     render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0); | ||||||
|                         renderer.remove_buffer(buffer); |                 } | ||||||
|                     } |                 // TODO: Verify buffer format matches render pass
 | ||||||
|                     current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( |                 current_mesh_handle = Some(mesh); | ||||||
|                         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; |  | ||||||
|                 }; |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // TODO: validate bind group properties against shader uniform properties at least once
 |             // TODO: validate bind group properties against shader uniform properties at least once
 | ||||||
|             render_pass.setup_bind_groups(Some(&entity)); |             render_pass.setup_bind_groups(Some(&entity)); | ||||||
|             render_pass.draw_indexed(0..current_mesh_index_length, 0, 0..1); |             render_pass.draw_indexed(0..current_mesh_index_len, 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); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,24 +1,19 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{AssetStorage, Handle, Mesh}, |     asset::{Handle, Mesh}, | ||||||
|     legion::prelude::*, |     legion::prelude::*, | ||||||
|     render::{ |     render::{ | ||||||
|         render_graph::{PipelineDescriptor, RenderPass, Renderable}, |         render_graph::{PipelineDescriptor, RenderPass, Renderable, ResourceInfo}, | ||||||
|         Instanced, |         Instanced, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use zerocopy::AsBytes; |  | ||||||
| 
 |  | ||||||
| pub fn meshes_draw_target( | pub fn meshes_draw_target( | ||||||
|     world: &World, |     world: &World, | ||||||
|     render_pass: &mut dyn RenderPass, |     render_pass: &mut dyn RenderPass, | ||||||
|     _pipeline_handle: Handle<PipelineDescriptor>, |     _pipeline_handle: Handle<PipelineDescriptor>, | ||||||
| ) { | ) { | ||||||
|     let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); |     let mut current_mesh_handle = None; | ||||||
|     let mut current_mesh_id = None; |     let mut current_mesh_index_len = 0; | ||||||
|     let mut current_mesh_vertex_buffer = None; |  | ||||||
|     let mut current_mesh_index_buffer = None; |  | ||||||
|     let mut current_mesh_index_length = 0; |  | ||||||
|     let mesh_query = |     let mesh_query = | ||||||
|         <(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(!component::<Instanced>()); |         <(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(!component::<Instanced>()); | ||||||
| 
 | 
 | ||||||
| @ -27,51 +22,26 @@ pub fn meshes_draw_target( | |||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let mut should_load_mesh = current_mesh_id == None; |         let renderer = render_pass.get_renderer(); | ||||||
|         if let Some(current) = current_mesh_id { |         let render_resources = renderer.get_render_resources(); | ||||||
|             should_load_mesh = current != mesh.id; |         if current_mesh_handle != Some(*mesh) { | ||||||
|         } |             if let Some(vertex_buffer_resource) = render_resources.get_mesh_vertices_resource(*mesh) | ||||||
| 
 |             { | ||||||
|         if should_load_mesh { |                 let index_buffer_resource = | ||||||
|             if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) { |                     render_resources.get_mesh_indices_resource(*mesh).unwrap(); | ||||||
|                 let renderer = render_pass.get_renderer(); |                 match renderer.get_resource_info(index_buffer_resource).unwrap() { | ||||||
|                 if let Some(buffer) = current_mesh_vertex_buffer { |                     ResourceInfo::Buffer { size, .. } => current_mesh_index_len = (size / 2) as u32, | ||||||
|                     renderer.remove_buffer(buffer); |                     _ => panic!("expected a buffer type"), | ||||||
|                 } |                 } | ||||||
| 
 |                 render_pass.set_index_buffer(index_buffer_resource, 0); | ||||||
|                 if let Some(buffer) = current_mesh_index_buffer { |                 render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0); | ||||||
|                     renderer.remove_buffer(buffer); |             } | ||||||
|                 } |             // TODO: Verify buffer format matches render pass
 | ||||||
|                 current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( |             current_mesh_handle = Some(*mesh); | ||||||
|                     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; |  | ||||||
|             }; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // TODO: validate bind group properties against shader uniform properties at least once
 |         // TODO: validate bind group properties against shader uniform properties at least once
 | ||||||
|         render_pass.setup_bind_groups(Some(&entity)); |         render_pass.setup_bind_groups(Some(&entity)); | ||||||
|         render_pass.draw_indexed(0..current_mesh_index_length, 0, 0..1); |         render_pass.draw_indexed(0..current_mesh_index_len, 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); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,66 +11,67 @@ pub fn ui_draw_target( | |||||||
|     render_pass: &mut dyn RenderPass, |     render_pass: &mut dyn RenderPass, | ||||||
|     _pipeline_handle: Handle<PipelineDescriptor>, |     _pipeline_handle: Handle<PipelineDescriptor>, | ||||||
| ) { | ) { | ||||||
|     let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); |     // TODO: re-add support for this
 | ||||||
|     let mut current_mesh_vertex_buffer = None; |     // let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
 | ||||||
|     let mut current_mesh_index_buffer = None; |     // let mut current_mesh_vertex_buffer = None;
 | ||||||
|     let ui_instances_buffer = { |     // let mut current_mesh_index_buffer = None;
 | ||||||
|         let renderer = render_pass.get_renderer(); |     // let ui_instances_buffer = {
 | ||||||
|         match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) { |     //     let renderer = render_pass.get_renderer();
 | ||||||
|             Some(buffer) => buffer, |     //     match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) {
 | ||||||
|             None => return, |     //         Some(buffer) => buffer,
 | ||||||
|         } |     //         None => return,
 | ||||||
|     }; |     //     }
 | ||||||
|     // NOTE: this is ugly and borrowing is stupid
 |     // };
 | ||||||
|     let result = { |     // // NOTE: this is ugly and borrowing is stupid
 | ||||||
|         let renderer = render_pass.get_renderer(); |     // let result = {
 | ||||||
|         let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) = |     //     let renderer = render_pass.get_renderer();
 | ||||||
|             renderer.get_resource_info(ui_instances_buffer) |     //     let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) =
 | ||||||
|         { |     //         renderer.get_resource_info(ui_instances_buffer)
 | ||||||
|             Some((*count, *mesh_id)) |     //     {
 | ||||||
|         } else { |     //         Some((*count, *mesh_id))
 | ||||||
|             None |     //     } else {
 | ||||||
|         }; |     //         None
 | ||||||
|  |     //     };
 | ||||||
| 
 | 
 | ||||||
|         if let Some((instance_count, mesh_id)) = result { |     //     if let Some((instance_count, mesh_id)) = result {
 | ||||||
|             if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) { |     //         if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) {
 | ||||||
|                 if let Some(buffer) = current_mesh_vertex_buffer { |     //             if let Some(buffer) = current_mesh_vertex_buffer {
 | ||||||
|                     renderer.remove_buffer(buffer); |     //                 renderer.remove_buffer(buffer);
 | ||||||
|                 } |     //             }
 | ||||||
| 
 | 
 | ||||||
|                 if let Some(buffer) = current_mesh_index_buffer { |     //             if let Some(buffer) = current_mesh_index_buffer {
 | ||||||
|                     renderer.remove_buffer(buffer); |     //                 renderer.remove_buffer(buffer);
 | ||||||
|                 } |     //             }
 | ||||||
|                 current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data( |     //             current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
 | ||||||
|                     mesh_asset.vertices.as_bytes(), |     //                 mesh_asset.vertices.as_bytes(),
 | ||||||
|                     wgpu::BufferUsage::VERTEX, |     //                 wgpu::BufferUsage::VERTEX,
 | ||||||
|                 )); |     //             ));
 | ||||||
|                 current_mesh_index_buffer = Some(renderer.create_buffer_with_data( |     //             current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
 | ||||||
|                     mesh_asset.indices.as_bytes(), |     //                 mesh_asset.indices.as_bytes(),
 | ||||||
|                     wgpu::BufferUsage::INDEX, |     //                 wgpu::BufferUsage::INDEX,
 | ||||||
|                 )); |     //             ));
 | ||||||
|                 Some((instance_count, mesh_asset.indices.len())) |     //             Some((instance_count, mesh_asset.indices.len()))
 | ||||||
|             } else { |     //         } else {
 | ||||||
|                 None |     //             None
 | ||||||
|             } |     //         }
 | ||||||
|         } else { |     //     } else {
 | ||||||
|             None |     //         None
 | ||||||
|         } |     //     }
 | ||||||
|     }; |     // };
 | ||||||
|     if let Some((instance_count, indices_length)) = result { |     // if let Some((instance_count, indices_length)) = result {
 | ||||||
|         render_pass.setup_bind_groups(None); |     //     render_pass.setup_bind_groups(None);
 | ||||||
|         render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0); |     //     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(0, current_mesh_vertex_buffer.unwrap(), 0);
 | ||||||
|         render_pass.set_vertex_buffer(1, ui_instances_buffer, 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)); |     //     render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32));
 | ||||||
|     } |     // }
 | ||||||
| 
 | 
 | ||||||
|     let renderer = render_pass.get_renderer(); |     // let renderer = render_pass.get_renderer();
 | ||||||
|     if let Some(buffer) = current_mesh_vertex_buffer { |     // if let Some(buffer) = current_mesh_vertex_buffer {
 | ||||||
|         renderer.remove_buffer(buffer); |     //     renderer.remove_buffer(buffer);
 | ||||||
|     } |     // }
 | ||||||
| 
 | 
 | ||||||
|     if let Some(buffer) = current_mesh_index_buffer { |     // if let Some(buffer) = current_mesh_index_buffer {
 | ||||||
|         renderer.remove_buffer(buffer); |     //     renderer.remove_buffer(buffer);
 | ||||||
|     } |     // }
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| use crate::asset::{Handle, Texture}; | use crate::asset::{Handle, Texture, Mesh}; | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| #[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)] | #[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)] | ||||||
| @ -11,6 +11,8 @@ pub struct RenderResources { | |||||||
|     pub name_to_resource: HashMap<String, RenderResource>, |     pub name_to_resource: HashMap<String, RenderResource>, | ||||||
|     pub texture_to_resource: HashMap<Handle<Texture>, RenderResource>, |     pub texture_to_resource: HashMap<Handle<Texture>, RenderResource>, | ||||||
|     pub texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>, |     pub texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>, | ||||||
|  |     pub mesh_to_vertices_resource: HashMap<Handle<Mesh>, RenderResource>, | ||||||
|  |     pub mesh_to_indices_resource: HashMap<Handle<Mesh>, RenderResource>, | ||||||
|     pub resource_index: u64, |     pub resource_index: u64, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -31,6 +33,22 @@ impl RenderResources { | |||||||
|         self.texture_to_resource.get(&texture).cloned() |         self.texture_to_resource.get(&texture).cloned() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn set_mesh_vertices_resource(&mut self, mesh: Handle<Mesh>, resource: RenderResource) { | ||||||
|  |         self.mesh_to_vertices_resource.insert(mesh, resource); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> { | ||||||
|  |         self.mesh_to_vertices_resource.get(&mesh).cloned() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn set_mesh_indices_resource(&mut self, mesh: Handle<Mesh>, resource: RenderResource) { | ||||||
|  |         self.mesh_to_indices_resource.insert(mesh, resource); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> { | ||||||
|  |         self.mesh_to_indices_resource.get(&mesh).cloned() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     pub fn set_texture_sampler_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) { |     pub fn set_texture_sampler_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) { | ||||||
|         self.texture_to_sampler_resource.insert(texture, resource); |         self.texture_to_sampler_resource.insert(texture, resource); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -86,7 +86,7 @@ pub trait Renderer { | |||||||
| 
 | 
 | ||||||
| pub trait RenderPass { | pub trait RenderPass { | ||||||
|     // TODO: consider using static dispatch for the renderer: Renderer<WgpuBackend>. compare compile times
 |     // TODO: consider using static dispatch for the renderer: Renderer<WgpuBackend>. 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 get_pipeline_descriptor(&self) -> &PipelineDescriptor; | ||||||
|     fn set_index_buffer(&mut self, resource: RenderResource, offset: u64); |     fn set_index_buffer(&mut self, resource: RenderResource, offset: u64); | ||||||
|     fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64); |     fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64); | ||||||
|  | |||||||
| @ -18,7 +18,6 @@ pub struct WgpuResources { | |||||||
|     pub buffers: HashMap<RenderResource, wgpu::Buffer>, |     pub buffers: HashMap<RenderResource, wgpu::Buffer>, | ||||||
|     pub textures: HashMap<RenderResource, wgpu::TextureView>, |     pub textures: HashMap<RenderResource, wgpu::TextureView>, | ||||||
|     pub samplers: HashMap<RenderResource, wgpu::Sampler>, |     pub samplers: HashMap<RenderResource, wgpu::Sampler>, | ||||||
|     pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>, |  | ||||||
|     pub resource_info: HashMap<RenderResource, ResourceInfo>, |     pub resource_info: HashMap<RenderResource, ResourceInfo>, | ||||||
|     pub bind_groups: HashMap<u64, BindGroupInfo>, |     pub bind_groups: HashMap<u64, BindGroupInfo>, | ||||||
|     pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>, |     pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>, | ||||||
| @ -32,7 +31,6 @@ pub struct WgpuResources { | |||||||
| impl WgpuResources { | impl WgpuResources { | ||||||
|     pub fn new() -> Self { |     pub fn new() -> Self { | ||||||
|         WgpuResources { |         WgpuResources { | ||||||
|             render_pipelines: HashMap::new(), |  | ||||||
|             buffers: HashMap::new(), |             buffers: HashMap::new(), | ||||||
|             textures: HashMap::new(), |             textures: HashMap::new(), | ||||||
|             samplers: HashMap::new(), |             samplers: HashMap::new(), | ||||||
| @ -455,6 +453,7 @@ pub struct WgpuRenderer { | |||||||
|     pub surface: Option<wgpu::Surface>, |     pub surface: Option<wgpu::Surface>, | ||||||
|     pub encoder: Option<wgpu::CommandEncoder>, |     pub encoder: Option<wgpu::CommandEncoder>, | ||||||
|     pub swap_chain_descriptor: wgpu::SwapChainDescriptor, |     pub swap_chain_descriptor: wgpu::SwapChainDescriptor, | ||||||
|  |     pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>, | ||||||
|     pub wgpu_resources: WgpuResources, |     pub wgpu_resources: WgpuResources, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -490,6 +489,7 @@ impl WgpuRenderer { | |||||||
|             encoder: None, |             encoder: None, | ||||||
|             swap_chain_descriptor, |             swap_chain_descriptor, | ||||||
|             wgpu_resources: WgpuResources::new(), |             wgpu_resources: WgpuResources::new(), | ||||||
|  |             render_pipelines: HashMap::new(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -620,7 +620,7 @@ impl WgpuRenderer { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn create_render_pass<'a>( |     pub fn create_render_pass<'a>( | ||||||
|         wgpu_resources: &WgpuResources, |         wgpu_resources: &'a WgpuResources, | ||||||
|         pass_descriptor: &PassDescriptor, |         pass_descriptor: &PassDescriptor, | ||||||
|         encoder: &'a mut wgpu::CommandEncoder, |         encoder: &'a mut wgpu::CommandEncoder, | ||||||
|         frame: &'a wgpu::SwapChainOutput, |         frame: &'a wgpu::SwapChainOutput, | ||||||
| @ -686,7 +686,7 @@ impl WgpuRenderer { | |||||||
|         wgpu_resources: &'a WgpuResources, |         wgpu_resources: &'a WgpuResources, | ||||||
|         depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor, |         depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor, | ||||||
|         frame: &'a wgpu::SwapChainOutput, |         frame: &'a wgpu::SwapChainOutput, | ||||||
|     ) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<&'a wgpu::TextureView> { |     ) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> { | ||||||
|         let attachment = match depth_stencil_attachment_descriptor.attachment.as_str() { |         let attachment = match depth_stencil_attachment_descriptor.attachment.as_str() { | ||||||
|             resource_name::texture::SWAP_CHAIN => &frame.view, |             resource_name::texture::SWAP_CHAIN => &frame.view, | ||||||
|             _ => { |             _ => { | ||||||
| @ -828,7 +828,6 @@ impl Renderer for WgpuRenderer { | |||||||
|                 .unwrap(); |                 .unwrap(); | ||||||
|             // create pipelines
 |             // create pipelines
 | ||||||
|             if !self |             if !self | ||||||
|                 .wgpu_resources |  | ||||||
|                 .render_pipelines |                 .render_pipelines | ||||||
|                 .contains_key(pipeline_descriptor_handle) |                 .contains_key(pipeline_descriptor_handle) | ||||||
|             { |             { | ||||||
| @ -849,7 +848,7 @@ impl Renderer for WgpuRenderer { | |||||||
|                     vertex_shader, |                     vertex_shader, | ||||||
|                     fragment_shader, |                     fragment_shader, | ||||||
|                 ); |                 ); | ||||||
|                 self.wgpu_resources.render_pipelines |                 self.render_pipelines | ||||||
|                     .insert(*pipeline_descriptor_handle, render_pipeline); |                     .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() { |         for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() { | ||||||
|             // run passes
 |             // 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) { |             if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) { | ||||||
|                 for pass_pipeline in pass_pipelines.iter() { |                 for pass_pipeline in pass_pipelines.iter() { | ||||||
|                     let pipeline_descriptor = pipeline_storage.get(pass_pipeline).unwrap(); |                     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); |                     render_pass.set_pipeline(render_pipeline); | ||||||
| 
 | 
 | ||||||
|                     let mut render_pass = WgpuRenderPass { |                     let mut wgpu_render_pass = WgpuRenderPass { | ||||||
|                         render_pass: &mut render_pass, |                         render_pass: &mut render_pass, | ||||||
|                         renderer: self, |  | ||||||
|                         pipeline_descriptor, |                         pipeline_descriptor, | ||||||
|  |                         wgpu_resources: &self.wgpu_resources, | ||||||
|  |                         renderer: &self | ||||||
|                     }; |                     }; | ||||||
| 
 | 
 | ||||||
|                     for draw_target_name in pipeline_descriptor.draw_targets.iter() { |                     for draw_target_name in pipeline_descriptor.draw_targets.iter() { | ||||||
|                         let draw_target = render_graph.draw_targets.get(draw_target_name).unwrap(); |                         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 struct WgpuRenderPass<'a, 'b, 'c, 'd> { | ||||||
|     pub render_pass: &'b mut wgpu::RenderPass<'a>, |     pub render_pass: &'b mut wgpu::RenderPass<'a>, | ||||||
|     pub pipeline_descriptor: &'c PipelineDescriptor, |     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> { | 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 |         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) { |     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 |         self.render_pass | ||||||
|             .set_vertex_buffers(start_slot, &[(&buffer, offset)]); |             .set_vertex_buffers(start_slot, &[(&buffer, offset)]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn set_index_buffer(&mut self, resource: RenderResource, offset: u64) { |     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); |         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(); |         let pipeline_layout = self.pipeline_descriptor.get_layout().unwrap(); | ||||||
|         for bind_group in pipeline_layout.bind_groups.iter() { |         for bind_group in pipeline_layout.bind_groups.iter() { | ||||||
|             let bind_group_id = bind_group.get_hash().unwrap(); |             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
 |                 // if there is a "global" bind group, use that
 | ||||||
|                 Some(bind_group_info) => bind_group_info, |                 Some(bind_group_info) => bind_group_info, | ||||||
|                 // otherwise try to get an entity-specific bind group
 |                 // otherwise try to get an entity-specific bind group
 | ||||||
|                 None => { |                 None => { | ||||||
|                     if let Some(entity) = entity { |                     if let Some(entity) = entity { | ||||||
|                         if let None = self.renderer.wgpu_resources.get_entity_bind_group(*entity, bind_group_id) { |                         if let None = self.wgpu_resources.get_entity_bind_group(*entity, bind_group_id) { | ||||||
|                             self.renderer.wgpu_resources.create_entity_bind_group(&self.renderer.device, bind_group, *entity); |                             // 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) |                             .get_entity_bind_group(*entity, bind_group_id) | ||||||
|                             .unwrap() |                             .unwrap() | ||||||
|                     } else { |                     } else { | ||||||
| @ -1082,14 +1084,13 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { | |||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     if let Some(resource) = self |                     if let Some(resource) = self | ||||||
|                         .renderer |  | ||||||
|                         .wgpu_resources |                         .wgpu_resources | ||||||
|                         .render_resources |                         .render_resources | ||||||
|                         .get_named_resource(&binding.name) |                         .get_named_resource(&binding.name) | ||||||
|                     { |                     { | ||||||
|                         // PERF: This hashmap get is pretty expensive (10 fps for 10000 entities)
 |                         // PERF: This hashmap get is pretty expensive (10 fps for 10000 entities)
 | ||||||
|                         if let Some(dynamic_uniform_buffer_info) = |                         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 |                             let index = dynamic_uniform_buffer_info | ||||||
|                                 .offsets |                                 .offsets | ||||||
|  | |||||||
| @ -1,8 +1,4 @@ | |||||||
| pub enum ResourceInfo { | pub enum ResourceInfo { | ||||||
|     BufferMapped { |  | ||||||
|         size: u64, |  | ||||||
|         buffer_usage: wgpu::BufferUsage, |  | ||||||
|     }, |  | ||||||
|     Buffer { |     Buffer { | ||||||
|         size: u64, |         size: u64, | ||||||
|         buffer_usage: wgpu::BufferUsage, |         buffer_usage: wgpu::BufferUsage, | ||||||
|  | |||||||
| @ -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<Handle<Mesh>>, Read<Renderable>), | ||||||
|  |         EntityFilterTuple< | ||||||
|  |             And<( | ||||||
|  |                 ComponentFilter<Handle<Mesh>>, | ||||||
|  |                 ComponentFilter<Renderable>, | ||||||
|  |                 ComponentFilter<Handle<Mesh>>, | ||||||
|  |             )>, | ||||||
|  |             And<(Passthrough, Passthrough)>, | ||||||
|  |             And<( | ||||||
|  |                 Passthrough, | ||||||
|  |                 Passthrough, | ||||||
|  |                 ComponentChangedFilter<Handle<Mesh>>, | ||||||
|  |             )>, | ||||||
|  |         >, | ||||||
|  |     >, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl MeshResourceProvider { | ||||||
|  |     pub fn new() -> Self { | ||||||
|  |         MeshResourceProvider { | ||||||
|  |             mesh_query: <(Read<Handle<Mesh>>, Read<Renderable>)>::query() | ||||||
|  |                 .filter(changed::<Handle<Mesh>>()), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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::<AssetStorage<Mesh>>().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, | ||||||
|  |     ) { | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -4,6 +4,7 @@ mod frame_texture_resource_provider; | |||||||
| mod light_resource_provider; | mod light_resource_provider; | ||||||
| mod ui_resource_provider; | mod ui_resource_provider; | ||||||
| mod uniform_resource_provider; | mod uniform_resource_provider; | ||||||
|  | mod mesh_resource_provider; | ||||||
| 
 | 
 | ||||||
| pub use camera2d_resource_provider::*; | pub use camera2d_resource_provider::*; | ||||||
| pub use camera_resource_provider::*; | pub use camera_resource_provider::*; | ||||||
| @ -11,3 +12,4 @@ pub use frame_texture_resource_provider::*; | |||||||
| pub use light_resource_provider::*; | pub use light_resource_provider::*; | ||||||
| pub use ui_resource_provider::*; | pub use ui_resource_provider::*; | ||||||
| pub use uniform_resource_provider::*; | pub use uniform_resource_provider::*; | ||||||
|  | pub use mesh_resource_provider::*; | ||||||
|  | |||||||
| @ -63,7 +63,7 @@ where | |||||||
|                                 .insert(uniform_info.name.to_string(), (None, 0, HashSet::new())); |                                 .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); |                         entities.insert(entity); | ||||||
|                         *counts += 1; |                         *counts += 1; | ||||||
|                     } |                     } | ||||||
| @ -112,7 +112,7 @@ where | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // allocate uniform buffers
 |         // 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; |             let count = *count as u64; | ||||||
|             if let Some(resource) = resource { |             if let Some(resource) = resource { | ||||||
|                 let mut info = renderer |                 let mut info = renderer | ||||||
| @ -158,7 +158,7 @@ where | |||||||
|                 // TODO: check if index has changed. if it has, then entity should be updated
 |                 // TODO: check if index has changed. if it has, then entity should be updated
 | ||||||
|                 // TODO: only mem-map entities if their data has changed
 |                 // TODO: only mem-map entities if their data has changed
 | ||||||
|                 // PERF: These hashmap inserts are pretty expensive (10 fps for 10000 entities)
 |                 // 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
 |                 // TODO: try getting ref first
 | ||||||
|                 offset += alignment; |                 offset += alignment; | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -171,7 +171,7 @@ pub struct UniformInfo<'a> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct DynamicUniformBufferInfo { | pub struct DynamicUniformBufferInfo { | ||||||
|     pub offsets: HashMap<Entity, u64>, |     pub offsets: HashMap<Entity, u32>, | ||||||
|     pub capacity: u64, |     pub capacity: u64, | ||||||
|     pub count: u64, |     pub count: u64, | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson