use RenderResourceAssignments in place of Entity

This commit is contained in:
Carter Anderson 2020-03-20 17:49:29 -07:00
parent f90205a40d
commit ae0d5abf45
12 changed files with 54 additions and 44 deletions

View File

@ -11,6 +11,7 @@
"hashset",
"multizip",
"passthrough",
"precompile",
"rspirv",
"rustc",
"spirv"

View File

@ -19,6 +19,9 @@ Here is the current list of planned features. All items are sorted in approximat
* Add feature docs
* Add "template" projects
* Add ```#![deny(warnings, missing_docs)]``` to ensure future contributions meet style/doc standards
* ECS
* Remove as many references to Resources as possible in favor of resolved resource types
* Consider adding Renderer and World to Resources
* Error Handling
* Custom error type?
* Remove as many panics / unwraps as possible

View File

@ -184,7 +184,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
// create_entities_insert_vec(world, plane_handle, cube_handle);
// no-archetype precompile: .93
// noarchetype precompile: .93
// no-archetype precompile: .93
// create_entities_builder_add_component(world, plane_handle, cube_handle);
// archetype precompile: 0.65

View File

@ -26,13 +26,23 @@ fn setup(world: &mut World, resources: &mut Resources) {
.add_entity(MeshEntity {
mesh: plane_handle,
material: plane_material_handle,
// renderable: Renderable::instanced(),
..Default::default()
})
// cube
.add_entity(MeshEntity {
mesh: cube_handle,
material: cube_material_handle,
translation: Translation::new(0.0, 0.0, 1.0),
// renderable: Renderable::instanced(),
translation: Translation::new(-1.5, 0.0, 1.0),
..Default::default()
})
// cube
.add_entity(MeshEntity {
mesh: cube_handle,
material: cube_material_handle,
// renderable: Renderable::instanced(),
translation: Translation::new(1.5, 0.0, 1.0),
..Default::default()
})
// light

View File

@ -23,6 +23,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
pipeline_handle: Handle<PipelineDescriptor>,
) {
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
let mut current_mesh_handle = None;
let mut current_mesh_index_len = 0;
@ -61,7 +62,8 @@ impl DrawTarget for AssignedMeshesDrawTarget {
}
// TODO: validate bind group properties against shader uniform properties at least once
render_pass.set_bind_groups(Some(&entity));
let render_resource_assignments = entity_render_resource_assignments.get(*entity);
render_pass.set_bind_groups(render_resource_assignments);
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
}
}
@ -90,7 +92,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
}
if let Some(render_resource_assignments) = entity_render_resource_assignments.get(*entity) {
renderer.setup_entity_bind_groups(*entity, render_resource_assignments, pipeline_descriptor);
renderer.setup_bind_groups(render_resource_assignments, pipeline_descriptor);
}
}
}

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,
Renderable,
},
@ -18,13 +18,14 @@ impl DrawTarget for MeshesDrawTarget {
fn draw(
&self,
world: &World,
_resources: &Resources,
resources: &Resources,
render_pass: &mut dyn RenderPass,
_pipeline_handle: Handle<PipelineDescriptor>,
) {
let mut current_mesh_handle = None;
let mut current_mesh_index_len = 0;
let mesh_query = <(Read<Handle<Mesh>>, Read<Renderable>)>::query();
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
for (entity, (mesh, renderable)) in mesh_query.iter_entities(world) {
if !renderable.is_visible || renderable.is_instanced {
@ -53,7 +54,8 @@ impl DrawTarget for MeshesDrawTarget {
}
// TODO: validate bind group properties against shader uniform properties at least once
render_pass.set_bind_groups(Some(&entity));
let render_resource_assignments = entity_render_resource_assignments.get(entity);
render_pass.set_bind_groups(render_resource_assignments);
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
}
}

View File

@ -23,7 +23,7 @@ impl RenderResourceAssignments {
}
}
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
pub struct RenderResourceAssignmentsId(usize);
#[derive(Default)]

View File

@ -254,6 +254,7 @@ where
world: &World,
resources: &Resources,
) {
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
// allocate uniform buffers
for (name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() {
let count = *count as u64;

View File

@ -89,9 +89,8 @@ pub trait Renderer {
);
fn get_render_resources(&self) -> &RenderResources;
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
fn setup_entity_bind_groups(
fn setup_bind_groups(
&mut self,
entity: Entity,
render_resource_assignments: &RenderResourceAssignments,
pipeline_descriptor: &PipelineDescriptor,
);
@ -106,5 +105,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<u32>, base_vertex: i32, instances: Range<u32>);
fn set_bind_groups(&mut self, entity: Option<&Entity>);
fn set_bind_groups(&mut self, render_resource_assignments: Option<&RenderResourceAssignments>);
}

View File

@ -1,10 +1,10 @@
use super::{WgpuRenderer, WgpuResources};
use crate::render::{
pipeline::{BindType, PipelineDescriptor},
render_resource::RenderResource,
render_resource::{RenderResource, RenderResourceAssignments},
renderer::{RenderPass, Renderer},
};
use legion::prelude::Entity;
use std::ops::Range;
pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
pub render_pass: &'b mut wgpu::RenderPass<'a>,
@ -33,17 +33,12 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
self.render_pass.set_index_buffer(&buffer, offset);
}
fn draw_indexed(
&mut self,
indices: core::ops::Range<u32>,
base_vertex: i32,
instances: core::ops::Range<u32>,
) {
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
self.render_pass
.draw_indexed(indices, base_vertex, instances);
}
fn set_bind_groups(&mut self, entity: Option<&Entity>) {
fn set_bind_groups(&mut self, render_resource_assignments: Option<&RenderResourceAssignments>) {
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();
@ -52,9 +47,9 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
Some(bind_group_info) => bind_group_info,
// otherwise try to get an entity-specific bind group
None => {
if let Some(entity) = entity {
if let Some(assignments) = render_resource_assignments {
self.wgpu_resources
.get_entity_bind_group(*entity, bind_group_id)
.get_assignments_bind_group(assignments.get_id(), bind_group_id)
.unwrap()
} else {
panic!("No bind group exists that matches: {:?}");
@ -81,12 +76,12 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
.dynamic_uniform_buffer_info
.get(&resource)
{
let index = dynamic_uniform_buffer_info
.offsets
.get(entity.unwrap())
.unwrap();
// let index = dynamic_uniform_buffer_info
// .offsets
// .get(entity.unwrap())
// .unwrap();
dynamic_uniform_indices.push(*index);
// dynamic_uniform_indices.push(*index);
}
}
}

View File

@ -677,9 +677,8 @@ impl Renderer for WgpuRenderer {
&mut self.wgpu_resources.render_resources
}
fn setup_entity_bind_groups(
fn setup_bind_groups(
&mut self,
entity: Entity,
render_resource_assignments: &RenderResourceAssignments,
pipeline_descriptor: &PipelineDescriptor,
) {
@ -690,10 +689,10 @@ impl Renderer for WgpuRenderer {
if let None = self.wgpu_resources.bind_groups.get(&bind_group_id) {
if let None = self
.wgpu_resources
.get_entity_bind_group(entity, bind_group_id)
.get_assignments_bind_group(render_resource_assignments.get_id(), bind_group_id)
{
self.wgpu_resources
.create_entity_bind_group(&self.device, bind_group, entity, render_resource_assignments);
.create_assignments_bind_group(&self.device, bind_group, render_resource_assignments);
}
}
}

View File

@ -1,9 +1,8 @@
use crate::{
legion::prelude::*,
render::{
pipeline::{BindGroup, BindType},
render_resource::{
BufferUsage, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo,
BufferUsage, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo, RenderResourceAssignmentsId,
},
shader::DynamicUniformBufferInfo,
texture::{SamplerDescriptor, TextureDescriptor},
@ -23,7 +22,7 @@ pub struct WgpuResources {
pub resource_info: HashMap<RenderResource, ResourceInfo>,
pub bind_groups: HashMap<u64, BindGroupInfo>,
pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>,
pub entity_bind_groups: HashMap<(Entity, u64), BindGroupInfo>,
pub assignment_bind_groups: HashMap<(RenderResourceAssignmentsId, u64), BindGroupInfo>,
pub dynamic_uniform_buffer_info: HashMap<RenderResource, DynamicUniformBufferInfo>,
}
@ -37,7 +36,7 @@ impl WgpuResources {
bind_groups: HashMap::new(),
bind_group_layouts: HashMap::new(),
dynamic_uniform_buffer_info: HashMap::new(),
entity_bind_groups: HashMap::new(),
assignment_bind_groups: HashMap::new(),
render_resources: RenderResources::default(),
}
}
@ -109,19 +108,18 @@ impl WgpuResources {
.insert(bind_group_id, BindGroupInfo { bind_group });
}
}
pub fn get_entity_bind_group(
pub fn get_assignments_bind_group(
&self,
entity: Entity,
render_resource_assignment_id: RenderResourceAssignmentsId,
bind_group_id: u64,
) -> Option<&BindGroupInfo> {
self.entity_bind_groups.get(&(entity, bind_group_id))
self.assignment_bind_groups.get(&(render_resource_assignment_id, bind_group_id))
}
pub fn create_entity_bind_group(
pub fn create_assignments_bind_group(
&mut self,
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
@ -167,8 +165,8 @@ impl WgpuResources {
}
} else {
panic!(
"No resource assigned to uniform \"{}\" for entity {}",
binding.name, entity
"No resource assigned to uniform \"{}\" for RenderResourceAssignments {:?}",
binding.name, render_resource_assignments.get_id()
);
}
})
@ -181,8 +179,8 @@ impl WgpuResources {
let bind_group = device.create_bind_group(&bind_group_descriptor);
// TODO: storing a large number entity bind groups might actually be really bad. make sure this is ok
self.entity_bind_groups
.insert((entity, bind_group_id), BindGroupInfo { bind_group });
self.assignment_bind_groups
.insert((render_resource_assignments.get_id(), bind_group_id), BindGroupInfo { bind_group });
}
pub fn create_buffer(