Use RenderGraphApp in more places (#8298)

# Objective

- RenderGraphExt was merged, but only used in limited situations

## Solution

- Fix some remaining issues with the existing api
- Use the new api in the main pass and mass writeback
- Add CORE_2D and CORE_3D constant to make render_graph code shorter
This commit is contained in:
IceSentry 2023-04-05 16:57:56 -04:00 committed by GitHub
parent 0a17751d16
commit c70776b3cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 160 additions and 152 deletions

View File

@ -4,7 +4,10 @@ mod upsampling_pipeline;
pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};
use crate::{core_2d, core_3d};
use crate::{
core_2d::{self, CORE_2D},
core_3d::{self, CORE_3D},
};
use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_ecs::prelude::*;
@ -73,9 +76,9 @@ impl Plugin for BloomPlugin {
),
)
// Add bloom to the 3d render graph
.add_render_graph_node::<BloomNode>(core_3d::graph::NAME, core_3d::graph::node::BLOOM)
.add_render_graph_node::<BloomNode>(CORE_3D, core_3d::graph::node::BLOOM)
.add_render_graph_edges(
core_3d::graph::NAME,
CORE_3D,
&[
core_3d::graph::node::END_MAIN_PASS,
core_3d::graph::node::BLOOM,
@ -83,9 +86,9 @@ impl Plugin for BloomPlugin {
],
)
// Add bloom to the 2d render graph
.add_render_graph_node::<BloomNode>(core_2d::graph::NAME, core_2d::graph::node::BLOOM)
.add_render_graph_node::<BloomNode>(CORE_2D, core_2d::graph::node::BLOOM)
.add_render_graph_edges(
core_2d::graph::NAME,
CORE_2D,
&[
core_2d::graph::node::MAIN_PASS,
core_2d::graph::node::BLOOM,

View File

@ -1,4 +1,8 @@
use crate::{core_2d, core_3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state};
use crate::{
core_2d::{self, CORE_2D},
core_3d::{self, CORE_3D},
fullscreen_vertex_shader::fullscreen_shader_vertex_state,
};
use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_ecs::{prelude::*, query::QueryItem};
@ -114,47 +118,36 @@ impl Plugin for CASPlugin {
render_app
.init_resource::<CASPipeline>()
.init_resource::<SpecializedRenderPipelines<CASPipeline>>()
.add_systems(Render, prepare_cas_pipelines.in_set(RenderSet::Prepare))
// 3d
.add_render_graph_node::<CASNode>(
core_3d::graph::NAME,
core_3d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
)
.add_render_graph_edge(
core_3d::graph::NAME,
core_3d::graph::node::TONEMAPPING,
core_3d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
)
.add_render_graph_edge(
core_3d::graph::NAME,
core_3d::graph::node::FXAA,
core_3d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
)
.add_render_graph_edge(
core_3d::graph::NAME,
core_3d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING,
)
// 2d
.add_render_graph_node::<CASNode>(
core_2d::graph::NAME,
core_2d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
)
.add_render_graph_edge(
core_2d::graph::NAME,
core_2d::graph::node::TONEMAPPING,
core_2d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
)
.add_render_graph_edge(
core_2d::graph::NAME,
core_2d::graph::node::FXAA,
core_2d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
)
.add_render_graph_edge(
core_2d::graph::NAME,
core_2d::graph::node::CONTRAST_ADAPTIVE_SHARPENING,
core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING,
);
.add_systems(Render, prepare_cas_pipelines.in_set(RenderSet::Prepare));
{
use core_3d::graph::node::*;
render_app
.add_render_graph_node::<CASNode>(CORE_3D, CONTRAST_ADAPTIVE_SHARPENING)
.add_render_graph_edge(CORE_3D, TONEMAPPING, CONTRAST_ADAPTIVE_SHARPENING)
.add_render_graph_edges(
CORE_3D,
&[
FXAA,
CONTRAST_ADAPTIVE_SHARPENING,
END_MAIN_PASS_POST_PROCESSING,
],
);
}
{
use core_2d::graph::node::*;
render_app
.add_render_graph_node::<CASNode>(CORE_2D, CONTRAST_ADAPTIVE_SHARPENING)
.add_render_graph_edge(CORE_2D, TONEMAPPING, CONTRAST_ADAPTIVE_SHARPENING)
.add_render_graph_edges(
CORE_2D,
&[
FXAA,
CONTRAST_ADAPTIVE_SHARPENING,
END_MAIN_PASS_POST_PROCESSING,
],
);
}
}
}

View File

@ -26,8 +26,8 @@ pub struct MainPass2dNode {
>,
}
impl MainPass2dNode {
pub fn new(world: &mut World) -> Self {
impl FromWorld for MainPass2dNode {
fn from_world(world: &mut World) -> Self {
Self {
query: world.query_filtered(),
}

View File

@ -17,6 +17,7 @@ pub mod graph {
pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing";
}
}
pub const CORE_2D: &str = graph::NAME;
pub use camera_2d::*;
pub use main_pass_2d_node::*;
@ -26,7 +27,7 @@ use bevy_ecs::prelude::*;
use bevy_render::{
camera::Camera,
extract_component::ExtractComponentPlugin,
render_graph::{EmptyNode, RenderGraph},
render_graph::{EmptyNode, RenderGraphApp},
render_phase::{
batch_phase_system, sort_phase_system, BatchedPhaseItem, CachedRenderPipelinePhaseItem,
DrawFunctionId, DrawFunctions, PhaseItem, RenderPhase,
@ -64,25 +65,24 @@ impl Plugin for Core2dPlugin {
),
);
let pass_node_2d = MainPass2dNode::new(&mut render_app.world);
let tonemapping = TonemappingNode::new(&mut render_app.world);
let upscaling = UpscalingNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let mut draw_2d_graph = RenderGraph::default();
draw_2d_graph.add_node(graph::node::MAIN_PASS, pass_node_2d);
draw_2d_graph.add_node(graph::node::TONEMAPPING, tonemapping);
draw_2d_graph.add_node(graph::node::END_MAIN_PASS_POST_PROCESSING, EmptyNode);
draw_2d_graph.add_node(graph::node::UPSCALING, upscaling);
draw_2d_graph.add_node_edges(&[
graph::node::MAIN_PASS,
graph::node::TONEMAPPING,
graph::node::END_MAIN_PASS_POST_PROCESSING,
graph::node::UPSCALING,
]);
graph.add_sub_graph(graph::NAME, draw_2d_graph);
{
use graph::node::*;
render_app
.add_render_sub_graph(CORE_2D)
.add_render_graph_node::<MainPass2dNode>(CORE_2D, MAIN_PASS)
.add_render_graph_node::<TonemappingNode>(CORE_2D, TONEMAPPING)
.add_render_graph_node::<EmptyNode>(CORE_2D, END_MAIN_PASS_POST_PROCESSING)
.add_render_graph_node::<UpscalingNode>(CORE_2D, UPSCALING)
.add_render_graph_edges(
CORE_2D,
&[
MAIN_PASS,
TONEMAPPING,
END_MAIN_PASS_POST_PROCESSING,
UPSCALING,
],
);
}
}
}

View File

@ -41,8 +41,8 @@ pub struct MainOpaquePass3dNode {
>,
}
impl MainOpaquePass3dNode {
pub fn new(world: &mut World) -> Self {
impl FromWorld for MainOpaquePass3dNode {
fn from_world(world: &mut World) -> Self {
Self {
query: world.query_filtered(),
}

View File

@ -24,8 +24,8 @@ pub struct MainTransparentPass3dNode {
>,
}
impl MainTransparentPass3dNode {
pub fn new(world: &mut World) -> Self {
impl FromWorld for MainTransparentPass3dNode {
fn from_world(world: &mut World) -> Self {
Self {
query: world.query_filtered(),
}

View File

@ -22,6 +22,7 @@ pub mod graph {
pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing";
}
}
pub const CORE_3D: &str = graph::NAME;
use std::cmp::Reverse;
@ -35,7 +36,7 @@ use bevy_render::{
camera::{Camera, ExtractedCamera},
extract_component::ExtractComponentPlugin,
prelude::Msaa,
render_graph::{EmptyNode, RenderGraph},
render_graph::{EmptyNode, RenderGraphApp},
render_phase::{
sort_phase_system, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem,
RenderPhase,
@ -89,35 +90,30 @@ impl Plugin for Core3dPlugin {
),
);
let prepass_node = PrepassNode::new(&mut render_app.world);
let opaque_node_3d = MainOpaquePass3dNode::new(&mut render_app.world);
let transparent_node_3d = MainTransparentPass3dNode::new(&mut render_app.world);
let tonemapping = TonemappingNode::new(&mut render_app.world);
let upscaling = UpscalingNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let mut draw_3d_graph = RenderGraph::default();
draw_3d_graph.add_node(graph::node::PREPASS, prepass_node);
draw_3d_graph.add_node(graph::node::START_MAIN_PASS, EmptyNode);
draw_3d_graph.add_node(graph::node::MAIN_OPAQUE_PASS, opaque_node_3d);
draw_3d_graph.add_node(graph::node::MAIN_TRANSPARENT_PASS, transparent_node_3d);
draw_3d_graph.add_node(graph::node::END_MAIN_PASS, EmptyNode);
draw_3d_graph.add_node(graph::node::TONEMAPPING, tonemapping);
draw_3d_graph.add_node(graph::node::END_MAIN_PASS_POST_PROCESSING, EmptyNode);
draw_3d_graph.add_node(graph::node::UPSCALING, upscaling);
draw_3d_graph.add_node_edges(&[
graph::node::PREPASS,
graph::node::START_MAIN_PASS,
graph::node::MAIN_OPAQUE_PASS,
graph::node::MAIN_TRANSPARENT_PASS,
graph::node::END_MAIN_PASS,
graph::node::TONEMAPPING,
graph::node::END_MAIN_PASS_POST_PROCESSING,
graph::node::UPSCALING,
]);
graph.add_sub_graph(graph::NAME, draw_3d_graph);
use graph::node::*;
render_app
.add_render_sub_graph(CORE_3D)
.add_render_graph_node::<PrepassNode>(CORE_3D, PREPASS)
.add_render_graph_node::<EmptyNode>(CORE_3D, START_MAIN_PASS)
.add_render_graph_node::<MainOpaquePass3dNode>(CORE_3D, MAIN_OPAQUE_PASS)
.add_render_graph_node::<MainTransparentPass3dNode>(CORE_3D, MAIN_TRANSPARENT_PASS)
.add_render_graph_node::<EmptyNode>(CORE_3D, END_MAIN_PASS)
.add_render_graph_node::<TonemappingNode>(CORE_3D, TONEMAPPING)
.add_render_graph_node::<EmptyNode>(CORE_3D, END_MAIN_PASS_POST_PROCESSING)
.add_render_graph_node::<UpscalingNode>(CORE_3D, UPSCALING)
.add_render_graph_edges(
CORE_3D,
&[
PREPASS,
START_MAIN_PASS,
MAIN_OPAQUE_PASS,
MAIN_TRANSPARENT_PASS,
END_MAIN_PASS,
TONEMAPPING,
END_MAIN_PASS_POST_PROCESSING,
UPSCALING,
],
);
}
}

View File

@ -1,4 +1,8 @@
use crate::{core_2d, core_3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state};
use crate::{
core_2d::{self, CORE_2D},
core_3d::{self, CORE_3D},
fullscreen_vertex_shader::fullscreen_shader_vertex_state,
};
use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, HandleUntyped};
use bevy_derive::Deref;
@ -91,18 +95,18 @@ impl Plugin for FxaaPlugin {
.init_resource::<FxaaPipeline>()
.init_resource::<SpecializedRenderPipelines<FxaaPipeline>>()
.add_systems(Render, prepare_fxaa_pipelines.in_set(RenderSet::Prepare))
.add_render_graph_node::<FxaaNode>(core_3d::graph::NAME, core_3d::graph::node::FXAA)
.add_render_graph_node::<FxaaNode>(CORE_3D, core_3d::graph::node::FXAA)
.add_render_graph_edges(
core_3d::graph::NAME,
CORE_3D,
&[
core_3d::graph::node::TONEMAPPING,
core_3d::graph::node::FXAA,
core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING,
],
)
.add_render_graph_node::<FxaaNode>(core_2d::graph::NAME, core_2d::graph::node::FXAA)
.add_render_graph_node::<FxaaNode>(CORE_2D, core_2d::graph::node::FXAA)
.add_render_graph_edges(
core_2d::graph::NAME,
CORE_2D,
&[
core_2d::graph::node::TONEMAPPING,
core_2d::graph::node::FXAA,

View File

@ -1,9 +1,13 @@
use crate::blit::{BlitPipeline, BlitPipelineKey};
use crate::{
blit::{BlitPipeline, BlitPipelineKey},
core_2d::{self, CORE_2D},
core_3d::{self, CORE_3D},
};
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
use bevy_render::{
camera::ExtractedCamera,
render_graph::{Node, NodeRunError, RenderGraph, RenderGraphContext},
render_graph::{Node, NodeRunError, RenderGraphApp, RenderGraphContext},
renderer::RenderContext,
view::{Msaa, ViewTarget},
Render, RenderSet,
@ -24,29 +28,17 @@ impl Plugin for MsaaWritebackPlugin {
Render,
queue_msaa_writeback_pipelines.in_set(RenderSet::Queue),
);
let msaa_writeback_2d = MsaaWritebackNode::new(&mut render_app.world);
let msaa_writeback_3d = MsaaWritebackNode::new(&mut render_app.world);
let mut graph = render_app.world.resource_mut::<RenderGraph>();
if let Some(core_2d) = graph.get_sub_graph_mut(crate::core_2d::graph::NAME) {
core_2d.add_node(
crate::core_2d::graph::node::MSAA_WRITEBACK,
msaa_writeback_2d,
);
core_2d.add_node_edge(
crate::core_2d::graph::node::MSAA_WRITEBACK,
crate::core_2d::graph::node::MAIN_PASS,
);
{
use core_2d::graph::node::*;
render_app
.add_render_graph_node::<MsaaWritebackNode>(CORE_2D, MSAA_WRITEBACK)
.add_render_graph_edge(CORE_2D, MSAA_WRITEBACK, MAIN_PASS);
}
if let Some(core_3d) = graph.get_sub_graph_mut(crate::core_3d::graph::NAME) {
core_3d.add_node(
crate::core_3d::graph::node::MSAA_WRITEBACK,
msaa_writeback_3d,
);
core_3d.add_node_edge(
crate::core_3d::graph::node::MSAA_WRITEBACK,
crate::core_3d::graph::node::START_MAIN_PASS,
);
{
use core_3d::graph::node::*;
render_app
.add_render_graph_node::<MsaaWritebackNode>(CORE_3D, MSAA_WRITEBACK)
.add_render_graph_edge(CORE_3D, MSAA_WRITEBACK, START_MAIN_PASS);
}
}
}
@ -55,8 +47,8 @@ pub struct MsaaWritebackNode {
cameras: QueryState<(&'static ViewTarget, &'static MsaaWritebackBlitPipeline)>,
}
impl MsaaWritebackNode {
pub fn new(world: &mut World) -> Self {
impl FromWorld for MsaaWritebackNode {
fn from_world(world: &mut World) -> Self {
Self {
cameras: world.query(),
}

View File

@ -33,8 +33,8 @@ pub struct PrepassNode {
>,
}
impl PrepassNode {
pub fn new(world: &mut World) -> Self {
impl FromWorld for PrepassNode {
fn from_world(world: &mut World) -> Self {
Self {
main_view_query: QueryState::new(world),
}

View File

@ -1,5 +1,5 @@
use crate::{
core_3d,
core_3d::{self, CORE_3D},
fullscreen_vertex_shader::fullscreen_shader_vertex_state,
prelude::Camera3d,
prepass::{DepthPrepass, MotionVectorPrepass, ViewPrepassTextures},
@ -73,9 +73,9 @@ impl Plugin for TemporalAntiAliasPlugin {
prepare_taa_pipelines.in_set(RenderSet::Prepare),
),
)
.add_render_graph_node::<TAANode>(core_3d::graph::NAME, draw_3d_graph::node::TAA)
.add_render_graph_node::<TAANode>(CORE_3D, draw_3d_graph::node::TAA)
.add_render_graph_edges(
core_3d::graph::NAME,
CORE_3D,
&[
core_3d::graph::node::END_MAIN_PASS,
draw_3d_graph::node::TAA,

View File

@ -33,8 +33,8 @@ pub struct TonemappingNode {
last_tonemapping: Mutex<Option<Tonemapping>>,
}
impl TonemappingNode {
pub fn new(world: &mut World) -> Self {
impl FromWorld for TonemappingNode {
fn from_world(world: &mut World) -> Self {
Self {
query: QueryState::new(world),
cached_bind_group: Mutex::new(None),

View File

@ -26,8 +26,8 @@ pub struct UpscalingNode {
cached_texture_bind_group: Mutex<Option<(TextureViewId, BindGroup)>>,
}
impl UpscalingNode {
pub fn new(world: &mut World) -> Self {
impl FromWorld for UpscalingNode {
fn from_world(world: &mut World) -> Self {
Self {
query: QueryState::new(world),
cached_texture_bind_group: Mutex::new(None),

View File

@ -1,10 +1,13 @@
use bevy_app::App;
use bevy_ecs::world::FromWorld;
use bevy_log::warn;
use super::{Node, RenderGraph};
/// Adds common [`RenderGraph`] operations to [`App`].
pub trait RenderGraphApp {
// Add a sub graph to the [`RenderGraph`]
fn add_render_sub_graph(&mut self, sub_graph_name: &'static str) -> &mut Self;
/// Add a [`Node`] to the [`RenderGraph`]:
/// * Create the [`Node`] using the [`FromWorld`] implementation
/// * Add it to the graph
@ -38,9 +41,11 @@ impl RenderGraphApp for App {
let mut render_graph = self.world.get_resource_mut::<RenderGraph>().expect(
"RenderGraph not found. Make sure you are using add_render_graph_node on the RenderApp",
);
let graph = render_graph.sub_graph_mut(sub_graph_name);
graph.add_node(node_name, node);
if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) {
graph.add_node(node_name, node);
} else {
warn!("Tried adding a render graph node to {sub_graph_name} but the sub graph doesn't exist");
}
self
}
@ -50,10 +55,13 @@ impl RenderGraphApp for App {
edges: &[&'static str],
) -> &mut Self {
let mut render_graph = self.world.get_resource_mut::<RenderGraph>().expect(
"RenderGraph not found. Make sure you are using add_render_graph_node on the RenderApp",
"RenderGraph not found. Make sure you are using add_render_graph_edges on the RenderApp",
);
let graph = render_graph.sub_graph_mut(sub_graph_name);
graph.add_node_edges(edges);
if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) {
graph.add_node_edges(edges);
} else {
warn!("Tried adding render graph edges to {sub_graph_name} but the sub graph doesn't exist");
}
self
}
@ -64,10 +72,21 @@ impl RenderGraphApp for App {
input_edge: &'static str,
) -> &mut Self {
let mut render_graph = self.world.get_resource_mut::<RenderGraph>().expect(
"RenderGraph not found. Make sure you are using add_render_graph_node on the RenderApp",
"RenderGraph not found. Make sure you are using add_render_graph_edge on the RenderApp",
);
let graph = render_graph.sub_graph_mut(sub_graph_name);
graph.add_node_edge(output_edge, input_edge);
if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) {
graph.add_node_edge(output_edge, input_edge);
} else {
warn!("Tried adding a render graph edge to {sub_graph_name} but the sub graph doesn't exist");
}
self
}
fn add_render_sub_graph(&mut self, sub_graph_name: &'static str) -> &mut Self {
let mut render_graph = self.world.get_resource_mut::<RenderGraph>().expect(
"RenderGraph not found. Make sure you are using add_render_sub_graph on the RenderApp",
);
render_graph.add_sub_graph(sub_graph_name, RenderGraph::default());
self
}
}

View File

@ -293,6 +293,7 @@ impl From<NodeId> for NodeLabel {
/// A [`Node`] without any inputs, outputs and subgraphs, which does nothing when run.
/// Used (as a label) to bundle multiple dependencies into one inside
/// the [`RenderGraph`](super::RenderGraph).
#[derive(Default)]
pub struct EmptyNode;
impl Node for EmptyNode {