migrate entity render resources to RenderResourceAssignments

This commit is contained in:
Carter Anderson 2020-03-20 14:17:50 -07:00
parent 9881f64715
commit 43e69484ba
9 changed files with 62 additions and 70 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::AssetBatchers;
use render_resource::{EntityRenderResourceAssignments, AssetBatchers};
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(EntityRenderResourceAssignments::default());
self.resources.insert(asset_batchers);
self
}

View File

@ -5,7 +5,7 @@ use crate::{
draw_target::DrawTarget,
mesh::Mesh,
pipeline::PipelineDescriptor,
render_resource::{resource_name, ResourceInfo},
render_resource::{resource_name, ResourceInfo, EntityRenderResourceAssignments},
renderer::{RenderPass, Renderer},
Renderable, ShaderPipelineAssignments,
},
@ -79,6 +79,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
.assignments
.get(&pipeline_handle);
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap();
if let Some(assigned_entities) = assigned_entities {
for entity in assigned_entities.iter() {
@ -88,7 +89,9 @@ impl DrawTarget for AssignedMeshesDrawTarget {
continue;
}
renderer.setup_entity_bind_groups(*entity, pipeline_descriptor);
if let Some(render_resource_assignments) = entity_render_resource_assignments.get(*entity) {
renderer.setup_entity_bind_groups(*entity, render_resource_assignments, pipeline_descriptor);
}
}
}
}

View File

