RenderResourceAssignmentsProvider / unique ids

This commit is contained in:
Carter Anderson 2020-03-20 17:15:56 -07:00
parent 71d091e10c
commit f90205a40d
6 changed files with 66 additions and 30 deletions

View file

@ -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::<PipelineDescriptor>::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

View file

@ -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<Entity, usize>,
pub current_index: usize,
pub render_resource_assignments: RenderResourceAssignments,
pub render_resource_assignments: Option<RenderResourceAssignments>,
}
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<String, RenderResource>,
}
impl RenderResourceAssignments {
pub fn get(&self, name: &str) -> Option<RenderResource> {
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<BatchKey2, Batch>,

View file

@ -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)
}

View file

@ -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::*;
pub use entity_render_resource_assignments::*;
pub use render_resource_assignments::*;

View file

@ -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<String, RenderResource>,
}
impl RenderResourceAssignments {
pub fn get(&self, name: &str) -> Option<RenderResource> {
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
}
}

View file

@ -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::<AssetBatchers>().unwrap();
let mut entity_render_resource_assignments = resources.get_mut::<EntityRenderResourceAssignments>().unwrap();
let mut render_resource_assignments_provider = resources.get_mut::<RenderResourceAssignmentsProvider>().unwrap();
// TODO: only update handle values when Asset value has changed
if let Some(asset_storage) = resources.get::<AssetStorage<T>>() {
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::<EntityRenderResourceAssignments>().unwrap();
let mut render_resource_assignments_provider = resources.get_mut::<RenderResourceAssignmentsProvider>().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);
}