RenderGraph2: rendering works again!

This commit is contained in:
Carter Anderson 2020-04-23 21:41:13 -07:00
parent b7d2f068ec
commit 209b4b48d9
4 changed files with 63 additions and 81 deletions

View file

@ -255,6 +255,19 @@ impl PipelineCompiler {
None
}
}
pub fn iter_all_compiled_pipelines(
&self,
) -> impl Iterator<Item = &Handle<PipelineDescriptor>> {
self.pipeline_source_to_compiled
.values()
.map(|compiled_pipelines| {
compiled_pipelines
.iter()
.map(|(_, pipeline_handle)| pipeline_handle)
})
.flatten()
}
}
pub struct PipelineAssignments {

View file

@ -76,7 +76,6 @@ impl Node for PassNode {
input: &ResourceSlots,
_output: &mut ResourceSlots,
) {
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
@ -103,6 +102,18 @@ impl Node for PassNode {
for compiled_pipeline_handle in compiled_pipelines_iter {
let compiled_pipeline_descriptor =
pipeline_storage.get(compiled_pipeline_handle).unwrap();
let pipeline_layout = compiled_pipeline_descriptor.get_layout().unwrap();
{
// TODO: this breaks down in a parallel setting. it needs to change. ideally in a way that
// doesn't require modifying RenderResourceAssignments
let mut render_resource_assignments =
resources.get_mut::<RenderResourceAssignments>().unwrap();
for bind_group in pipeline_layout.bind_groups.iter() {
render_resource_assignments.update_render_resource_set_id(bind_group);
}
}
render_context.create_render_pipeline(
*compiled_pipeline_handle,
&compiled_pipeline_descriptor,
@ -121,6 +132,7 @@ impl Node for PassNode {
}
}
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
render_context.begin_pass(
&self.descriptor,
&render_resource_assignments,

View file

@ -1,69 +1,51 @@
use bevy_asset::AssetStorage;
use bevy_render::{
pipeline::{PipelineAssignments, PipelineCompiler, PipelineDescriptor},
render_graph::RenderGraph,
render_resource::{EntityRenderResourceAssignments, RenderResourceAssignments},
render_resource::{EntityRenderResourceAssignments},
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() {
if let Some(compiled_pipelines) =
pipeline_compiler.iter_compiled_pipelines(*handle)
for compiled_pipeline_handle in pipeline_compiler.iter_all_compiled_pipelines() {
if let Some(compiled_pipeline_assignments) = pipeline_assignments
.assignments
.get(compiled_pipeline_handle)
{
for compiled_pipeline_handle in compiled_pipelines {
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();
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 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
}
}
for bind_group in pipeline_layout.bind_groups.iter() {
renderable
.render_resource_assignments
.update_render_resource_set_id(bind_group);
}
}
}

View file

@ -1,11 +1,12 @@
use crate::renderer_2::{
render_resource_sets_system, WgpuRenderContext, WgpuRenderResourceContext, WgpuRenderGraphExecutor,
render_resource_sets_system, WgpuRenderContext, WgpuRenderGraphExecutor,
WgpuRenderResourceContext,
};
use bevy_app::{EventReader, Events};
use bevy_render::{
pipeline::{update_shader_assignments},
pipeline::update_shader_assignments,
render_graph::RenderGraph,
render_graph_2::{RenderGraph2, RenderGraphStager, DependentNodeStager},
render_graph_2::{DependentNodeStager, RenderGraph2, RenderGraphStager},
render_resource::RenderResourceAssignments,
renderer_2::{GlobalRenderResourceContext, RenderResourceContext},
};
@ -127,30 +128,19 @@ impl WgpuRenderer {
let chunk_size = (render_graph.resource_providers.len() + thread_count - 1) / thread_count; // divide ints rounding remainder up
// crossbeam_utils::thread::scope(|s| {
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
// TODO: try to unify this Device usage
let device = self.device.clone();
// let sender = sender.clone();
// s.spawn(|_| {
// TODO: replace WgpuResources with Global+Local resources
let mut render_context =
WgpuRenderContext::new(device, render_resource_context.clone());
for resource_provider in resource_provider_chunk.iter_mut() {
resource_provider.finish_update(&mut render_context, world, resources);
}
results.push(render_context.finish());
// sender.send(render_context.finish()).unwrap();
// });
}
// });
for command_buffer in results {
// for i in 0..thread_count {
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
if let Some(command_buffer) = command_buffer {
command_buffers.push(command_buffer);
}
// println!("got {}", i);
}
self.queue.submit(&command_buffers);
@ -206,6 +196,8 @@ impl WgpuRenderer {
executor.execute(world, resources);
}
render_resource_sets_system().run(world, resources);
let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap();
if let Some(executor) = executor.take() {
render_graph.set_executor(executor);
@ -220,11 +212,17 @@ impl WgpuRenderer {
let executor = WgpuRenderGraphExecutor {
max_thread_count: 2,
};
executor.execute(world, resources, self.device.clone(), &mut self.queue, &mut borrowed);
executor.execute(
world,
resources,
self.device.clone(),
&mut self.queue,
&mut borrowed,
);
}
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
let mut encoder = {
{
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
let render_resource_context = global_context
.context
@ -248,36 +246,13 @@ impl WgpuRenderer {
update_shader_assignments(world, resources, &render_context);
self.create_queued_textures(resources, &mut render_context.render_resources);
render_context.command_encoder.take()
};
self.run_graph(world, resources);
render_resource_sets_system().run(world, resources);
// TODO: add to POST_UPDATE and remove redundant global_context
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
let render_resource_context = global_context
let render_resource_context = resources.get::<GlobalRenderResourceContext>().unwrap();
render_resource_context
.context
.downcast_mut::<WgpuRenderResourceContext>()
.unwrap();
let mut render_context =
WgpuRenderContext::new(self.device.clone(), render_resource_context.clone());
if let Some(command_encoder) = encoder.take() {
render_context.command_encoder.set(command_encoder);
}
// setup draw targets
// let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
// render_graph.setup_pipeline_draw_targets(world, resources, &mut render_context);
let command_buffer = render_context.finish();
if let Some(command_buffer) = command_buffer {
self.queue.submit(&[command_buffer]);
}
// clear swap chain textures
render_context
.render_resources
.drop_all_swap_chain_textures();
}
}