use RenderResourceAssignments in place of Entity
This commit is contained in:
parent
f90205a40d
commit
ae0d5abf45
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -11,6 +11,7 @@
|
|||||||
"hashset",
|
"hashset",
|
||||||
"multizip",
|
"multizip",
|
||||||
"passthrough",
|
"passthrough",
|
||||||
|
"precompile",
|
||||||
"rspirv",
|
"rspirv",
|
||||||
"rustc",
|
"rustc",
|
||||||
"spirv"
|
"spirv"
|
||||||
|
|||||||
@ -19,6 +19,9 @@ Here is the current list of planned features. All items are sorted in approximat
|
|||||||
* Add feature docs
|
* Add feature docs
|
||||||
* Add "template" projects
|
* Add "template" projects
|
||||||
* Add ```#![deny(warnings, missing_docs)]``` to ensure future contributions meet style/doc standards
|
* 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
|
* Error Handling
|
||||||
* Custom error type?
|
* Custom error type?
|
||||||
* Remove as many panics / unwraps as possible
|
* Remove as many panics / unwraps as possible
|
||||||
|
|||||||
@ -184,7 +184,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||||||
// create_entities_insert_vec(world, plane_handle, cube_handle);
|
// create_entities_insert_vec(world, plane_handle, cube_handle);
|
||||||
|
|
||||||
// no-archetype precompile: .93
|
// no-archetype precompile: .93
|
||||||
// noarchetype precompile: .93
|
// no-archetype precompile: .93
|
||||||
// create_entities_builder_add_component(world, plane_handle, cube_handle);
|
// create_entities_builder_add_component(world, plane_handle, cube_handle);
|
||||||
|
|
||||||
// archetype precompile: 0.65
|
// archetype precompile: 0.65
|
||||||
|
|||||||
@ -26,13 +26,23 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: plane_handle,
|
mesh: plane_handle,
|
||||||
material: plane_material_handle,
|
material: plane_material_handle,
|
||||||
|
// renderable: Renderable::instanced(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
// cube
|
// cube
|
||||||
.add_entity(MeshEntity {
|
.add_entity(MeshEntity {
|
||||||
mesh: cube_handle,
|
mesh: cube_handle,
|
||||||
material: cube_material_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()
|
..Default::default()
|
||||||
})
|
})
|
||||||
// light
|
// light
|
||||||
|
|||||||
@ -23,6 +23,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
) {
|
) {
|
||||||
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();
|
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_handle = None;
|
||||||
let mut current_mesh_index_len = 0;
|
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
|
// 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);
|
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) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::{
|
|||||||
draw_target::DrawTarget,
|
draw_target::DrawTarget,
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_resource::{resource_name, ResourceInfo},
|
render_resource::{resource_name, ResourceInfo, EntityRenderResourceAssignments},
|
||||||
renderer::RenderPass,
|
renderer::RenderPass,
|
||||||
Renderable,
|
Renderable,
|
||||||
},
|
},
|
||||||
@ -18,13 +18,14 @@ impl DrawTarget for MeshesDrawTarget {
|
|||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
world: &World,
|
world: &World,
|
||||||
_resources: &Resources,
|
resources: &Resources,
|
||||||
render_pass: &mut dyn RenderPass,
|
render_pass: &mut dyn RenderPass,
|
||||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
) {
|
) {
|
||||||
let mut current_mesh_handle = None;
|
let mut current_mesh_handle = None;
|
||||||
let mut current_mesh_index_len = 0;
|
let mut current_mesh_index_len = 0;
|
||||||
let mesh_query = <(Read<Handle<Mesh>>, Read<Renderable>)>::query();
|
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) {
|
for (entity, (mesh, renderable)) in mesh_query.iter_entities(world) {
|
||||||
if !renderable.is_visible || renderable.is_instanced {
|
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
|
// 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);
|
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ impl RenderResourceAssignments {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone)]
|
||||||
pub struct RenderResourceAssignmentsId(usize);
|
pub struct RenderResourceAssignmentsId(usize);
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|||||||
@ -254,6 +254,7 @@ where
|
|||||||
world: &World,
|
world: &World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
|
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
|
||||||
// allocate uniform buffers
|
// allocate uniform buffers
|
||||||
for (name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() {
|
for (name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() {
|
||||||
let count = *count as u64;
|
let count = *count as u64;
|
||||||
|
|||||||
@ -89,9 +89,8 @@ pub trait Renderer {
|
|||||||
);
|
);
|
||||||
fn get_render_resources(&self) -> &RenderResources;
|
fn get_render_resources(&self) -> &RenderResources;
|
||||||
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
|
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
|
||||||
fn setup_entity_bind_groups(
|
fn setup_bind_groups(
|
||||||
&mut self,
|
&mut self,
|
||||||
entity: Entity,
|
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
pipeline_descriptor: &PipelineDescriptor,
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
);
|
);
|
||||||
@ -106,5 +105,5 @@ pub trait RenderPass {
|
|||||||
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
|
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
|
||||||
fn set_vertex_buffer(&mut self, start_slot: u32, 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 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>);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
use super::{WgpuRenderer, WgpuResources};
|
use super::{WgpuRenderer, WgpuResources};
|
||||||
use crate::render::{
|
use crate::render::{
|
||||||
pipeline::{BindType, PipelineDescriptor},
|
pipeline::{BindType, PipelineDescriptor},
|
||||||
render_resource::RenderResource,
|
render_resource::{RenderResource, RenderResourceAssignments},
|
||||||
renderer::{RenderPass, Renderer},
|
renderer::{RenderPass, Renderer},
|
||||||
};
|
};
|
||||||
use legion::prelude::Entity;
|
use std::ops::Range;
|
||||||
|
|
||||||
pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
|
pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
|
||||||
pub render_pass: &'b mut wgpu::RenderPass<'a>,
|
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);
|
self.render_pass.set_index_buffer(&buffer, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_indexed(
|
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
|
||||||
&mut self,
|
|
||||||
indices: core::ops::Range<u32>,
|
|
||||||
base_vertex: i32,
|
|
||||||
instances: core::ops::Range<u32>,
|
|
||||||
) {
|
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.draw_indexed(indices, base_vertex, instances);
|
.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();
|
let pipeline_layout = self.pipeline_descriptor.get_layout().unwrap();
|
||||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||||
let bind_group_id = bind_group.get_hash().unwrap();
|
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,
|
Some(bind_group_info) => bind_group_info,
|
||||||
// otherwise try to get an entity-specific bind group
|
// otherwise try to get an entity-specific bind group
|
||||||
None => {
|
None => {
|
||||||
if let Some(entity) = entity {
|
if let Some(assignments) = render_resource_assignments {
|
||||||
self.wgpu_resources
|
self.wgpu_resources
|
||||||
.get_entity_bind_group(*entity, bind_group_id)
|
.get_assignments_bind_group(assignments.get_id(), bind_group_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
} else {
|
} else {
|
||||||
panic!("No bind group exists that matches: {:?}");
|
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
|
.dynamic_uniform_buffer_info
|
||||||
.get(&resource)
|
.get(&resource)
|
||||||
{
|
{
|
||||||
let index = dynamic_uniform_buffer_info
|
// let index = dynamic_uniform_buffer_info
|
||||||
.offsets
|
// .offsets
|
||||||
.get(entity.unwrap())
|
// .get(entity.unwrap())
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
dynamic_uniform_indices.push(*index);
|
// dynamic_uniform_indices.push(*index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -677,9 +677,8 @@ impl Renderer for WgpuRenderer {
|
|||||||
&mut self.wgpu_resources.render_resources
|
&mut self.wgpu_resources.render_resources
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_entity_bind_groups(
|
fn setup_bind_groups(
|
||||||
&mut self,
|
&mut self,
|
||||||
entity: Entity,
|
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
pipeline_descriptor: &PipelineDescriptor,
|
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.bind_groups.get(&bind_group_id) {
|
||||||
if let None = self
|
if let None = self
|
||||||
.wgpu_resources
|
.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
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
legion::prelude::*,
|
|
||||||
render::{
|
render::{
|
||||||
pipeline::{BindGroup, BindType},
|
pipeline::{BindGroup, BindType},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BufferUsage, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo,
|
BufferUsage, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo, RenderResourceAssignmentsId,
|
||||||
},
|
},
|
||||||
shader::DynamicUniformBufferInfo,
|
shader::DynamicUniformBufferInfo,
|
||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
texture::{SamplerDescriptor, TextureDescriptor},
|
||||||
@ -23,7 +22,7 @@ pub struct WgpuResources {
|
|||||||
pub resource_info: HashMap<RenderResource, ResourceInfo>,
|
pub resource_info: HashMap<RenderResource, ResourceInfo>,
|
||||||
pub bind_groups: HashMap<u64, BindGroupInfo>,
|
pub bind_groups: HashMap<u64, BindGroupInfo>,
|
||||||
pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>,
|
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>,
|
pub dynamic_uniform_buffer_info: HashMap<RenderResource, DynamicUniformBufferInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ impl WgpuResources {
|
|||||||
bind_groups: HashMap::new(),
|
bind_groups: HashMap::new(),
|
||||||
bind_group_layouts: HashMap::new(),
|
bind_group_layouts: HashMap::new(),
|
||||||
dynamic_uniform_buffer_info: HashMap::new(),
|
dynamic_uniform_buffer_info: HashMap::new(),
|
||||||
entity_bind_groups: HashMap::new(),
|
assignment_bind_groups: HashMap::new(),
|
||||||
render_resources: RenderResources::default(),
|
render_resources: RenderResources::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,19 +108,18 @@ impl WgpuResources {
|
|||||||
.insert(bind_group_id, BindGroupInfo { bind_group });
|
.insert(bind_group_id, BindGroupInfo { bind_group });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_entity_bind_group(
|
pub fn get_assignments_bind_group(
|
||||||
&self,
|
&self,
|
||||||
entity: Entity,
|
render_resource_assignment_id: RenderResourceAssignmentsId,
|
||||||
bind_group_id: u64,
|
bind_group_id: u64,
|
||||||
) -> Option<&BindGroupInfo> {
|
) -> 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,
|
&mut self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
bind_group: &BindGroup,
|
bind_group: &BindGroup,
|
||||||
entity: Entity,
|
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
) {
|
) {
|
||||||
// TODO: don't make this per-entity. bind groups should be re-used across the same resource when possible
|
// 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 {
|
} else {
|
||||||
panic!(
|
panic!(
|
||||||
"No resource assigned to uniform \"{}\" for entity {}",
|
"No resource assigned to uniform \"{}\" for RenderResourceAssignments {:?}",
|
||||||
binding.name, entity
|
binding.name, render_resource_assignments.get_id()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -181,8 +179,8 @@ impl WgpuResources {
|
|||||||
|
|
||||||
let bind_group = device.create_bind_group(&bind_group_descriptor);
|
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
|
// TODO: storing a large number entity bind groups might actually be really bad. make sure this is ok
|
||||||
self.entity_bind_groups
|
self.assignment_bind_groups
|
||||||
.insert((entity, bind_group_id), BindGroupInfo { bind_group });
|
.insert((render_resource_assignments.get_id(), bind_group_id), BindGroupInfo { bind_group });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_buffer(
|
pub fn create_buffer(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user