From f90205a40d3485046ad527f01aadc72dc6c60b60 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Fri, 20 Mar 2020 17:15:56 -0700 Subject: [PATCH] RenderResourceAssignmentsProvider / unique ids --- src/app/app_builder.rs | 3 +- src/render/render_resource/asset_batcher.rs | 21 +-------- .../entity_render_resource_assignments.rs | 6 --- src/render/render_resource/mod.rs | 4 +- .../render_resource_assignments.rs | 44 +++++++++++++++++++ .../uniform_resource_provider.rs | 18 ++++++-- 6 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 src/render/render_resource/render_resource_assignments.rs diff --git a/src/app/app_builder.rs b/src/app/app_builder.rs index 4958f04255..9e4e50f17a 100644 --- a/src/app/app_builder.rs +++ b/src/app/app_builder.rs @@ -15,7 +15,7 @@ use crate::{ use bevy_transform::{prelude::LocalToWorld, transform_system_bundle}; use pipeline::PipelineDescriptor; use render_graph::RenderGraphBuilder; -use render_resource::{EntityRenderResourceAssignments, AssetBatchers}; +use render_resource::{EntityRenderResourceAssignments, AssetBatchers, RenderResourceAssignmentsProvider}; use shader::Shader; use std::collections::HashMap; @@ -134,6 +134,7 @@ impl AppBuilder { .insert(AssetStorage::::new()); self.resources.insert(ShaderPipelineAssignments::new()); self.resources.insert(CompiledShaderMap::new()); + self.resources.insert(RenderResourceAssignmentsProvider::default()); self.resources.insert(EntityRenderResourceAssignments::default()); self.resources.insert(asset_batchers); self diff --git a/src/render/render_resource/asset_batcher.rs b/src/render/render_resource/asset_batcher.rs index 4851bf122e..245adc77eb 100644 --- a/src/render/render_resource/asset_batcher.rs +++ b/src/render/render_resource/asset_batcher.rs @@ -1,4 +1,4 @@ -use super::RenderResource; +use super::{RenderResourceAssignments}; use crate::asset::{Handle, HandleId}; use legion::prelude::Entity; use std::{any::TypeId, collections::HashMap, hash::Hash}; @@ -32,7 +32,7 @@ impl EntitySetState2 { pub struct Batch { pub entity_indices: HashMap, pub current_index: usize, - pub render_resource_assignments: RenderResourceAssignments, + pub render_resource_assignments: Option, } impl Batch { @@ -44,23 +44,6 @@ impl Batch { } } -// TODO: consider merging this with entity_uniform_resource -// 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, Default)] -pub struct RenderResourceAssignments { - render_resources: HashMap, -} - -impl RenderResourceAssignments { - pub fn get(&self, name: &str) -> Option { - self.render_resources.get(name).cloned() - } - - pub fn set(&mut self, name: &str, resource: RenderResource) { - self.render_resources.insert(name.to_string(), resource); - } -} - pub struct AssetSetBatcher2 { key: AssetSetBatcherKey2, set_batches: HashMap, diff --git a/src/render/render_resource/entity_render_resource_assignments.rs b/src/render/render_resource/entity_render_resource_assignments.rs index 2c61ddd710..63db53dc19 100644 --- a/src/render/render_resource/entity_render_resource_assignments.rs +++ b/src/render/render_resource/entity_render_resource_assignments.rs @@ -16,12 +16,6 @@ impl EntityRenderResourceAssignments { self.entity_assignments.get(&entity) } - pub fn get_mut_or_create(&mut self, entity: Entity) -> &mut RenderResourceAssignments { - self.entity_assignments.entry(entity).or_insert_with(|| { - RenderResourceAssignments::default() - }) - } - pub fn get_mut(&mut self, entity: Entity) -> Option<&mut RenderResourceAssignments> { self.entity_assignments.get_mut(&entity) } diff --git a/src/render/render_resource/mod.rs b/src/render/render_resource/mod.rs index a5af4c0207..f32f254a06 100644 --- a/src/render/render_resource/mod.rs +++ b/src/render/render_resource/mod.rs @@ -5,6 +5,7 @@ mod resource_info; pub mod resource_name; mod resource_provider; mod entity_render_resource_assignments; +mod render_resource_assignments; pub mod resource_providers; pub use asset_batcher::*; @@ -12,4 +13,5 @@ pub use buffer::*; pub use render_resource::*; pub use resource_info::*; pub use resource_provider::*; -pub use entity_render_resource_assignments::*; \ No newline at end of file +pub use entity_render_resource_assignments::*; +pub use render_resource_assignments::*; \ No newline at end of file diff --git a/src/render/render_resource/render_resource_assignments.rs b/src/render/render_resource/render_resource_assignments.rs new file mode 100644 index 0000000000..2401d1d3c9 --- /dev/null +++ b/src/render/render_resource/render_resource_assignments.rs @@ -0,0 +1,44 @@ +use super::RenderResource; +use std::collections::HashMap; + +// TODO: consider merging this with entity_uniform_resource +// 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)] +pub struct RenderResourceAssignments { + id: RenderResourceAssignmentsId, + render_resources: HashMap, +} + +impl RenderResourceAssignments { + pub fn get(&self, name: &str) -> Option { + self.render_resources.get(name).cloned() + } + + pub fn set(&mut self, name: &str, resource: RenderResource) { + self.render_resources.insert(name.to_string(), resource); + } + + pub fn get_id(&self) -> RenderResourceAssignmentsId { + self.id + } +} + +#[derive(Eq, PartialEq, Debug, Copy, Clone)] +pub struct RenderResourceAssignmentsId(usize); + +#[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(), + }; + + self.current_id += 1; + assignments + } +} \ 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 26ac66f754..a9cedb9d87 100644 --- a/src/render/render_resource/resource_providers/uniform_resource_provider.rs +++ b/src/render/render_resource/resource_providers/uniform_resource_provider.rs @@ -2,7 +2,7 @@ use crate::{ asset::{AssetStorage, Handle}, render::{ pipeline::BindType, - render_resource::{AssetBatchers, BufferUsage, RenderResource, ResourceProvider, RenderResourceAssignments, EntityRenderResourceAssignments}, + render_resource::{AssetBatchers, BufferUsage, RenderResource, ResourceProvider, RenderResourceAssignments, EntityRenderResourceAssignments, RenderResourceAssignmentsProvider}, renderer::Renderer, shader::{AsUniforms, DynamicUniformBufferInfo, UniformInfoIter}, texture::{SamplerDescriptor, Texture, TextureDescriptor}, @@ -69,13 +69,19 @@ where let handle_query = self.handle_query.take().unwrap(); let mut asset_batchers = resources.get_mut::().unwrap(); let mut entity_render_resource_assignments = resources.get_mut::().unwrap(); + let mut render_resource_assignments_provider = resources.get_mut::().unwrap(); // TODO: only update handle values when Asset value has changed if let Some(asset_storage) = resources.get::>() { for (entity, (handle, renderable)) in handle_query.iter_entities(world) { if renderable.is_instanced { asset_batchers.set_entity_handle(entity, *handle); } else { - let render_resource_assignments = entity_render_resource_assignments.get_mut_or_create(entity); + let render_resource_assignments = if let Some(assignments) = entity_render_resource_assignments.get_mut(entity) { + assignments + } else { + entity_render_resource_assignments.set(entity, render_resource_assignments_provider.next()); + entity_render_resource_assignments.get_mut(entity).unwrap() + }; if let Some(uniforms) = asset_storage.get(&handle) { self.setup_entity_uniform_resources( entity, @@ -408,12 +414,18 @@ where self.update_asset_uniforms(renderer, world, resources); let mut entity_render_resource_assignments = resources.get_mut::().unwrap(); + let mut render_resource_assignments_provider = resources.get_mut::().unwrap(); for (entity, (uniforms, renderable)) in query.iter_entities(world) { if renderable.is_instanced { continue; } - let render_resource_assignments = entity_render_resource_assignments.get_mut_or_create(entity); + let render_resource_assignments = if let Some(assignments) = entity_render_resource_assignments.get_mut(entity) { + assignments + } else { + entity_render_resource_assignments.set(entity, render_resource_assignments_provider.next()); + entity_render_resource_assignments.get_mut(entity).unwrap() + }; self.setup_entity_uniform_resources(entity, &uniforms, renderer, resources, render_resource_assignments, true, None); }