@ -45,17 +45,18 @@ 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_render_resource(&self, name: &str) -> Option<RenderResource> {
pub fn get(&self, name: &str) -> Option<RenderResource> {
self.render_resources.get(name).cloned()
}
pub fn set_render_resource(&mut self, name: &str, resource: RenderResource) {
pub fn set(&mut self, name: &str, resource: RenderResource) {
self.render_resources.insert(name.to_string(), resource);
}
}

View File

@ -0,0 +1,28 @@
use super::RenderResourceAssignments;
use legion::prelude::Entity;
use std::collections::HashMap;
#[derive(Default)]
pub struct EntityRenderResourceAssignments {
entity_assignments: HashMap<Entity, RenderResourceAssignments>,
}
impl EntityRenderResourceAssignments {
pub fn set(&mut self, entity: Entity, assignments: RenderResourceAssignments) {
self.entity_assignments.insert(entity, assignments);
}
pub fn get(&self, entity: Entity) -> Option<&RenderResourceAssignments> {
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

@ -4,6 +4,7 @@ mod render_resource;
mod resource_info;
pub mod resource_name;
mod resource_provider;
mod entity_render_resource_assignments;
pub mod resource_providers;
pub use asset_batcher::*;
@ -11,3 +12,4 @@ pub use buffer::*;
pub use render_resource::*;
pub use resource_info::*;
pub use resource_provider::*;
pub use entity_render_resource_assignments::*;

View File

@ -2,7 +2,7 @@ use crate::{
asset::{AssetStorage, Handle},
render::{
pipeline::BindType,
render_resource::{AssetBatchers, BufferUsage, RenderResource, ResourceProvider},
render_resource::{AssetBatchers, BufferUsage, RenderResource, ResourceProvider, RenderResourceAssignments, EntityRenderResourceAssignments},
renderer::Renderer,
shader::{AsUniforms, DynamicUniformBufferInfo, UniformInfoIter},
texture::{SamplerDescriptor, Texture, TextureDescriptor},
@ -68,16 +68,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();
// 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) {
asset_batchers.set_entity_handle(entity, *handle);
let render_resource_assignments = entity_render_resource_assignments.get_mut_or_create(entity);
if let Some(uniforms) = asset_storage.get(&handle) {
self.setup_entity_uniform_resources(
entity,
uniforms,
renderer,
resources,
render_resource_assignments,
true,
Some(*handle),
)
@ -94,6 +97,7 @@ where
uniforms: &T,
renderer: &mut dyn Renderer,
resources: &Resources,
render_resource_assignments: &mut RenderResourceAssignments,
dynamic_unforms: bool,
asset_handle: Option<Handle<T>>,
) {
@ -138,8 +142,7 @@ where
}
};
renderer.set_entity_uniform_resource(
entity,
render_resource_assignments.set(
uniform_info.name,
render_resource,
);
@ -205,7 +208,7 @@ where
}
};
renderer.set_entity_uniform_resource(entity, uniform_info.name, resource);
render_resource_assignments.set(uniform_info.name, resource);
}
BindType::Sampler { .. } => {
let texture_handle = uniforms.get_uniform_texture(&uniform_info.name).unwrap();
@ -226,7 +229,7 @@ where
}
};
renderer.set_entity_uniform_resource(entity, uniform_info.name, resource);
render_resource_assignments.set(uniform_info.name, resource);
}
_ => panic!(
"encountered unsupported bind_type {:?}",
@ -394,8 +397,10 @@ where
self.update_asset_uniforms(renderer, world, resources);
let mut entity_render_resource_assignments = resources.get_mut::<EntityRenderResourceAssignments>().unwrap();
for (entity, (uniforms, _renderable)) in query.iter_entities(world) {
self.setup_entity_uniform_resources(entity, &uniforms, renderer, resources, true, None);
let render_resource_assignments = entity_render_resource_assignments.get_mut_or_create(entity);
self.setup_entity_uniform_resources(entity, &uniforms, renderer, resources, render_resource_assignments, true, None);
}
self.setup_dynamic_uniform_buffers(renderer, world, resources);

View File

@ -3,7 +3,7 @@ use crate::{
render::{
pipeline::{PipelineDescriptor, VertexBufferDescriptor},
render_graph::RenderGraph,
render_resource::{BufferUsage, RenderResource, RenderResources, ResourceInfo},
render_resource::{BufferUsage, RenderResource, RenderResources, ResourceInfo, RenderResourceAssignments},
shader::DynamicUniformBufferInfo,
texture::{SamplerDescriptor, TextureDescriptor},
},
@ -89,20 +89,10 @@ pub trait Renderer {
);
fn get_render_resources(&self) -> &RenderResources;
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
fn set_entity_uniform_resource(
&mut self,
entity: Entity,
uniform_name: &str,
resource: RenderResource,
);
fn get_entity_uniform_resource(
&self,
entity: Entity,
uniform_name: &str,
) -> Option<RenderResource>;
fn setup_entity_bind_groups(
&mut self,
entity: Entity,
render_resource_assignments: &RenderResourceAssignments,
pipeline_descriptor: &PipelineDescriptor,
);
fn set_vertex_buffer_descriptor(&mut self, vertex_buffer_descriptor: VertexBufferDescriptor);

View File

@ -13,7 +13,7 @@ use crate::{
},
render_graph::RenderGraph,
render_resource::{
resource_name, BufferUsage, RenderResource, RenderResources, ResourceInfo,
resource_name, BufferUsage, RenderResource, RenderResources, ResourceInfo, RenderResourceAssignments,
},
renderer::Renderer,
shader::{DynamicUniformBufferInfo, Shader},
@ -677,27 +677,10 @@ impl Renderer for WgpuRenderer {
&mut self.wgpu_resources.render_resources
}
fn set_entity_uniform_resource(
&mut self,
entity: Entity,
uniform_name: &str,
resource: RenderResource,
) {
self.wgpu_resources
.set_entity_uniform_resource(entity, uniform_name, resource)
}
fn get_entity_uniform_resource(
&self,
entity: Entity,
uniform_name: &str,
) -> Option<RenderResource> {
self.wgpu_resources
.get_entity_uniform_resource(entity, uniform_name)
}
fn setup_entity_bind_groups(
&mut self,
entity: Entity,
render_resource_assignments: &RenderResourceAssignments,
pipeline_descriptor: &PipelineDescriptor,
) {
let pipeline_layout = pipeline_descriptor.get_layout().unwrap();
@ -710,7 +693,7 @@ impl Renderer for WgpuRenderer {
.get_entity_bind_group(entity, bind_group_id)
{
self.wgpu_resources
.create_entity_bind_group(&self.device, bind_group, entity);
.create_entity_bind_group(&self.device, bind_group, entity, render_resource_assignments);
}
}
}

View File

@ -2,12 +2,14 @@ use crate::{
legion::prelude::*,
render::{
pipeline::{BindGroup, BindType},
render_resource::{BufferUsage, RenderResource, RenderResources, ResourceInfo},
render_resource::{
BufferUsage, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo,
},
shader::DynamicUniformBufferInfo,
texture::{SamplerDescriptor, TextureDescriptor},
},
};
use std::{borrow::Cow, collections::HashMap};
use std::collections::HashMap;
pub struct BindGroupInfo {
pub bind_group: wgpu::BindGroup,
@ -21,8 +23,6 @@ pub struct WgpuResources {
pub bind_groups: HashMap<u64, BindGroupInfo>,
pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>,
pub entity_bind_groups: HashMap<(Entity, u64), BindGroupInfo>,
pub entity_uniform_resources:
HashMap<(Cow<'static, Entity>, Cow<'static, str>), RenderResource>,
pub dynamic_uniform_buffer_info: HashMap<RenderResource, DynamicUniformBufferInfo>,
pub render_resources: RenderResources,
}
@ -38,7 +38,6 @@ impl WgpuResources {
bind_group_layouts: HashMap::new(),
dynamic_uniform_buffer_info: HashMap::new(),
entity_bind_groups: HashMap::new(),
entity_uniform_resources: HashMap::new(),
render_resources: RenderResources::default(),
}
}
@ -123,6 +122,7 @@ impl WgpuResources {
device: &wgpu::Device,
bind_group: &BindGroup,
entity: Entity,
render_resource_assignments: &RenderResourceAssignments,
) {
// TODO: don't make this per-entity. bind groups should be re-used across the same resource when possible
let bind_group_id = bind_group.get_hash().unwrap();
@ -130,7 +130,7 @@ impl WgpuResources {
.bindings
.iter()
.map(|binding| {
if let Some(resource) = self.get_entity_uniform_resource(entity, &binding.name) {
if let Some(resource) = render_resource_assignments.get(&binding.name) {
let resource_info = self.resource_info.get(&resource).unwrap();
wgpu::Binding {
binding: binding.index,
@ -411,25 +411,4 @@ impl WgpuResources {
pub fn get_render_resources_mut(&mut self) -> &mut RenderResources {
&mut self.render_resources
}
pub fn set_entity_uniform_resource(
&mut self,
entity: Entity,
uniform_name: &str,
resource: RenderResource,
) {
self.entity_uniform_resources.insert(
(Cow::Owned(entity), Cow::Owned(uniform_name.to_string())),
resource,
);
}
pub fn get_entity_uniform_resource(
&self,
entity: Entity,
uniform_name: &str,
) -> Option<RenderResource> {
self.entity_uniform_resources
.get(&(Cow::Owned(entity), Cow::Borrowed(uniform_name)))
.cloned()
}
}