From 64cd9244131015f0954f3ec227fd8d78caf6b047 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Wed, 25 Mar 2020 17:31:59 -0700 Subject: [PATCH] refactor render resource assignments --- Cargo.toml | 2 +- src/app/app_builder.rs | 25 ++- .../assigned_meshes_draw_target.rs | 4 +- .../draw_targets/meshes_draw_target.rs | 2 +- .../draw_targets/ui_draw_target.rs | 2 +- src/render/pipeline/pipelines/forward/mod.rs | 4 +- .../{ => batching}/asset_batcher.rs | 161 +----------------- .../batching/asset_batcher2.rs | 144 ++++++++++++++++ src/render/render_resource/batching/batch.rs | 25 +++ src/render/render_resource/batching/mod.rs | 7 + .../entity_render_resource_assignments.rs | 14 +- src/render/render_resource/mod.rs | 4 +- .../render_resource_assignments.rs | 34 ++-- .../uniform_resource_provider.rs | 28 ++- src/render/renderable.rs | 8 +- src/render/renderer/renderer.rs | 2 +- .../wgpu_renderer/wgpu_render_pass.rs | 7 +- 17 files changed, 249 insertions(+), 224 deletions(-) rename src/render/render_resource/{ => batching}/asset_batcher.rs (61%) create mode 100644 src/render/render_resource/batching/asset_batcher2.rs create mode 100644 src/render/render_resource/batching/batch.rs create mode 100644 src/render/render_resource/batching/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 539dd770a0..6b2c7abcdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ rand = "0.7.2" gltf = "0.14.0" serde = { version = "1", features = ["derive"]} serde_json = "1.0" -uuid = { version = "0.8", features = ["v4"] } +uuid = { version = "0.8", features = ["v4", "serde"] } erased-serde = "0.3" type-uuid = "0.1" shaderc = "0.6" diff --git a/src/app/app_builder.rs b/src/app/app_builder.rs index 50a6799109..d65881f515 100644 --- a/src/app/app_builder.rs +++ b/src/app/app_builder.rs @@ -16,8 +16,7 @@ use bevy_transform::{prelude::LocalToWorld, transform_system_bundle}; use pipeline::PipelineDescriptor; use render_graph::{RenderGraph, RenderGraphBuilder}; use render_resource::{ - build_entity_render_resource_assignments_system, AssetBatchers, - EntityRenderResourceAssignments, RenderResourceAssignmentsProvider, + build_entity_render_resource_assignments_system, AssetBatchers, EntityRenderResourceAssignments, }; use shader::Shader; use std::collections::HashMap; @@ -158,8 +157,6 @@ impl AppBuilder { } pub fn add_default_resources(&mut self) -> &mut Self { - let mut asset_batchers = AssetBatchers::default(); - asset_batchers.batch_types2::(); let resources = self.resources.as_mut().unwrap(); resources.insert(Time::new()); resources.insert(AssetStorage::::new()); @@ -169,9 +166,25 @@ impl AppBuilder { resources.insert(AssetStorage::::new()); resources.insert(ShaderPipelineAssignments::new()); resources.insert(CompiledShaderMap::new()); - resources.insert(RenderResourceAssignmentsProvider::default()); resources.insert(EntityRenderResourceAssignments::default()); - resources.insert(asset_batchers); + self.batch_types2::(); + self + } + + pub fn batch_types2(&mut self) -> &mut Self + where + T1: 'static, + T2: 'static, + { + { + let resources = self.resources.as_mut().unwrap(); + let mut asset_batchers = resources + .get_mut_or_insert_with(|| AssetBatchers::default()) + .unwrap(); + + asset_batchers.batch_types2::(); + } + self } diff --git a/src/render/draw_target/draw_targets/assigned_meshes_draw_target.rs b/src/render/draw_target/draw_targets/assigned_meshes_draw_target.rs index 388a142aa9..4ee18247fe 100644 --- a/src/render/draw_target/draw_targets/assigned_meshes_draw_target.rs +++ b/src/render/draw_target/draw_targets/assigned_meshes_draw_target.rs @@ -66,7 +66,7 @@ impl DrawTarget for AssignedMeshesDrawTarget { } // TODO: validate bind group properties against shader uniform properties at least once - render_pass.set_bind_groups(renderable.render_resource_assignments.as_ref()); + render_pass.set_render_resource_assignments(Some(&renderable.render_resource_assignments)); render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1); } } @@ -99,7 +99,7 @@ impl DrawTarget for AssignedMeshesDrawTarget { } renderer.setup_bind_groups( - renderable.render_resource_assignments.as_ref().unwrap(), + &renderable.render_resource_assignments, pipeline_descriptor, ); } diff --git a/src/render/draw_target/draw_targets/meshes_draw_target.rs b/src/render/draw_target/draw_targets/meshes_draw_target.rs index eb0c530c70..3dfc7e1e1b 100644 --- a/src/render/draw_target/draw_targets/meshes_draw_target.rs +++ b/src/render/draw_target/draw_targets/meshes_draw_target.rs @@ -52,7 +52,7 @@ impl DrawTarget for MeshesDrawTarget { } // TODO: validate bind group properties against shader uniform properties at least once - render_pass.set_bind_groups(renderable.render_resource_assignments.as_ref()); + render_pass.set_render_resource_assignments(Some(&renderable.render_resource_assignments)); render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1); } } diff --git a/src/render/draw_target/draw_targets/ui_draw_target.rs b/src/render/draw_target/draw_targets/ui_draw_target.rs index 6958743613..a909d95365 100644 --- a/src/render/draw_target/draw_targets/ui_draw_target.rs +++ b/src/render/draw_target/draw_targets/ui_draw_target.rs @@ -54,7 +54,7 @@ impl DrawTarget for UiDrawTarget { } }; - render_pass.set_bind_groups(None); + render_pass.set_render_resource_assignments(None); render_pass.set_index_buffer(self.mesh_index_buffer.unwrap(), 0); render_pass.set_vertex_buffer(0, self.mesh_vertex_buffer.unwrap(), 0); render_pass.set_vertex_buffer(1, ui_instances_buffer, 0); diff --git a/src/render/pipeline/pipelines/forward/mod.rs b/src/render/pipeline/pipelines/forward/mod.rs index 8de964e0ea..0ca98e04aa 100644 --- a/src/render/pipeline/pipelines/forward/mod.rs +++ b/src/render/pipeline/pipelines/forward/mod.rs @@ -55,8 +55,8 @@ impl<'a> ForwardPipelineBuilder for RenderGraphBuilder<'a> { }, write_mask: ColorWrite::ALL, }) - .add_draw_target(resource_name::draw_target::ASSIGNED_MESHES) - .add_draw_target(resource_name::draw_target::ASSIGNED_BATCHES); + .add_draw_target(resource_name::draw_target::ASSIGNED_MESHES); + // .add_draw_target(resource_name::draw_target::ASSIGNED_BATCHES); }) } } diff --git a/src/render/render_resource/asset_batcher.rs b/src/render/render_resource/batching/asset_batcher.rs similarity index 61% rename from src/render/render_resource/asset_batcher.rs rename to src/render/render_resource/batching/asset_batcher.rs index e0b5b952be..cd4ede0f4f 100644 --- a/src/render/render_resource/asset_batcher.rs +++ b/src/render/render_resource/batching/asset_batcher.rs @@ -1,162 +1,7 @@ -use super::RenderResourceAssignments; -use crate::asset::{Handle, HandleId, HandleUntyped}; +use super::{AssetSetBatcher2, AssetSetBatcherKey2, Batch, BatchKey2}; +use crate::asset::{Handle, HandleId}; use legion::prelude::Entity; -use std::{any::TypeId, collections::HashMap, hash::Hash}; - -// TODO: if/when const generics land, revisit this design - -#[derive(Hash, Eq, PartialEq, Debug, Ord, PartialOrd)] -pub struct BatchKey2 { - pub handle1: HandleId, - pub handle2: HandleId, -} - -#[derive(Hash, Eq, PartialEq, Clone, Debug)] -pub struct AssetSetBatcherKey2 { - handle1_type: TypeId, - handle2_type: TypeId, -} - -struct EntitySetState2 { - handle1: Option, - handle2: Option, -} - -impl EntitySetState2 { - fn is_full(&self) -> bool { - self.handle1.is_some() && self.handle2.is_some() - } -} - -#[derive(PartialEq, Eq, Debug, Default)] -pub struct Batch { - pub handles: Vec, - pub entity_indices: HashMap, - pub current_index: usize, - pub render_resource_assignments: Option, -} - -impl Batch { - pub fn add_entity(&mut self, entity: Entity) { - if let None = self.entity_indices.get(&entity) { - self.entity_indices.insert(entity, self.current_index); - self.current_index += 1; - } - } -} - -pub struct AssetSetBatcher2 { - key: AssetSetBatcherKey2, - set_batches: HashMap, - entity_set_states: HashMap, -} - -impl AssetSetBatcher2 { - fn new(key: AssetSetBatcherKey2) -> Self { - AssetSetBatcher2 { - key, - set_batches: HashMap::new(), - entity_set_states: HashMap::new(), - } - } - - fn add_entity_to_set(&mut self, entity: Entity) { - // these unwraps are safe because this function is only called from set_entity_handle on a "full" state - let state = self.entity_set_states.get(&entity).unwrap(); - let key = BatchKey2 { - handle1: state.handle1.unwrap(), - handle2: state.handle2.unwrap(), - }; - - match self.set_batches.get_mut(&key) { - Some(batch) => { - batch.add_entity(entity); - } - None => { - let mut batch = Batch::default(); - - batch.handles.push(HandleUntyped { - id: key.handle1, - type_id: self.key.handle1_type, - }); - batch.handles.push(HandleUntyped { - id: key.handle2, - type_id: self.key.handle2_type, - }); - - batch.add_entity(entity); - self.set_batches.insert(key, batch); - } - } - } - - pub fn set_entity_handle1(&mut self, entity: Entity, handle_id: HandleId) { - match self.entity_set_states.get_mut(&entity) { - None => { - // TODO: when generalizing to set size 1, ensure you treat set as "full" here - self.entity_set_states.insert( - entity, - EntitySetState2 { - handle1: Some(handle_id), - handle2: None, - }, - ); - } - Some(state) => { - state.handle1 = Some(handle_id); - if state.is_full() { - self.add_entity_to_set(entity); - } - } - } - } - - pub fn set_entity_handle2(&mut self, entity: Entity, handle_id: HandleId) { - match self.entity_set_states.get_mut(&entity) { - None => { - // TODO: when generalizing to set size 1, ensure you treat set as "full" here - self.entity_set_states.insert( - entity, - EntitySetState2 { - handle1: None, - handle2: Some(handle_id), - }, - ); - } - Some(state) => { - state.handle2 = Some(handle_id); - if state.is_full() { - self.add_entity_to_set(entity); - } - } - } - } -} - -impl AssetBatcher for AssetSetBatcher2 { - fn set_entity_handle(&mut self, entity: Entity, handle_type: TypeId, handle_id: HandleId) { - if handle_type == self.key.handle1_type { - self.set_entity_handle1(entity, handle_id); - } else if handle_type == self.key.handle2_type { - self.set_entity_handle2(entity, handle_id); - } - } - fn get_batch2(&self, key: &BatchKey2) -> Option<&Batch> { - self.set_batches.get(key) - } - - fn get_batches2(&self) -> std::collections::hash_map::Iter<'_, BatchKey2, Batch> { - self.set_batches.iter() - } - - fn get_batches<'a>(&'a self) -> Box + 'a> { - Box::new(self.set_batches.values()) - } - - fn get_batches_mut<'a>(&'a mut self) -> Box + 'a> { - Box::new(self.set_batches.values_mut()) - } -} +use std::{any::TypeId, collections::HashMap}; pub trait AssetBatcher { fn set_entity_handle(&mut self, entity: Entity, handle_type: TypeId, handle_id: HandleId); diff --git a/src/render/render_resource/batching/asset_batcher2.rs b/src/render/render_resource/batching/asset_batcher2.rs new file mode 100644 index 0000000000..ec5bf57930 --- /dev/null +++ b/src/render/render_resource/batching/asset_batcher2.rs @@ -0,0 +1,144 @@ +use crate::{ + asset::{HandleId, HandleUntyped}, +}; +use legion::prelude::Entity; +use std::{any::TypeId, collections::HashMap, hash::Hash}; +use super::{AssetBatcher, Batch}; + +// TODO: if/when const generics land, revisit this design in favor of generic array lengths + +#[derive(Hash, Eq, PartialEq, Debug, Ord, PartialOrd)] +pub struct BatchKey2 { + pub handle1: HandleId, + pub handle2: HandleId, +} + +#[derive(Hash, Eq, PartialEq, Clone, Debug)] +pub struct AssetSetBatcherKey2 { + pub handle1_type: TypeId, + pub handle2_type: TypeId, +} + +struct EntitySetState2 { + handle1: Option, + handle2: Option, +} + +impl EntitySetState2 { + fn is_full(&self) -> bool { + self.handle1.is_some() && self.handle2.is_some() + } +} + +pub struct AssetSetBatcher2 { + key: AssetSetBatcherKey2, + set_batches: HashMap, + entity_set_states: HashMap, +} + +impl AssetSetBatcher2 { + pub fn new(key: AssetSetBatcherKey2) -> Self { + AssetSetBatcher2 { + key, + set_batches: HashMap::new(), + entity_set_states: HashMap::new(), + } + } + + pub fn add_entity_to_set(&mut self, entity: Entity) { + // these unwraps are safe because this function is only called from set_entity_handle on a "full" state + let state = self.entity_set_states.get(&entity).unwrap(); + let key = BatchKey2 { + handle1: state.handle1.unwrap(), + handle2: state.handle2.unwrap(), + }; + + match self.set_batches.get_mut(&key) { + Some(batch) => { + batch.add_entity(entity); + } + None => { + let mut batch = Batch::default(); + + batch.handles.push(HandleUntyped { + id: key.handle1, + type_id: self.key.handle1_type, + }); + batch.handles.push(HandleUntyped { + id: key.handle2, + type_id: self.key.handle2_type, + }); + + batch.add_entity(entity); + self.set_batches.insert(key, batch); + } + } + } + + pub fn set_entity_handle1(&mut self, entity: Entity, handle_id: HandleId) { + match self.entity_set_states.get_mut(&entity) { + None => { + // TODO: when generalizing to set size 1, ensure you treat set as "full" here + self.entity_set_states.insert( + entity, + EntitySetState2 { + handle1: Some(handle_id), + handle2: None, + }, + ); + } + Some(state) => { + state.handle1 = Some(handle_id); + if state.is_full() { + self.add_entity_to_set(entity); + } + } + } + } + + pub fn set_entity_handle2(&mut self, entity: Entity, handle_id: HandleId) { + match self.entity_set_states.get_mut(&entity) { + None => { + // TODO: when generalizing to set size 1, ensure you treat set as "full" here + self.entity_set_states.insert( + entity, + EntitySetState2 { + handle1: None, + handle2: Some(handle_id), + }, + ); + } + Some(state) => { + state.handle2 = Some(handle_id); + if state.is_full() { + self.add_entity_to_set(entity); + } + } + } + } +} + +impl AssetBatcher for AssetSetBatcher2 { + fn set_entity_handle(&mut self, entity: Entity, handle_type: TypeId, handle_id: HandleId) { + if handle_type == self.key.handle1_type { + self.set_entity_handle1(entity, handle_id); + } else if handle_type == self.key.handle2_type { + self.set_entity_handle2(entity, handle_id); + } + } + fn get_batch2(&self, key: &BatchKey2) -> Option<&Batch> { + self.set_batches.get(key) + } + + fn get_batches2(&self) -> std::collections::hash_map::Iter<'_, BatchKey2, Batch> { + self.set_batches.iter() + } + + fn get_batches<'a>(&'a self) -> Box + 'a> { + Box::new(self.set_batches.values()) + } + + fn get_batches_mut<'a>(&'a mut self) -> Box + 'a> { + Box::new(self.set_batches.values_mut()) + } +} \ No newline at end of file diff --git a/src/render/render_resource/batching/batch.rs b/src/render/render_resource/batching/batch.rs new file mode 100644 index 0000000000..fa79955066 --- /dev/null +++ b/src/render/render_resource/batching/batch.rs @@ -0,0 +1,25 @@ +use crate::{asset::HandleUntyped, render::render_resource::RenderResourceAssignments}; +use legion::prelude::Entity; +use std::collections::{HashSet, HashMap}; + +#[derive(PartialEq, Eq, Debug, Default)] +pub struct Batch { + pub handles: Vec, + pub entities: HashSet, + pub instanced_entity_indices: HashMap, + pub current_instanced_entity_index: usize, + pub render_resource_assignments: RenderResourceAssignments, +} + +impl Batch { + pub fn add_entity(&mut self, entity: Entity) { + self.entities.insert(entity); + } + + pub fn add_instanced_entity(&mut self, entity: Entity) { + if let None = self.instanced_entity_indices.get(&entity) { + self.instanced_entity_indices.insert(entity, self.current_instanced_entity_index); + self.current_instanced_entity_index += 1; + } + } +} diff --git a/src/render/render_resource/batching/mod.rs b/src/render/render_resource/batching/mod.rs new file mode 100644 index 0000000000..f60f4b96b8 --- /dev/null +++ b/src/render/render_resource/batching/mod.rs @@ -0,0 +1,7 @@ +mod asset_batcher; +mod asset_batcher2; +mod batch; + +pub use asset_batcher::*; +pub use asset_batcher2::*; +pub use batch::*; \ No newline at end of file diff --git a/src/render/render_resource/entity_render_resource_assignments.rs b/src/render/render_resource/entity_render_resource_assignments.rs index a6d5c4e45c..16bd7123ba 100644 --- a/src/render/render_resource/entity_render_resource_assignments.rs +++ b/src/render/render_resource/entity_render_resource_assignments.rs @@ -1,4 +1,4 @@ -use super::{RenderResourceAssignmentsId, RenderResourceAssignmentsProvider}; +use super::RenderResourceAssignmentsId; use crate::prelude::Renderable; use legion::prelude::*; use std::collections::HashMap; @@ -18,20 +18,14 @@ impl EntityRenderResourceAssignments { } } +// TODO: make sure this runs right before rendering pub fn build_entity_render_resource_assignments_system() -> Box { SystemBuilder::new("EntityRenderResourceAssignments") .write_resource::() - .write_resource::() .with_query(>::query().filter(changed::())) - .build(|_, world, (entity_assignments, provider), query| { + .build(|_, world, entity_assignments, query| { for (entity, mut renderable) in query.iter_entities_mut(world) { - if renderable.is_instanced { - renderable.render_resource_assignments = None; - } else if let None = renderable.render_resource_assignments { - let render_resource_assignments = provider.next(); - entity_assignments.set(render_resource_assignments.get_id(), entity); - renderable.render_resource_assignments = Some(render_resource_assignments); - } + entity_assignments.set(renderable.render_resource_assignments.get_id(), entity); } }) } diff --git a/src/render/render_resource/mod.rs b/src/render/render_resource/mod.rs index 2824c6348f..dd8f45daf9 100644 --- a/src/render/render_resource/mod.rs +++ b/src/render/render_resource/mod.rs @@ -1,4 +1,4 @@ -mod asset_batcher; +mod batching; mod buffer; mod entity_render_resource_assignments; mod render_resource; @@ -8,7 +8,7 @@ pub mod resource_name; mod resource_provider; pub mod resource_providers; -pub use asset_batcher::*; +pub use batching::*; pub use buffer::*; pub use entity_render_resource_assignments::*; pub use render_resource::*; diff --git a/src/render/render_resource/render_resource_assignments.rs b/src/render/render_resource/render_resource_assignments.rs index 3341930572..41cdc1f1e3 100644 --- a/src/render/render_resource/render_resource_assignments.rs +++ b/src/render/render_resource/render_resource_assignments.rs @@ -1,11 +1,13 @@ use super::RenderResource; use std::collections::{HashMap, HashSet}; +use uuid::Uuid; // PERF: if the assignments are scoped to a specific pipeline layout, then names could be replaced with indices here for a perf boost -#[derive(Eq, PartialEq, Debug)] +#[derive(Eq, PartialEq, Debug, Default)] pub struct RenderResourceAssignments { id: RenderResourceAssignmentsId, render_resources: HashMap, + vertex_buffers: HashMap)>, pub(crate) shader_defs: HashSet, // TODO: move offsets here to reduce hashing costs? // render_resource_offsets: HashMap, @@ -20,28 +22,24 @@ impl RenderResourceAssignments { self.render_resources.insert(name.to_string(), resource); } + pub fn get_vertex_buffer(&self, name: &str) -> Option<(RenderResource, Option)> { + self.vertex_buffers.get(name).cloned() + } + + pub fn set_vertex_buffer(&mut self, name: &str, vertices_resource: RenderResource, indices_resource: Option) { + self.vertex_buffers.insert(name.to_string(), (vertices_resource, indices_resource)); + } + pub fn get_id(&self) -> RenderResourceAssignmentsId { self.id } } #[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)] -pub struct RenderResourceAssignmentsId(usize); +pub struct RenderResourceAssignmentsId(Uuid); -#[derive(Default)] -pub struct RenderResourceAssignmentsProvider { - pub current_id: usize, -} - -impl RenderResourceAssignmentsProvider { - pub fn next(&mut self) -> RenderResourceAssignments { - let assignments = RenderResourceAssignments { - id: RenderResourceAssignmentsId(self.current_id), - render_resources: HashMap::new(), - shader_defs: HashSet::new(), - }; - - self.current_id += 1; - assignments +impl Default for RenderResourceAssignmentsId { + fn default() -> Self { + RenderResourceAssignmentsId(Uuid::new_v4()) } -} +} \ No newline at end of file diff --git a/src/render/render_resource/resource_providers/uniform_resource_provider.rs b/src/render/render_resource/resource_providers/uniform_resource_provider.rs index 278d5d0285..82d0fd580b 100644 --- a/src/render/render_resource/resource_providers/uniform_resource_provider.rs +++ b/src/render/render_resource/resource_providers/uniform_resource_provider.rs @@ -4,7 +4,7 @@ use crate::{ render_graph::RenderGraph, render_resource::{ AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, - RenderResourceAssignments, RenderResourceAssignmentsProvider, ResourceInfo, + RenderResourceAssignments, ResourceInfo, ResourceProvider, }, renderer::Renderer, @@ -51,6 +51,7 @@ type UniformHandleQuery = Query< >, >; +// TODO: rename to RenderResourceProvider pub struct UniformResourceProvider where T: AsUniforms + Send + Sync + 'static, @@ -123,7 +124,7 @@ where Self::update_shader_defs( &uniforms, - renderable.render_resource_assignments.as_mut().unwrap(), + &mut renderable.render_resource_assignments, ); } @@ -142,7 +143,6 @@ where if renderable.is_instanced { if self.is_instanceable { - asset_batchers.set_entity_handle(entity, *handle); self.increment_instance_count(|| { let uniforms = assets.get(&handle).unwrap(); Self::get_instance_size(uniforms) @@ -154,12 +154,13 @@ where ); } } else { + asset_batchers.set_entity_handle(entity, *handle); let uniforms = assets .get(&handle) .expect("Handle points to a non-existent resource"); Self::update_shader_defs( uniforms, - renderable.render_resource_assignments.as_mut().unwrap(), + &mut renderable.render_resource_assignments, ); self.increment_uniform_counts(&uniforms); @@ -391,7 +392,7 @@ where &uniforms, renderer, resources, - renderable.render_resource_assignments.as_mut().unwrap(), + &mut renderable.render_resource_assignments, staging_buffer, ) } @@ -422,7 +423,7 @@ where &uniforms, renderer, resources, - renderable.render_resource_assignments.as_mut().unwrap(), + &mut renderable.render_resource_assignments, staging_buffer, ) } @@ -443,9 +444,6 @@ where // all members of the batch until "UniformResourceProvider.update" has run for all members of the batch if let Some(asset_storage) = resources.get::>() { let mut asset_batchers = resources.get_mut::().unwrap(); - let mut render_resource_assignments_provider = resources - .get_mut::() - .unwrap(); let handle_type = std::any::TypeId::of::(); for batch in asset_batchers.get_handle_batches_mut::().unwrap() { let handle: Handle = batch @@ -455,19 +453,16 @@ where .map(|h| (*h).into()) .unwrap(); - let render_resource_assignments = batch - .render_resource_assignments - .get_or_insert_with(|| render_resource_assignments_provider.next()); if let Some(uniforms) = asset_storage.get(&handle) { self.setup_uniform_resources( uniforms, renderer, resources, - render_resource_assignments, + &mut batch.render_resource_assignments, staging_buffer, ); - Self::update_shader_defs(&uniforms, render_resource_assignments); + Self::update_shader_defs(&uniforms, &mut batch.render_resource_assignments); } } } @@ -628,7 +623,7 @@ where let mut staging_buffer: [u8; 0] = []; self.setup_uniforms_resources(world, resources, renderer, &mut staging_buffer); self.setup_handles_resources(world, resources, renderer, &mut staging_buffer); - // self.setup_batched_resources(world, resources, renderer, &mut staging_buffer); + // self.setup_batched_resources(world, resources, renderer, &mut staging_buffer); } else { let staging_buffer = renderer.create_buffer_mapped( BufferInfo { @@ -643,7 +638,8 @@ where }, ); - self.copy_staging_buffer_to_final_buffers(renderer, staging_buffer) + self.copy_staging_buffer_to_final_buffers(renderer, staging_buffer); + renderer.remove_buffer(staging_buffer); } } } diff --git a/src/render/renderable.rs b/src/render/renderable.rs index c035c10623..3a6d3bf989 100644 --- a/src/render/renderable.rs +++ b/src/render/renderable.rs @@ -16,7 +16,7 @@ pub struct Renderable { // TODO: make these hidden if possible pub pipelines: Vec>, - pub render_resource_assignments: Option, + pub render_resource_assignments: RenderResourceAssignments, } impl Renderable { @@ -35,7 +35,7 @@ impl Default for Renderable { pipelines: vec![ Handle::new(0), // TODO: this could be better ], - render_resource_assignments: None, + render_resource_assignments: RenderResourceAssignments::default(), is_instanced: false, } } @@ -232,14 +232,12 @@ pub fn update_shader_assignments(world: &mut World, resources: &mut Resources) { &mut pipeline_descriptor_storage, &mut shader_storage, &renderable.pipelines, - renderable.render_resource_assignments.as_ref().unwrap(), + &renderable.render_resource_assignments, ); // reset shader_defs so they can be changed next frame renderable .render_resource_assignments - .as_mut() - .unwrap() .shader_defs .clear(); } diff --git a/src/render/renderer/renderer.rs b/src/render/renderer/renderer.rs index 99accc7a8d..2c03ffb2e2 100644 --- a/src/render/renderer/renderer.rs +++ b/src/render/renderer/renderer.rs @@ -55,5 +55,5 @@ pub trait RenderPass { fn set_index_buffer(&mut self, resource: RenderResource, offset: u64); fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64); fn draw_indexed(&mut self, indices: Range, base_vertex: i32, instances: Range); - fn set_bind_groups(&mut self, render_resource_assignments: Option<&RenderResourceAssignments>); + fn set_render_resource_assignments(&mut self, render_resource_assignments: Option<&RenderResourceAssignments>) -> Option>; } diff --git a/src/render/renderer/renderers/wgpu_renderer/wgpu_render_pass.rs b/src/render/renderer/renderers/wgpu_renderer/wgpu_render_pass.rs index 5d9889c74e..106e9f9c78 100644 --- a/src/render/renderer/renderers/wgpu_renderer/wgpu_render_pass.rs +++ b/src/render/renderer/renderers/wgpu_renderer/wgpu_render_pass.rs @@ -38,7 +38,10 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { .draw_indexed(indices, base_vertex, instances); } - fn set_bind_groups(&mut self, render_resource_assignments: Option<&RenderResourceAssignments>) { + fn set_render_resource_assignments( + &mut self, + render_resource_assignments: Option<&RenderResourceAssignments>, + ) -> Option> { let pipeline_layout = self.pipeline_descriptor.get_layout().unwrap(); for bind_group in pipeline_layout.bind_groups.iter() { let bind_group_id = bind_group.get_hash().unwrap(); @@ -96,5 +99,7 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { dynamic_uniform_indices.as_slice(), ); } + + None } }