refactor renderer to avoid resource access collisions. this fixes the legion errors in debug builds.
NOTE: these "random resource access" issues are a pretty compelling reason to remove Resources from the render api
This commit is contained in:
		
							parent
							
								
									6d53100ff3
								
							
						
					
					
						commit
						7bb889bada
					
				| @ -22,6 +22,7 @@ pub trait DrawTarget { | |||||||
|         _resources: &Resources, |         _resources: &Resources, | ||||||
|         _renderer: &mut dyn Renderer, |         _renderer: &mut dyn Renderer, | ||||||
|         _pipeline_handle: Handle<PipelineDescriptor>, |         _pipeline_handle: Handle<PipelineDescriptor>, | ||||||
|  |         _pipeline_descriptor: &PipelineDescriptor, | ||||||
|     ) { |     ) { | ||||||
|     } |     } | ||||||
|     fn get_name(&self) -> String; |     fn get_name(&self) -> String; | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{AssetStorage, Handle}, |     asset::Handle, | ||||||
|     legion::prelude::*, |     legion::prelude::*, | ||||||
|     prelude::Renderable, |     prelude::Renderable, | ||||||
|     render::{ |     render::{ | ||||||
| @ -68,17 +68,17 @@ impl DrawTarget for AssignedBatchesDrawTarget { | |||||||
|         resources: &Resources, |         resources: &Resources, | ||||||
|         renderer: &mut dyn Renderer, |         renderer: &mut dyn Renderer, | ||||||
|         pipeline_handle: Handle<PipelineDescriptor>, |         pipeline_handle: Handle<PipelineDescriptor>, | ||||||
|  |         pipeline_descriptor: &PipelineDescriptor, | ||||||
|     ) { |     ) { | ||||||
|         let mut asset_batches = resources.get_mut::<AssetBatchers>().unwrap(); |         let mut asset_batches = resources.get_mut::<AssetBatchers>().unwrap(); | ||||||
|         let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap(); |  | ||||||
|         let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap(); |  | ||||||
| 
 | 
 | ||||||
|         let mut global_render_resource_assignments = |         let mut global_render_resource_assignments = | ||||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); |             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||||
| 
 | 
 | ||||||
|         log::debug!( |         log::debug!( | ||||||
|             "setting up batch bind groups for pipeline: {:?}", |             "setting up batch bind groups for pipeline: {:?} {:?}", | ||||||
|             pipeline_handle |             pipeline_handle, | ||||||
|  |             pipeline_descriptor.name, | ||||||
|         ); |         ); | ||||||
|         log::trace!("setting up global bind groups"); |         log::trace!("setting up global bind groups"); | ||||||
|         renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor); |         renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor); | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{AssetStorage, Handle}, |     asset::Handle, | ||||||
|     legion::prelude::*, |     legion::prelude::*, | ||||||
|     render::{ |     render::{ | ||||||
|         draw_target::DrawTarget, |         draw_target::DrawTarget, | ||||||
| @ -83,6 +83,7 @@ impl DrawTarget for AssignedMeshesDrawTarget { | |||||||
|         resources: &Resources, |         resources: &Resources, | ||||||
|         renderer: &mut dyn Renderer, |         renderer: &mut dyn Renderer, | ||||||
|         pipeline_handle: Handle<PipelineDescriptor>, |         pipeline_handle: Handle<PipelineDescriptor>, | ||||||
|  |         pipeline_descriptor: &PipelineDescriptor, | ||||||
|     ) { |     ) { | ||||||
|         let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap(); |         let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap(); | ||||||
|         let entity_render_resource_assignments = |         let entity_render_resource_assignments = | ||||||
| @ -90,14 +91,11 @@ impl DrawTarget for AssignedMeshesDrawTarget { | |||||||
|         let assigned_render_resource_assignments = shader_pipeline_assignments |         let assigned_render_resource_assignments = shader_pipeline_assignments | ||||||
|             .assignments |             .assignments | ||||||
|             .get(&pipeline_handle); |             .get(&pipeline_handle); | ||||||
|         let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap(); |  | ||||||
|         let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap(); |  | ||||||
|         let mut global_render_resource_assignments = |         let mut global_render_resource_assignments = | ||||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); |             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||||
|         renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor); |         renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor); | ||||||
|         if let Some(assigned_render_resource_assignments) = assigned_render_resource_assignments { |         if let Some(assigned_render_resource_assignments) = assigned_render_resource_assignments { | ||||||
|             for assignment_id in assigned_render_resource_assignments.iter() { |             for assignment_id in assigned_render_resource_assignments.iter() { | ||||||
|                 // TODO: hopefully legion has better random access apis that are more like queries?
 |  | ||||||
|                 let entity = entity_render_resource_assignments |                 let entity = entity_render_resource_assignments | ||||||
|                     .get(*assignment_id) |                     .get(*assignment_id) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{Asset, AssetStorage, Handle}, |     asset::{Asset, Handle}, | ||||||
|     legion::prelude::*, |     legion::prelude::*, | ||||||
|     math, |     math, | ||||||
|     prelude::MeshType, |     prelude::MeshType, | ||||||
| @ -72,7 +72,8 @@ impl DrawTarget for UiDrawTarget { | |||||||
|         _world: &mut World, |         _world: &mut World, | ||||||
|         resources: &Resources, |         resources: &Resources, | ||||||
|         renderer: &mut dyn Renderer, |         renderer: &mut dyn Renderer, | ||||||
|         pipeline_handle: Handle<PipelineDescriptor>, |         _pipeline_handle: Handle<PipelineDescriptor>, | ||||||
|  |         pipeline_descriptor: &PipelineDescriptor, | ||||||
|     ) { |     ) { | ||||||
|         // don't create meshes if they have already been created
 |         // don't create meshes if they have already been created
 | ||||||
|         if let Some(_) = self.mesh_vertex_buffer { |         if let Some(_) = self.mesh_vertex_buffer { | ||||||
| @ -100,8 +101,6 @@ impl DrawTarget for UiDrawTarget { | |||||||
| 
 | 
 | ||||||
|         let mut global_render_resource_assignments = |         let mut global_render_resource_assignments = | ||||||
|             resources.get_mut::<RenderResourceAssignments>().unwrap(); |             resources.get_mut::<RenderResourceAssignments>().unwrap(); | ||||||
|         let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap(); |  | ||||||
|         let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap(); |  | ||||||
|         renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor); |         renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor); | ||||||
|     } |     } | ||||||
|     fn get_name(&self) -> String { |     fn get_name(&self) -> String { | ||||||
|  | |||||||
| @ -1,9 +1,8 @@ | |||||||
| use super::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType}; | use super::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType, VertexBufferDescriptors}; | ||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{AssetStorage, Handle}, |     asset::{AssetStorage, Handle}, | ||||||
|     prelude::{Renderable, Resources, Shader, World}, |     prelude::{Renderable, Resources, Shader, World}, | ||||||
|     render::{ |     render::{ | ||||||
|         render_graph::RenderGraph, |  | ||||||
|         render_resource::{ |         render_resource::{ | ||||||
|             BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, |             BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, | ||||||
|         }, |         }, | ||||||
| @ -32,7 +31,7 @@ impl PipelineCompiler { | |||||||
| 
 | 
 | ||||||
|     fn reflect_layout( |     fn reflect_layout( | ||||||
|         shader_storage: &AssetStorage<Shader>, |         shader_storage: &AssetStorage<Shader>, | ||||||
|         render_graph: &RenderGraph, |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|         pipeline_descriptor: &mut PipelineDescriptor, |         pipeline_descriptor: &mut PipelineDescriptor, | ||||||
|         renderer: &dyn Renderer, |         renderer: &dyn Renderer, | ||||||
|         render_resource_assignments: &RenderResourceAssignments, |         render_resource_assignments: &RenderResourceAssignments, | ||||||
| @ -52,7 +51,7 @@ impl PipelineCompiler { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let mut layout = PipelineLayout::from_shader_layouts(&mut layouts); |         let mut layout = PipelineLayout::from_shader_layouts(&mut layouts); | ||||||
|         layout.sync_vertex_buffer_descriptors_with_render_graph(render_graph); |         layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors); | ||||||
| 
 | 
 | ||||||
|         // set binding uniforms to dynamic if render resource assignments use dynamic
 |         // set binding uniforms to dynamic if render resource assignments use dynamic
 | ||||||
|         // TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes.
 |         // TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes.
 | ||||||
| @ -113,7 +112,7 @@ impl PipelineCompiler { | |||||||
| 
 | 
 | ||||||
|     fn compile_pipeline( |     fn compile_pipeline( | ||||||
|         &mut self, |         &mut self, | ||||||
|         render_graph: &RenderGraph, |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|         shader_storage: &mut AssetStorage<Shader>, |         shader_storage: &mut AssetStorage<Shader>, | ||||||
|         renderer: &dyn Renderer, |         renderer: &dyn Renderer, | ||||||
|         pipeline_descriptor: &PipelineDescriptor, |         pipeline_descriptor: &PipelineDescriptor, | ||||||
| @ -140,7 +139,7 @@ impl PipelineCompiler { | |||||||
| 
 | 
 | ||||||
|         Self::reflect_layout( |         Self::reflect_layout( | ||||||
|             shader_storage, |             shader_storage, | ||||||
|             render_graph, |             vertex_buffer_descriptors, | ||||||
|             &mut compiled_pipeline_descriptor, |             &mut compiled_pipeline_descriptor, | ||||||
|             renderer, |             renderer, | ||||||
|             render_resource_assignments, |             render_resource_assignments, | ||||||
| @ -151,7 +150,7 @@ impl PipelineCompiler { | |||||||
| 
 | 
 | ||||||
|     fn update_shader_assignments( |     fn update_shader_assignments( | ||||||
|         &mut self, |         &mut self, | ||||||
|         render_graph: &RenderGraph, |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|         shader_pipeline_assignments: &mut ShaderPipelineAssignments, |         shader_pipeline_assignments: &mut ShaderPipelineAssignments, | ||||||
|         renderer: &dyn Renderer, |         renderer: &dyn Renderer, | ||||||
|         pipeline_storage: &mut AssetStorage<PipelineDescriptor>, |         pipeline_storage: &mut AssetStorage<PipelineDescriptor>, | ||||||
| @ -177,7 +176,7 @@ impl PipelineCompiler { | |||||||
|             } else { |             } else { | ||||||
|                 let pipeline_descriptor = pipeline_storage.get(pipeline_handle).unwrap(); |                 let pipeline_descriptor = pipeline_storage.get(pipeline_handle).unwrap(); | ||||||
|                 let compiled_pipeline = self.compile_pipeline( |                 let compiled_pipeline = self.compile_pipeline( | ||||||
|                     render_graph, |                     vertex_buffer_descriptors, | ||||||
|                     shader_storage, |                     shader_storage, | ||||||
|                     renderer, |                     renderer, | ||||||
|                     pipeline_descriptor, |                     pipeline_descriptor, | ||||||
| @ -248,7 +247,7 @@ pub fn update_shader_assignments( | |||||||
|             resources.get_mut::<ShaderPipelineAssignments>().unwrap(); |             resources.get_mut::<ShaderPipelineAssignments>().unwrap(); | ||||||
|         let mut pipeline_compiler = resources.get_mut::<PipelineCompiler>().unwrap(); |         let mut pipeline_compiler = resources.get_mut::<PipelineCompiler>().unwrap(); | ||||||
|         let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap(); |         let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap(); | ||||||
|         let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); |         let vertex_buffer_descriptors = resources.get::<VertexBufferDescriptors>().unwrap(); | ||||||
|         let mut pipeline_descriptor_storage = resources |         let mut pipeline_descriptor_storage = resources | ||||||
|             .get_mut::<AssetStorage<PipelineDescriptor>>() |             .get_mut::<AssetStorage<PipelineDescriptor>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
| @ -264,7 +263,7 @@ pub fn update_shader_assignments( | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             pipeline_compiler.update_shader_assignments( |             pipeline_compiler.update_shader_assignments( | ||||||
|                 &mut render_graph, |                 &vertex_buffer_descriptors, | ||||||
|                 &mut shader_pipeline_assignments, |                 &mut shader_pipeline_assignments, | ||||||
|                 renderer, |                 renderer, | ||||||
|                 &mut pipeline_descriptor_storage, |                 &mut pipeline_descriptor_storage, | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| use super::{BindGroupDescriptor, VertexBufferDescriptor}; | use super::{BindGroupDescriptor, VertexBufferDescriptor, VertexBufferDescriptors}; | ||||||
| use crate::render::{render_graph::RenderGraph, shader::ShaderLayout}; | use crate::render::shader::ShaderLayout; | ||||||
| use std::{collections::HashMap, hash::Hash}; | use std::{collections::HashMap, hash::Hash}; | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, Debug, Default)] | #[derive(Clone, Debug, Default)] | ||||||
| @ -56,10 +56,13 @@ impl PipelineLayout { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn sync_vertex_buffer_descriptors_with_render_graph(&mut self, render_graph: &RenderGraph) { |     pub fn sync_vertex_buffer_descriptors( | ||||||
|  |         &mut self, | ||||||
|  |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|  |     ) { | ||||||
|         for vertex_buffer_descriptor in self.vertex_buffer_descriptors.iter_mut() { |         for vertex_buffer_descriptor in self.vertex_buffer_descriptors.iter_mut() { | ||||||
|             if let Some(graph_descriptor) = |             if let Some(graph_descriptor) = | ||||||
|                 render_graph.get_vertex_buffer_descriptor(&vertex_buffer_descriptor.name) |                 vertex_buffer_descriptors.get(&vertex_buffer_descriptor.name) | ||||||
|             { |             { | ||||||
|                 vertex_buffer_descriptor.sync_with_descriptor(graph_descriptor); |                 vertex_buffer_descriptor.sync_with_descriptor(graph_descriptor); | ||||||
|             } else { |             } else { | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| use super::VertexFormat; | use super::VertexFormat; | ||||||
|  | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, Debug, Eq, PartialEq)] | #[derive(Clone, Debug, Eq, PartialEq)] | ||||||
| pub struct VertexBufferDescriptor { | pub struct VertexBufferDescriptor { | ||||||
| @ -41,3 +42,21 @@ pub struct VertexAttributeDescriptor { | |||||||
|     pub format: VertexFormat, |     pub format: VertexFormat, | ||||||
|     pub shader_location: u32, |     pub shader_location: u32, | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | #[derive(Default)] | ||||||
|  | pub struct VertexBufferDescriptors { | ||||||
|  |     pub descriptors: HashMap<String, VertexBufferDescriptor>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl VertexBufferDescriptors { | ||||||
|  |     pub fn set(&mut self, vertex_buffer_descriptor: VertexBufferDescriptor) { | ||||||
|  |         self.descriptors.insert( | ||||||
|  |             vertex_buffer_descriptor.name.to_string(), | ||||||
|  |             vertex_buffer_descriptor, | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn get(&self, name: &str) -> Option<&VertexBufferDescriptor> { | ||||||
|  |         self.descriptors.get(name) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,12 +1,13 @@ | |||||||
| use super::RenderGraphBuilder; | use super::RenderGraphBuilder; | ||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{AssetStorage, Handle}, |     asset::{AssetStorage, Handle}, | ||||||
|     prelude::Shader, |     prelude::{Resources, Shader, World}, | ||||||
|     render::{ |     render::{ | ||||||
|         draw_target::DrawTarget, |         draw_target::DrawTarget, | ||||||
|         pass::PassDescriptor, |         pass::PassDescriptor, | ||||||
|         pipeline::{PipelineDescriptor, VertexBufferDescriptor}, |         pipeline::{PipelineCompiler, PipelineDescriptor}, | ||||||
|         render_resource::ResourceProvider, |         render_resource::ResourceProvider, | ||||||
|  |         renderer::Renderer, | ||||||
|         texture::TextureDescriptor, |         texture::TextureDescriptor, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| @ -21,7 +22,6 @@ pub struct RenderGraph { | |||||||
|     pub resource_providers: Vec<Box<dyn ResourceProvider + Send + Sync>>, |     pub resource_providers: Vec<Box<dyn ResourceProvider + Send + Sync>>, | ||||||
|     pub queued_textures: Vec<(String, TextureDescriptor)>, |     pub queued_textures: Vec<(String, TextureDescriptor)>, | ||||||
|     pub draw_targets: HashMap<String, Box<dyn DrawTarget + Send + Sync>>, |     pub draw_targets: HashMap<String, Box<dyn DrawTarget + Send + Sync>>, | ||||||
|     pub vertex_buffer_descriptors: HashMap<String, VertexBufferDescriptor>, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl RenderGraph { | impl RenderGraph { | ||||||
| @ -49,17 +49,52 @@ impl RenderGraph { | |||||||
|         pass_pipelines.push(pipeline); |         pass_pipelines.push(pipeline); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn set_vertex_buffer_descriptor( |     pub fn setup_pipeline_draw_targets( | ||||||
|         &mut self, |         &mut self, | ||||||
|         vertex_buffer_descriptor: VertexBufferDescriptor, |         world: &mut World, | ||||||
|  |         resources: &Resources, | ||||||
|  |         renderer: &mut dyn Renderer, | ||||||
|     ) { |     ) { | ||||||
|         self.vertex_buffer_descriptors.insert( |         let shader_storage = resources.get::<AssetStorage<Shader>>().unwrap(); | ||||||
|             vertex_buffer_descriptor.name.to_string(), |         let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap(); | ||||||
|             vertex_buffer_descriptor, | 
 | ||||||
|  |         for (pass_name, _pass_descriptor) in self.pass_descriptors.iter() { | ||||||
|  |             if let Some(pass_pipelines) = self.pass_pipelines.get(pass_name) { | ||||||
|  |                 for pass_pipeline in pass_pipelines.iter() { | ||||||
|  |                     if let Some(compiled_pipelines_iter) = | ||||||
|  |                         pipeline_compiler.iter_compiled_pipelines(*pass_pipeline) | ||||||
|  |                     { | ||||||
|  |                         for compiled_pipeline_handle in compiled_pipelines_iter { | ||||||
|  |                             let mut pipeline_storage = resources | ||||||
|  |                                 .get_mut::<AssetStorage<PipelineDescriptor>>() | ||||||
|  |                                 .unwrap(); | ||||||
|  |                             let compiled_pipeline_descriptor = | ||||||
|  |                                 pipeline_storage.get_mut(compiled_pipeline_handle).unwrap(); | ||||||
|  | 
 | ||||||
|  |                             // create wgpu pipeline if it doesn't exist
 | ||||||
|  |                             renderer.setup_render_pipeline( | ||||||
|  |                                 *compiled_pipeline_handle, | ||||||
|  |                                 compiled_pipeline_descriptor, | ||||||
|  |                                 &shader_storage, | ||||||
|  |                             ); | ||||||
|  | 
 | ||||||
|  |                             // setup pipeline draw targets
 | ||||||
|  |                             for draw_target_name in compiled_pipeline_descriptor.draw_targets.iter() | ||||||
|  |                             { | ||||||
|  |                                 let draw_target = | ||||||
|  |                                     self.draw_targets.get_mut(draw_target_name).unwrap(); | ||||||
|  |                                 draw_target.setup( | ||||||
|  |                                     world, | ||||||
|  |                                     resources, | ||||||
|  |                                     renderer, | ||||||
|  |                                     *compiled_pipeline_handle, | ||||||
|  |                                     compiled_pipeline_descriptor, | ||||||
|                                 ); |                                 ); | ||||||
|                             } |                             } | ||||||
| 
 |                         } | ||||||
|     pub fn get_vertex_buffer_descriptor(&self, name: &str) -> Option<&VertexBufferDescriptor> { |                     } | ||||||
|         self.vertex_buffer_descriptors.get(name) |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ use super::{ | |||||||
|         AssignedBatchesDrawTarget, AssignedMeshesDrawTarget, MeshesDrawTarget, UiDrawTarget, |         AssignedBatchesDrawTarget, AssignedMeshesDrawTarget, MeshesDrawTarget, UiDrawTarget, | ||||||
|     }, |     }, | ||||||
|     pass::passes::ForwardPassBuilder, |     pass::passes::ForwardPassBuilder, | ||||||
|     pipeline::{pipelines::ForwardPipelineBuilder, PipelineCompiler, ShaderPipelineAssignments}, |     pipeline::{pipelines::ForwardPipelineBuilder, PipelineCompiler, ShaderPipelineAssignments, VertexBufferDescriptors}, | ||||||
|     render_graph::RenderGraph, |     render_graph::RenderGraph, | ||||||
|     render_resource::{ |     render_resource::{ | ||||||
|         build_entity_render_resource_assignments_system, |         build_entity_render_resource_assignments_system, | ||||||
| @ -62,6 +62,7 @@ impl AppPlugin for RenderPlugin { | |||||||
|             .add_resource(AssetStorage::<StandardMaterial>::new()) |             .add_resource(AssetStorage::<StandardMaterial>::new()) | ||||||
|             .add_resource(AssetStorage::<PipelineDescriptor>::new()) |             .add_resource(AssetStorage::<PipelineDescriptor>::new()) | ||||||
|             .add_resource(ShaderPipelineAssignments::new()) |             .add_resource(ShaderPipelineAssignments::new()) | ||||||
|  |             .add_resource(VertexBufferDescriptors::default()) | ||||||
|             .add_resource(PipelineCompiler::new()) |             .add_resource(PipelineCompiler::new()) | ||||||
|             .add_resource(RenderResourceAssignments::default()) |             .add_resource(RenderResourceAssignments::default()) | ||||||
|             .add_resource(EntityRenderResourceAssignments::default()) |             .add_resource(EntityRenderResourceAssignments::default()) | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ use crate::{ | |||||||
|     prelude::Renderable, |     prelude::Renderable, | ||||||
|     render::{ |     render::{ | ||||||
|         mesh::Mesh, |         mesh::Mesh, | ||||||
|         render_graph::RenderGraph, |         pipeline::VertexBufferDescriptors, | ||||||
|         render_resource::{ |         render_resource::{ | ||||||
|             AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider, |             AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider, | ||||||
|         }, |         }, | ||||||
| @ -92,9 +92,8 @@ impl ResourceProvider for MeshResourceProvider { | |||||||
|         _world: &mut World, |         _world: &mut World, | ||||||
|         resources: &Resources, |         resources: &Resources, | ||||||
|     ) { |     ) { | ||||||
|         let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); |         let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap(); | ||||||
|         render_graph |         vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap()); | ||||||
|             .set_vertex_buffer_descriptor(Vertex::get_vertex_buffer_descriptor().cloned().unwrap()); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn update(&mut self, _renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) { |     fn update(&mut self, _renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) { | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ use crate::{ | |||||||
|     ecs, |     ecs, | ||||||
|     prelude::Node, |     prelude::Node, | ||||||
|     render::{ |     render::{ | ||||||
|         render_graph::RenderGraph, |         pipeline::VertexBufferDescriptors, | ||||||
|         render_resource::{ |         render_resource::{ | ||||||
|             resource_name, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, |             resource_name, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, | ||||||
|             RenderResourceAssignments, ResourceProvider, |             RenderResourceAssignments, ResourceProvider, | ||||||
| @ -113,9 +113,8 @@ impl ResourceProvider for UiResourceProvider { | |||||||
|         _world: &mut World, |         _world: &mut World, | ||||||
|         resources: &Resources, |         resources: &Resources, | ||||||
|     ) { |     ) { | ||||||
|         let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); |         let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap(); | ||||||
|         render_graph |         vertex_buffer_descriptors.set(Rect::get_vertex_buffer_descriptor().cloned().unwrap()); | ||||||
|             .set_vertex_buffer_descriptor(Rect::get_vertex_buffer_descriptor().cloned().unwrap()); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) { |     fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) { | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     asset::{AssetStorage, Handle}, |     asset::{AssetStorage, Handle}, | ||||||
|     render::{ |     render::{ | ||||||
|         render_graph::RenderGraph, |         pipeline::VertexBufferDescriptors, | ||||||
|         render_resource::{ |         render_resource::{ | ||||||
|             AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, |             AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, | ||||||
|             RenderResourceAssignments, ResourceInfo, ResourceProvider, |             RenderResourceAssignments, ResourceInfo, ResourceProvider, | ||||||
| @ -543,12 +543,14 @@ where | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn initialize_vertex_buffer_descriptor(&self, render_graph: &mut RenderGraph) { |     fn initialize_vertex_buffer_descriptor( | ||||||
|  |         &self, | ||||||
|  |         vertex_buffer_descriptors: &mut VertexBufferDescriptors, | ||||||
|  |     ) { | ||||||
|         let vertex_buffer_descriptor = T::get_vertex_buffer_descriptor(); |         let vertex_buffer_descriptor = T::get_vertex_buffer_descriptor(); | ||||||
|         if let Some(vertex_buffer_descriptor) = vertex_buffer_descriptor { |         if let Some(vertex_buffer_descriptor) = vertex_buffer_descriptor { | ||||||
|             if let None = render_graph.get_vertex_buffer_descriptor(&vertex_buffer_descriptor.name) |             if let None = vertex_buffer_descriptors.get(&vertex_buffer_descriptor.name) { | ||||||
|             { |                 vertex_buffer_descriptors.set(vertex_buffer_descriptor.clone()); | ||||||
|                 render_graph.set_vertex_buffer_descriptor(vertex_buffer_descriptor.clone()); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -601,8 +603,8 @@ where | |||||||
|         world: &mut World, |         world: &mut World, | ||||||
|         resources: &Resources, |         resources: &Resources, | ||||||
|     ) { |     ) { | ||||||
|         let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); |         let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap(); | ||||||
|         self.initialize_vertex_buffer_descriptor(&mut render_graph); |         self.initialize_vertex_buffer_descriptor(&mut vertex_buffer_descriptors); | ||||||
|         self.update(renderer, world, resources); |         self.update(renderer, world, resources); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,10 +1,12 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|  |     asset::{AssetStorage, Handle}, | ||||||
|     legion::prelude::*, |     legion::prelude::*, | ||||||
|     render::{ |     render::{ | ||||||
|         pipeline::PipelineDescriptor, |         pipeline::PipelineDescriptor, | ||||||
|         render_resource::{ |         render_resource::{ | ||||||
|             BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo, |             BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo, | ||||||
|         }, |         }, | ||||||
|  |         shader::Shader, | ||||||
|         texture::{SamplerDescriptor, TextureDescriptor}, |         texture::{SamplerDescriptor, TextureDescriptor}, | ||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| @ -40,6 +42,12 @@ pub trait Renderer { | |||||||
|     ); |     ); | ||||||
|     fn get_render_resources(&self) -> &RenderResources; |     fn get_render_resources(&self) -> &RenderResources; | ||||||
|     fn get_render_resources_mut(&mut self) -> &mut RenderResources; |     fn get_render_resources_mut(&mut self) -> &mut RenderResources; | ||||||
|  |     fn setup_render_pipeline( | ||||||
|  |         &mut self, | ||||||
|  |         pipeline_handle: Handle<PipelineDescriptor>, | ||||||
|  |         pipeline_descriptor: &mut PipelineDescriptor, | ||||||
|  |         shader_storage: &AssetStorage<Shader>, | ||||||
|  |     ); | ||||||
|     fn setup_bind_groups( |     fn setup_bind_groups( | ||||||
|         &mut self, |         &mut self, | ||||||
|         render_resource_assignments: &mut RenderResourceAssignments, |         render_resource_assignments: &mut RenderResourceAssignments, | ||||||
|  | |||||||
| @ -82,143 +82,10 @@ impl WgpuRenderer { | |||||||
|         self.intialized = true; |         self.intialized = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn create_render_pipeline( |     pub fn create_render_pass<'a, 'b>( | ||||||
|         &mut self, |  | ||||||
|         pipeline_handle: Handle<PipelineDescriptor>, |  | ||||||
|         pipeline_descriptor: &mut PipelineDescriptor, |  | ||||||
|         shader_storage: &AssetStorage<Shader>, |  | ||||||
|     ) { |  | ||||||
|         let device = self.device.borrow(); |  | ||||||
|         let layout = pipeline_descriptor.get_layout().unwrap(); |  | ||||||
|         for bind_group in layout.bind_groups.iter() { |  | ||||||
|             if let None = self.wgpu_resources.bind_group_layouts.get(&bind_group.id) { |  | ||||||
|                 let bind_group_layout_binding = bind_group |  | ||||||
|                     .bindings |  | ||||||
|                     .iter() |  | ||||||
|                     .map(|binding| wgpu::BindGroupLayoutEntry { |  | ||||||
|                         binding: binding.index, |  | ||||||
|                         visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, |  | ||||||
|                         ty: (&binding.bind_type).into(), |  | ||||||
|                     }) |  | ||||||
|                     .collect::<Vec<wgpu::BindGroupLayoutEntry>>(); |  | ||||||
|                 let wgpu_bind_group_layout = |  | ||||||
|                     device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { |  | ||||||
|                         bindings: bind_group_layout_binding.as_slice(), |  | ||||||
|                     }); |  | ||||||
| 
 |  | ||||||
|                 self.wgpu_resources |  | ||||||
|                     .bind_group_layouts |  | ||||||
|                     .insert(bind_group.id, wgpu_bind_group_layout); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // setup and collect bind group layouts
 |  | ||||||
|         let bind_group_layouts = layout |  | ||||||
|             .bind_groups |  | ||||||
|             .iter() |  | ||||||
|             .map(|bind_group| { |  | ||||||
|                 self.wgpu_resources |  | ||||||
|                     .bind_group_layouts |  | ||||||
|                     .get(&bind_group.id) |  | ||||||
|                     .unwrap() |  | ||||||
|             }) |  | ||||||
|             .collect::<Vec<&wgpu::BindGroupLayout>>(); |  | ||||||
| 
 |  | ||||||
|         let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { |  | ||||||
|             bind_group_layouts: bind_group_layouts.as_slice(), |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         let owned_vertex_buffer_descriptors = layout |  | ||||||
|             .vertex_buffer_descriptors |  | ||||||
|             .iter() |  | ||||||
|             .map(|v| v.into()) |  | ||||||
|             .collect::<Vec<OwnedWgpuVertexBufferDescriptor>>(); |  | ||||||
| 
 |  | ||||||
|         let color_states = pipeline_descriptor |  | ||||||
|             .color_states |  | ||||||
|             .iter() |  | ||||||
|             .map(|c| c.into()) |  | ||||||
|             .collect::<Vec<wgpu::ColorStateDescriptor>>(); |  | ||||||
| 
 |  | ||||||
|         if let None = self |  | ||||||
|             .wgpu_resources |  | ||||||
|             .shader_modules |  | ||||||
|             .get(&pipeline_descriptor.shader_stages.vertex) |  | ||||||
|         { |  | ||||||
|             self.wgpu_resources.create_shader_module( |  | ||||||
|                 &device, |  | ||||||
|                 pipeline_descriptor.shader_stages.vertex, |  | ||||||
|                 shader_storage, |  | ||||||
|             ); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment { |  | ||||||
|             if let None = self.wgpu_resources.shader_modules.get(&fragment_handle) { |  | ||||||
|                 self.wgpu_resources |  | ||||||
|                     .create_shader_module(&device, fragment_handle, shader_storage); |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let vertex_shader_module = self |  | ||||||
|             .wgpu_resources |  | ||||||
|             .shader_modules |  | ||||||
|             .get(&pipeline_descriptor.shader_stages.vertex) |  | ||||||
|             .unwrap(); |  | ||||||
| 
 |  | ||||||
|         let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment { |  | ||||||
|             Some(fragment_handle) => Some( |  | ||||||
|                 self.wgpu_resources |  | ||||||
|                     .shader_modules |  | ||||||
|                     .get(&fragment_handle) |  | ||||||
|                     .unwrap(), |  | ||||||
|             ), |  | ||||||
|             None => None, |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let mut render_pipeline_descriptor = wgpu::RenderPipelineDescriptor { |  | ||||||
|             layout: &pipeline_layout, |  | ||||||
|             vertex_stage: wgpu::ProgrammableStageDescriptor { |  | ||||||
|                 module: &vertex_shader_module, |  | ||||||
|                 entry_point: "main", |  | ||||||
|             }, |  | ||||||
|             fragment_stage: match pipeline_descriptor.shader_stages.fragment { |  | ||||||
|                 Some(_) => Some(wgpu::ProgrammableStageDescriptor { |  | ||||||
|                     entry_point: "main", |  | ||||||
|                     module: fragment_shader_module.as_ref().unwrap(), |  | ||||||
|                 }), |  | ||||||
|                 None => None, |  | ||||||
|             }, |  | ||||||
|             rasterization_state: pipeline_descriptor |  | ||||||
|                 .rasterization_state |  | ||||||
|                 .as_ref() |  | ||||||
|                 .map(|r| r.into()), |  | ||||||
|             primitive_topology: pipeline_descriptor.primitive_topology.into(), |  | ||||||
|             color_states: &color_states, |  | ||||||
|             depth_stencil_state: pipeline_descriptor |  | ||||||
|                 .depth_stencil_state |  | ||||||
|                 .as_ref() |  | ||||||
|                 .map(|d| d.into()), |  | ||||||
|             vertex_state: wgpu::VertexStateDescriptor { |  | ||||||
|                 index_format: pipeline_descriptor.index_format.into(), |  | ||||||
|                 vertex_buffers: &owned_vertex_buffer_descriptors |  | ||||||
|                     .iter() |  | ||||||
|                     .map(|v| v.into()) |  | ||||||
|                     .collect::<Vec<wgpu::VertexBufferDescriptor>>(), |  | ||||||
|             }, |  | ||||||
|             sample_count: pipeline_descriptor.sample_count, |  | ||||||
|             sample_mask: pipeline_descriptor.sample_mask, |  | ||||||
|             alpha_to_coverage_enabled: pipeline_descriptor.alpha_to_coverage_enabled, |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let render_pipeline = device.create_render_pipeline(&mut render_pipeline_descriptor); |  | ||||||
|         self.render_pipelines |  | ||||||
|             .insert(pipeline_handle, render_pipeline); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn create_render_pass<'a>( |  | ||||||
|         wgpu_resources: &'a WgpuResources, |         wgpu_resources: &'a WgpuResources, | ||||||
|         pass_descriptor: &PassDescriptor, |         pass_descriptor: &PassDescriptor, | ||||||
|         global_render_resource_assignments: &RenderResourceAssignments, |         global_render_resource_assignments: &'b RenderResourceAssignments, | ||||||
|         encoder: &'a mut wgpu::CommandEncoder, |         encoder: &'a mut wgpu::CommandEncoder, | ||||||
|         primary_swap_chain: &Option<String>, |         primary_swap_chain: &Option<String>, | ||||||
|         swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>, |         swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>, | ||||||
| @ -344,12 +211,13 @@ impl WgpuRenderer { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn initialize_resource_providers(&mut self, world: &mut World, resources: &mut Resources) { |     pub fn initialize_resource_providers(&mut self, world: &mut World, resources: &mut Resources) { | ||||||
|         let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); |  | ||||||
|         self.encoder = Some( |         self.encoder = Some( | ||||||
|             self.device |             self.device | ||||||
|                 .borrow() |                 .borrow() | ||||||
|                 .create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }), |                 .create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }), | ||||||
|         ); |         ); | ||||||
|  | 
 | ||||||
|  |         let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); | ||||||
|         for resource_provider in render_graph.resource_providers.iter_mut() { |         for resource_provider in render_graph.resource_providers.iter_mut() { | ||||||
|             resource_provider.initialize(self, world, resources); |             resource_provider.initialize(self, world, resources); | ||||||
|         } |         } | ||||||
| @ -491,68 +359,29 @@ impl Renderer for WgpuRenderer { | |||||||
| 
 | 
 | ||||||
|         let mut encoder = self.encoder.take().unwrap(); |         let mut encoder = self.encoder.take().unwrap(); | ||||||
| 
 | 
 | ||||||
|         let mut pipeline_storage = resources |  | ||||||
|             .get_mut::<AssetStorage<PipelineDescriptor>>() |  | ||||||
|             .unwrap(); |  | ||||||
|         let shader_storage = resources.get::<AssetStorage<Shader>>().unwrap(); |  | ||||||
|         let render_graph = resources.get::<RenderGraph>().unwrap(); |  | ||||||
|         let mut render_graph_mut = resources.get_mut::<RenderGraph>().unwrap(); |  | ||||||
|         let global_render_resource_assignments = |  | ||||||
|             resources.get::<RenderResourceAssignments>().unwrap(); |  | ||||||
|         let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap(); |  | ||||||
| 
 |  | ||||||
|         // setup draw targets
 |         // setup draw targets
 | ||||||
|         for (pass_name, _pass_descriptor) in render_graph.pass_descriptors.iter() { |         let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); | ||||||
|             if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) { |         render_graph.setup_pipeline_draw_targets(world, resources, self); | ||||||
|                 for pass_pipeline in pass_pipelines.iter() { |  | ||||||
|                     if let Some(compiled_pipelines_iter) = |  | ||||||
|                         pipeline_compiler.iter_compiled_pipelines(*pass_pipeline) |  | ||||||
|                     { |  | ||||||
|                         for compiled_pipeline_handle in compiled_pipelines_iter { |  | ||||||
|                             let compiled_pipeline_descriptor = |  | ||||||
|                                 pipeline_storage.get_mut(compiled_pipeline_handle).unwrap(); |  | ||||||
| 
 |  | ||||||
|                             // create wgpu pipeline if it doesn't exist
 |  | ||||||
|                             if !self.render_pipelines.contains_key(compiled_pipeline_handle) { |  | ||||||
|                                 self.create_render_pipeline( |  | ||||||
|                                     *compiled_pipeline_handle, |  | ||||||
|                                     compiled_pipeline_descriptor, |  | ||||||
|                                     &shader_storage, |  | ||||||
|                                 ); |  | ||||||
|                             } |  | ||||||
| 
 |  | ||||||
|                             // setup pipeline draw targets
 |  | ||||||
|                             for draw_target_name in compiled_pipeline_descriptor.draw_targets.iter() |  | ||||||
|                             { |  | ||||||
|                                 let draw_target = render_graph_mut |  | ||||||
|                                     .draw_targets |  | ||||||
|                                     .get_mut(draw_target_name) |  | ||||||
|                                     .unwrap(); |  | ||||||
|                                 draw_target.setup( |  | ||||||
|                                     world, |  | ||||||
|                                     resources, |  | ||||||
|                                     self, |  | ||||||
|                                     *compiled_pipeline_handle, |  | ||||||
|                                 ); |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         let (primary_swap_chain, swap_chain_outputs) = self.get_swap_chain_outputs(resources); |         let (primary_swap_chain, swap_chain_outputs) = self.get_swap_chain_outputs(resources); | ||||||
| 
 | 
 | ||||||
|         // begin render passes
 |         // begin render passes
 | ||||||
|  |         let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap(); | ||||||
|  |         let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap(); | ||||||
|  | 
 | ||||||
|         for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() { |         for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() { | ||||||
|             let mut render_pass = Self::create_render_pass( |             let mut render_pass = { | ||||||
|  |                 let global_render_resource_assignments = | ||||||
|  |                     resources.get::<RenderResourceAssignments>().unwrap(); | ||||||
|  |                 Self::create_render_pass( | ||||||
|                     &self.wgpu_resources, |                     &self.wgpu_resources, | ||||||
|                     pass_descriptor, |                     pass_descriptor, | ||||||
|                     &global_render_resource_assignments, |                     &global_render_resource_assignments, | ||||||
|                     &mut encoder, |                     &mut encoder, | ||||||
|                     &primary_swap_chain, |                     &primary_swap_chain, | ||||||
|                     &swap_chain_outputs, |                     &swap_chain_outputs, | ||||||
|             ); |                 ) | ||||||
|  |             }; | ||||||
|             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() { | ||||||
|                     if let Some(compiled_pipelines_iter) = |                     if let Some(compiled_pipelines_iter) = | ||||||
| @ -705,4 +534,141 @@ impl Renderer for WgpuRenderer { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fn setup_render_pipeline( | ||||||
|  |         &mut self, | ||||||
|  |         pipeline_handle: Handle<PipelineDescriptor>, | ||||||
|  |         pipeline_descriptor: &mut PipelineDescriptor, | ||||||
|  |         shader_storage: &AssetStorage<Shader>, | ||||||
|  |     ) { | ||||||
|  |         if self.render_pipelines.contains_key(&pipeline_handle) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let device = self.device.borrow(); | ||||||
|  |         let layout = pipeline_descriptor.get_layout().unwrap(); | ||||||
|  |         for bind_group in layout.bind_groups.iter() { | ||||||
|  |             if let None = self.wgpu_resources.bind_group_layouts.get(&bind_group.id) { | ||||||
|  |                 let bind_group_layout_binding = bind_group | ||||||
|  |                     .bindings | ||||||
|  |                     .iter() | ||||||
|  |                     .map(|binding| wgpu::BindGroupLayoutEntry { | ||||||
|  |                         binding: binding.index, | ||||||
|  |                         visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, | ||||||
|  |                         ty: (&binding.bind_type).into(), | ||||||
|  |                     }) | ||||||
|  |                     .collect::<Vec<wgpu::BindGroupLayoutEntry>>(); | ||||||
|  |                 let wgpu_bind_group_layout = | ||||||
|  |                     device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { | ||||||
|  |                         bindings: bind_group_layout_binding.as_slice(), | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|  |                 self.wgpu_resources | ||||||
|  |                     .bind_group_layouts | ||||||
|  |                     .insert(bind_group.id, wgpu_bind_group_layout); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // setup and collect bind group layouts
 | ||||||
|  |         let bind_group_layouts = layout | ||||||
|  |             .bind_groups | ||||||
|  |             .iter() | ||||||
|  |             .map(|bind_group| { | ||||||
|  |                 self.wgpu_resources | ||||||
|  |                     .bind_group_layouts | ||||||
|  |                     .get(&bind_group.id) | ||||||
|  |                     .unwrap() | ||||||
|  |             }) | ||||||
|  |             .collect::<Vec<&wgpu::BindGroupLayout>>(); | ||||||
|  | 
 | ||||||
|  |         let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { | ||||||
|  |             bind_group_layouts: bind_group_layouts.as_slice(), | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         let owned_vertex_buffer_descriptors = layout | ||||||
|  |             .vertex_buffer_descriptors | ||||||
|  |             .iter() | ||||||
|  |             .map(|v| v.into()) | ||||||
|  |             .collect::<Vec<OwnedWgpuVertexBufferDescriptor>>(); | ||||||
|  | 
 | ||||||
|  |         let color_states = pipeline_descriptor | ||||||
|  |             .color_states | ||||||
|  |             .iter() | ||||||
|  |             .map(|c| c.into()) | ||||||
|  |             .collect::<Vec<wgpu::ColorStateDescriptor>>(); | ||||||
|  | 
 | ||||||
|  |         if let None = self | ||||||
|  |             .wgpu_resources | ||||||
|  |             .shader_modules | ||||||
|  |             .get(&pipeline_descriptor.shader_stages.vertex) | ||||||
|  |         { | ||||||
|  |             self.wgpu_resources.create_shader_module( | ||||||
|  |                 &device, | ||||||
|  |                 pipeline_descriptor.shader_stages.vertex, | ||||||
|  |                 shader_storage, | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment { | ||||||
|  |             if let None = self.wgpu_resources.shader_modules.get(&fragment_handle) { | ||||||
|  |                 self.wgpu_resources | ||||||
|  |                     .create_shader_module(&device, fragment_handle, shader_storage); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let vertex_shader_module = self | ||||||
|  |             .wgpu_resources | ||||||
|  |             .shader_modules | ||||||
|  |             .get(&pipeline_descriptor.shader_stages.vertex) | ||||||
|  |             .unwrap(); | ||||||
|  | 
 | ||||||
|  |         let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment { | ||||||
|  |             Some(fragment_handle) => Some( | ||||||
|  |                 self.wgpu_resources | ||||||
|  |                     .shader_modules | ||||||
|  |                     .get(&fragment_handle) | ||||||
|  |                     .unwrap(), | ||||||
|  |             ), | ||||||
|  |             None => None, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let mut render_pipeline_descriptor = wgpu::RenderPipelineDescriptor { | ||||||
|  |             layout: &pipeline_layout, | ||||||
|  |             vertex_stage: wgpu::ProgrammableStageDescriptor { | ||||||
|  |                 module: &vertex_shader_module, | ||||||
|  |                 entry_point: "main", | ||||||
|  |             }, | ||||||
|  |             fragment_stage: match pipeline_descriptor.shader_stages.fragment { | ||||||
|  |                 Some(_) => Some(wgpu::ProgrammableStageDescriptor { | ||||||
|  |                     entry_point: "main", | ||||||
|  |                     module: fragment_shader_module.as_ref().unwrap(), | ||||||
|  |                 }), | ||||||
|  |                 None => None, | ||||||
|  |             }, | ||||||
|  |             rasterization_state: pipeline_descriptor | ||||||
|  |                 .rasterization_state | ||||||
|  |                 .as_ref() | ||||||
|  |                 .map(|r| r.into()), | ||||||
|  |             primitive_topology: pipeline_descriptor.primitive_topology.into(), | ||||||
|  |             color_states: &color_states, | ||||||
|  |             depth_stencil_state: pipeline_descriptor | ||||||
|  |                 .depth_stencil_state | ||||||
|  |                 .as_ref() | ||||||
|  |                 .map(|d| d.into()), | ||||||
|  |             vertex_state: wgpu::VertexStateDescriptor { | ||||||
|  |                 index_format: pipeline_descriptor.index_format.into(), | ||||||
|  |                 vertex_buffers: &owned_vertex_buffer_descriptors | ||||||
|  |                     .iter() | ||||||
|  |                     .map(|v| v.into()) | ||||||
|  |                     .collect::<Vec<wgpu::VertexBufferDescriptor>>(), | ||||||
|  |             }, | ||||||
|  |             sample_count: pipeline_descriptor.sample_count, | ||||||
|  |             sample_mask: pipeline_descriptor.sample_mask, | ||||||
|  |             alpha_to_coverage_enabled: pipeline_descriptor.alpha_to_coverage_enabled, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         let render_pipeline = device.create_render_pipeline(&mut render_pipeline_descriptor); | ||||||
|  |         self.render_pipelines | ||||||
|  |             .insert(pipeline_handle, render_pipeline); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson