RenderGraph2: rendering works again!
This commit is contained in:
parent
b7d2f068ec
commit
209b4b48d9
@ -255,6 +255,19 @@ impl PipelineCompiler {
|
|||||||
None
|
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 {
|
pub struct PipelineAssignments {
|
||||||
|
|||||||
@ -76,7 +76,6 @@ impl Node for PassNode {
|
|||||||
input: &ResourceSlots,
|
input: &ResourceSlots,
|
||||||
_output: &mut ResourceSlots,
|
_output: &mut ResourceSlots,
|
||||||
) {
|
) {
|
||||||
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
|
|
||||||
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
|
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
|
||||||
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().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 {
|
for compiled_pipeline_handle in compiled_pipelines_iter {
|
||||||
let compiled_pipeline_descriptor =
|
let compiled_pipeline_descriptor =
|
||||||
pipeline_storage.get(compiled_pipeline_handle).unwrap();
|
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(
|
render_context.create_render_pipeline(
|
||||||
*compiled_pipeline_handle,
|
*compiled_pipeline_handle,
|
||||||
&compiled_pipeline_descriptor,
|
&compiled_pipeline_descriptor,
|
||||||
@ -121,6 +132,7 @@ impl Node for PassNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
render_context.begin_pass(
|
render_context.begin_pass(
|
||||||
&self.descriptor,
|
&self.descriptor,
|
||||||
&render_resource_assignments,
|
&render_resource_assignments,
|
||||||
|
|||||||
@ -1,69 +1,51 @@
|
|||||||
use bevy_asset::AssetStorage;
|
use bevy_asset::AssetStorage;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{PipelineAssignments, PipelineCompiler, PipelineDescriptor},
|
pipeline::{PipelineAssignments, PipelineCompiler, PipelineDescriptor},
|
||||||
render_graph::RenderGraph,
|
render_resource::{EntityRenderResourceAssignments},
|
||||||
render_resource::{EntityRenderResourceAssignments, RenderResourceAssignments},
|
|
||||||
Renderable,
|
Renderable,
|
||||||
};
|
};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
|
|
||||||
pub fn render_resource_sets_system() -> Box<dyn Schedulable> {
|
pub fn render_resource_sets_system() -> Box<dyn Schedulable> {
|
||||||
SystemBuilder::new("update_render_resource_sets")
|
SystemBuilder::new("update_render_resource_sets")
|
||||||
.read_resource::<RenderGraph>()
|
|
||||||
.read_resource::<AssetStorage<PipelineDescriptor>>()
|
.read_resource::<AssetStorage<PipelineDescriptor>>()
|
||||||
.read_resource::<PipelineCompiler>()
|
.read_resource::<PipelineCompiler>()
|
||||||
.read_resource::<PipelineAssignments>()
|
.read_resource::<PipelineAssignments>()
|
||||||
.read_resource::<EntityRenderResourceAssignments>()
|
.read_resource::<EntityRenderResourceAssignments>()
|
||||||
.write_resource::<RenderResourceAssignments>()
|
|
||||||
.write_component::<Renderable>()
|
.write_component::<Renderable>()
|
||||||
.build(
|
.build(
|
||||||
|_,
|
|_,
|
||||||
world,
|
world,
|
||||||
(
|
(
|
||||||
render_graph,
|
|
||||||
pipelines,
|
pipelines,
|
||||||
pipeline_compiler,
|
pipeline_compiler,
|
||||||
pipeline_assignments,
|
pipeline_assignments,
|
||||||
entity_render_resource_assignments,
|
entity_render_resource_assignments,
|
||||||
global_render_resource_assignments,
|
|
||||||
),
|
),
|
||||||
_| {
|
_| {
|
||||||
// PERF: consider doing a par-iter over all renderable components so this can be parallelized
|
// 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_all_compiled_pipelines() {
|
||||||
if let Some(compiled_pipelines) =
|
if let Some(compiled_pipeline_assignments) = pipeline_assignments
|
||||||
pipeline_compiler.iter_compiled_pipelines(*handle)
|
.assignments
|
||||||
|
.get(compiled_pipeline_handle)
|
||||||
{
|
{
|
||||||
for compiled_pipeline_handle in compiled_pipelines {
|
let compiled_pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
|
||||||
if let Some(compiled_pipeline_assignments) = pipeline_assignments
|
let pipeline_layout = compiled_pipeline.get_layout().unwrap();
|
||||||
.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() {
|
for assignment_id in compiled_pipeline_assignments.iter() {
|
||||||
global_render_resource_assignments
|
let entity = entity_render_resource_assignments
|
||||||
.update_render_resource_set_id(bind_group);
|
.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() {
|
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||||
let entity = entity_render_resource_assignments
|
renderable
|
||||||
.get(*assignment_id)
|
.render_resource_assignments
|
||||||
.unwrap();
|
.update_render_resource_set_id(bind_group);
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
use crate::renderer_2::{
|
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_app::{EventReader, Events};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{update_shader_assignments},
|
pipeline::update_shader_assignments,
|
||||||
render_graph::RenderGraph,
|
render_graph::RenderGraph,
|
||||||
render_graph_2::{RenderGraph2, RenderGraphStager, DependentNodeStager},
|
render_graph_2::{DependentNodeStager, RenderGraph2, RenderGraphStager},
|
||||||
render_resource::RenderResourceAssignments,
|
render_resource::RenderResourceAssignments,
|
||||||
renderer_2::{GlobalRenderResourceContext, RenderResourceContext},
|
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
|
let chunk_size = (render_graph.resource_providers.len() + thread_count - 1) / thread_count; // divide ints rounding remainder up
|
||||||
// crossbeam_utils::thread::scope(|s| {
|
// crossbeam_utils::thread::scope(|s| {
|
||||||
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
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 device = self.device.clone();
|
||||||
// let sender = sender.clone();
|
|
||||||
// s.spawn(|_| {
|
|
||||||
// TODO: replace WgpuResources with Global+Local resources
|
|
||||||
let mut render_context =
|
let mut render_context =
|
||||||
WgpuRenderContext::new(device, render_resource_context.clone());
|
WgpuRenderContext::new(device, render_resource_context.clone());
|
||||||
for resource_provider in resource_provider_chunk.iter_mut() {
|
for resource_provider in resource_provider_chunk.iter_mut() {
|
||||||
resource_provider.finish_update(&mut render_context, world, resources);
|
resource_provider.finish_update(&mut render_context, world, resources);
|
||||||
}
|
}
|
||||||
results.push(render_context.finish());
|
results.push(render_context.finish());
|
||||||
// sender.send(render_context.finish()).unwrap();
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
// });
|
|
||||||
|
|
||||||
for command_buffer in results {
|
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 {
|
if let Some(command_buffer) = command_buffer {
|
||||||
command_buffers.push(command_buffer);
|
command_buffers.push(command_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// println!("got {}", i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.queue.submit(&command_buffers);
|
self.queue.submit(&command_buffers);
|
||||||
@ -206,6 +196,8 @@ impl WgpuRenderer {
|
|||||||
executor.execute(world, resources);
|
executor.execute(world, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render_resource_sets_system().run(world, resources);
|
||||||
|
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap();
|
||||||
if let Some(executor) = executor.take() {
|
if let Some(executor) = executor.take() {
|
||||||
render_graph.set_executor(executor);
|
render_graph.set_executor(executor);
|
||||||
@ -220,11 +212,17 @@ impl WgpuRenderer {
|
|||||||
let executor = WgpuRenderGraphExecutor {
|
let executor = WgpuRenderGraphExecutor {
|
||||||
max_thread_count: 2,
|
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) {
|
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
||||||
let mut encoder = {
|
{
|
||||||
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
||||||
let render_resource_context = global_context
|
let render_resource_context = global_context
|
||||||
.context
|
.context
|
||||||
@ -248,36 +246,13 @@ impl WgpuRenderer {
|
|||||||
|
|
||||||
update_shader_assignments(world, resources, &render_context);
|
update_shader_assignments(world, resources, &render_context);
|
||||||
self.create_queued_textures(resources, &mut render_context.render_resources);
|
self.create_queued_textures(resources, &mut render_context.render_resources);
|
||||||
render_context.command_encoder.take()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.run_graph(world, resources);
|
self.run_graph(world, resources);
|
||||||
render_resource_sets_system().run(world, resources);
|
|
||||||
// TODO: add to POST_UPDATE and remove redundant global_context
|
let render_resource_context = resources.get::<GlobalRenderResourceContext>().unwrap();
|
||||||
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
render_resource_context
|
||||||
let render_resource_context = global_context
|
|
||||||
.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();
|
.drop_all_swap_chain_textures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user