mirror of
https://github.com/bevyengine/bevy
synced 2024-11-26 14:40:19 +00:00
make DrawTarget setup world read only. add render_resource_sets_system
This commit is contained in:
parent
1d44b4034f
commit
a8f5402ff1
13 changed files with 101 additions and 33 deletions
|
@ -163,6 +163,10 @@ impl<T> AssetStorage<T> {
|
|||
pub fn get_mut(&mut self, handle: &Handle<T>) -> Option<&mut T> {
|
||||
self.assets.get_mut(&handle.id)
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item=(Handle<T>, &T)> {
|
||||
self.assets.iter().map(|(k,v)| (Handle::new(*k), v))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> GetBytes for Handle<T> {
|
||||
|
|
|
@ -16,7 +16,7 @@ pub trait DrawTarget {
|
|||
);
|
||||
fn setup(
|
||||
&mut self,
|
||||
_world: &mut World,
|
||||
_world: &World,
|
||||
_resources: &Resources,
|
||||
_renderer: &mut dyn Renderer,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
|
|
|
@ -62,7 +62,7 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||
|
||||
fn setup(
|
||||
&mut self,
|
||||
world: &mut World,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
renderer: &mut dyn Renderer,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
|
@ -89,8 +89,8 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||
log::trace!("{:#?}", batch);
|
||||
renderer.setup_bind_groups(&mut batch.render_resource_assignments, pipeline_descriptor);
|
||||
for batched_entity in batch.entities.iter() {
|
||||
let mut renderable = world
|
||||
.get_component_mut::<Renderable>(*batched_entity)
|
||||
let renderable = world
|
||||
.get_component::<Renderable>(*batched_entity)
|
||||
.unwrap();
|
||||
if !renderable.is_visible || renderable.is_instanced {
|
||||
continue;
|
||||
|
@ -102,7 +102,7 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||
batch.render_resource_assignments.id
|
||||
);
|
||||
renderer.setup_bind_groups(
|
||||
&mut renderable.render_resource_assignments,
|
||||
&renderable.render_resource_assignments,
|
||||
pipeline_descriptor,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use legion::prelude::*;
|
|||
use crate::{
|
||||
draw_target::DrawTarget,
|
||||
mesh::Mesh,
|
||||
pipeline::{PipelineDescriptor, ShaderPipelineAssignments},
|
||||
pipeline::{PipelineDescriptor, PipelineAssignments},
|
||||
render_resource::{
|
||||
resource_name, EntityRenderResourceAssignments, RenderResourceAssignments, ResourceInfo,
|
||||
},
|
||||
|
@ -23,7 +23,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||
render_pass: &mut dyn RenderPass,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();
|
||||
let shader_pipeline_assignments = resources.get::<PipelineAssignments>().unwrap();
|
||||
let entity_render_resource_assignments =
|
||||
resources.get::<EntityRenderResourceAssignments>().unwrap();
|
||||
let mut current_mesh_handle = None;
|
||||
|
@ -78,16 +78,16 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||
|
||||
fn setup(
|
||||
&mut self,
|
||||
world: &mut World,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
renderer: &mut dyn Renderer,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();
|
||||
let pipeline_assignments = resources.get::<PipelineAssignments>().unwrap();
|
||||
let entity_render_resource_assignments =
|
||||
resources.get::<EntityRenderResourceAssignments>().unwrap();
|
||||
let assigned_render_resource_assignments = shader_pipeline_assignments
|
||||
let assigned_render_resource_assignments = pipeline_assignments
|
||||
.assignments
|
||||
.get(&pipeline_handle);
|
||||
let mut global_render_resource_assignments =
|
||||
|
@ -98,13 +98,13 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||
let entity = entity_render_resource_assignments
|
||||
.get(*assignment_id)
|
||||
.unwrap();
|
||||
let mut renderable = world.get_component_mut::<Renderable>(*entity).unwrap();
|
||||
let renderable = world.get_component::<Renderable>(*entity).unwrap();
|
||||
if !renderable.is_visible || renderable.is_instanced {
|
||||
continue;
|
||||
}
|
||||
|
||||
renderer.setup_bind_groups(
|
||||
&mut renderable.render_resource_assignments,
|
||||
&renderable.render_resource_assignments,
|
||||
pipeline_descriptor,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ impl DrawTarget for UiDrawTarget {
|
|||
|
||||
fn setup(
|
||||
&mut self,
|
||||
_world: &mut World,
|
||||
_world: &World,
|
||||
resources: &Resources,
|
||||
renderer: &mut dyn Renderer,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
|
|
|
@ -36,7 +36,7 @@ use self::{
|
|||
pass::passes::ForwardPassBuilder,
|
||||
pipeline::{
|
||||
pipelines::ForwardPipelineBuilder, PipelineCompiler, PipelineDescriptor,
|
||||
ShaderPipelineAssignments, VertexBufferDescriptors,
|
||||
PipelineAssignments, VertexBufferDescriptors,
|
||||
},
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{
|
||||
|
@ -107,7 +107,7 @@ impl AppPlugin for RenderPlugin {
|
|||
.add_resource(AssetStorage::<Shader>::new())
|
||||
.add_resource(AssetStorage::<StandardMaterial>::new())
|
||||
.add_resource(AssetStorage::<PipelineDescriptor>::new())
|
||||
.add_resource(ShaderPipelineAssignments::new())
|
||||
.add_resource(PipelineAssignments::new())
|
||||
.add_resource(VertexBufferDescriptors::default())
|
||||
.add_resource(PipelineCompiler::new())
|
||||
.add_resource(RenderResourceAssignments::default())
|
||||
|
|
|
@ -151,7 +151,7 @@ impl PipelineCompiler {
|
|||
fn update_shader_assignments(
|
||||
&mut self,
|
||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||
shader_pipeline_assignments: &mut ShaderPipelineAssignments,
|
||||
shader_pipeline_assignments: &mut PipelineAssignments,
|
||||
renderer: &dyn Renderer,
|
||||
pipeline_storage: &mut AssetStorage<PipelineDescriptor>,
|
||||
shader_storage: &mut AssetStorage<Shader>,
|
||||
|
@ -222,13 +222,13 @@ impl PipelineCompiler {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ShaderPipelineAssignments {
|
||||
pub struct PipelineAssignments {
|
||||
pub assignments: HashMap<Handle<PipelineDescriptor>, Vec<RenderResourceAssignmentsId>>,
|
||||
}
|
||||
|
||||
impl ShaderPipelineAssignments {
|
||||
impl PipelineAssignments {
|
||||
pub fn new() -> Self {
|
||||
ShaderPipelineAssignments {
|
||||
PipelineAssignments {
|
||||
assignments: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ pub fn update_shader_assignments(
|
|||
// lots of string + hashset allocations. sees uniform_resource_provider for more context
|
||||
{
|
||||
let mut shader_pipeline_assignments =
|
||||
resources.get_mut::<ShaderPipelineAssignments>().unwrap();
|
||||
resources.get_mut::<PipelineAssignments>().unwrap();
|
||||
let mut pipeline_compiler = resources.get_mut::<PipelineCompiler>().unwrap();
|
||||
let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||
let vertex_buffer_descriptors = resources.get::<VertexBufferDescriptors>().unwrap();
|
||||
|
|
|
@ -15,7 +15,6 @@ use std::collections::{HashMap, HashSet};
|
|||
#[derive(Default)]
|
||||
pub struct RenderGraph {
|
||||
pub pipeline_descriptors: HashSet<Handle<PipelineDescriptor>>,
|
||||
// TODO: make this ordered
|
||||
pub pass_descriptors: HashMap<String, PassDescriptor>,
|
||||
pub pass_pipelines: HashMap<String, Vec<Handle<PipelineDescriptor>>>,
|
||||
pub resource_providers: Vec<Box<dyn ResourceProvider + Send + Sync>>,
|
||||
|
|
|
@ -68,7 +68,7 @@ impl RenderResourceAssignments {
|
|||
.insert(name.to_string(), (vertices_resource, indices_resource));
|
||||
}
|
||||
|
||||
pub fn get_or_update_render_resource_set_id(
|
||||
pub fn update_render_resource_set_id(
|
||||
&mut self,
|
||||
bind_group_descriptor: &BindGroupDescriptor,
|
||||
) -> Option<RenderResourceSetId> {
|
||||
|
@ -191,23 +191,23 @@ mod tests {
|
|||
equal_assignments.set("a", RenderResource(1));
|
||||
equal_assignments.set("b", RenderResource(2));
|
||||
|
||||
let set_id = assignments.get_or_update_render_resource_set_id(&bind_group_descriptor);
|
||||
let set_id = assignments.update_render_resource_set_id(&bind_group_descriptor);
|
||||
assert_ne!(set_id, None);
|
||||
|
||||
let different_set_id =
|
||||
different_assignments.get_or_update_render_resource_set_id(&bind_group_descriptor);
|
||||
different_assignments.update_render_resource_set_id(&bind_group_descriptor);
|
||||
assert_ne!(different_set_id, None);
|
||||
assert_ne!(different_set_id, set_id);
|
||||
|
||||
let equal_set_id =
|
||||
equal_assignments.get_or_update_render_resource_set_id(&bind_group_descriptor);
|
||||
equal_assignments.update_render_resource_set_id(&bind_group_descriptor);
|
||||
assert_ne!(equal_set_id, None);
|
||||
assert_eq!(equal_set_id, set_id);
|
||||
|
||||
let mut unmatched_assignments = RenderResourceAssignments::default();
|
||||
unmatched_assignments.set("a", RenderResource(1));
|
||||
let unmatched_set_id =
|
||||
unmatched_assignments.get_or_update_render_resource_set_id(&bind_group_descriptor);
|
||||
unmatched_assignments.update_render_resource_set_id(&bind_group_descriptor);
|
||||
assert_eq!(unmatched_set_id, None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ pub trait Renderer {
|
|||
);
|
||||
fn setup_bind_groups(
|
||||
&mut self,
|
||||
render_resource_assignments: &mut RenderResourceAssignments,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
mod wgpu_render_context;
|
||||
mod wgpu_render_resource_context;
|
||||
mod wgpu_transactional_render_resource_context;
|
||||
mod systems;
|
||||
|
||||
pub use wgpu_render_context::*;
|
||||
pub use wgpu_render_resource_context::*;
|
||||
pub use wgpu_transactional_render_resource_context::*;
|
||||
pub use systems::*;
|
62
bevy_wgpu/src/renderer_2/systems.rs
Normal file
62
bevy_wgpu/src/renderer_2/systems.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use bevy_asset::AssetStorage;
|
||||
use bevy_render::{
|
||||
pipeline::{PipelineCompiler, PipelineDescriptor, PipelineAssignments},
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{EntityRenderResourceAssignments, RenderResourceAssignments}, Renderable,
|
||||
};
|
||||
use legion::prelude::*;
|
||||
|
||||
pub fn render_resource_sets_system() -> Box<dyn Schedulable> {
|
||||
SystemBuilder::new("update_render_resource_sets")
|
||||
.read_resource::<RenderGraph>()
|
||||
.read_resource::<AssetStorage<PipelineDescriptor>>()
|
||||
.read_resource::<PipelineCompiler>()
|
||||
.read_resource::<PipelineAssignments>()
|
||||
.read_resource::<EntityRenderResourceAssignments>()
|
||||
.write_resource::<RenderResourceAssignments>()
|
||||
.write_component::<Renderable>()
|
||||
.build(
|
||||
|_,
|
||||
world,
|
||||
(
|
||||
render_graph,
|
||||
pipelines,
|
||||
pipeline_compiler,
|
||||
pipeline_assignments,
|
||||
entity_render_resource_assignments,
|
||||
global_render_resource_assignments,
|
||||
),
|
||||
_| {
|
||||
// PERF: consider doing a par-iter over all renderable components so this can be parallelized
|
||||
for handle in render_graph.pipeline_descriptors.iter() {
|
||||
for compiled_pipeline_handle in pipeline_compiler.iter_compiled_pipelines(*handle).unwrap() {
|
||||
if let Some(compiled_pipeline_assignments) =
|
||||
pipeline_assignments.assignments.get(compiled_pipeline_handle)
|
||||
{
|
||||
let compiled_pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
|
||||
let pipeline_layout = compiled_pipeline.get_layout().unwrap();
|
||||
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
global_render_resource_assignments.update_render_resource_set_id(bind_group);
|
||||
}
|
||||
|
||||
for assignment_id in compiled_pipeline_assignments.iter() {
|
||||
let entity = entity_render_resource_assignments
|
||||
.get(*assignment_id)
|
||||
.unwrap();
|
||||
let mut renderable = world.get_component_mut::<Renderable>(*entity).unwrap();
|
||||
if !renderable.is_visible || renderable.is_instanced {
|
||||
continue;
|
||||
}
|
||||
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
renderable.render_resource_assignments.update_render_resource_set_id(bind_group);
|
||||
// TODO: also setup bind groups here if possible
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
|
@ -3,7 +3,7 @@ use super::{
|
|||
WgpuRenderPass, WgpuResources,
|
||||
};
|
||||
use crate::renderer_2::{
|
||||
WgpuRenderContext, WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext,
|
||||
WgpuRenderContext, WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext, render_resource_sets_system,
|
||||
};
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
|
@ -467,6 +467,7 @@ impl Renderer for WgpuRenderer {
|
|||
self.create_queued_textures(resources);
|
||||
let mut encoder = self.encoder.take().unwrap();
|
||||
|
||||
render_resource_sets_system().run(world, resources);
|
||||
// setup draw targets
|
||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||
render_graph.setup_pipeline_draw_targets(world, resources, self);
|
||||
|
@ -665,19 +666,19 @@ impl Renderer for WgpuRenderer {
|
|||
|
||||
fn setup_bind_groups(
|
||||
&mut self,
|
||||
render_resource_assignments: &mut RenderResourceAssignments,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
let pipeline_layout = pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
if let Some(render_resource_set_id) =
|
||||
render_resource_assignments.get_or_update_render_resource_set_id(bind_group)
|
||||
if let Some((render_resource_set_id, _indices)) =
|
||||
render_resource_assignments.get_render_resource_set_id(bind_group.id)
|
||||
{
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.get_bind_group(bind_group.id, render_resource_set_id)
|
||||
.get_bind_group(bind_group.id, *render_resource_set_id)
|
||||
{
|
||||
self.global_context
|
||||
.render_resources
|
||||
|
|
Loading…
Reference in a new issue