RenderGraph2: UniformNode
This commit is contained in:
		
							parent
							
								
									209b4b48d9
								
							
						
					
					
						commit
						512bf118bf
					
				| @ -54,7 +54,7 @@ use bevy_window::{WindowCreated, WindowReference, WindowResized}; | |||||||
| use pass::PassDescriptor; | use pass::PassDescriptor; | ||||||
| use pipeline::pipelines::build_forward_pipeline; | use pipeline::pipelines::build_forward_pipeline; | ||||||
| use render_graph_2::{ | use render_graph_2::{ | ||||||
|     nodes::{Camera2dNode, CameraNode, PassNode, WindowSwapChainNode, WindowTextureNode}, |     nodes::{Camera2dNode, CameraNode, PassNode, WindowSwapChainNode, WindowTextureNode, UniformNode}, | ||||||
|     RenderGraph2, |     RenderGraph2, | ||||||
| }; | }; | ||||||
| use render_resource::resource_providers::mesh_resource_provider_system; | use render_resource::resource_providers::mesh_resource_provider_system; | ||||||
| @ -78,7 +78,6 @@ impl RenderPlugin { | |||||||
|         render_graph |         render_graph | ||||||
|             .build(&mut pipelines, &mut shaders) |             .build(&mut pipelines, &mut shaders) | ||||||
|             .add_resource_provider(LightResourceProvider::new(10)) |             .add_resource_provider(LightResourceProvider::new(10)) | ||||||
|             .add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true)) |  | ||||||
|             .add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true)); |             .add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -124,6 +123,7 @@ impl AppPlugin for RenderPlugin { | |||||||
|             let resources = app.resources_mut(); |             let resources = app.resources_mut(); | ||||||
|             render_graph.add_system_node_named("camera", CameraNode::default(), resources); |             render_graph.add_system_node_named("camera", CameraNode::default(), resources); | ||||||
|             render_graph.add_system_node_named("camera2d", Camera2dNode::default(), resources); |             render_graph.add_system_node_named("camera2d", Camera2dNode::default(), resources); | ||||||
|  |             render_graph.add_system_node_named("standard_material", UniformNode::<StandardMaterial>::new(true), resources); | ||||||
|             render_graph.add_node_named( |             render_graph.add_node_named( | ||||||
|                 "swapchain", |                 "swapchain", | ||||||
|                 WindowSwapChainNode::new( |                 WindowSwapChainNode::new( | ||||||
| @ -185,6 +185,7 @@ impl AppPlugin for RenderPlugin { | |||||||
|             // TODO: replace these with "autowire" groups
 |             // TODO: replace these with "autowire" groups
 | ||||||
|             render_graph.add_node_edge("camera", "main_pass").unwrap(); |             render_graph.add_node_edge("camera", "main_pass").unwrap(); | ||||||
|             render_graph.add_node_edge("camera2d", "main_pass").unwrap(); |             render_graph.add_node_edge("camera2d", "main_pass").unwrap(); | ||||||
|  |             render_graph.add_node_edge("standard_material", "main_pass").unwrap(); | ||||||
|             render_graph |             render_graph | ||||||
|                 .add_slot_edge( |                 .add_slot_edge( | ||||||
|                     "swapchain", |                     "swapchain", | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ use crate::{ | |||||||
|     render_resource::{ |     render_resource::{ | ||||||
|         BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, |         BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, | ||||||
|     }, |     }, | ||||||
|     renderer_2::RenderContext, |     renderer_2::{RenderResourceContext, GlobalRenderResourceContext}, | ||||||
|     shader::{Shader, ShaderSource}, |     shader::{Shader, ShaderSource}, | ||||||
|     Renderable, |     Renderable, | ||||||
| }; | }; | ||||||
| @ -48,7 +48,7 @@ impl PipelineCompiler { | |||||||
|         shader_storage: &AssetStorage<Shader>, |         shader_storage: &AssetStorage<Shader>, | ||||||
|         vertex_buffer_descriptors: &VertexBufferDescriptors, |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|         pipeline_descriptor: &mut PipelineDescriptor, |         pipeline_descriptor: &mut PipelineDescriptor, | ||||||
|         render_context: &dyn RenderContext, |         render_resource_context: &dyn RenderResourceContext, | ||||||
|         render_resource_assignments: &RenderResourceAssignments, |         render_resource_assignments: &RenderResourceAssignments, | ||||||
|     ) { |     ) { | ||||||
|         let vertex_spirv = shader_storage |         let vertex_spirv = shader_storage | ||||||
| @ -75,7 +75,7 @@ impl PipelineCompiler { | |||||||
|         for bind_group in layout.bind_groups.iter_mut() { |         for bind_group in layout.bind_groups.iter_mut() { | ||||||
|             for binding in bind_group.bindings.iter_mut() { |             for binding in bind_group.bindings.iter_mut() { | ||||||
|                 if let Some(render_resource) = render_resource_assignments.get(&binding.name) { |                 if let Some(render_resource) = render_resource_assignments.get(&binding.name) { | ||||||
|                     render_context.resources().get_resource_info( |                     render_resource_context.get_resource_info( | ||||||
|                         render_resource, |                         render_resource, | ||||||
|                         &mut |resource_info| { |                         &mut |resource_info| { | ||||||
|                             if let Some(ResourceInfo::Buffer(BufferInfo { is_dynamic, .. })) = |                             if let Some(ResourceInfo::Buffer(BufferInfo { is_dynamic, .. })) = | ||||||
| @ -142,7 +142,7 @@ impl PipelineCompiler { | |||||||
|         &mut self, |         &mut self, | ||||||
|         vertex_buffer_descriptors: &VertexBufferDescriptors, |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|         shader_storage: &mut AssetStorage<Shader>, |         shader_storage: &mut AssetStorage<Shader>, | ||||||
|         render_context: &dyn RenderContext, |         render_resource_context: &dyn RenderResourceContext, | ||||||
|         pipeline_descriptor: &PipelineDescriptor, |         pipeline_descriptor: &PipelineDescriptor, | ||||||
|         render_resource_assignments: &RenderResourceAssignments, |         render_resource_assignments: &RenderResourceAssignments, | ||||||
|     ) -> PipelineDescriptor { |     ) -> PipelineDescriptor { | ||||||
| @ -173,7 +173,7 @@ impl PipelineCompiler { | |||||||
|             shader_storage, |             shader_storage, | ||||||
|             vertex_buffer_descriptors, |             vertex_buffer_descriptors, | ||||||
|             &mut compiled_pipeline_descriptor, |             &mut compiled_pipeline_descriptor, | ||||||
|             render_context, |             render_resource_context, | ||||||
|             render_resource_assignments, |             render_resource_assignments, | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
| @ -187,7 +187,7 @@ impl PipelineCompiler { | |||||||
|         &mut self, |         &mut self, | ||||||
|         vertex_buffer_descriptors: &VertexBufferDescriptors, |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|         shader_pipeline_assignments: &mut PipelineAssignments, |         shader_pipeline_assignments: &mut PipelineAssignments, | ||||||
|         render_context: &dyn RenderContext, |         render_resource_context: &dyn RenderResourceContext, | ||||||
|         pipeline_storage: &mut AssetStorage<PipelineDescriptor>, |         pipeline_storage: &mut AssetStorage<PipelineDescriptor>, | ||||||
|         shader_storage: &mut AssetStorage<Shader>, |         shader_storage: &mut AssetStorage<Shader>, | ||||||
|         pipelines: &[Handle<PipelineDescriptor>], |         pipelines: &[Handle<PipelineDescriptor>], | ||||||
| @ -213,7 +213,7 @@ impl PipelineCompiler { | |||||||
|                 let compiled_pipeline = self.compile_pipeline( |                 let compiled_pipeline = self.compile_pipeline( | ||||||
|                     vertex_buffer_descriptors, |                     vertex_buffer_descriptors, | ||||||
|                     shader_storage, |                     shader_storage, | ||||||
|                     render_context, |                     render_resource_context, | ||||||
|                     pipeline_descriptor, |                     pipeline_descriptor, | ||||||
|                     render_resource_assignments, |                     render_resource_assignments, | ||||||
|                 ); |                 ); | ||||||
| @ -286,7 +286,6 @@ impl PipelineAssignments { | |||||||
| pub fn update_shader_assignments( | pub fn update_shader_assignments( | ||||||
|     world: &mut World, |     world: &mut World, | ||||||
|     resources: &Resources, |     resources: &Resources, | ||||||
|     render_context: &dyn RenderContext, |  | ||||||
| ) { | ) { | ||||||
|     // PERF: this seems like a lot of work for things that don't change that often.
 |     // PERF: this seems like a lot of work for things that don't change that often.
 | ||||||
|     // lots of string + hashset allocations. sees uniform_resource_provider for more context
 |     // lots of string + hashset allocations. sees uniform_resource_provider for more context
 | ||||||
| @ -295,6 +294,7 @@ pub fn update_shader_assignments( | |||||||
|         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 vertex_buffer_descriptors = resources.get::<VertexBufferDescriptors>().unwrap(); |         let vertex_buffer_descriptors = resources.get::<VertexBufferDescriptors>().unwrap(); | ||||||
|  |         let global_render_resource_context = resources.get::<GlobalRenderResourceContext>().unwrap(); | ||||||
|         let mut pipeline_descriptor_storage = resources |         let mut pipeline_descriptor_storage = resources | ||||||
|             .get_mut::<AssetStorage<PipelineDescriptor>>() |             .get_mut::<AssetStorage<PipelineDescriptor>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
| @ -312,7 +312,7 @@ pub fn update_shader_assignments( | |||||||
|             pipeline_compiler.update_shader_assignments( |             pipeline_compiler.update_shader_assignments( | ||||||
|                 &vertex_buffer_descriptors, |                 &vertex_buffer_descriptors, | ||||||
|                 &mut shader_pipeline_assignments, |                 &mut shader_pipeline_assignments, | ||||||
|                 render_context, |                 &*global_render_resource_context.context, | ||||||
|                 &mut pipeline_descriptor_storage, |                 &mut pipeline_descriptor_storage, | ||||||
|                 &mut shader_storage, |                 &mut shader_storage, | ||||||
|                 &renderable.pipelines, |                 &renderable.pipelines, | ||||||
|  | |||||||
| @ -3,9 +3,11 @@ mod camera2d_node; | |||||||
| mod window_texture_node; | mod window_texture_node; | ||||||
| mod window_swapchain_node; | mod window_swapchain_node; | ||||||
| mod pass_node; | mod pass_node; | ||||||
|  | mod uniform_node; | ||||||
| 
 | 
 | ||||||
| pub use camera_node::*; | pub use camera_node::*; | ||||||
| pub use camera2d_node::*; | pub use camera2d_node::*; | ||||||
| pub use window_texture_node::*; | pub use window_texture_node::*; | ||||||
| pub use window_swapchain_node::*; | pub use window_swapchain_node::*; | ||||||
| pub use pass_node::*; | pub use pass_node::*; | ||||||
|  | pub use uniform_node::*; | ||||||
							
								
								
									
										649
									
								
								bevy_render/src/render_graph_2/nodes/uniform_node.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										649
									
								
								bevy_render/src/render_graph_2/nodes/uniform_node.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,649 @@ | |||||||
|  | use crate::{ | ||||||
|  |     pipeline::VertexBufferDescriptors, | ||||||
|  |     render_graph_2::{CommandQueue, Node, ResourceSlots, SystemNode}, | ||||||
|  |     render_resource::{ | ||||||
|  |         BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments, | ||||||
|  |         RenderResourceAssignmentsId, ResourceInfo, | ||||||
|  |     }, | ||||||
|  |     renderer_2::{GlobalRenderResourceContext, RenderContext, RenderResourceContext}, | ||||||
|  |     shader::{AsUniforms, FieldBindType}, | ||||||
|  |     texture, Renderable, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use bevy_asset::{AssetStorage, Handle}; | ||||||
|  | use legion::prelude::*; | ||||||
|  | use std::{collections::HashMap, marker::PhantomData}; | ||||||
|  | use texture::{SamplerDescriptor, Texture, TextureDescriptor}; | ||||||
|  | 
 | ||||||
|  | pub const BIND_BUFFER_ALIGNMENT: usize = 256; | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct QueuedBufferWrite { | ||||||
|  |     buffer: RenderResource, | ||||||
|  |     offset: usize, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct BufferArrayStatus { | ||||||
|  |     new_item_count: usize, | ||||||
|  |     item_size: usize, | ||||||
|  |     aligned_size: usize, | ||||||
|  |     staging_buffer_offset: usize, | ||||||
|  |     buffer: Option<RenderResource>, | ||||||
|  |     queued_buffer_writes: Vec<QueuedBufferWrite>, | ||||||
|  |     current_item_count: usize, | ||||||
|  |     current_item_capacity: usize, | ||||||
|  |     indices: HashMap<RenderResourceAssignmentsId, usize>, | ||||||
|  |     current_index: usize, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl BufferArrayStatus { | ||||||
|  |     pub fn get_or_assign_index(&mut self, id: RenderResourceAssignmentsId) -> usize { | ||||||
|  |         if let Some(offset) = self.indices.get(&id) { | ||||||
|  |             *offset | ||||||
|  |         } else { | ||||||
|  |             if self.current_index == self.current_item_capacity { | ||||||
|  |                 panic!("no empty slots available in array"); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             let index = self.current_index; | ||||||
|  |             self.indices.insert(id, index); | ||||||
|  |             self.current_index += 1; | ||||||
|  |             index | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct UniformBufferArrays<T> | ||||||
|  | where | ||||||
|  |     T: AsUniforms, | ||||||
|  | { | ||||||
|  |     uniform_arrays: Vec<Option<(String, BufferArrayStatus)>>, | ||||||
|  |     _marker: PhantomData<T>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T> UniformBufferArrays<T> | ||||||
|  | where | ||||||
|  |     T: AsUniforms, | ||||||
|  | { | ||||||
|  |     fn new() -> Self { | ||||||
|  |         let mut uniform_arrays = Vec::new(); | ||||||
|  |         let field_infos = T::get_field_infos(); | ||||||
|  |         uniform_arrays.resize_with(field_infos.len(), || None); | ||||||
|  |         UniformBufferArrays { | ||||||
|  |             uniform_arrays, | ||||||
|  |             _marker: PhantomData::default(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     fn reset_new_item_counts(&mut self) { | ||||||
|  |         for buffer_status in self.uniform_arrays.iter_mut() { | ||||||
|  |             if let Some((_name, buffer_status)) = buffer_status { | ||||||
|  |                 buffer_status.new_item_count = 0; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn increment_uniform_counts(&mut self, uniforms: &T) { | ||||||
|  |         for (i, field_info) in T::get_field_infos().iter().enumerate() { | ||||||
|  |             if let Some(FieldBindType::Uniform { size }) = | ||||||
|  |                 uniforms.get_field_bind_type(&field_info.name) | ||||||
|  |             { | ||||||
|  |                 if let Some((ref _name, ref mut buffer_array_status)) = self.uniform_arrays[i] { | ||||||
|  |                     buffer_array_status.new_item_count += 1; | ||||||
|  |                 } else { | ||||||
|  |                     self.uniform_arrays[i] = Some(( | ||||||
|  |                         field_info.uniform_name.to_string(), | ||||||
|  |                         BufferArrayStatus { | ||||||
|  |                             new_item_count: 1, | ||||||
|  |                             queued_buffer_writes: Vec::new(), | ||||||
|  |                             aligned_size: Self::get_aligned_dynamic_uniform_size(size), | ||||||
|  |                             item_size: size, | ||||||
|  |                             staging_buffer_offset: 0, | ||||||
|  |                             buffer: None, | ||||||
|  |                             current_index: 0, | ||||||
|  |                             current_item_count: 0, | ||||||
|  |                             current_item_capacity: 0, | ||||||
|  |                             indices: HashMap::new(), | ||||||
|  |                         }, | ||||||
|  |                     )) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_aligned_dynamic_uniform_size(data_size: usize) -> usize { | ||||||
|  |         BIND_BUFFER_ALIGNMENT * ((data_size as f32 / BIND_BUFFER_ALIGNMENT as f32).ceil() as usize) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn setup_buffer_arrays( | ||||||
|  |         &mut self, | ||||||
|  |         render_resource_context: &dyn RenderResourceContext, | ||||||
|  |         dynamic_uniforms: bool, | ||||||
|  |     ) { | ||||||
|  |         for buffer_array_status in self.uniform_arrays.iter_mut() { | ||||||
|  |             if let Some((_name, buffer_array_status)) = buffer_array_status { | ||||||
|  |                 if dynamic_uniforms { | ||||||
|  |                     Self::setup_buffer_array(buffer_array_status, render_resource_context, true); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 buffer_array_status.queued_buffer_writes = | ||||||
|  |                     Vec::with_capacity(buffer_array_status.new_item_count); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn setup_buffer_array( | ||||||
|  |         buffer_array_status: &mut BufferArrayStatus, | ||||||
|  |         render_resource_context: &dyn RenderResourceContext, | ||||||
|  |         align: bool, | ||||||
|  |     ) { | ||||||
|  |         let new_capacity = if let Some(buffer) = buffer_array_status.buffer { | ||||||
|  |             let mut new_capacity = None; | ||||||
|  |             render_resource_context.get_resource_info(buffer, &mut |resource_info| { | ||||||
|  |                 new_capacity = if let Some(ResourceInfo::Buffer(BufferInfo { | ||||||
|  |                     array_info: Some(array_info), | ||||||
|  |                     .. | ||||||
|  |                 })) = resource_info | ||||||
|  |                 { | ||||||
|  |                     if array_info.item_capacity < buffer_array_status.new_item_count { | ||||||
|  |                         // over capacity. lets resize
 | ||||||
|  |                         Some( | ||||||
|  |                             buffer_array_status.new_item_count | ||||||
|  |                                 + buffer_array_status.new_item_count / 2, | ||||||
|  |                         ) | ||||||
|  |                     } else { | ||||||
|  |                         // under capacity. no change needed
 | ||||||
|  |                         None | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     // incorrect resource type. overwrite with new buffer
 | ||||||
|  |                     Some(buffer_array_status.new_item_count) | ||||||
|  |                 }; | ||||||
|  |             }); | ||||||
|  |             new_capacity | ||||||
|  |         } else { | ||||||
|  |             // buffer does not exist. create it now.
 | ||||||
|  |             Some(buffer_array_status.new_item_count) | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         if let Some(new_capacity) = new_capacity { | ||||||
|  |             let mut item_size = buffer_array_status.item_size; | ||||||
|  |             if align { | ||||||
|  |                 item_size = Self::get_aligned_dynamic_uniform_size(item_size); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             let total_size = item_size * new_capacity; | ||||||
|  | 
 | ||||||
|  |             let buffer = render_resource_context.create_buffer(BufferInfo { | ||||||
|  |                 array_info: Some(BufferArrayInfo { | ||||||
|  |                     item_capacity: new_capacity, | ||||||
|  |                     item_size, | ||||||
|  |                     ..Default::default() | ||||||
|  |                 }), | ||||||
|  |                 size: total_size, | ||||||
|  |                 buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, | ||||||
|  |                 is_dynamic: true, | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             buffer_array_status.current_item_capacity = new_capacity; | ||||||
|  | 
 | ||||||
|  |             log::trace!( | ||||||
|  |                 "creating buffer for uniform {}. size: {} item_capacity: {} item_size: {}", | ||||||
|  |                 std::any::type_name::<T>(), | ||||||
|  |                 total_size, | ||||||
|  |                 new_capacity, | ||||||
|  |                 item_size | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |             buffer_array_status.buffer = Some(buffer); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     fn update_staging_buffer_offsets(&mut self) -> usize { | ||||||
|  |         let mut size = 0; | ||||||
|  |         for dynamic_buffer_array_status in self.uniform_arrays.iter_mut() { | ||||||
|  |             if let Some((_name, ref mut buffer_array_status)) = dynamic_buffer_array_status { | ||||||
|  |                 buffer_array_status.staging_buffer_offset = size; | ||||||
|  |                 size += buffer_array_status.item_size * buffer_array_status.new_item_count; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         size | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn setup_uniform_buffer_resources( | ||||||
|  |         &mut self, | ||||||
|  |         uniforms: &T, | ||||||
|  |         dynamic_uniforms: bool, | ||||||
|  |         render_resources: &dyn RenderResourceContext, | ||||||
|  |         render_resource_assignments: &mut RenderResourceAssignments, | ||||||
|  |         staging_buffer: &mut [u8], | ||||||
|  |     ) { | ||||||
|  |         for (i, field_info) in T::get_field_infos().iter().enumerate() { | ||||||
|  |             let bind_type = uniforms.get_field_bind_type(&field_info.name); | ||||||
|  |             match bind_type { | ||||||
|  |                 Some(FieldBindType::Uniform { size }) => { | ||||||
|  |                     let (_name, uniform_buffer_status) = self.uniform_arrays[i].as_mut().unwrap(); | ||||||
|  |                     let (target_buffer, target_offset) = if dynamic_uniforms { | ||||||
|  |                         let buffer = uniform_buffer_status.buffer.unwrap(); | ||||||
|  |                         let mut offset = 0; | ||||||
|  |                         render_resources.get_resource_info(buffer, &mut |resource_info| { | ||||||
|  |                             if let Some(ResourceInfo::Buffer(BufferInfo { | ||||||
|  |                                 array_info: Some(ref array_info), | ||||||
|  |                                 is_dynamic: true, | ||||||
|  |                                 .. | ||||||
|  |                             })) = resource_info | ||||||
|  |                             { | ||||||
|  |                                 let index = uniform_buffer_status | ||||||
|  |                                     .get_or_assign_index(render_resource_assignments.id); | ||||||
|  |                                 render_resource_assignments.set_indexed( | ||||||
|  |                                     &field_info.uniform_name, | ||||||
|  |                                     buffer, | ||||||
|  |                                     (index * array_info.item_size) as u32, | ||||||
|  |                                 ); | ||||||
|  |                                 offset = index * uniform_buffer_status.aligned_size; | ||||||
|  |                             } else { | ||||||
|  |                                 panic!("Expected a dynamic uniform buffer"); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                         (buffer, offset) | ||||||
|  |                     } else { | ||||||
|  |                         let resource = match render_resource_assignments | ||||||
|  |                             .get(field_info.uniform_name) | ||||||
|  |                         { | ||||||
|  |                             Some(render_resource) => render_resource, | ||||||
|  |                             None => { | ||||||
|  |                                 let resource = render_resources.create_buffer(BufferInfo { | ||||||
|  |                                     size, | ||||||
|  |                                     buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, | ||||||
|  |                                     ..Default::default() | ||||||
|  |                                 }); | ||||||
|  |                                 render_resource_assignments.set(&field_info.uniform_name, resource); | ||||||
|  |                                 resource | ||||||
|  |                             } | ||||||
|  |                         }; | ||||||
|  | 
 | ||||||
|  |                         (resource, 0) | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|  |                     let staging_buffer_start = uniform_buffer_status.staging_buffer_offset | ||||||
|  |                         + (uniform_buffer_status.queued_buffer_writes.len() | ||||||
|  |                             * uniform_buffer_status.item_size); | ||||||
|  |                     if let Some(uniform_bytes) = | ||||||
|  |                         uniforms.get_uniform_bytes_ref(&field_info.uniform_name) | ||||||
|  |                     { | ||||||
|  |                         if size != uniform_bytes.len() { | ||||||
|  |                             panic!("The number of bytes produced for {} do not match the expected count. Actual: {}. Expected: {}.", field_info.uniform_name, uniform_bytes.len(), size); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         staging_buffer | ||||||
|  |                             [staging_buffer_start..(staging_buffer_start + uniform_bytes.len())] | ||||||
|  |                             .copy_from_slice(uniform_bytes); | ||||||
|  |                     } else if let Some(uniform_bytes) = | ||||||
|  |                         uniforms.get_uniform_bytes(field_info.uniform_name) | ||||||
|  |                     { | ||||||
|  |                         if size != uniform_bytes.len() { | ||||||
|  |                             panic!("The number of bytes produced for {} do not match the expected count. Actual: {}. Expected: {}.", field_info.uniform_name, uniform_bytes.len(), size); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         staging_buffer | ||||||
|  |                             [staging_buffer_start..(staging_buffer_start + uniform_bytes.len())] | ||||||
|  |                             .copy_from_slice(&uniform_bytes); | ||||||
|  |                     } else { | ||||||
|  |                         panic!( | ||||||
|  |                             "failed to get data from uniform: {}", | ||||||
|  |                             field_info.uniform_name | ||||||
|  |                         ); | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|  |                     uniform_buffer_status | ||||||
|  |                         .queued_buffer_writes | ||||||
|  |                         .push(QueuedBufferWrite { | ||||||
|  |                             buffer: target_buffer, | ||||||
|  |                             offset: target_offset, | ||||||
|  |                         }); | ||||||
|  |                 } | ||||||
|  |                 _ => {} | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn copy_staging_buffer_to_final_buffers( | ||||||
|  |         &mut self, | ||||||
|  |         command_queue: &mut CommandQueue, | ||||||
|  |         staging_buffer: RenderResource, | ||||||
|  |     ) { | ||||||
|  |         for uniform_buffer_status in self.uniform_arrays.iter_mut() { | ||||||
|  |             if let Some((_name, buffer_array_status)) = uniform_buffer_status { | ||||||
|  |                 let start = buffer_array_status.staging_buffer_offset; | ||||||
|  |                 for (i, queued_buffer_write) in buffer_array_status | ||||||
|  |                     .queued_buffer_writes | ||||||
|  |                     .drain(..) | ||||||
|  |                     .enumerate() | ||||||
|  |                 { | ||||||
|  |                     command_queue.copy_buffer_to_buffer( | ||||||
|  |                         staging_buffer, | ||||||
|  |                         (start + (i * buffer_array_status.item_size)) as u64, | ||||||
|  |                         queued_buffer_write.buffer, | ||||||
|  |                         queued_buffer_write.offset as u64, | ||||||
|  |                         buffer_array_status.item_size as u64, | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Default)] | ||||||
|  | pub struct UniformNode<T> | ||||||
|  | where | ||||||
|  |     T: AsUniforms, | ||||||
|  | { | ||||||
|  |     command_queue: CommandQueue, | ||||||
|  |     dynamic_uniforms: bool, | ||||||
|  |     _marker: PhantomData<T>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T> UniformNode<T> | ||||||
|  | where | ||||||
|  |     T: AsUniforms, | ||||||
|  | { | ||||||
|  |     pub fn new(dynamic_uniforms: bool) -> Self { | ||||||
|  |         UniformNode { | ||||||
|  |             command_queue: CommandQueue::default(), | ||||||
|  |             dynamic_uniforms, | ||||||
|  |             _marker: PhantomData::default(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn initialize_vertex_buffer_descriptor( | ||||||
|  |         vertex_buffer_descriptors: &mut VertexBufferDescriptors, | ||||||
|  |     ) { | ||||||
|  |         let vertex_buffer_descriptor = T::get_vertex_buffer_descriptor(); | ||||||
|  |         if let Some(vertex_buffer_descriptor) = vertex_buffer_descriptor { | ||||||
|  |             if let None = vertex_buffer_descriptors.get(&vertex_buffer_descriptor.name) { | ||||||
|  |                 vertex_buffer_descriptors.set(vertex_buffer_descriptor.clone()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn setup_uniform_texture_resources( | ||||||
|  |         uniforms: &T, | ||||||
|  |         texture_storage: &AssetStorage<Texture>, | ||||||
|  |         render_resource_context: &dyn RenderResourceContext, | ||||||
|  |         render_resource_assignments: &mut RenderResourceAssignments, | ||||||
|  |     ) { | ||||||
|  |         for field_info in T::get_field_infos().iter() { | ||||||
|  |             let bind_type = uniforms.get_field_bind_type(&field_info.name); | ||||||
|  |             match bind_type { | ||||||
|  |                 Some(FieldBindType::Texture) => { | ||||||
|  |                     let texture_handle = uniforms | ||||||
|  |                         .get_uniform_texture(&field_info.texture_name) | ||||||
|  |                         .unwrap(); | ||||||
|  |                     let (texture_resource, sampler_resource) = match render_resource_context | ||||||
|  |                         .get_asset_resource(texture_handle, texture::TEXTURE_ASSET_INDEX) | ||||||
|  |                     { | ||||||
|  |                         Some(texture_resource) => ( | ||||||
|  |                             texture_resource, | ||||||
|  |                             render_resource_context | ||||||
|  |                                 .get_asset_resource(texture_handle, texture::SAMPLER_ASSET_INDEX) | ||||||
|  |                                 .unwrap(), | ||||||
|  |                         ), | ||||||
|  |                         None => { | ||||||
|  |                             let texture = texture_storage.get(&texture_handle).unwrap(); | ||||||
|  | 
 | ||||||
|  |                             let texture_descriptor: TextureDescriptor = texture.into(); | ||||||
|  |                             let texture_resource = | ||||||
|  |                                 render_resource_context.create_texture(&texture_descriptor); | ||||||
|  |                             // TODO: queue texture copy
 | ||||||
|  |                             // .create_texture_with_data(&texture_descriptor, &texture.data);
 | ||||||
|  | 
 | ||||||
|  |                             let sampler_descriptor: SamplerDescriptor = texture.into(); | ||||||
|  |                             let sampler_resource = | ||||||
|  |                                 render_resource_context.create_sampler(&sampler_descriptor); | ||||||
|  | 
 | ||||||
|  |                             render_resource_context.set_asset_resource( | ||||||
|  |                                 texture_handle, | ||||||
|  |                                 texture_resource, | ||||||
|  |                                 0, | ||||||
|  |                             ); | ||||||
|  |                             render_resource_context.set_asset_resource( | ||||||
|  |                                 texture_handle, | ||||||
|  |                                 sampler_resource, | ||||||
|  |                                 1, | ||||||
|  |                             ); | ||||||
|  |                             (texture_resource, sampler_resource) | ||||||
|  |                         } | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|  |                     render_resource_assignments.set(field_info.texture_name, texture_resource); | ||||||
|  |                     render_resource_assignments.set(field_info.sampler_name, sampler_resource); | ||||||
|  |                 } | ||||||
|  |                 _ => {} | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T> Node for UniformNode<T> | ||||||
|  | where | ||||||
|  |     T: AsUniforms, | ||||||
|  | { | ||||||
|  |     fn update( | ||||||
|  |         &mut self, | ||||||
|  |         _world: &World, | ||||||
|  |         _resources: &Resources, | ||||||
|  |         render_context: &mut dyn RenderContext, | ||||||
|  |         _input: &ResourceSlots, | ||||||
|  |         _output: &mut ResourceSlots, | ||||||
|  |     ) { | ||||||
|  |         self.command_queue.execute(render_context); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T> SystemNode for UniformNode<T> | ||||||
|  | where | ||||||
|  |     T: AsUniforms, | ||||||
|  | { | ||||||
|  |     fn get_system(&self, resources: &mut Resources) -> Box<dyn Schedulable> { | ||||||
|  |         let mut command_queue = self.command_queue.clone(); | ||||||
|  |         let mut uniform_buffer_arrays = UniformBufferArrays::<T>::new(); | ||||||
|  |         let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap(); | ||||||
|  |         let dynamic_uniforms = self.dynamic_uniforms; | ||||||
|  |         let mut staging_buffer_resource = None; | ||||||
|  |         UniformNode::<T>::initialize_vertex_buffer_descriptor(&mut vertex_buffer_descriptors); | ||||||
|  |         // TODO: maybe run "update" here
 | ||||||
|  |         SystemBuilder::new("uniform_resource_provider") | ||||||
|  |             .read_resource::<AssetStorage<T>>() | ||||||
|  |             .read_resource::<AssetStorage<Texture>>() | ||||||
|  |             .read_resource::<GlobalRenderResourceContext>() | ||||||
|  |             // TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same
 | ||||||
|  |             .with_query(<(Read<T>, Read<Renderable>)>::query()) | ||||||
|  |             .with_query(<(Read<Handle<T>>, Read<Renderable>)>::query()) | ||||||
|  |             .with_query(<(Read<T>, Write<Renderable>)>::query()) | ||||||
|  |             .with_query(<(Read<Handle<T>>, Write<Renderable>)>::query()) | ||||||
|  |             .build( | ||||||
|  |                 move |_, | ||||||
|  |                       world, | ||||||
|  |                       (assets, textures, global_render_resource_context), | ||||||
|  |                       ( | ||||||
|  |                     read_resource_query, | ||||||
|  |                     read_handle_query, | ||||||
|  |                     write_resource_query, | ||||||
|  |                     write_handle_query, | ||||||
|  |                 )| { | ||||||
|  |                     let render_resource_context = &*global_render_resource_context.context; | ||||||
|  |                     if let Some(staging_buffer_resource) = staging_buffer_resource { | ||||||
|  |                         render_resource_context.remove_buffer(staging_buffer_resource); | ||||||
|  |                     } | ||||||
|  |                     staging_buffer_resource = None; | ||||||
|  | 
 | ||||||
|  |                     uniform_buffer_arrays.reset_new_item_counts(); | ||||||
|  |                     // update uniforms info
 | ||||||
|  |                     for (uniforms, renderable) in read_resource_query.iter(world) { | ||||||
|  |                         if !renderable.is_visible { | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if renderable.is_instanced { | ||||||
|  |                             panic!("instancing not currently supported"); | ||||||
|  |                         } else { | ||||||
|  |                             uniform_buffer_arrays.increment_uniform_counts(&uniforms); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // update uniform handles info
 | ||||||
|  |                     for (handle, renderable) in read_handle_query.iter(world) { | ||||||
|  |                         if !renderable.is_visible { | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if renderable.is_instanced { | ||||||
|  |                             panic!("instancing not currently supported"); | ||||||
|  |                         } else { | ||||||
|  |                             let uniforms = assets | ||||||
|  |                                 .get(&handle) | ||||||
|  |                                 .expect("Handle points to a non-existent resource"); | ||||||
|  |                             // TODO: only increment count if we haven't seen this uniform handle before
 | ||||||
|  |                             uniform_buffer_arrays.increment_uniform_counts(&uniforms); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     uniform_buffer_arrays | ||||||
|  |                         .setup_buffer_arrays(render_resource_context, dynamic_uniforms); | ||||||
|  |                     let staging_buffer_size = uniform_buffer_arrays.update_staging_buffer_offsets(); | ||||||
|  | 
 | ||||||
|  |                     for (uniforms, mut renderable) in write_resource_query.iter_mut(world) { | ||||||
|  |                         if !renderable.is_visible { | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if renderable.is_instanced { | ||||||
|  |                             panic!("instancing not currently supported"); | ||||||
|  |                         } else { | ||||||
|  |                             Self::setup_uniform_texture_resources( | ||||||
|  |                                 &uniforms, | ||||||
|  |                                 textures, | ||||||
|  |                                 render_resource_context, | ||||||
|  |                                 &mut renderable.render_resource_assignments, | ||||||
|  |                             ) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     for (handle, mut renderable) in write_handle_query.iter_mut(world) { | ||||||
|  |                         if !renderable.is_visible { | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if renderable.is_instanced { | ||||||
|  |                             panic!("instancing not currently supported"); | ||||||
|  |                         } else { | ||||||
|  |                             let uniforms = assets | ||||||
|  |                                 .get(&handle) | ||||||
|  |                                 .expect("Handle points to a non-existent resource"); | ||||||
|  |                             Self::setup_uniform_texture_resources( | ||||||
|  |                                 &uniforms, | ||||||
|  |                                 textures, | ||||||
|  |                                 render_resource_context, | ||||||
|  |                                 &mut renderable.render_resource_assignments, | ||||||
|  |                             ) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     if staging_buffer_size == 0 { | ||||||
|  |                         let mut staging_buffer: [u8; 0] = []; | ||||||
|  |                         for (uniforms, mut renderable) in write_resource_query.iter_mut(world) { | ||||||
|  |                             if !renderable.is_visible { | ||||||
|  |                                 return; | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             if renderable.is_instanced { | ||||||
|  |                                 panic!("instancing not currently supported"); | ||||||
|  |                             } else { | ||||||
|  |                                 uniform_buffer_arrays.setup_uniform_buffer_resources( | ||||||
|  |                                     &uniforms, | ||||||
|  |                                     dynamic_uniforms, | ||||||
|  |                                     render_resource_context, | ||||||
|  |                                     &mut renderable.render_resource_assignments, | ||||||
|  |                                     &mut staging_buffer, | ||||||
|  |                                 ); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         for (handle, mut renderable) in write_handle_query.iter_mut(world) { | ||||||
|  |                             if !renderable.is_visible { | ||||||
|  |                                 return; | ||||||
|  |                             } | ||||||
|  |                             if renderable.is_instanced { | ||||||
|  |                                 panic!("instancing not currently supported"); | ||||||
|  |                             } else { | ||||||
|  |                                 let uniforms = assets | ||||||
|  |                                     .get(&handle) | ||||||
|  |                                     .expect("Handle points to a non-existent resource"); | ||||||
|  |                                 // TODO: only setup buffer if we haven't seen this handle before
 | ||||||
|  |                                 uniform_buffer_arrays.setup_uniform_buffer_resources( | ||||||
|  |                                     &uniforms, | ||||||
|  |                                     dynamic_uniforms, | ||||||
|  |                                     render_resource_context, | ||||||
|  |                                     &mut renderable.render_resource_assignments, | ||||||
|  |                                     &mut staging_buffer, | ||||||
|  |                                 ); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         let staging_buffer = render_resource_context.create_buffer_mapped( | ||||||
|  |                             BufferInfo { | ||||||
|  |                                 buffer_usage: BufferUsage::COPY_SRC, | ||||||
|  |                                 size: staging_buffer_size, | ||||||
|  |                                 ..Default::default() | ||||||
|  |                             }, | ||||||
|  |                             &mut |mut staging_buffer, _render_resources| { | ||||||
|  |                                 for (uniforms, mut renderable) in | ||||||
|  |                                     write_resource_query.iter_mut(world) | ||||||
|  |                                 { | ||||||
|  |                                     if !renderable.is_visible { | ||||||
|  |                                         return; | ||||||
|  |                                     } | ||||||
|  | 
 | ||||||
|  |                                     if renderable.is_instanced { | ||||||
|  |                                         panic!("instancing not currently supported"); | ||||||
|  |                                     } else { | ||||||
|  |                                         uniform_buffer_arrays.setup_uniform_buffer_resources( | ||||||
|  |                                             &uniforms, | ||||||
|  |                                             dynamic_uniforms, | ||||||
|  |                                             render_resource_context, | ||||||
|  |                                             &mut renderable.render_resource_assignments, | ||||||
|  |                                             &mut staging_buffer, | ||||||
|  |                                         ); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                                 for (handle, mut renderable) in write_handle_query.iter_mut(world) { | ||||||
|  |                                     if !renderable.is_visible { | ||||||
|  |                                         return; | ||||||
|  |                                     } | ||||||
|  |                                     if renderable.is_instanced { | ||||||
|  |                                         panic!("instancing not currently supported"); | ||||||
|  |                                     } else { | ||||||
|  |                                         let uniforms = assets | ||||||
|  |                                             .get(&handle) | ||||||
|  |                                             .expect("Handle points to a non-existent resource"); | ||||||
|  |                                         // TODO: only setup buffer if we haven't seen this handle before
 | ||||||
|  |                                         uniform_buffer_arrays.setup_uniform_buffer_resources( | ||||||
|  |                                             &uniforms, | ||||||
|  |                                             dynamic_uniforms, | ||||||
|  |                                             render_resource_context, | ||||||
|  |                                             &mut renderable.render_resource_assignments, | ||||||
|  |                                             &mut staging_buffer, | ||||||
|  |                                         ); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             }, | ||||||
|  |                         ); | ||||||
|  | 
 | ||||||
|  |                         uniform_buffer_arrays.copy_staging_buffer_to_final_buffers( | ||||||
|  |                             &mut command_queue, | ||||||
|  |                             staging_buffer, | ||||||
|  |                         ); | ||||||
|  | 
 | ||||||
|  |                         staging_buffer_resource = Some(staging_buffer); | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |             ) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -30,6 +30,7 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static { | |||||||
|     fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> RenderResource; |     fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> RenderResource; | ||||||
|     fn create_texture(&self, texture_descriptor: &TextureDescriptor) -> RenderResource; |     fn create_texture(&self, texture_descriptor: &TextureDescriptor) -> RenderResource; | ||||||
|     fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResource; |     fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResource; | ||||||
|  |     // TODO: remove RenderResourceContext here
 | ||||||
|     fn create_buffer_mapped( |     fn create_buffer_mapped( | ||||||
|         &self, |         &self, | ||||||
|         buffer_info: BufferInfo, |         buffer_info: BufferInfo, | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ use bevy_asset::{AssetStorage, Handle}; | |||||||
| use bevy_core::bytes::GetBytes; | use bevy_core::bytes::GetBytes; | ||||||
| use legion::prelude::*; | use legion::prelude::*; | ||||||
| 
 | 
 | ||||||
| pub trait AsUniforms { | pub trait AsUniforms: Send + Sync + 'static { | ||||||
|     fn get_field_infos() -> &'static [FieldInfo]; |     fn get_field_infos() -> &'static [FieldInfo]; | ||||||
|     fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>; |     fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>; | ||||||
|     fn get_uniform_texture(&self, name: &str) -> Option<Handle<Texture>>; |     fn get_uniform_texture(&self, name: &str) -> Option<Handle<Texture>>; | ||||||
|  | |||||||
| @ -187,19 +187,20 @@ impl WgpuRenderer { | |||||||
| 
 | 
 | ||||||
|     pub fn run_graph(&mut self, world: &mut World, resources: &mut Resources) { |     pub fn run_graph(&mut self, world: &mut World, resources: &mut Resources) { | ||||||
|         // run systems
 |         // run systems
 | ||||||
|         let mut executor = { |         let mut system_executor = { | ||||||
|             let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap(); |             let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap(); | ||||||
|             render_graph.take_executor() |             render_graph.take_executor() | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         if let Some(executor) = executor.as_mut() { |         if let Some(executor) = system_executor.as_mut() { | ||||||
|             executor.execute(world, resources); |             executor.execute(world, resources); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         update_shader_assignments(world, resources); | ||||||
|         render_resource_sets_system().run(world, resources); |         render_resource_sets_system().run(world, resources); | ||||||
| 
 | 
 | ||||||
|         let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap(); |         let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap(); | ||||||
|         if let Some(executor) = executor.take() { |         if let Some(executor) = system_executor.take() { | ||||||
|             render_graph.set_executor(executor); |             render_graph.set_executor(executor); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -209,10 +210,10 @@ impl WgpuRenderer { | |||||||
|         let mut borrowed = stages.borrow(&mut render_graph); |         let mut borrowed = stages.borrow(&mut render_graph); | ||||||
|         
 |         
 | ||||||
|         // execute stages
 |         // execute stages
 | ||||||
|         let executor = WgpuRenderGraphExecutor { |         let graph_executor = WgpuRenderGraphExecutor { | ||||||
|             max_thread_count: 2, |             max_thread_count: 2, | ||||||
|         }; |         }; | ||||||
|         executor.execute( |         graph_executor.execute( | ||||||
|             world, |             world, | ||||||
|             resources, |             resources, | ||||||
|             self.device.clone(), |             self.device.clone(), | ||||||
| @ -244,7 +245,6 @@ impl WgpuRenderer { | |||||||
| 
 | 
 | ||||||
|             self.update_resource_providers(world, resources, render_resource_context); |             self.update_resource_providers(world, resources, render_resource_context); | ||||||
| 
 | 
 | ||||||
|             update_shader_assignments(world, resources, &render_context); |  | ||||||
|             self.create_queued_textures(resources, &mut render_context.render_resources); |             self.create_queued_textures(resources, &mut render_context.render_resources); | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson