From 72e5abec02d4b6ba2030f97ae6b6eeeb419fe4a0 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Fri, 17 Nov 2023 21:50:24 +0100 Subject: [PATCH 01/20] First iteration of labelization --- crates/bevy_render/macros/src/lib.rs | 21 +- crates/bevy_render/src/camera/mod.rs | 2 +- crates/bevy_render/src/lib.rs | 5 +- crates/bevy_render/src/render_graph/app.rs | 27 +- crates/bevy_render/src/render_graph/edge.rs | 14 +- crates/bevy_render/src/render_graph/graph.rs | 367 +++++++++--------- crates/bevy_render/src/render_graph/mod.rs | 22 +- crates/bevy_render/src/render_graph/node.rs | 25 +- .../bevy_render/src/renderer/graph_runner.rs | 20 +- 9 files changed, 267 insertions(+), 236 deletions(-) diff --git a/crates/bevy_render/macros/src/lib.rs b/crates/bevy_render/macros/src/lib.rs index 89eec6b220c9a..019e70871fa77 100644 --- a/crates/bevy_render/macros/src/lib.rs +++ b/crates/bevy_render/macros/src/lib.rs @@ -2,8 +2,9 @@ mod as_bind_group; mod extract_component; mod extract_resource; -use bevy_macro_utils::BevyManifest; +use bevy_macro_utils::{derive_label, BevyManifest}; use proc_macro::TokenStream; +use quote::format_ident; use syn::{parse_macro_input, DeriveInput}; pub(crate) fn bevy_render_path() -> syn::Path { @@ -58,3 +59,21 @@ pub fn derive_as_bind_group(input: TokenStream) -> TokenStream { as_bind_group::derive_as_bind_group(input).unwrap_or_else(|err| err.to_compile_error().into()) } + +/// Derive macro generating an impl of the trait `RenderGraphLabel`. +/// +/// This does not work for unions. +#[proc_macro_derive(RenderGraphLabel)] +pub fn derive_render_graph_label(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let mut trait_path = bevy_render_path(); + trait_path + .segments + .push(format_ident!("render_graph").into()); + let mut dyn_eq_path = trait_path.clone(); + trait_path + .segments + .push(format_ident!("RenderGraphLabel").into()); + dyn_eq_path.segments.push(format_ident!("DynEq").into()); + derive_label(input, "RenderGraphLabel", &trait_path, &dyn_eq_path) +} diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index 2a92ff159692c..3bfa6f29972c5 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -42,7 +42,7 @@ impl Plugin for CameraPlugin { .add_systems(Render, sort_cameras.in_set(RenderSet::ManageViews)); let camera_driver_node = CameraDriverNode::new(&mut render_app.world); let mut render_graph = render_app.world.resource_mut::(); - render_graph.add_node(crate::main_graph::node::CAMERA_DRIVER, camera_driver_node); + render_graph.add_node(crate::main_graph::node::CameraDriver, camera_driver_node); } } } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 4f06c11e0291d..2faa5e1c15cbc 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -208,7 +208,10 @@ impl DerefMut for MainWorld { pub mod main_graph { pub mod node { - pub const CAMERA_DRIVER: &str = "camera_driver"; + use bevy_render_macros::RenderGraphLabel; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderGraphLabel)] + pub struct CameraDriver; } } diff --git a/crates/bevy_render/src/render_graph/app.rs b/crates/bevy_render/src/render_graph/app.rs index 185260f95b7d9..0418705b8f6b2 100644 --- a/crates/bevy_render/src/render_graph/app.rs +++ b/crates/bevy_render/src/render_graph/app.rs @@ -2,7 +2,7 @@ use bevy_app::App; use bevy_ecs::world::FromWorld; use bevy_log::warn; -use super::{Node, RenderGraph}; +use super::{Node, RenderGraph, RenderGraphLabel}; /// Adds common [`RenderGraph`] operations to [`App`]. pub trait RenderGraphApp { @@ -14,20 +14,22 @@ pub trait RenderGraphApp { fn add_render_graph_node( &mut self, sub_graph_name: &'static str, - node_name: &'static str, + node_label: impl RenderGraphLabel, ) -> &mut Self; + /* TODO: /// Automatically add the required node edges based on the given ordering fn add_render_graph_edges( &mut self, sub_graph_name: &'static str, edges: &[&'static str], - ) -> &mut Self; + ) -> &mut Self;*/ + /// Add node edge to the specified graph fn add_render_graph_edge( &mut self, sub_graph_name: &'static str, - output_edge: &'static str, - input_edge: &'static str, + output_node: impl RenderGraphLabel, + input_node: impl RenderGraphLabel, ) -> &mut Self; } @@ -35,21 +37,22 @@ impl RenderGraphApp for App { fn add_render_graph_node( &mut self, sub_graph_name: &'static str, - node_name: &'static str, + node_label: impl RenderGraphLabel, ) -> &mut Self { let node = T::from_world(&mut self.world); let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_node on the RenderApp", ); if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) { - graph.add_node(node_name, node); + graph.add_node(node_label, node); } else { warn!("Tried adding a render graph node to {sub_graph_name} but the sub graph doesn't exist"); } self } - fn add_render_graph_edges( + // TODO: + /*fn add_render_graph_edges( &mut self, sub_graph_name: &'static str, edges: &[&'static str], @@ -63,19 +66,19 @@ impl RenderGraphApp for App { warn!("Tried adding render graph edges to {sub_graph_name} but the sub graph doesn't exist"); } self - } + }*/ fn add_render_graph_edge( &mut self, sub_graph_name: &'static str, - output_edge: &'static str, - input_edge: &'static str, + output_node: impl RenderGraphLabel, + input_node: impl RenderGraphLabel, ) -> &mut Self { let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_edge on the RenderApp", ); if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) { - graph.add_node_edge(output_edge, input_edge); + graph.add_node_edge(output_node, input_node); } else { warn!("Tried adding a render graph edge to {sub_graph_name} but the sub graph doesn't exist"); } diff --git a/crates/bevy_render/src/render_graph/edge.rs b/crates/bevy_render/src/render_graph/edge.rs index 4ba85fca57892..5d999e83645b7 100644 --- a/crates/bevy_render/src/render_graph/edge.rs +++ b/crates/bevy_render/src/render_graph/edge.rs @@ -1,4 +1,4 @@ -use super::NodeId; +use super::InternedRGLabel; /// An edge, which connects two [`Nodes`](super::Node) in /// a [`RenderGraph`](crate::render_graph::RenderGraph). @@ -22,28 +22,28 @@ pub enum Edge { /// and connecting the output slot at the `output_index` of the output_node /// with the slot at the `input_index` of the `input_node`. SlotEdge { - input_node: NodeId, + input_node: InternedRGLabel, input_index: usize, - output_node: NodeId, + output_node: InternedRGLabel, output_index: usize, }, /// An edge describing to ordering of both nodes (`output_node` before `input_node`). NodeEdge { - input_node: NodeId, - output_node: NodeId, + input_node: InternedRGLabel, + output_node: InternedRGLabel, }, } impl Edge { /// Returns the id of the `input_node`. - pub fn get_input_node(&self) -> NodeId { + pub fn get_input_node(&self) -> InternedRGLabel { match self { Edge::SlotEdge { input_node, .. } | Edge::NodeEdge { input_node, .. } => *input_node, } } /// Returns the id of the `output_node`. - pub fn get_output_node(&self) -> NodeId { + pub fn get_output_node(&self) -> InternedRGLabel { match self { Edge::SlotEdge { output_node, .. } | Edge::NodeEdge { output_node, .. } => *output_node, } diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 03d06b9a4f0ec..38ecebd86129e 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -1,15 +1,16 @@ use crate::{ render_graph::{ - Edge, Node, NodeId, NodeLabel, NodeRunError, NodeState, RenderGraphContext, - RenderGraphError, SlotInfo, SlotLabel, + Edge, Node, NodeId, NodeRunError, NodeState, RenderGraphContext, RenderGraphError, + SlotInfo, SlotLabel, }, renderer::RenderContext, }; use bevy_ecs::{prelude::World, system::Resource}; +use bevy_render_macros::RenderGraphLabel; use bevy_utils::HashMap; use std::{borrow::Cow, fmt::Debug}; -use super::EdgeExistence; +use super::{EdgeExistence, InternedRGLabel, RenderGraphLabel}; /// The render graph configures the modular, parallel and re-usable render logic. /// It is a retained and stateless (nodes themselves may have their own internal state) structure, @@ -50,16 +51,15 @@ use super::EdgeExistence; /// ``` #[derive(Resource, Default)] pub struct RenderGraph { - nodes: HashMap, - node_names: HashMap, NodeId>, + nodes: HashMap, sub_graphs: HashMap, RenderGraph>, - input_node: Option, } -impl RenderGraph { - /// The name of the [`GraphInputNode`] of this graph. Used to connect other nodes to it. - pub const INPUT_NODE_NAME: &'static str = "GraphInputNode"; +/// The label for the input node of a graph. Used to connect other nodes to it. +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderGraphLabel)] +pub struct GraphInput; +impl RenderGraph { /// Updates all nodes and sub graphs of the render graph. Should be called before executing it. pub fn update(&mut self, world: &mut World) { for node in self.nodes.values_mut() { @@ -73,11 +73,15 @@ impl RenderGraph { /// Creates an [`GraphInputNode`] with the specified slots if not already present. pub fn set_input(&mut self, inputs: Vec) -> NodeId { - assert!(self.input_node.is_none(), "Graph already has an input node"); + assert!( + matches!( + self.get_node_state(GraphInput), + Err(RenderGraphError::InvalidNode(_)) + ), + "Graph already has an input node" + ); - let id = self.add_node("GraphInputNode", GraphInputNode { inputs }); - self.input_node = Some(id); - id + self.add_node(GraphInput, GraphInputNode { inputs }) } /// Returns the [`NodeState`] of the input node of this graph. @@ -87,7 +91,7 @@ impl RenderGraph { /// - [`input_node`](Self::input_node) for an unchecked version. #[inline] pub fn get_input_node(&self) -> Option<&NodeState> { - self.input_node.and_then(|id| self.get_node_state(id).ok()) + self.get_node_state(GraphInput).ok() } /// Returns the [`NodeState`] of the input node of this graph. @@ -104,82 +108,55 @@ impl RenderGraph { self.get_input_node().unwrap() } - /// Adds the `node` with the `name` to the graph. - /// If the name is already present replaces it instead. - pub fn add_node(&mut self, name: impl Into>, node: T) -> NodeId + /// Adds the `node` with the `label` to the graph. + /// If the label is already present replaces it instead. + pub fn add_node(&mut self, label: impl RenderGraphLabel, node: T) -> NodeId where T: Node, { let id = NodeId::new(); - let name = name.into(); - let mut node_state = NodeState::new(id, node); - node_state.name = Some(name.clone()); - self.nodes.insert(id, node_state); - self.node_names.insert(name, id); + let label = label.intern(); + let node_state = NodeState::new(id, node, label); + self.nodes.insert(label, node_state); id } - /// Add `node_edge`s based on the order of the given `edges` array. - /// - /// Defining an edge that already exists is not considered an error with this api. - /// It simply won't create a new edge. - pub fn add_node_edges(&mut self, edges: &[&'static str]) { - for window in edges.windows(2) { - let [a, b] = window else { - break; - }; - if let Err(err) = self.try_add_node_edge(*a, *b) { - match err { - // Already existing edges are very easy to produce with this api - // and shouldn't cause a panic - RenderGraphError::EdgeAlreadyExists(_) => {} - _ => panic!("{err:?}"), - } - } - } - } - - /// Removes the `node` with the `name` from the graph. - /// If the name is does not exist, nothing happens. - pub fn remove_node( - &mut self, - name: impl Into>, - ) -> Result<(), RenderGraphError> { - let name = name.into(); - if let Some(id) = self.node_names.remove(&name) { - if let Some(node_state) = self.nodes.remove(&id) { - // Remove all edges from other nodes to this one. Note that as we're removing this - // node, we don't need to remove its input edges - for input_edge in node_state.edges.input_edges() { - match input_edge { - Edge::SlotEdge { output_node, .. } - | Edge::NodeEdge { - input_node: _, - output_node, - } => { - if let Ok(output_node) = self.get_node_state_mut(*output_node) { - output_node.edges.remove_output_edge(input_edge.clone())?; - } + /// Removes the `node` with the `label` from the graph. + /// If the label does not exist, nothing happens. + pub fn remove_node(&mut self, label: impl RenderGraphLabel) -> Result<(), RenderGraphError> { + let label = label.intern(); + if let Some(node_state) = self.nodes.remove(&label) { + // Remove all edges from other nodes to this one. Note that as we're removing this + // node, we don't need to remove its input edges + for input_edge in node_state.edges.input_edges() { + match input_edge { + Edge::SlotEdge { output_node, .. } + | Edge::NodeEdge { + input_node: _, + output_node, + } => { + if let Ok(output_node) = self.get_node_state_mut(*output_node) { + output_node.edges.remove_output_edge(input_edge.clone())?; } } } - // Remove all edges from this node to other nodes. Note that as we're removing this - // node, we don't need to remove its output edges - for output_edge in node_state.edges.output_edges() { - match output_edge { - Edge::SlotEdge { - output_node: _, - output_index: _, - input_node, - input_index: _, - } - | Edge::NodeEdge { - output_node: _, - input_node, - } => { - if let Ok(input_node) = self.get_node_state_mut(*input_node) { - input_node.edges.remove_input_edge(output_edge.clone())?; - } + } + // Remove all edges from this node to other nodes. Note that as we're removing this + // node, we don't need to remove its output edges + for output_edge in node_state.edges.output_edges() { + match output_edge { + Edge::SlotEdge { + output_node: _, + output_index: _, + input_node, + input_index: _, + } + | Edge::NodeEdge { + output_node: _, + input_node, + } => { + if let Ok(input_node) = self.get_node_state_mut(*input_node) { + input_node.edges.remove_input_edge(output_edge.clone())?; } } } @@ -192,42 +169,27 @@ impl RenderGraph { /// Retrieves the [`NodeState`] referenced by the `label`. pub fn get_node_state( &self, - label: impl Into, + label: impl RenderGraphLabel, ) -> Result<&NodeState, RenderGraphError> { - let label = label.into(); - let node_id = self.get_node_id(&label)?; + let label = label.intern(); self.nodes - .get(&node_id) + .get(&label) .ok_or(RenderGraphError::InvalidNode(label)) } /// Retrieves the [`NodeState`] referenced by the `label` mutably. pub fn get_node_state_mut( &mut self, - label: impl Into, + label: impl RenderGraphLabel, ) -> Result<&mut NodeState, RenderGraphError> { - let label = label.into(); - let node_id = self.get_node_id(&label)?; + let label = label.intern(); self.nodes - .get_mut(&node_id) + .get_mut(&label) .ok_or(RenderGraphError::InvalidNode(label)) } - /// Retrieves the [`NodeId`] referenced by the `label`. - pub fn get_node_id(&self, label: impl Into) -> Result { - let label = label.into(); - match label { - NodeLabel::Id(id) => Ok(id), - NodeLabel::Name(ref name) => self - .node_names - .get(name) - .cloned() - .ok_or(RenderGraphError::InvalidNode(label)), - } - } - /// Retrieves the [`Node`] referenced by the `label`. - pub fn get_node(&self, label: impl Into) -> Result<&T, RenderGraphError> + pub fn get_node(&self, label: impl RenderGraphLabel) -> Result<&T, RenderGraphError> where T: Node, { @@ -237,7 +199,7 @@ impl RenderGraph { /// Retrieves the [`Node`] referenced by the `label` mutably. pub fn get_node_mut( &mut self, - label: impl Into, + label: impl RenderGraphLabel, ) -> Result<&mut T, RenderGraphError> where T: Node, @@ -248,48 +210,49 @@ impl RenderGraph { /// Adds the [`Edge::SlotEdge`] to the graph. This guarantees that the `output_node` /// is run before the `input_node` and also connects the `output_slot` to the `input_slot`. /// - /// Fails if any invalid [`NodeLabel`]s or [`SlotLabel`]s are given. + /// Fails if any invalid [`RenderGraphLabel`]s or [`SlotLabel`]s are given. /// /// # See also /// /// - [`add_slot_edge`](Self::add_slot_edge) for an infallible version. pub fn try_add_slot_edge( &mut self, - output_node: impl Into, + output_node: impl RenderGraphLabel, output_slot: impl Into, - input_node: impl Into, + input_node: impl RenderGraphLabel, input_slot: impl Into, ) -> Result<(), RenderGraphError> { let output_slot = output_slot.into(); let input_slot = input_slot.into(); - let output_node_id = self.get_node_id(output_node)?; - let input_node_id = self.get_node_id(input_node)?; + + let output_node = output_node.intern(); + let input_node = input_node.intern(); let output_index = self - .get_node_state(output_node_id)? + .get_node_state(output_node)? .output_slots .get_slot_index(output_slot.clone()) .ok_or(RenderGraphError::InvalidOutputNodeSlot(output_slot))?; let input_index = self - .get_node_state(input_node_id)? + .get_node_state(input_node)? .input_slots .get_slot_index(input_slot.clone()) .ok_or(RenderGraphError::InvalidInputNodeSlot(input_slot))?; let edge = Edge::SlotEdge { - output_node: output_node_id, + output_node, output_index, - input_node: input_node_id, + input_node, input_index, }; self.validate_edge(&edge, EdgeExistence::DoesNotExist)?; { - let output_node = self.get_node_state_mut(output_node_id)?; + let output_node = self.get_node_state_mut(output_node)?; output_node.edges.add_output_edge(edge.clone())?; } - let input_node = self.get_node_state_mut(input_node_id)?; + let input_node = self.get_node_state_mut(input_node)?; input_node.edges.add_input_edge(edge)?; Ok(()) @@ -300,16 +263,16 @@ impl RenderGraph { /// /// # Panics /// - /// Any invalid [`NodeLabel`]s or [`SlotLabel`]s are given. + /// Any invalid [`RenderGraphLabel`]s or [`SlotLabel`]s are given. /// /// # See also /// /// - [`try_add_slot_edge`](Self::try_add_slot_edge) for a fallible version. pub fn add_slot_edge( &mut self, - output_node: impl Into, + output_node: impl RenderGraphLabel, output_slot: impl Into, - input_node: impl Into, + input_node: impl RenderGraphLabel, input_slot: impl Into, ) { self.try_add_slot_edge(output_node, output_slot, input_node, input_slot) @@ -320,41 +283,42 @@ impl RenderGraph { /// nothing happens. pub fn remove_slot_edge( &mut self, - output_node: impl Into, + output_node: impl RenderGraphLabel, output_slot: impl Into, - input_node: impl Into, + input_node: impl RenderGraphLabel, input_slot: impl Into, ) -> Result<(), RenderGraphError> { let output_slot = output_slot.into(); let input_slot = input_slot.into(); - let output_node_id = self.get_node_id(output_node)?; - let input_node_id = self.get_node_id(input_node)?; + + let output_node = output_node.intern(); + let input_node = input_node.intern(); let output_index = self - .get_node_state(output_node_id)? + .get_node_state(output_node)? .output_slots .get_slot_index(output_slot.clone()) .ok_or(RenderGraphError::InvalidOutputNodeSlot(output_slot))?; let input_index = self - .get_node_state(input_node_id)? + .get_node_state(input_node)? .input_slots .get_slot_index(input_slot.clone()) .ok_or(RenderGraphError::InvalidInputNodeSlot(input_slot))?; let edge = Edge::SlotEdge { - output_node: output_node_id, + output_node, output_index, - input_node: input_node_id, + input_node, input_index, }; self.validate_edge(&edge, EdgeExistence::Exists)?; { - let output_node = self.get_node_state_mut(output_node_id)?; + let output_node = self.get_node_state_mut(output_node)?; output_node.edges.remove_output_edge(edge.clone())?; } - let input_node = self.get_node_state_mut(input_node_id)?; + let input_node = self.get_node_state_mut(input_node)?; input_node.edges.remove_input_edge(edge)?; Ok(()) @@ -363,31 +327,31 @@ impl RenderGraph { /// Adds the [`Edge::NodeEdge`] to the graph. This guarantees that the `output_node` /// is run before the `input_node`. /// - /// Fails if any invalid [`NodeLabel`] is given. + /// Fails if any invalid [`RenderGraphLabel`] is given. /// /// # See also /// /// - [`add_node_edge`](Self::add_node_edge) for an infallible version. pub fn try_add_node_edge( &mut self, - output_node: impl Into, - input_node: impl Into, + output_node: impl RenderGraphLabel, + input_node: impl RenderGraphLabel, ) -> Result<(), RenderGraphError> { - let output_node_id = self.get_node_id(output_node)?; - let input_node_id = self.get_node_id(input_node)?; + let output_node = output_node.intern(); + let input_node = input_node.intern(); let edge = Edge::NodeEdge { - output_node: output_node_id, - input_node: input_node_id, + output_node, + input_node, }; self.validate_edge(&edge, EdgeExistence::DoesNotExist)?; { - let output_node = self.get_node_state_mut(output_node_id)?; + let output_node = self.get_node_state_mut(output_node)?; output_node.edges.add_output_edge(edge.clone())?; } - let input_node = self.get_node_state_mut(input_node_id)?; + let input_node = self.get_node_state_mut(input_node)?; input_node.edges.add_input_edge(edge)?; Ok(()) @@ -398,15 +362,15 @@ impl RenderGraph { /// /// # Panics /// - /// Panics if any invalid [`NodeLabel`] is given. + /// Panics if any invalid [`RenderGraphLabel`] is given. /// /// # See also /// /// - [`try_add_node_edge`](Self::try_add_node_edge) for a fallible version. pub fn add_node_edge( &mut self, - output_node: impl Into, - input_node: impl Into, + output_node: impl RenderGraphLabel, + input_node: impl RenderGraphLabel, ) { self.try_add_node_edge(output_node, input_node).unwrap(); } @@ -415,24 +379,24 @@ impl RenderGraph { /// happens. pub fn remove_node_edge( &mut self, - output_node: impl Into, - input_node: impl Into, + output_node: impl RenderGraphLabel, + input_node: impl RenderGraphLabel, ) -> Result<(), RenderGraphError> { - let output_node_id = self.get_node_id(output_node)?; - let input_node_id = self.get_node_id(input_node)?; + let output_node = output_node.intern(); + let input_node = input_node.intern(); let edge = Edge::NodeEdge { - output_node: output_node_id, - input_node: input_node_id, + output_node, + input_node, }; self.validate_edge(&edge, EdgeExistence::Exists)?; { - let output_node = self.get_node_state_mut(output_node_id)?; + let output_node = self.get_node_state_mut(output_node)?; output_node.edges.remove_output_edge(edge.clone())?; } - let input_node = self.get_node_state_mut(input_node_id)?; + let input_node = self.get_node_state_mut(input_node)?; input_node.edges.remove_input_edge(edge)?; Ok(()) @@ -554,7 +518,7 @@ impl RenderGraph { /// for the node referenced by the label. pub fn iter_node_inputs( &self, - label: impl Into, + label: impl RenderGraphLabel, ) -> Result, RenderGraphError> { let node = self.get_node_state(label)?; Ok(node @@ -562,16 +526,14 @@ impl RenderGraph { .input_edges() .iter() .map(|edge| (edge, edge.get_output_node())) - .map(move |(edge, output_node_id)| { - (edge, self.get_node_state(output_node_id).unwrap()) - })) + .map(move |(edge, output_node)| (edge, self.get_node_state(output_node).unwrap()))) } /// Returns an iterator over a tuple of the output edges and the corresponding input nodes /// for the node referenced by the label. pub fn iter_node_outputs( &self, - label: impl Into, + label: impl RenderGraphLabel, ) -> Result, RenderGraphError> { let node = self.get_node_state(label)?; Ok(node @@ -579,7 +541,7 @@ impl RenderGraph { .output_edges() .iter() .map(|edge| (edge, edge.get_input_node())) - .map(move |(edge, input_node_id)| (edge, self.get_node_state(input_node_id).unwrap()))) + .map(move |(edge, input_node)| (edge, self.get_node_state(input_node).unwrap()))) } /// Adds the `sub_graph` with the `name` to the graph. @@ -681,13 +643,22 @@ mod tests { use crate::{ render_graph::{ Edge, Node, NodeId, NodeRunError, RenderGraph, RenderGraphContext, RenderGraphError, - SlotInfo, SlotType, + RenderGraphLabel, SlotInfo, SlotType, }, renderer::RenderContext, }; use bevy_ecs::world::{FromWorld, World}; + use bevy_render_macros::RenderGraphLabel; use bevy_utils::HashSet; + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderGraphLabel)] + enum TestLabels { + A, + B, + C, + D, + } + #[derive(Debug)] struct TestNode { inputs: Vec, @@ -726,17 +697,17 @@ mod tests { } } - fn input_nodes(name: &'static str, graph: &RenderGraph) -> HashSet { + fn input_nodes(label: impl RenderGraphLabel, graph: &RenderGraph) -> HashSet { graph - .iter_node_inputs(name) + .iter_node_inputs(label) .unwrap() .map(|(_edge, node)| node.id) .collect::>() } - fn output_nodes(name: &'static str, graph: &RenderGraph) -> HashSet { + fn output_nodes(label: impl RenderGraphLabel, graph: &RenderGraph) -> HashSet { graph - .iter_node_outputs(name) + .iter_node_outputs(label) .unwrap() .map(|(_edge, node)| node.id) .collect::>() @@ -745,41 +716,50 @@ mod tests { #[test] fn test_graph_edges() { let mut graph = RenderGraph::default(); - let a_id = graph.add_node("A", TestNode::new(0, 1)); - let b_id = graph.add_node("B", TestNode::new(0, 1)); - let c_id = graph.add_node("C", TestNode::new(1, 1)); - let d_id = graph.add_node("D", TestNode::new(1, 0)); + let a_id = graph.add_node(TestLabels::A, TestNode::new(0, 1)); + let b_id = graph.add_node(TestLabels::B, TestNode::new(0, 1)); + let c_id = graph.add_node(TestLabels::C, TestNode::new(1, 1)); + let d_id = graph.add_node(TestLabels::D, TestNode::new(1, 0)); - graph.add_slot_edge("A", "out_0", "C", "in_0"); - graph.add_node_edge("B", "C"); - graph.add_slot_edge("C", 0, "D", 0); + graph.add_slot_edge(TestLabels::A, "out_0", TestLabels::C, "in_0"); + graph.add_node_edge(TestLabels::B, TestLabels::C); + graph.add_slot_edge(TestLabels::C, 0, TestLabels::D, 0); - assert!(input_nodes("A", &graph).is_empty(), "A has no inputs"); assert!( - output_nodes("A", &graph) == HashSet::from_iter(vec![c_id]), + input_nodes(TestLabels::A, &graph).is_empty(), + "A has no inputs" + ); + assert!( + output_nodes(TestLabels::A, &graph) == HashSet::from_iter(vec![c_id]), "A outputs to C" ); - assert!(input_nodes("B", &graph).is_empty(), "B has no inputs"); assert!( - output_nodes("B", &graph) == HashSet::from_iter(vec![c_id]), + input_nodes(TestLabels::B, &graph).is_empty(), + "B has no inputs" + ); + assert!( + output_nodes(TestLabels::B, &graph) == HashSet::from_iter(vec![c_id]), "B outputs to C" ); assert!( - input_nodes("C", &graph) == HashSet::from_iter(vec![a_id, b_id]), + input_nodes(TestLabels::C, &graph) == HashSet::from_iter(vec![a_id, b_id]), "A and B input to C" ); assert!( - output_nodes("C", &graph) == HashSet::from_iter(vec![d_id]), + output_nodes(TestLabels::D, &graph) == HashSet::from_iter(vec![d_id]), "C outputs to D" ); assert!( - input_nodes("D", &graph) == HashSet::from_iter(vec![c_id]), + input_nodes(TestLabels::D, &graph) == HashSet::from_iter(vec![c_id]), "C inputs to D" ); - assert!(output_nodes("D", &graph).is_empty(), "D has no outputs"); + assert!( + output_nodes(TestLabels::D, &graph).is_empty(), + "D has no outputs" + ); } #[test] @@ -801,12 +781,12 @@ mod tests { let mut graph = RenderGraph::default(); - graph.add_node("A", MyNode { value: 42 }); + graph.add_node(TestLabels::A, MyNode { value: 42 }); - let node: &MyNode = graph.get_node("A").unwrap(); + let node: &MyNode = graph.get_node(TestLabels::A).unwrap(); assert_eq!(node.value, 42, "node value matches"); - let result: Result<&TestNode, RenderGraphError> = graph.get_node("A"); + let result: Result<&TestNode, RenderGraphError> = graph.get_node(TestLabels::A); assert_eq!( result.unwrap_err(), RenderGraphError::WrongNodeType, @@ -818,17 +798,17 @@ mod tests { fn test_slot_already_occupied() { let mut graph = RenderGraph::default(); - graph.add_node("A", TestNode::new(0, 1)); - graph.add_node("B", TestNode::new(0, 1)); - graph.add_node("C", TestNode::new(1, 1)); + graph.add_node(TestLabels::A, TestNode::new(0, 1)); + graph.add_node(TestLabels::B, TestNode::new(0, 1)); + graph.add_node(TestLabels::C, TestNode::new(1, 1)); - graph.add_slot_edge("A", 0, "C", 0); + graph.add_slot_edge(TestLabels::A, 0, TestLabels::C, 0); assert_eq!( - graph.try_add_slot_edge("B", 0, "C", 0), + graph.try_add_slot_edge(TestLabels::B, 0, TestLabels::C, 0), Err(RenderGraphError::NodeInputSlotAlreadyOccupied { - node: graph.get_node_id("C").unwrap(), + node: TestLabels::C.intern(), input_slot: 0, - occupied_by_node: graph.get_node_id("A").unwrap(), + occupied_by_node: TestLabels::A.intern(), }), "Adding to a slot that is already occupied should return an error" ); @@ -838,16 +818,16 @@ mod tests { fn test_edge_already_exists() { let mut graph = RenderGraph::default(); - graph.add_node("A", TestNode::new(0, 1)); - graph.add_node("B", TestNode::new(1, 0)); + graph.add_node(TestLabels::A, TestNode::new(0, 1)); + graph.add_node(TestLabels::B, TestNode::new(1, 0)); - graph.add_slot_edge("A", 0, "B", 0); + graph.add_slot_edge(TestLabels::A, 0, TestLabels::B, 0); assert_eq!( - graph.try_add_slot_edge("A", 0, "B", 0), + graph.try_add_slot_edge(TestLabels::A, 0, TestLabels::B, 0), Err(RenderGraphError::EdgeAlreadyExists(Edge::SlotEdge { - output_node: graph.get_node_id("A").unwrap(), + output_node: TestLabels::A.intern(), output_index: 0, - input_node: graph.get_node_id("B").unwrap(), + input_node: TestLabels::B.intern(), input_index: 0, })), "Adding to a duplicate edge should return an error" @@ -874,10 +854,12 @@ mod tests { } let mut graph = RenderGraph::default(); - let a_id = graph.add_node("A", SimpleNode); - let b_id = graph.add_node("B", SimpleNode); - let c_id = graph.add_node("C", SimpleNode); + let a_id = graph.add_node(TestLabels::A, SimpleNode); + let b_id = graph.add_node(TestLabels::B, SimpleNode); + let c_id = graph.add_node(TestLabels::C, SimpleNode); + // TODO: + /* graph.add_node_edges(&["A", "B", "C"]); assert!( @@ -896,5 +878,6 @@ mod tests { input_nodes("C", &graph) == HashSet::from_iter(vec![b_id]), "B -> C" ); + */ } } diff --git a/crates/bevy_render/src/render_graph/mod.rs b/crates/bevy_render/src/render_graph/mod.rs index 8ba77ec24528c..a59f70c790079 100644 --- a/crates/bevy_render/src/render_graph/mod.rs +++ b/crates/bevy_render/src/render_graph/mod.rs @@ -16,8 +16,8 @@ use thiserror::Error; #[derive(Error, Debug, Eq, PartialEq)] pub enum RenderGraphError { - #[error("node does not exist")] - InvalidNode(NodeLabel), + #[error("node {0:?} does not exist")] + InvalidNode(InternedRGLabel), #[error("output node slot does not exist")] InvalidOutputNodeSlot(SlotLabel), #[error("input node slot does not exist")] @@ -26,9 +26,9 @@ pub enum RenderGraphError { WrongNodeType, #[error("attempted to connect a node output slot to an incompatible input node slot")] MismatchedNodeSlots { - output_node: NodeId, + output_node: InternedRGLabel, output_slot: usize, - input_node: NodeId, + input_node: InternedRGLabel, input_slot: usize, }, #[error("attempted to add an edge that already exists")] @@ -36,13 +36,19 @@ pub enum RenderGraphError { #[error("attempted to remove an edge that does not exist")] EdgeDoesNotExist(Edge), #[error("node has an unconnected input slot")] - UnconnectedNodeInputSlot { node: NodeId, input_slot: usize }, + UnconnectedNodeInputSlot { + node: InternedRGLabel, + input_slot: usize, + }, #[error("node has an unconnected output slot")] - UnconnectedNodeOutputSlot { node: NodeId, output_slot: usize }, + UnconnectedNodeOutputSlot { + node: InternedRGLabel, + output_slot: usize, + }, #[error("node input slot already occupied")] NodeInputSlotAlreadyOccupied { - node: NodeId, + node: InternedRGLabel, input_slot: usize, - occupied_by_node: NodeId, + occupied_by_node: InternedRGLabel, }, } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 0e4630e3c72ef..5d839f8a92ed1 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -10,10 +10,21 @@ use bevy_ecs::{ query::{QueryItem, QueryState, ReadOnlyWorldQuery}, world::{FromWorld, World}, }; +pub use bevy_utils::label::DynEq; +use bevy_utils::{define_label, intern::Interned}; use downcast_rs::{impl_downcast, Downcast}; use std::{borrow::Cow, fmt::Debug}; use thiserror::Error; +define_label!( + /// A strongly-typed class of labels used to identify an [`Node`] in a render graph. + RenderGraphLabel, + RENDER_GRAPH_LABEL_INTERNER +); + +/// A shorthand for `Interned`. +pub type InternedRGLabel = Interned; + define_atomic_id!(NodeId); /// A render node that can be added to a [`RenderGraph`](super::RenderGraph). @@ -70,7 +81,7 @@ pub enum NodeRunError { /// A collection of input and output [`Edges`](Edge) for a [`Node`]. #[derive(Debug)] pub struct Edges { - id: NodeId, + id: InternedRGLabel, input_edges: Vec, output_edges: Vec, } @@ -90,7 +101,7 @@ impl Edges { /// Returns this node's id. #[inline] - pub fn id(&self) -> NodeId { + pub fn id(&self) -> InternedRGLabel { self.id } @@ -185,7 +196,7 @@ impl Edges { /// The `input_slots` and `output_slots` are provided by the `node`. pub struct NodeState { pub id: NodeId, - pub name: Option>, + pub label: InternedRGLabel, /// The name of the type that implements [`Node`]. pub type_name: &'static str, pub node: Box, @@ -196,26 +207,26 @@ pub struct NodeState { impl Debug for NodeState { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "{:?} ({:?})", self.id, self.name) + writeln!(f, "{:?} ({:?})", self.id, self.label) } } impl NodeState { /// Creates an [`NodeState`] without edges, but the `input_slots` and `output_slots` /// are provided by the `node`. - pub fn new(id: NodeId, node: T) -> Self + pub fn new(id: NodeId, node: T, label: InternedRGLabel) -> Self where T: Node, { NodeState { id, - name: None, + label, input_slots: node.input().into(), output_slots: node.output().into(), node: Box::new(node), type_name: std::any::type_name::(), edges: Edges { - id, + id: label, input_edges: Vec::new(), output_edges: Vec::new(), }, diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index c046ef11a17be..c5cd118e6ebf7 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -10,8 +10,8 @@ use thiserror::Error; use crate::{ render_graph::{ - Edge, NodeId, NodeRunError, NodeState, RenderGraph, RenderGraphContext, SlotLabel, - SlotType, SlotValue, + Edge, InternedRGLabel, NodeId, NodeRunError, NodeState, RenderGraph, RenderGraphContext, + SlotLabel, SlotType, SlotValue, }, renderer::{RenderContext, RenderDevice}, }; @@ -45,7 +45,7 @@ pub enum RenderGraphRunnerError { "node (name: '{node_name:?}') has {slot_count} input slots, but was provided {value_count} values" )] MismatchedInputCount { - node_name: Option>, + node_name: InternedRGLabel, slot_count: usize, value_count: usize, }, @@ -120,7 +120,10 @@ impl RenderGraphRunner { node_outputs.insert(input_node.id, input_values); - for (_, node_state) in graph.iter_node_outputs(input_node.id).expect("node exists") { + for (_, node_state) in graph + .iter_node_outputs(input_node.label) + .expect("node exists") + { node_queue.push_front(node_state); } } @@ -134,7 +137,7 @@ impl RenderGraphRunner { let mut slot_indices_and_inputs: SmallVec<[(usize, SlotValue); 4]> = SmallVec::new(); // check if all dependencies have finished running for (edge, input_node) in graph - .iter_node_inputs(node_state.id) + .iter_node_inputs(node_state.label) .expect("node is in graph") { match edge { @@ -169,7 +172,7 @@ impl RenderGraphRunner { if inputs.len() != node_state.input_slots.len() { return Err(RenderGraphRunnerError::MismatchedInputCount { - node_name: node_state.name.clone(), + node_name: node_state.label, slot_count: node_state.input_slots.len(), value_count: inputs.len(), }); @@ -220,7 +223,10 @@ impl RenderGraphRunner { } node_outputs.insert(node_state.id, values); - for (_, node_state) in graph.iter_node_outputs(node_state.id).expect("node exists") { + for (_, node_state) in graph + .iter_node_outputs(node_state.label) + .expect("node exists") + { node_queue.push_front(node_state); } } From 1ea09edc9ba6f40ee4e204d7bd15ab27f8314139 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 18 Nov 2023 12:47:42 +0100 Subject: [PATCH 02/20] Revive `add_render_graph_edges` --- crates/bevy_render/src/render_graph/app.rs | 16 ++++----- crates/bevy_render/src/render_graph/graph.rs | 35 +++++++++++++++----- crates/bevy_render/src/render_graph/node.rs | 20 ++++++++++- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/crates/bevy_render/src/render_graph/app.rs b/crates/bevy_render/src/render_graph/app.rs index 0418705b8f6b2..99d4e2f125350 100644 --- a/crates/bevy_render/src/render_graph/app.rs +++ b/crates/bevy_render/src/render_graph/app.rs @@ -2,7 +2,7 @@ use bevy_app::App; use bevy_ecs::world::FromWorld; use bevy_log::warn; -use super::{Node, RenderGraph, RenderGraphLabel}; +use super::{IntoRGLabelArray, Node, RenderGraph, RenderGraphLabel}; /// Adds common [`RenderGraph`] operations to [`App`]. pub trait RenderGraphApp { @@ -16,13 +16,12 @@ pub trait RenderGraphApp { sub_graph_name: &'static str, node_label: impl RenderGraphLabel, ) -> &mut Self; - /* TODO: /// Automatically add the required node edges based on the given ordering - fn add_render_graph_edges( + fn add_render_graph_edges( &mut self, sub_graph_name: &'static str, - edges: &[&'static str], - ) -> &mut Self;*/ + edges: impl IntoRGLabelArray, + ) -> &mut Self; /// Add node edge to the specified graph fn add_render_graph_edge( @@ -51,11 +50,10 @@ impl RenderGraphApp for App { self } - // TODO: - /*fn add_render_graph_edges( + fn add_render_graph_edges( &mut self, sub_graph_name: &'static str, - edges: &[&'static str], + edges: impl IntoRGLabelArray, ) -> &mut Self { let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_edges on the RenderApp", @@ -66,7 +64,7 @@ impl RenderGraphApp for App { warn!("Tried adding render graph edges to {sub_graph_name} but the sub graph doesn't exist"); } self - }*/ + } fn add_render_graph_edge( &mut self, diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 38ecebd86129e..e7d7f34a5642d 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -10,7 +10,7 @@ use bevy_render_macros::RenderGraphLabel; use bevy_utils::HashMap; use std::{borrow::Cow, fmt::Debug}; -use super::{EdgeExistence, InternedRGLabel, RenderGraphLabel}; +use super::{EdgeExistence, InternedRGLabel, IntoRGLabelArray, RenderGraphLabel}; /// The render graph configures the modular, parallel and re-usable render logic. /// It is a retained and stateless (nodes themselves may have their own internal state) structure, @@ -121,6 +121,26 @@ impl RenderGraph { id } + /// Add `node_edge`s based on the order of the given `edges` array. + /// + /// Defining an edge that already exists is not considered an error with this api. + /// It simply won't create a new edge. + pub fn add_node_edges(&mut self, edges: impl IntoRGLabelArray) { + for window in edges.into_array().windows(2) { + let [a, b] = window else { + break; + }; + if let Err(err) = self.try_add_node_edge(*a, *b) { + match err { + // Already existing edges are very easy to produce with this api + // and shouldn't cause a panic + RenderGraphError::EdgeAlreadyExists(_) => {} + _ => panic!("{err:?}"), + } + } + } + } + /// Removes the `node` with the `label` from the graph. /// If the label does not exist, nothing happens. pub fn remove_node(&mut self, label: impl RenderGraphLabel) -> Result<(), RenderGraphError> { @@ -858,26 +878,23 @@ mod tests { let b_id = graph.add_node(TestLabels::B, SimpleNode); let c_id = graph.add_node(TestLabels::C, SimpleNode); - // TODO: - /* - graph.add_node_edges(&["A", "B", "C"]); + graph.add_node_edges((TestLabels::A, TestLabels::B, TestLabels::C)); assert!( - output_nodes("A", &graph) == HashSet::from_iter(vec![b_id]), + output_nodes(TestLabels::A, &graph) == HashSet::from_iter(vec![b_id]), "A -> B" ); assert!( - input_nodes("B", &graph) == HashSet::from_iter(vec![a_id]), + input_nodes(TestLabels::B, &graph) == HashSet::from_iter(vec![a_id]), "A -> B" ); assert!( - output_nodes("B", &graph) == HashSet::from_iter(vec![c_id]), + output_nodes(TestLabels::B, &graph) == HashSet::from_iter(vec![c_id]), "B -> C" ); assert!( - input_nodes("C", &graph) == HashSet::from_iter(vec![b_id]), + input_nodes(TestLabels::C, &graph) == HashSet::from_iter(vec![b_id]), "B -> C" ); - */ } } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 5d839f8a92ed1..f02012e6d4f37 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -11,7 +11,7 @@ use bevy_ecs::{ world::{FromWorld, World}, }; pub use bevy_utils::label::DynEq; -use bevy_utils::{define_label, intern::Interned}; +use bevy_utils::{all_tuples_with_size, define_label, intern::Interned}; use downcast_rs::{impl_downcast, Downcast}; use std::{borrow::Cow, fmt::Debug}; use thiserror::Error; @@ -25,6 +25,24 @@ define_label!( /// A shorthand for `Interned`. pub type InternedRGLabel = Interned; +pub trait IntoRGLabelArray { + fn into_array(self) -> [InternedRGLabel; N]; +} + +macro_rules! impl_rg_label_tuples { + ($N: expr, $(($T: ident, $I: ident)),*) => { + impl<$($T: RenderGraphLabel),*> IntoRGLabelArray<$N> for ($($T,)*) { + #[inline] + fn into_array(self) -> [InternedRGLabel; $N] { + let ($($I,)*) = self; + [$($I.intern(), )*] + } + } + } +} + +all_tuples_with_size!(impl_rg_label_tuples, 2, 32, T, l); + define_atomic_id!(NodeId); /// A render node that can be added to a [`RenderGraph`](super::RenderGraph). From a0cfd5b7ed2014bbd9f009299fc92fe5ab0e89c5 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 18 Nov 2023 13:01:53 +0100 Subject: [PATCH 03/20] Renaming --- crates/bevy_render/macros/src/lib.rs | 12 ++- crates/bevy_render/src/lib.rs | 4 +- crates/bevy_render/src/render_graph/app.rs | 18 ++--- crates/bevy_render/src/render_graph/edge.rs | 14 ++-- crates/bevy_render/src/render_graph/graph.rs | 78 ++++++++----------- crates/bevy_render/src/render_graph/mod.rs | 22 +++--- crates/bevy_render/src/render_graph/node.rs | 37 ++++----- .../bevy_render/src/renderer/graph_runner.rs | 4 +- 8 files changed, 89 insertions(+), 100 deletions(-) diff --git a/crates/bevy_render/macros/src/lib.rs b/crates/bevy_render/macros/src/lib.rs index 019e70871fa77..3bc4e434c3595 100644 --- a/crates/bevy_render/macros/src/lib.rs +++ b/crates/bevy_render/macros/src/lib.rs @@ -60,20 +60,18 @@ pub fn derive_as_bind_group(input: TokenStream) -> TokenStream { as_bind_group::derive_as_bind_group(input).unwrap_or_else(|err| err.to_compile_error().into()) } -/// Derive macro generating an impl of the trait `RenderGraphLabel`. +/// Derive macro generating an impl of the trait `RenderNode`. /// /// This does not work for unions. -#[proc_macro_derive(RenderGraphLabel)] -pub fn derive_render_graph_label(input: TokenStream) -> TokenStream { +#[proc_macro_derive(RenderNode)] +pub fn derive_render_node(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let mut trait_path = bevy_render_path(); trait_path .segments .push(format_ident!("render_graph").into()); let mut dyn_eq_path = trait_path.clone(); - trait_path - .segments - .push(format_ident!("RenderGraphLabel").into()); + trait_path.segments.push(format_ident!("RenderNode").into()); dyn_eq_path.segments.push(format_ident!("DynEq").into()); - derive_label(input, "RenderGraphLabel", &trait_path, &dyn_eq_path) + derive_label(input, "RenderNode", &trait_path, &dyn_eq_path) } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 2faa5e1c15cbc..ff266856f5ecb 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -208,9 +208,9 @@ impl DerefMut for MainWorld { pub mod main_graph { pub mod node { - use bevy_render_macros::RenderGraphLabel; + use bevy_render_macros::RenderNode; - #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderGraphLabel)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderNode)] pub struct CameraDriver; } } diff --git a/crates/bevy_render/src/render_graph/app.rs b/crates/bevy_render/src/render_graph/app.rs index 99d4e2f125350..83c777cb17373 100644 --- a/crates/bevy_render/src/render_graph/app.rs +++ b/crates/bevy_render/src/render_graph/app.rs @@ -2,7 +2,7 @@ use bevy_app::App; use bevy_ecs::world::FromWorld; use bevy_log::warn; -use super::{IntoRGLabelArray, Node, RenderGraph, RenderGraphLabel}; +use super::{IntoRenderNodeArray, Node, RenderGraph, RenderNode}; /// Adds common [`RenderGraph`] operations to [`App`]. pub trait RenderGraphApp { @@ -14,21 +14,21 @@ pub trait RenderGraphApp { fn add_render_graph_node( &mut self, sub_graph_name: &'static str, - node_label: impl RenderGraphLabel, + node_label: impl RenderNode, ) -> &mut Self; /// Automatically add the required node edges based on the given ordering fn add_render_graph_edges( &mut self, sub_graph_name: &'static str, - edges: impl IntoRGLabelArray, + edges: impl IntoRenderNodeArray, ) -> &mut Self; /// Add node edge to the specified graph fn add_render_graph_edge( &mut self, sub_graph_name: &'static str, - output_node: impl RenderGraphLabel, - input_node: impl RenderGraphLabel, + output_node: impl RenderNode, + input_node: impl RenderNode, ) -> &mut Self; } @@ -36,7 +36,7 @@ impl RenderGraphApp for App { fn add_render_graph_node( &mut self, sub_graph_name: &'static str, - node_label: impl RenderGraphLabel, + node_label: impl RenderNode, ) -> &mut Self { let node = T::from_world(&mut self.world); let mut render_graph = self.world.get_resource_mut::().expect( @@ -53,7 +53,7 @@ impl RenderGraphApp for App { fn add_render_graph_edges( &mut self, sub_graph_name: &'static str, - edges: impl IntoRGLabelArray, + edges: impl IntoRenderNodeArray, ) -> &mut Self { let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_edges on the RenderApp", @@ -69,8 +69,8 @@ impl RenderGraphApp for App { fn add_render_graph_edge( &mut self, sub_graph_name: &'static str, - output_node: impl RenderGraphLabel, - input_node: impl RenderGraphLabel, + output_node: impl RenderNode, + input_node: impl RenderNode, ) -> &mut Self { let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_edge on the RenderApp", diff --git a/crates/bevy_render/src/render_graph/edge.rs b/crates/bevy_render/src/render_graph/edge.rs index 5d999e83645b7..58f857f47f3f6 100644 --- a/crates/bevy_render/src/render_graph/edge.rs +++ b/crates/bevy_render/src/render_graph/edge.rs @@ -1,4 +1,4 @@ -use super::InternedRGLabel; +use super::InternedRenderNode; /// An edge, which connects two [`Nodes`](super::Node) in /// a [`RenderGraph`](crate::render_graph::RenderGraph). @@ -22,28 +22,28 @@ pub enum Edge { /// and connecting the output slot at the `output_index` of the output_node /// with the slot at the `input_index` of the `input_node`. SlotEdge { - input_node: InternedRGLabel, + input_node: InternedRenderNode, input_index: usize, - output_node: InternedRGLabel, + output_node: InternedRenderNode, output_index: usize, }, /// An edge describing to ordering of both nodes (`output_node` before `input_node`). NodeEdge { - input_node: InternedRGLabel, - output_node: InternedRGLabel, + input_node: InternedRenderNode, + output_node: InternedRenderNode, }, } impl Edge { /// Returns the id of the `input_node`. - pub fn get_input_node(&self) -> InternedRGLabel { + pub fn get_input_node(&self) -> InternedRenderNode { match self { Edge::SlotEdge { input_node, .. } | Edge::NodeEdge { input_node, .. } => *input_node, } } /// Returns the id of the `output_node`. - pub fn get_output_node(&self) -> InternedRGLabel { + pub fn get_output_node(&self) -> InternedRenderNode { match self { Edge::SlotEdge { output_node, .. } | Edge::NodeEdge { output_node, .. } => *output_node, } diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index e7d7f34a5642d..8a831e3eadfb5 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -1,16 +1,16 @@ use crate::{ render_graph::{ Edge, Node, NodeId, NodeRunError, NodeState, RenderGraphContext, RenderGraphError, - SlotInfo, SlotLabel, + RenderNode, SlotInfo, SlotLabel, }, renderer::RenderContext, }; use bevy_ecs::{prelude::World, system::Resource}; -use bevy_render_macros::RenderGraphLabel; +use bevy_render_macros::RenderNode; use bevy_utils::HashMap; use std::{borrow::Cow, fmt::Debug}; -use super::{EdgeExistence, InternedRGLabel, IntoRGLabelArray, RenderGraphLabel}; +use super::{EdgeExistence, InternedRenderNode, IntoRenderNodeArray}; /// The render graph configures the modular, parallel and re-usable render logic. /// It is a retained and stateless (nodes themselves may have their own internal state) structure, @@ -51,12 +51,12 @@ use super::{EdgeExistence, InternedRGLabel, IntoRGLabelArray, RenderGraphLabel}; /// ``` #[derive(Resource, Default)] pub struct RenderGraph { - nodes: HashMap, + nodes: HashMap, sub_graphs: HashMap, RenderGraph>, } /// The label for the input node of a graph. Used to connect other nodes to it. -#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderGraphLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderNode)] pub struct GraphInput; impl RenderGraph { @@ -110,7 +110,7 @@ impl RenderGraph { /// Adds the `node` with the `label` to the graph. /// If the label is already present replaces it instead. - pub fn add_node(&mut self, label: impl RenderGraphLabel, node: T) -> NodeId + pub fn add_node(&mut self, label: impl RenderNode, node: T) -> NodeId where T: Node, { @@ -125,7 +125,7 @@ impl RenderGraph { /// /// Defining an edge that already exists is not considered an error with this api. /// It simply won't create a new edge. - pub fn add_node_edges(&mut self, edges: impl IntoRGLabelArray) { + pub fn add_node_edges(&mut self, edges: impl IntoRenderNodeArray) { for window in edges.into_array().windows(2) { let [a, b] = window else { break; @@ -143,7 +143,7 @@ impl RenderGraph { /// Removes the `node` with the `label` from the graph. /// If the label does not exist, nothing happens. - pub fn remove_node(&mut self, label: impl RenderGraphLabel) -> Result<(), RenderGraphError> { + pub fn remove_node(&mut self, label: impl RenderNode) -> Result<(), RenderGraphError> { let label = label.intern(); if let Some(node_state) = self.nodes.remove(&label) { // Remove all edges from other nodes to this one. Note that as we're removing this @@ -187,10 +187,7 @@ impl RenderGraph { } /// Retrieves the [`NodeState`] referenced by the `label`. - pub fn get_node_state( - &self, - label: impl RenderGraphLabel, - ) -> Result<&NodeState, RenderGraphError> { + pub fn get_node_state(&self, label: impl RenderNode) -> Result<&NodeState, RenderGraphError> { let label = label.intern(); self.nodes .get(&label) @@ -200,7 +197,7 @@ impl RenderGraph { /// Retrieves the [`NodeState`] referenced by the `label` mutably. pub fn get_node_state_mut( &mut self, - label: impl RenderGraphLabel, + label: impl RenderNode, ) -> Result<&mut NodeState, RenderGraphError> { let label = label.intern(); self.nodes @@ -209,7 +206,7 @@ impl RenderGraph { } /// Retrieves the [`Node`] referenced by the `label`. - pub fn get_node(&self, label: impl RenderGraphLabel) -> Result<&T, RenderGraphError> + pub fn get_node(&self, label: impl RenderNode) -> Result<&T, RenderGraphError> where T: Node, { @@ -217,10 +214,7 @@ impl RenderGraph { } /// Retrieves the [`Node`] referenced by the `label` mutably. - pub fn get_node_mut( - &mut self, - label: impl RenderGraphLabel, - ) -> Result<&mut T, RenderGraphError> + pub fn get_node_mut(&mut self, label: impl RenderNode) -> Result<&mut T, RenderGraphError> where T: Node, { @@ -230,16 +224,16 @@ impl RenderGraph { /// Adds the [`Edge::SlotEdge`] to the graph. This guarantees that the `output_node` /// is run before the `input_node` and also connects the `output_slot` to the `input_slot`. /// - /// Fails if any invalid [`RenderGraphLabel`]s or [`SlotLabel`]s are given. + /// Fails if any invalid [`RenderNode`]s or [`SlotLabel`]s are given. /// /// # See also /// /// - [`add_slot_edge`](Self::add_slot_edge) for an infallible version. pub fn try_add_slot_edge( &mut self, - output_node: impl RenderGraphLabel, + output_node: impl RenderNode, output_slot: impl Into, - input_node: impl RenderGraphLabel, + input_node: impl RenderNode, input_slot: impl Into, ) -> Result<(), RenderGraphError> { let output_slot = output_slot.into(); @@ -283,16 +277,16 @@ impl RenderGraph { /// /// # Panics /// - /// Any invalid [`RenderGraphLabel`]s or [`SlotLabel`]s are given. + /// Any invalid [`RenderNode`]s or [`SlotLabel`]s are given. /// /// # See also /// /// - [`try_add_slot_edge`](Self::try_add_slot_edge) for a fallible version. pub fn add_slot_edge( &mut self, - output_node: impl RenderGraphLabel, + output_node: impl RenderNode, output_slot: impl Into, - input_node: impl RenderGraphLabel, + input_node: impl RenderNode, input_slot: impl Into, ) { self.try_add_slot_edge(output_node, output_slot, input_node, input_slot) @@ -303,9 +297,9 @@ impl RenderGraph { /// nothing happens. pub fn remove_slot_edge( &mut self, - output_node: impl RenderGraphLabel, + output_node: impl RenderNode, output_slot: impl Into, - input_node: impl RenderGraphLabel, + input_node: impl RenderNode, input_slot: impl Into, ) -> Result<(), RenderGraphError> { let output_slot = output_slot.into(); @@ -347,15 +341,15 @@ impl RenderGraph { /// Adds the [`Edge::NodeEdge`] to the graph. This guarantees that the `output_node` /// is run before the `input_node`. /// - /// Fails if any invalid [`RenderGraphLabel`] is given. + /// Fails if any invalid [`RenderNode`] is given. /// /// # See also /// /// - [`add_node_edge`](Self::add_node_edge) for an infallible version. pub fn try_add_node_edge( &mut self, - output_node: impl RenderGraphLabel, - input_node: impl RenderGraphLabel, + output_node: impl RenderNode, + input_node: impl RenderNode, ) -> Result<(), RenderGraphError> { let output_node = output_node.intern(); let input_node = input_node.intern(); @@ -382,16 +376,12 @@ impl RenderGraph { /// /// # Panics /// - /// Panics if any invalid [`RenderGraphLabel`] is given. + /// Panics if any invalid [`RenderNode`] is given. /// /// # See also /// /// - [`try_add_node_edge`](Self::try_add_node_edge) for a fallible version. - pub fn add_node_edge( - &mut self, - output_node: impl RenderGraphLabel, - input_node: impl RenderGraphLabel, - ) { + pub fn add_node_edge(&mut self, output_node: impl RenderNode, input_node: impl RenderNode) { self.try_add_node_edge(output_node, input_node).unwrap(); } @@ -399,8 +389,8 @@ impl RenderGraph { /// happens. pub fn remove_node_edge( &mut self, - output_node: impl RenderGraphLabel, - input_node: impl RenderGraphLabel, + output_node: impl RenderNode, + input_node: impl RenderNode, ) -> Result<(), RenderGraphError> { let output_node = output_node.intern(); let input_node = input_node.intern(); @@ -538,7 +528,7 @@ impl RenderGraph { /// for the node referenced by the label. pub fn iter_node_inputs( &self, - label: impl RenderGraphLabel, + label: impl RenderNode, ) -> Result, RenderGraphError> { let node = self.get_node_state(label)?; Ok(node @@ -553,7 +543,7 @@ impl RenderGraph { /// for the node referenced by the label. pub fn iter_node_outputs( &self, - label: impl RenderGraphLabel, + label: impl RenderNode, ) -> Result, RenderGraphError> { let node = self.get_node_state(label)?; Ok(node @@ -663,15 +653,15 @@ mod tests { use crate::{ render_graph::{ Edge, Node, NodeId, NodeRunError, RenderGraph, RenderGraphContext, RenderGraphError, - RenderGraphLabel, SlotInfo, SlotType, + RenderNode, SlotInfo, SlotType, }, renderer::RenderContext, }; use bevy_ecs::world::{FromWorld, World}; - use bevy_render_macros::RenderGraphLabel; + use bevy_render_macros::RenderNode; use bevy_utils::HashSet; - #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderGraphLabel)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderNode)] enum TestLabels { A, B, @@ -717,7 +707,7 @@ mod tests { } } - fn input_nodes(label: impl RenderGraphLabel, graph: &RenderGraph) -> HashSet { + fn input_nodes(label: impl RenderNode, graph: &RenderGraph) -> HashSet { graph .iter_node_inputs(label) .unwrap() @@ -725,7 +715,7 @@ mod tests { .collect::>() } - fn output_nodes(label: impl RenderGraphLabel, graph: &RenderGraph) -> HashSet { + fn output_nodes(label: impl RenderNode, graph: &RenderGraph) -> HashSet { graph .iter_node_outputs(label) .unwrap() diff --git a/crates/bevy_render/src/render_graph/mod.rs b/crates/bevy_render/src/render_graph/mod.rs index a59f70c790079..f6cdeead4e000 100644 --- a/crates/bevy_render/src/render_graph/mod.rs +++ b/crates/bevy_render/src/render_graph/mod.rs @@ -17,38 +17,38 @@ use thiserror::Error; #[derive(Error, Debug, Eq, PartialEq)] pub enum RenderGraphError { #[error("node {0:?} does not exist")] - InvalidNode(InternedRGLabel), + InvalidNode(InternedRenderNode), #[error("output node slot does not exist")] InvalidOutputNodeSlot(SlotLabel), #[error("input node slot does not exist")] InvalidInputNodeSlot(SlotLabel), #[error("node does not match the given type")] WrongNodeType, - #[error("attempted to connect a node output slot to an incompatible input node slot")] + #[error("attempted to connect output slot {output_slot} from node {output_node:?} to incompatible input slot {input_slot} from node {input_node:?}")] MismatchedNodeSlots { - output_node: InternedRGLabel, + output_node: InternedRenderNode, output_slot: usize, - input_node: InternedRGLabel, + input_node: InternedRenderNode, input_slot: usize, }, #[error("attempted to add an edge that already exists")] EdgeAlreadyExists(Edge), #[error("attempted to remove an edge that does not exist")] EdgeDoesNotExist(Edge), - #[error("node has an unconnected input slot")] + #[error("node {node:?} has an unconnected input slot {input_slot}")] UnconnectedNodeInputSlot { - node: InternedRGLabel, + node: InternedRenderNode, input_slot: usize, }, - #[error("node has an unconnected output slot")] + #[error("node {node:?} has an unconnected output slot {output_slot}")] UnconnectedNodeOutputSlot { - node: InternedRGLabel, + node: InternedRenderNode, output_slot: usize, }, - #[error("node input slot already occupied")] + #[error("node {node:?} input slot {input_slot} already occupied by {occupied_by_node:?}")] NodeInputSlotAlreadyOccupied { - node: InternedRGLabel, + node: InternedRenderNode, input_slot: usize, - occupied_by_node: InternedRGLabel, + occupied_by_node: InternedRenderNode, }, } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index f02012e6d4f37..78e9f4b2c64af 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -18,22 +18,22 @@ use thiserror::Error; define_label!( /// A strongly-typed class of labels used to identify an [`Node`] in a render graph. - RenderGraphLabel, - RENDER_GRAPH_LABEL_INTERNER + RenderNode, + RENDER_NODE_INTERNER ); -/// A shorthand for `Interned`. -pub type InternedRGLabel = Interned; +/// A shorthand for `Interned`. +pub type InternedRenderNode = Interned; -pub trait IntoRGLabelArray { - fn into_array(self) -> [InternedRGLabel; N]; +pub trait IntoRenderNodeArray { + fn into_array(self) -> [InternedRenderNode; N]; } -macro_rules! impl_rg_label_tuples { +macro_rules! impl_render_node_tuples { ($N: expr, $(($T: ident, $I: ident)),*) => { - impl<$($T: RenderGraphLabel),*> IntoRGLabelArray<$N> for ($($T,)*) { + impl<$($T: RenderNode),*> IntoRenderNodeArray<$N> for ($($T,)*) { #[inline] - fn into_array(self) -> [InternedRGLabel; $N] { + fn into_array(self) -> [InternedRenderNode; $N] { let ($($I,)*) = self; [$($I.intern(), )*] } @@ -41,7 +41,7 @@ macro_rules! impl_rg_label_tuples { } } -all_tuples_with_size!(impl_rg_label_tuples, 2, 32, T, l); +all_tuples_with_size!(impl_render_node_tuples, 2, 32, T, l); define_atomic_id!(NodeId); @@ -99,7 +99,7 @@ pub enum NodeRunError { /// A collection of input and output [`Edges`](Edge) for a [`Node`]. #[derive(Debug)] pub struct Edges { - id: InternedRGLabel, + node: InternedRenderNode, input_edges: Vec, output_edges: Vec, } @@ -118,9 +118,10 @@ impl Edges { } /// Returns this node's id. + // TODO: rename #[inline] - pub fn id(&self) -> InternedRGLabel { - self.id + pub fn id(&self) -> InternedRenderNode { + self.node } /// Adds an edge to the `input_edges` if it does not already exist. @@ -185,7 +186,7 @@ impl Edges { }) .ok_or(RenderGraphError::UnconnectedNodeInputSlot { input_slot: index, - node: self.id, + node: self.node, }) } @@ -203,7 +204,7 @@ impl Edges { }) .ok_or(RenderGraphError::UnconnectedNodeOutputSlot { output_slot: index, - node: self.id, + node: self.node, }) } } @@ -214,7 +215,7 @@ impl Edges { /// The `input_slots` and `output_slots` are provided by the `node`. pub struct NodeState { pub id: NodeId, - pub label: InternedRGLabel, + pub label: InternedRenderNode, /// The name of the type that implements [`Node`]. pub type_name: &'static str, pub node: Box, @@ -232,7 +233,7 @@ impl Debug for NodeState { impl NodeState { /// Creates an [`NodeState`] without edges, but the `input_slots` and `output_slots` /// are provided by the `node`. - pub fn new(id: NodeId, node: T, label: InternedRGLabel) -> Self + pub fn new(id: NodeId, node: T, label: InternedRenderNode) -> Self where T: Node, { @@ -244,7 +245,7 @@ impl NodeState { node: Box::new(node), type_name: std::any::type_name::(), edges: Edges { - id: label, + node: label, input_edges: Vec::new(), output_edges: Vec::new(), }, diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index c5cd118e6ebf7..714a1d4cdca77 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -10,7 +10,7 @@ use thiserror::Error; use crate::{ render_graph::{ - Edge, InternedRGLabel, NodeId, NodeRunError, NodeState, RenderGraph, RenderGraphContext, + Edge, InternedRenderNode, NodeId, NodeRunError, NodeState, RenderGraph, RenderGraphContext, SlotLabel, SlotType, SlotValue, }, renderer::{RenderContext, RenderDevice}, @@ -45,7 +45,7 @@ pub enum RenderGraphRunnerError { "node (name: '{node_name:?}') has {slot_count} input slots, but was provided {value_count} values" )] MismatchedInputCount { - node_name: InternedRGLabel, + node_name: InternedRenderNode, slot_count: usize, value_count: usize, }, From fb6a61141a5c33d898729ce37a2abb52ef5f2160 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 18 Nov 2023 14:45:16 +0100 Subject: [PATCH 04/20] Another rename --- crates/bevy_render/macros/src/lib.rs | 12 ++-- crates/bevy_render/src/lib.rs | 4 +- crates/bevy_render/src/render_graph/app.rs | 14 ++--- crates/bevy_render/src/render_graph/edge.rs | 14 ++--- crates/bevy_render/src/render_graph/graph.rs | 56 +++++++++---------- crates/bevy_render/src/render_graph/mod.rs | 14 ++--- crates/bevy_render/src/render_graph/node.rs | 28 +++++----- .../bevy_render/src/renderer/graph_runner.rs | 6 +- 8 files changed, 75 insertions(+), 73 deletions(-) diff --git a/crates/bevy_render/macros/src/lib.rs b/crates/bevy_render/macros/src/lib.rs index 3bc4e434c3595..b748be7e401ac 100644 --- a/crates/bevy_render/macros/src/lib.rs +++ b/crates/bevy_render/macros/src/lib.rs @@ -60,18 +60,20 @@ pub fn derive_as_bind_group(input: TokenStream) -> TokenStream { as_bind_group::derive_as_bind_group(input).unwrap_or_else(|err| err.to_compile_error().into()) } -/// Derive macro generating an impl of the trait `RenderNode`. +/// Derive macro generating an impl of the trait `RenderLabel`. /// /// This does not work for unions. -#[proc_macro_derive(RenderNode)] -pub fn derive_render_node(input: TokenStream) -> TokenStream { +#[proc_macro_derive(RenderLabel)] +pub fn derive_render_label(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let mut trait_path = bevy_render_path(); trait_path .segments .push(format_ident!("render_graph").into()); let mut dyn_eq_path = trait_path.clone(); - trait_path.segments.push(format_ident!("RenderNode").into()); + trait_path + .segments + .push(format_ident!("RenderLabel").into()); dyn_eq_path.segments.push(format_ident!("DynEq").into()); - derive_label(input, "RenderNode", &trait_path, &dyn_eq_path) + derive_label(input, "RenderLabel", &trait_path, &dyn_eq_path) } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index ff266856f5ecb..d9e19d809d2b1 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -208,9 +208,9 @@ impl DerefMut for MainWorld { pub mod main_graph { pub mod node { - use bevy_render_macros::RenderNode; + use crate::render_graph::RenderLabel; - #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderNode)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] pub struct CameraDriver; } } diff --git a/crates/bevy_render/src/render_graph/app.rs b/crates/bevy_render/src/render_graph/app.rs index 83c777cb17373..4b566ac68a401 100644 --- a/crates/bevy_render/src/render_graph/app.rs +++ b/crates/bevy_render/src/render_graph/app.rs @@ -2,7 +2,7 @@ use bevy_app::App; use bevy_ecs::world::FromWorld; use bevy_log::warn; -use super::{IntoRenderNodeArray, Node, RenderGraph, RenderNode}; +use super::{IntoRenderNodeArray, Node, RenderGraph, RenderLabel}; /// Adds common [`RenderGraph`] operations to [`App`]. pub trait RenderGraphApp { @@ -14,7 +14,7 @@ pub trait RenderGraphApp { fn add_render_graph_node( &mut self, sub_graph_name: &'static str, - node_label: impl RenderNode, + node_label: impl RenderLabel, ) -> &mut Self; /// Automatically add the required node edges based on the given ordering fn add_render_graph_edges( @@ -27,8 +27,8 @@ pub trait RenderGraphApp { fn add_render_graph_edge( &mut self, sub_graph_name: &'static str, - output_node: impl RenderNode, - input_node: impl RenderNode, + output_node: impl RenderLabel, + input_node: impl RenderLabel, ) -> &mut Self; } @@ -36,7 +36,7 @@ impl RenderGraphApp for App { fn add_render_graph_node( &mut self, sub_graph_name: &'static str, - node_label: impl RenderNode, + node_label: impl RenderLabel, ) -> &mut Self { let node = T::from_world(&mut self.world); let mut render_graph = self.world.get_resource_mut::().expect( @@ -69,8 +69,8 @@ impl RenderGraphApp for App { fn add_render_graph_edge( &mut self, sub_graph_name: &'static str, - output_node: impl RenderNode, - input_node: impl RenderNode, + output_node: impl RenderLabel, + input_node: impl RenderLabel, ) -> &mut Self { let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_edge on the RenderApp", diff --git a/crates/bevy_render/src/render_graph/edge.rs b/crates/bevy_render/src/render_graph/edge.rs index 58f857f47f3f6..fa9943bb4dd02 100644 --- a/crates/bevy_render/src/render_graph/edge.rs +++ b/crates/bevy_render/src/render_graph/edge.rs @@ -1,4 +1,4 @@ -use super::InternedRenderNode; +use super::InternedRenderLabel; /// An edge, which connects two [`Nodes`](super::Node) in /// a [`RenderGraph`](crate::render_graph::RenderGraph). @@ -22,28 +22,28 @@ pub enum Edge { /// and connecting the output slot at the `output_index` of the output_node /// with the slot at the `input_index` of the `input_node`. SlotEdge { - input_node: InternedRenderNode, + input_node: InternedRenderLabel, input_index: usize, - output_node: InternedRenderNode, + output_node: InternedRenderLabel, output_index: usize, }, /// An edge describing to ordering of both nodes (`output_node` before `input_node`). NodeEdge { - input_node: InternedRenderNode, - output_node: InternedRenderNode, + input_node: InternedRenderLabel, + output_node: InternedRenderLabel, }, } impl Edge { /// Returns the id of the `input_node`. - pub fn get_input_node(&self) -> InternedRenderNode { + pub fn get_input_node(&self) -> InternedRenderLabel { match self { Edge::SlotEdge { input_node, .. } | Edge::NodeEdge { input_node, .. } => *input_node, } } /// Returns the id of the `output_node`. - pub fn get_output_node(&self) -> InternedRenderNode { + pub fn get_output_node(&self) -> InternedRenderLabel { match self { Edge::SlotEdge { output_node, .. } | Edge::NodeEdge { output_node, .. } => *output_node, } diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 8a831e3eadfb5..e2e02dc38f07e 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -1,16 +1,15 @@ use crate::{ render_graph::{ Edge, Node, NodeId, NodeRunError, NodeState, RenderGraphContext, RenderGraphError, - RenderNode, SlotInfo, SlotLabel, + RenderLabel, SlotInfo, SlotLabel, }, renderer::RenderContext, }; use bevy_ecs::{prelude::World, system::Resource}; -use bevy_render_macros::RenderNode; use bevy_utils::HashMap; use std::{borrow::Cow, fmt::Debug}; -use super::{EdgeExistence, InternedRenderNode, IntoRenderNodeArray}; +use super::{EdgeExistence, InternedRenderLabel, IntoRenderNodeArray}; /// The render graph configures the modular, parallel and re-usable render logic. /// It is a retained and stateless (nodes themselves may have their own internal state) structure, @@ -51,12 +50,12 @@ use super::{EdgeExistence, InternedRenderNode, IntoRenderNodeArray}; /// ``` #[derive(Resource, Default)] pub struct RenderGraph { - nodes: HashMap, + nodes: HashMap, sub_graphs: HashMap, RenderGraph>, } /// The label for the input node of a graph. Used to connect other nodes to it. -#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderNode)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] pub struct GraphInput; impl RenderGraph { @@ -110,7 +109,7 @@ impl RenderGraph { /// Adds the `node` with the `label` to the graph. /// If the label is already present replaces it instead. - pub fn add_node(&mut self, label: impl RenderNode, node: T) -> NodeId + pub fn add_node(&mut self, label: impl RenderLabel, node: T) -> NodeId where T: Node, { @@ -143,7 +142,7 @@ impl RenderGraph { /// Removes the `node` with the `label` from the graph. /// If the label does not exist, nothing happens. - pub fn remove_node(&mut self, label: impl RenderNode) -> Result<(), RenderGraphError> { + pub fn remove_node(&mut self, label: impl RenderLabel) -> Result<(), RenderGraphError> { let label = label.intern(); if let Some(node_state) = self.nodes.remove(&label) { // Remove all edges from other nodes to this one. Note that as we're removing this @@ -187,7 +186,7 @@ impl RenderGraph { } /// Retrieves the [`NodeState`] referenced by the `label`. - pub fn get_node_state(&self, label: impl RenderNode) -> Result<&NodeState, RenderGraphError> { + pub fn get_node_state(&self, label: impl RenderLabel) -> Result<&NodeState, RenderGraphError> { let label = label.intern(); self.nodes .get(&label) @@ -197,7 +196,7 @@ impl RenderGraph { /// Retrieves the [`NodeState`] referenced by the `label` mutably. pub fn get_node_state_mut( &mut self, - label: impl RenderNode, + label: impl RenderLabel, ) -> Result<&mut NodeState, RenderGraphError> { let label = label.intern(); self.nodes @@ -206,7 +205,7 @@ impl RenderGraph { } /// Retrieves the [`Node`] referenced by the `label`. - pub fn get_node(&self, label: impl RenderNode) -> Result<&T, RenderGraphError> + pub fn get_node(&self, label: impl RenderLabel) -> Result<&T, RenderGraphError> where T: Node, { @@ -214,7 +213,7 @@ impl RenderGraph { } /// Retrieves the [`Node`] referenced by the `label` mutably. - pub fn get_node_mut(&mut self, label: impl RenderNode) -> Result<&mut T, RenderGraphError> + pub fn get_node_mut(&mut self, label: impl RenderLabel) -> Result<&mut T, RenderGraphError> where T: Node, { @@ -231,9 +230,9 @@ impl RenderGraph { /// - [`add_slot_edge`](Self::add_slot_edge) for an infallible version. pub fn try_add_slot_edge( &mut self, - output_node: impl RenderNode, + output_node: impl RenderLabel, output_slot: impl Into, - input_node: impl RenderNode, + input_node: impl RenderLabel, input_slot: impl Into, ) -> Result<(), RenderGraphError> { let output_slot = output_slot.into(); @@ -284,9 +283,9 @@ impl RenderGraph { /// - [`try_add_slot_edge`](Self::try_add_slot_edge) for a fallible version. pub fn add_slot_edge( &mut self, - output_node: impl RenderNode, + output_node: impl RenderLabel, output_slot: impl Into, - input_node: impl RenderNode, + input_node: impl RenderLabel, input_slot: impl Into, ) { self.try_add_slot_edge(output_node, output_slot, input_node, input_slot) @@ -297,9 +296,9 @@ impl RenderGraph { /// nothing happens. pub fn remove_slot_edge( &mut self, - output_node: impl RenderNode, + output_node: impl RenderLabel, output_slot: impl Into, - input_node: impl RenderNode, + input_node: impl RenderLabel, input_slot: impl Into, ) -> Result<(), RenderGraphError> { let output_slot = output_slot.into(); @@ -348,8 +347,8 @@ impl RenderGraph { /// - [`add_node_edge`](Self::add_node_edge) for an infallible version. pub fn try_add_node_edge( &mut self, - output_node: impl RenderNode, - input_node: impl RenderNode, + output_node: impl RenderLabel, + input_node: impl RenderLabel, ) -> Result<(), RenderGraphError> { let output_node = output_node.intern(); let input_node = input_node.intern(); @@ -381,7 +380,7 @@ impl RenderGraph { /// # See also /// /// - [`try_add_node_edge`](Self::try_add_node_edge) for a fallible version. - pub fn add_node_edge(&mut self, output_node: impl RenderNode, input_node: impl RenderNode) { + pub fn add_node_edge(&mut self, output_node: impl RenderLabel, input_node: impl RenderLabel) { self.try_add_node_edge(output_node, input_node).unwrap(); } @@ -389,8 +388,8 @@ impl RenderGraph { /// happens. pub fn remove_node_edge( &mut self, - output_node: impl RenderNode, - input_node: impl RenderNode, + output_node: impl RenderLabel, + input_node: impl RenderLabel, ) -> Result<(), RenderGraphError> { let output_node = output_node.intern(); let input_node = input_node.intern(); @@ -528,7 +527,7 @@ impl RenderGraph { /// for the node referenced by the label. pub fn iter_node_inputs( &self, - label: impl RenderNode, + label: impl RenderLabel, ) -> Result, RenderGraphError> { let node = self.get_node_state(label)?; Ok(node @@ -543,7 +542,7 @@ impl RenderGraph { /// for the node referenced by the label. pub fn iter_node_outputs( &self, - label: impl RenderNode, + label: impl RenderLabel, ) -> Result, RenderGraphError> { let node = self.get_node_state(label)?; Ok(node @@ -653,15 +652,14 @@ mod tests { use crate::{ render_graph::{ Edge, Node, NodeId, NodeRunError, RenderGraph, RenderGraphContext, RenderGraphError, - RenderNode, SlotInfo, SlotType, + RenderLabel, SlotInfo, SlotType, }, renderer::RenderContext, }; use bevy_ecs::world::{FromWorld, World}; - use bevy_render_macros::RenderNode; use bevy_utils::HashSet; - #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderNode)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] enum TestLabels { A, B, @@ -707,7 +705,7 @@ mod tests { } } - fn input_nodes(label: impl RenderNode, graph: &RenderGraph) -> HashSet { + fn input_nodes(label: impl RenderLabel, graph: &RenderGraph) -> HashSet { graph .iter_node_inputs(label) .unwrap() @@ -715,7 +713,7 @@ mod tests { .collect::>() } - fn output_nodes(label: impl RenderNode, graph: &RenderGraph) -> HashSet { + fn output_nodes(label: impl RenderLabel, graph: &RenderGraph) -> HashSet { graph .iter_node_outputs(label) .unwrap() diff --git a/crates/bevy_render/src/render_graph/mod.rs b/crates/bevy_render/src/render_graph/mod.rs index f6cdeead4e000..fbed33a23c6f4 100644 --- a/crates/bevy_render/src/render_graph/mod.rs +++ b/crates/bevy_render/src/render_graph/mod.rs @@ -17,7 +17,7 @@ use thiserror::Error; #[derive(Error, Debug, Eq, PartialEq)] pub enum RenderGraphError { #[error("node {0:?} does not exist")] - InvalidNode(InternedRenderNode), + InvalidNode(InternedRenderLabel), #[error("output node slot does not exist")] InvalidOutputNodeSlot(SlotLabel), #[error("input node slot does not exist")] @@ -26,9 +26,9 @@ pub enum RenderGraphError { WrongNodeType, #[error("attempted to connect output slot {output_slot} from node {output_node:?} to incompatible input slot {input_slot} from node {input_node:?}")] MismatchedNodeSlots { - output_node: InternedRenderNode, + output_node: InternedRenderLabel, output_slot: usize, - input_node: InternedRenderNode, + input_node: InternedRenderLabel, input_slot: usize, }, #[error("attempted to add an edge that already exists")] @@ -37,18 +37,18 @@ pub enum RenderGraphError { EdgeDoesNotExist(Edge), #[error("node {node:?} has an unconnected input slot {input_slot}")] UnconnectedNodeInputSlot { - node: InternedRenderNode, + node: InternedRenderLabel, input_slot: usize, }, #[error("node {node:?} has an unconnected output slot {output_slot}")] UnconnectedNodeOutputSlot { - node: InternedRenderNode, + node: InternedRenderLabel, output_slot: usize, }, #[error("node {node:?} input slot {input_slot} already occupied by {occupied_by_node:?}")] NodeInputSlotAlreadyOccupied { - node: InternedRenderNode, + node: InternedRenderLabel, input_slot: usize, - occupied_by_node: InternedRenderNode, + occupied_by_node: InternedRenderLabel, }, } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 78e9f4b2c64af..fdc712adbd50e 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -16,24 +16,26 @@ use downcast_rs::{impl_downcast, Downcast}; use std::{borrow::Cow, fmt::Debug}; use thiserror::Error; +pub use bevy_render_macros::RenderLabel; + define_label!( /// A strongly-typed class of labels used to identify an [`Node`] in a render graph. - RenderNode, - RENDER_NODE_INTERNER + RenderLabel, + RENDER_LABEL_INTERNER ); -/// A shorthand for `Interned`. -pub type InternedRenderNode = Interned; +/// A shorthand for `Interned`. +pub type InternedRenderLabel = Interned; pub trait IntoRenderNodeArray { - fn into_array(self) -> [InternedRenderNode; N]; + fn into_array(self) -> [InternedRenderLabel; N]; } -macro_rules! impl_render_node_tuples { +macro_rules! impl_render_label_tuples { ($N: expr, $(($T: ident, $I: ident)),*) => { - impl<$($T: RenderNode),*> IntoRenderNodeArray<$N> for ($($T,)*) { + impl<$($T: RenderLabel),*> IntoRenderNodeArray<$N> for ($($T,)*) { #[inline] - fn into_array(self) -> [InternedRenderNode; $N] { + fn into_array(self) -> [InternedRenderLabel; $N] { let ($($I,)*) = self; [$($I.intern(), )*] } @@ -41,7 +43,7 @@ macro_rules! impl_render_node_tuples { } } -all_tuples_with_size!(impl_render_node_tuples, 2, 32, T, l); +all_tuples_with_size!(impl_render_label_tuples, 2, 32, T, l); define_atomic_id!(NodeId); @@ -99,7 +101,7 @@ pub enum NodeRunError { /// A collection of input and output [`Edges`](Edge) for a [`Node`]. #[derive(Debug)] pub struct Edges { - node: InternedRenderNode, + node: InternedRenderLabel, input_edges: Vec, output_edges: Vec, } @@ -120,7 +122,7 @@ impl Edges { /// Returns this node's id. // TODO: rename #[inline] - pub fn id(&self) -> InternedRenderNode { + pub fn id(&self) -> InternedRenderLabel { self.node } @@ -215,7 +217,7 @@ impl Edges { /// The `input_slots` and `output_slots` are provided by the `node`. pub struct NodeState { pub id: NodeId, - pub label: InternedRenderNode, + pub label: InternedRenderLabel, /// The name of the type that implements [`Node`]. pub type_name: &'static str, pub node: Box, @@ -233,7 +235,7 @@ impl Debug for NodeState { impl NodeState { /// Creates an [`NodeState`] without edges, but the `input_slots` and `output_slots` /// are provided by the `node`. - pub fn new(id: NodeId, node: T, label: InternedRenderNode) -> Self + pub fn new(id: NodeId, node: T, label: InternedRenderLabel) -> Self where T: Node, { diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index 714a1d4cdca77..a924ba2ab4d61 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -10,8 +10,8 @@ use thiserror::Error; use crate::{ render_graph::{ - Edge, InternedRenderNode, NodeId, NodeRunError, NodeState, RenderGraph, RenderGraphContext, - SlotLabel, SlotType, SlotValue, + Edge, InternedRenderLabel, NodeId, NodeRunError, NodeState, RenderGraph, + RenderGraphContext, SlotLabel, SlotType, SlotValue, }, renderer::{RenderContext, RenderDevice}, }; @@ -45,7 +45,7 @@ pub enum RenderGraphRunnerError { "node (name: '{node_name:?}') has {slot_count} input slots, but was provided {value_count} values" )] MismatchedInputCount { - node_name: InternedRenderNode, + node_name: InternedRenderLabel, slot_count: usize, value_count: usize, }, From e7cf991faa9293377fe388d6af4696256564fd09 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 18 Nov 2023 15:10:35 +0100 Subject: [PATCH 05/20] Remove NodeId --- crates/bevy_render/src/render_graph/graph.rs | 82 +++++++++++-------- crates/bevy_render/src/render_graph/node.rs | 58 +++---------- .../bevy_render/src/renderer/graph_runner.rs | 17 ++-- 3 files changed, 65 insertions(+), 92 deletions(-) diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index e2e02dc38f07e..6f2b6b124941c 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -1,7 +1,7 @@ use crate::{ render_graph::{ - Edge, Node, NodeId, NodeRunError, NodeState, RenderGraphContext, RenderGraphError, - RenderLabel, SlotInfo, SlotLabel, + Edge, Node, NodeRunError, NodeState, RenderGraphContext, RenderGraphError, RenderLabel, + SlotInfo, SlotLabel, }, renderer::RenderContext, }; @@ -32,9 +32,15 @@ use super::{EdgeExistence, InternedRenderLabel, IntoRenderNodeArray}; /// ``` /// # use bevy_app::prelude::*; /// # use bevy_ecs::prelude::World; -/// # use bevy_render::render_graph::{RenderGraph, Node, RenderGraphContext, NodeRunError}; +/// # use bevy_render::render_graph::{RenderGraph, RenderLabel, Node, RenderGraphContext, NodeRunError}; /// # use bevy_render::renderer::RenderContext; /// # +/// #[derive(RenderLabel)] +/// enum Labels { +/// A, +/// B, +/// } +/// /// # struct MyNode; /// # /// # impl Node for MyNode { @@ -44,9 +50,9 @@ use super::{EdgeExistence, InternedRenderLabel, IntoRenderNodeArray}; /// # } /// # /// let mut graph = RenderGraph::default(); -/// graph.add_node("input_node", MyNode); -/// graph.add_node("output_node", MyNode); -/// graph.add_node_edge("output_node", "input_node"); +/// graph.add_node(Labels::A, MyNode); +/// graph.add_node(Labels::B, MyNode); +/// graph.add_node_edge(Labels::B, Labels::A); /// ``` #[derive(Resource, Default)] pub struct RenderGraph { @@ -71,7 +77,7 @@ impl RenderGraph { } /// Creates an [`GraphInputNode`] with the specified slots if not already present. - pub fn set_input(&mut self, inputs: Vec) -> NodeId { + pub fn set_input(&mut self, inputs: Vec) { assert!( matches!( self.get_node_state(GraphInput), @@ -109,15 +115,13 @@ impl RenderGraph { /// Adds the `node` with the `label` to the graph. /// If the label is already present replaces it instead. - pub fn add_node(&mut self, label: impl RenderLabel, node: T) -> NodeId + pub fn add_node(&mut self, label: impl RenderLabel, node: T) where T: Node, { - let id = NodeId::new(); let label = label.intern(); - let node_state = NodeState::new(id, node, label); + let node_state = NodeState::new(label, node); self.nodes.insert(label, node_state); - id } /// Add `node_edge`s based on the order of the given `edges` array. @@ -609,7 +613,7 @@ impl RenderGraph { impl Debug for RenderGraph { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { for node in self.iter_nodes() { - writeln!(f, "{:?}", node.id)?; + writeln!(f, "{:?}", node.label)?; writeln!(f, " in: {:?}", node.input_slots)?; writeln!(f, " out: {:?}", node.output_slots)?; } @@ -651,8 +655,8 @@ impl Node for GraphInputNode { mod tests { use crate::{ render_graph::{ - Edge, Node, NodeId, NodeRunError, RenderGraph, RenderGraphContext, RenderGraphError, - RenderLabel, SlotInfo, SlotType, + node::IntoRenderNodeArray, Edge, InternedRenderLabel, Node, NodeRunError, RenderGraph, + RenderGraphContext, RenderGraphError, RenderLabel, SlotInfo, SlotType, }, renderer::RenderContext, }; @@ -705,29 +709,29 @@ mod tests { } } - fn input_nodes(label: impl RenderLabel, graph: &RenderGraph) -> HashSet { + fn input_nodes(label: impl RenderLabel, graph: &RenderGraph) -> HashSet { graph .iter_node_inputs(label) .unwrap() - .map(|(_edge, node)| node.id) - .collect::>() + .map(|(_edge, node)| node.label) + .collect::>() } - fn output_nodes(label: impl RenderLabel, graph: &RenderGraph) -> HashSet { + fn output_nodes(label: impl RenderLabel, graph: &RenderGraph) -> HashSet { graph .iter_node_outputs(label) .unwrap() - .map(|(_edge, node)| node.id) - .collect::>() + .map(|(_edge, node)| node.label) + .collect::>() } #[test] fn test_graph_edges() { let mut graph = RenderGraph::default(); - let a_id = graph.add_node(TestLabels::A, TestNode::new(0, 1)); - let b_id = graph.add_node(TestLabels::B, TestNode::new(0, 1)); - let c_id = graph.add_node(TestLabels::C, TestNode::new(1, 1)); - let d_id = graph.add_node(TestLabels::D, TestNode::new(1, 0)); + graph.add_node(TestLabels::A, TestNode::new(0, 1)); + graph.add_node(TestLabels::B, TestNode::new(0, 1)); + graph.add_node(TestLabels::C, TestNode::new(1, 1)); + graph.add_node(TestLabels::D, TestNode::new(1, 0)); graph.add_slot_edge(TestLabels::A, "out_0", TestLabels::C, "in_0"); graph.add_node_edge(TestLabels::B, TestLabels::C); @@ -738,7 +742,8 @@ mod tests { "A has no inputs" ); assert!( - output_nodes(TestLabels::A, &graph) == HashSet::from_iter(vec![c_id]), + output_nodes(TestLabels::A, &graph) + == HashSet::from_iter((TestLabels::C,).into_array()), "A outputs to C" ); @@ -747,21 +752,24 @@ mod tests { "B has no inputs" ); assert!( - output_nodes(TestLabels::B, &graph) == HashSet::from_iter(vec![c_id]), + output_nodes(TestLabels::B, &graph) + == HashSet::from_iter((TestLabels::C,).into_array()), "B outputs to C" ); assert!( - input_nodes(TestLabels::C, &graph) == HashSet::from_iter(vec![a_id, b_id]), + input_nodes(TestLabels::C, &graph) + == HashSet::from_iter((TestLabels::A, TestLabels::B).into_array()), "A and B input to C" ); assert!( - output_nodes(TestLabels::D, &graph) == HashSet::from_iter(vec![d_id]), + output_nodes(TestLabels::C, &graph) + == HashSet::from_iter((TestLabels::D,).into_array()), "C outputs to D" ); assert!( - input_nodes(TestLabels::D, &graph) == HashSet::from_iter(vec![c_id]), + input_nodes(TestLabels::D, &graph) == HashSet::from_iter((TestLabels::C,).into_array()), "C inputs to D" ); assert!( @@ -862,26 +870,28 @@ mod tests { } let mut graph = RenderGraph::default(); - let a_id = graph.add_node(TestLabels::A, SimpleNode); - let b_id = graph.add_node(TestLabels::B, SimpleNode); - let c_id = graph.add_node(TestLabels::C, SimpleNode); + graph.add_node(TestLabels::A, SimpleNode); + graph.add_node(TestLabels::B, SimpleNode); + graph.add_node(TestLabels::C, SimpleNode); graph.add_node_edges((TestLabels::A, TestLabels::B, TestLabels::C)); assert!( - output_nodes(TestLabels::A, &graph) == HashSet::from_iter(vec![b_id]), + output_nodes(TestLabels::A, &graph) + == HashSet::from_iter((TestLabels::B,).into_array()), "A -> B" ); assert!( - input_nodes(TestLabels::B, &graph) == HashSet::from_iter(vec![a_id]), + input_nodes(TestLabels::B, &graph) == HashSet::from_iter((TestLabels::A,).into_array()), "A -> B" ); assert!( - output_nodes(TestLabels::B, &graph) == HashSet::from_iter(vec![c_id]), + output_nodes(TestLabels::B, &graph) + == HashSet::from_iter((TestLabels::C,).into_array()), "B -> C" ); assert!( - input_nodes(TestLabels::C, &graph) == HashSet::from_iter(vec![b_id]), + input_nodes(TestLabels::C, &graph) == HashSet::from_iter((TestLabels::B,).into_array()), "B -> C" ); } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index fdc712adbd50e..11edf2e80ba6e 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -1,5 +1,4 @@ use crate::{ - define_atomic_id, render_graph::{ Edge, InputSlotError, OutputSlotError, RenderGraphContext, RenderGraphError, RunSubGraphError, SlotInfo, SlotInfos, @@ -43,9 +42,7 @@ macro_rules! impl_render_label_tuples { } } -all_tuples_with_size!(impl_render_label_tuples, 2, 32, T, l); - -define_atomic_id!(NodeId); +all_tuples_with_size!(impl_render_label_tuples, 1, 32, T, l); /// A render node that can be added to a [`RenderGraph`](super::RenderGraph). /// @@ -101,7 +98,7 @@ pub enum NodeRunError { /// A collection of input and output [`Edges`](Edge) for a [`Node`]. #[derive(Debug)] pub struct Edges { - node: InternedRenderLabel, + label: InternedRenderLabel, input_edges: Vec, output_edges: Vec, } @@ -119,11 +116,10 @@ impl Edges { &self.output_edges } - /// Returns this node's id. - // TODO: rename + /// Returns this node's label. #[inline] - pub fn id(&self) -> InternedRenderLabel { - self.node + pub fn label(&self) -> InternedRenderLabel { + self.label } /// Adds an edge to the `input_edges` if it does not already exist. @@ -188,7 +184,7 @@ impl Edges { }) .ok_or(RenderGraphError::UnconnectedNodeInputSlot { input_slot: index, - node: self.node, + node: self.label, }) } @@ -206,7 +202,7 @@ impl Edges { }) .ok_or(RenderGraphError::UnconnectedNodeOutputSlot { output_slot: index, - node: self.node, + node: self.label, }) } } @@ -216,7 +212,6 @@ impl Edges { /// /// The `input_slots` and `output_slots` are provided by the `node`. pub struct NodeState { - pub id: NodeId, pub label: InternedRenderLabel, /// The name of the type that implements [`Node`]. pub type_name: &'static str, @@ -228,26 +223,25 @@ pub struct NodeState { impl Debug for NodeState { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "{:?} ({:?})", self.id, self.label) + writeln!(f, "{:?} ({:?})", self.label, self.type_name) } } impl NodeState { /// Creates an [`NodeState`] without edges, but the `input_slots` and `output_slots` /// are provided by the `node`. - pub fn new(id: NodeId, node: T, label: InternedRenderLabel) -> Self + pub fn new(label: InternedRenderLabel, node: T) -> Self where T: Node, { NodeState { - id, label, input_slots: node.input().into(), output_slots: node.output().into(), node: Box::new(node), type_name: std::any::type_name::(), edges: Edges { - node: label, + label, input_edges: Vec::new(), output_edges: Vec::new(), }, @@ -293,38 +287,6 @@ impl NodeState { } } -/// A [`NodeLabel`] is used to reference a [`NodeState`] by either its name or [`NodeId`] -/// inside the [`RenderGraph`](super::RenderGraph). -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum NodeLabel { - Id(NodeId), - Name(Cow<'static, str>), -} - -impl From<&NodeLabel> for NodeLabel { - fn from(value: &NodeLabel) -> Self { - value.clone() - } -} - -impl From for NodeLabel { - fn from(value: String) -> Self { - NodeLabel::Name(value.into()) - } -} - -impl From<&'static str> for NodeLabel { - fn from(value: &'static str) -> Self { - NodeLabel::Name(value.into()) - } -} - -impl From for NodeLabel { - fn from(value: NodeId) -> Self { - NodeLabel::Id(value) - } -} - /// 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). diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index a924ba2ab4d61..f76140e1a4695 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -10,8 +10,8 @@ use thiserror::Error; use crate::{ render_graph::{ - Edge, InternedRenderLabel, NodeId, NodeRunError, NodeState, RenderGraph, - RenderGraphContext, SlotLabel, SlotType, SlotValue, + Edge, InternedRenderLabel, NodeRunError, NodeState, RenderGraph, RenderGraphContext, + SlotLabel, SlotType, SlotValue, }, renderer::{RenderContext, RenderDevice}, }; @@ -79,7 +79,8 @@ impl RenderGraphRunner { inputs: &[SlotValue], view_entity: Option, ) -> Result<(), RenderGraphRunnerError> { - let mut node_outputs: HashMap> = HashMap::default(); + let mut node_outputs: HashMap> = + HashMap::default(); #[cfg(feature = "trace")] let span = if let Some(name) = &graph_name { info_span!("run_graph", name = name.deref()) @@ -118,7 +119,7 @@ impl RenderGraphRunner { } } - node_outputs.insert(input_node.id, input_values); + node_outputs.insert(input_node.label, input_values); for (_, node_state) in graph .iter_node_outputs(input_node.label) @@ -130,7 +131,7 @@ impl RenderGraphRunner { 'handle_node: while let Some(node_state) = node_queue.pop_back() { // skip nodes that are already processed - if node_outputs.contains_key(&node_state.id) { + if node_outputs.contains_key(&node_state.label) { continue; } @@ -146,7 +147,7 @@ impl RenderGraphRunner { input_index, .. } => { - if let Some(outputs) = node_outputs.get(&input_node.id) { + if let Some(outputs) = node_outputs.get(&input_node.label) { slot_indices_and_inputs .push((*input_index, outputs[*output_index].clone())); } else { @@ -155,7 +156,7 @@ impl RenderGraphRunner { } } Edge::NodeEdge { .. } => { - if !node_outputs.contains_key(&input_node.id) { + if !node_outputs.contains_key(&input_node.label) { node_queue.push_front(node_state); continue 'handle_node; } @@ -221,7 +222,7 @@ impl RenderGraphRunner { }); } } - node_outputs.insert(node_state.id, values); + node_outputs.insert(node_state.label, values); for (_, node_state) in graph .iter_node_outputs(node_state.label) From 9d2bfb469dfb49811d53bfebfb44aac83cff646d Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 18 Nov 2023 20:54:50 +0100 Subject: [PATCH 06/20] Change everything to new Labels --- crates/bevy_core_pipeline/src/bloom/mod.rs | 30 ++---- .../src/contrast_adaptive_sharpening/mod.rs | 42 ++++---- crates/bevy_core_pipeline/src/core_2d/mod.rs | 50 ++++++---- crates/bevy_core_pipeline/src/core_3d/mod.rs | 99 ++++++++++--------- crates/bevy_core_pipeline/src/fxaa/mod.rs | 28 +++--- .../bevy_core_pipeline/src/msaa_writeback.rs | 14 ++- crates/bevy_core_pipeline/src/taa/mod.rs | 26 ++--- crates/bevy_pbr/src/deferred/mod.rs | 20 ++-- crates/bevy_pbr/src/lib.rs | 21 ++-- crates/bevy_pbr/src/ssao/mod.rs | 21 ++-- crates/bevy_ui/src/render/mod.rs | 53 ++++------ .../shader/compute_shader_game_of_life.rs | 11 ++- examples/shader/post_processing.rs | 25 ++--- 13 files changed, 218 insertions(+), 222 deletions(-) diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index 4c0d8ebf8f9cd..08d7da8c86aec 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -5,8 +5,8 @@ mod upsampling_pipeline; pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings}; use crate::{ - core_2d::{self, CORE_2D}, - core_3d::{self, CORE_3D}, + core_2d::{graph::Labels2d, CORE_2D}, + core_3d::{graph::Labels3d, CORE_3D}, }; use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Handle}; @@ -73,30 +73,20 @@ impl Plugin for BloomPlugin { ), ) // Add bloom to the 3d render graph - .add_render_graph_node::>( - CORE_3D, - core_3d::graph::node::BLOOM, - ) + .add_render_graph_node::>(CORE_3D, Labels3d::Bloom) .add_render_graph_edges( CORE_3D, - &[ - core_3d::graph::node::END_MAIN_PASS, - core_3d::graph::node::BLOOM, - core_3d::graph::node::TONEMAPPING, - ], + ( + Labels3d::EndMainPass, + Labels3d::Bloom, + Labels3d::Tonemapping, + ), ) // Add bloom to the 2d render graph - .add_render_graph_node::>( - CORE_2D, - core_2d::graph::node::BLOOM, - ) + .add_render_graph_node::>(CORE_2D, Labels2d::Bloom) .add_render_graph_edges( CORE_2D, - &[ - core_2d::graph::node::MAIN_PASS, - core_2d::graph::node::BLOOM, - core_2d::graph::node::TONEMAPPING, - ], + (Labels2d::MainPass, Labels2d::Bloom, Labels2d::Tonemapping), ); } diff --git a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs index 89879938e8a8b..be71066643cb8 100644 --- a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs +++ b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs @@ -1,6 +1,6 @@ use crate::{ - core_2d::{self, CORE_2D}, - core_3d::{self, CORE_3D}, + core_2d::{graph::Labels2d, CORE_2D}, + core_3d::{graph::Labels3d, CORE_3D}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }; use bevy_app::prelude::*; @@ -122,31 +122,37 @@ impl Plugin for CASPlugin { .add_systems(Render, prepare_cas_pipelines.in_set(RenderSet::Prepare)); { - use core_3d::graph::node::*; render_app - .add_render_graph_node::(CORE_3D, CONTRAST_ADAPTIVE_SHARPENING) - .add_render_graph_edge(CORE_3D, TONEMAPPING, CONTRAST_ADAPTIVE_SHARPENING) + .add_render_graph_node::(CORE_3D, Labels3d::ContrastAdaptiveSharpening) + .add_render_graph_edge( + CORE_3D, + Labels3d::Tonemapping, + Labels3d::ContrastAdaptiveSharpening, + ) .add_render_graph_edges( CORE_3D, - &[ - FXAA, - CONTRAST_ADAPTIVE_SHARPENING, - END_MAIN_PASS_POST_PROCESSING, - ], + ( + Labels3d::Fxaa, + Labels3d::ContrastAdaptiveSharpening, + Labels3d::EndMainPassPostProcessing, + ), ); } { - use core_2d::graph::node::*; render_app - .add_render_graph_node::(CORE_2D, CONTRAST_ADAPTIVE_SHARPENING) - .add_render_graph_edge(CORE_2D, TONEMAPPING, CONTRAST_ADAPTIVE_SHARPENING) + .add_render_graph_node::(CORE_2D, Labels2d::ConstrastAdaptiveSharpening) + .add_render_graph_edge( + CORE_2D, + Labels2d::Tonemapping, + Labels2d::ConstrastAdaptiveSharpening, + ) .add_render_graph_edges( CORE_2D, - &[ - FXAA, - CONTRAST_ADAPTIVE_SHARPENING, - END_MAIN_PASS_POST_PROCESSING, - ], + ( + Labels2d::Fxaa, + Labels2d::ConstrastAdaptiveSharpening, + Labels2d::EndMainPassPostProcessing, + ), ); } } diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index 530d48cde38a5..f012e2aaa6c5e 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -2,21 +2,27 @@ mod camera_2d; mod main_pass_2d_node; pub mod graph { + use bevy_render::render_graph::RenderLabel; + pub const NAME: &str = "core_2d"; + pub mod input { pub const VIEW_ENTITY: &str = "view_entity"; } - pub mod node { - pub const MSAA_WRITEBACK: &str = "msaa_writeback"; - pub const MAIN_PASS: &str = "main_pass"; - pub const BLOOM: &str = "bloom"; - pub const TONEMAPPING: &str = "tonemapping"; - pub const FXAA: &str = "fxaa"; - pub const UPSCALING: &str = "upscaling"; - pub const CONTRAST_ADAPTIVE_SHARPENING: &str = "contrast_adaptive_sharpening"; - pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing"; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] + pub enum Labels2d { + MsaaWriteback, + MainPass, + Bloom, + Tonemapping, + Fxaa, + Upscaling, + ConstrastAdaptiveSharpening, + EndMainPassPostProcessing, } } + pub const CORE_2D: &str = graph::NAME; use std::ops::Range; @@ -41,6 +47,8 @@ use bevy_utils::{nonmax::NonMaxU32, FloatOrd}; use crate::{tonemapping::TonemappingNode, upscaling::UpscalingNode}; +use self::graph::Labels2d; + pub struct Core2dPlugin; impl Plugin for Core2dPlugin { @@ -61,21 +69,23 @@ impl Plugin for Core2dPlugin { sort_phase_system::.in_set(RenderSet::PhaseSort), ); - use graph::node::*; render_app .add_render_sub_graph(CORE_2D) - .add_render_graph_node::(CORE_2D, MAIN_PASS) - .add_render_graph_node::>(CORE_2D, TONEMAPPING) - .add_render_graph_node::(CORE_2D, END_MAIN_PASS_POST_PROCESSING) - .add_render_graph_node::>(CORE_2D, UPSCALING) + .add_render_graph_node::(CORE_2D, Labels2d::MainPass) + .add_render_graph_node::>( + CORE_2D, + Labels2d::Tonemapping, + ) + .add_render_graph_node::(CORE_2D, Labels2d::EndMainPassPostProcessing) + .add_render_graph_node::>(CORE_2D, Labels2d::Upscaling) .add_render_graph_edges( CORE_2D, - &[ - MAIN_PASS, - TONEMAPPING, - END_MAIN_PASS_POST_PROCESSING, - UPSCALING, - ], + ( + Labels2d::MainPass, + Labels2d::Tonemapping, + Labels2d::EndMainPassPostProcessing, + Labels2d::Upscaling, + ), ); } } diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index f003ed6191f2b..f890a82646b7b 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -4,29 +4,36 @@ mod main_transmissive_pass_3d_node; mod main_transparent_pass_3d_node; pub mod graph { + use bevy_render::render_graph::RenderLabel; + pub const NAME: &str = "core_3d"; + pub mod input { pub const VIEW_ENTITY: &str = "view_entity"; } - pub mod node { - pub const MSAA_WRITEBACK: &str = "msaa_writeback"; - pub const PREPASS: &str = "prepass"; - pub const DEFERRED_PREPASS: &str = "deferred_prepass"; - pub const COPY_DEFERRED_LIGHTING_ID: &str = "copy_deferred_lighting_id"; - pub const END_PREPASSES: &str = "end_prepasses"; - pub const START_MAIN_PASS: &str = "start_main_pass"; - pub const MAIN_OPAQUE_PASS: &str = "main_opaque_pass"; - pub const MAIN_TRANSMISSIVE_PASS: &str = "main_transmissive_pass"; - pub const MAIN_TRANSPARENT_PASS: &str = "main_transparent_pass"; - pub const END_MAIN_PASS: &str = "end_main_pass"; - pub const BLOOM: &str = "bloom"; - pub const TONEMAPPING: &str = "tonemapping"; - pub const FXAA: &str = "fxaa"; - pub const UPSCALING: &str = "upscaling"; - pub const CONTRAST_ADAPTIVE_SHARPENING: &str = "contrast_adaptive_sharpening"; - pub const END_MAIN_PASS_POST_PROCESSING: &str = "end_main_pass_post_processing"; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] + pub enum Labels3d { + MsaaWriteback, + Prepass, + DeferredPrepass, + CopyDeferredLightingId, + EndPrepasses, + StartMainPass, + MainOpaquePass, + MainTransmissivePass, + MainTransparentPass, + EndMainPass, + Bloom, + Tonemapping, + Fxaa, + Taa, + Upscaling, + ContrastAdaptiveSharpening, + EndMainPassPostProcessing, } } + pub const CORE_3D: &str = graph::NAME; // PERF: vulkan docs recommend using 24 bit depth for better performance @@ -77,6 +84,8 @@ use crate::{ upscaling::UpscalingNode, }; +use self::graph::Labels3d; + pub struct Core3dPlugin; impl Plugin for Core3dPlugin { @@ -119,52 +128,54 @@ impl Plugin for Core3dPlugin { ), ); - use graph::node::*; render_app .add_render_sub_graph(CORE_3D) - .add_render_graph_node::>(CORE_3D, PREPASS) + .add_render_graph_node::>(CORE_3D, Labels3d::Prepass) .add_render_graph_node::>( CORE_3D, - DEFERRED_PREPASS, + Labels3d::DeferredPrepass, ) .add_render_graph_node::>( CORE_3D, - COPY_DEFERRED_LIGHTING_ID, + Labels3d::CopyDeferredLightingId, ) - .add_render_graph_node::(CORE_3D, END_PREPASSES) - .add_render_graph_node::(CORE_3D, START_MAIN_PASS) + .add_render_graph_node::(CORE_3D, Labels3d::EndPrepasses) + .add_render_graph_node::(CORE_3D, Labels3d::StartMainPass) .add_render_graph_node::>( CORE_3D, - MAIN_OPAQUE_PASS, + Labels3d::MainOpaquePass, ) .add_render_graph_node::>( CORE_3D, - MAIN_TRANSMISSIVE_PASS, + Labels3d::MainTransmissivePass, ) .add_render_graph_node::>( CORE_3D, - MAIN_TRANSPARENT_PASS, + Labels3d::MainTransparentPass, ) - .add_render_graph_node::(CORE_3D, END_MAIN_PASS) - .add_render_graph_node::>(CORE_3D, TONEMAPPING) - .add_render_graph_node::(CORE_3D, END_MAIN_PASS_POST_PROCESSING) - .add_render_graph_node::>(CORE_3D, UPSCALING) + .add_render_graph_node::(CORE_3D, Labels3d::EndMainPass) + .add_render_graph_node::>( + CORE_3D, + Labels3d::Tonemapping, + ) + .add_render_graph_node::(CORE_3D, Labels3d::EndMainPassPostProcessing) + .add_render_graph_node::>(CORE_3D, Labels3d::Upscaling) .add_render_graph_edges( CORE_3D, - &[ - PREPASS, - DEFERRED_PREPASS, - COPY_DEFERRED_LIGHTING_ID, - END_PREPASSES, - START_MAIN_PASS, - MAIN_OPAQUE_PASS, - MAIN_TRANSMISSIVE_PASS, - MAIN_TRANSPARENT_PASS, - END_MAIN_PASS, - TONEMAPPING, - END_MAIN_PASS_POST_PROCESSING, - UPSCALING, - ], + ( + Labels3d::Prepass, + Labels3d::DeferredPrepass, + Labels3d::CopyDeferredLightingId, + Labels3d::EndPrepasses, + Labels3d::StartMainPass, + Labels3d::MainOpaquePass, + Labels3d::MainTransmissivePass, + Labels3d::MainTransparentPass, + Labels3d::EndMainPass, + Labels3d::Tonemapping, + Labels3d::EndMainPassPostProcessing, + Labels3d::Upscaling, + ), ); } } diff --git a/crates/bevy_core_pipeline/src/fxaa/mod.rs b/crates/bevy_core_pipeline/src/fxaa/mod.rs index df37eaa1a8e76..bfb6fa42b5cd2 100644 --- a/crates/bevy_core_pipeline/src/fxaa/mod.rs +++ b/crates/bevy_core_pipeline/src/fxaa/mod.rs @@ -1,6 +1,6 @@ use crate::{ - core_2d::{self, CORE_2D}, - core_3d::{self, CORE_3D}, + core_2d::{graph::Labels2d, CORE_2D}, + core_3d::{ graph::Labels3d, CORE_3D}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }; use bevy_app::prelude::*; @@ -93,23 +93,23 @@ impl Plugin for FxaaPlugin { render_app .init_resource::>() .add_systems(Render, prepare_fxaa_pipelines.in_set(RenderSet::Prepare)) - .add_render_graph_node::>(CORE_3D, core_3d::graph::node::FXAA) + .add_render_graph_node::>(CORE_3D, Labels3d::Fxaa) .add_render_graph_edges( CORE_3D, - &[ - core_3d::graph::node::TONEMAPPING, - core_3d::graph::node::FXAA, - core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING, - ], + ( + Labels3d::Tonemapping, + Labels3d::Fxaa, + Labels3d::EndMainPassPostProcessing, + ), ) - .add_render_graph_node::>(CORE_2D, core_2d::graph::node::FXAA) + .add_render_graph_node::>(CORE_2D, Labels2d::Fxaa) .add_render_graph_edges( CORE_2D, - &[ - core_2d::graph::node::TONEMAPPING, - core_2d::graph::node::FXAA, - core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING, - ], + ( + Labels2d::Tonemapping, + Labels2d::Fxaa, + Labels2d::EndMainPassPostProcessing, + ), ); } diff --git a/crates/bevy_core_pipeline/src/msaa_writeback.rs b/crates/bevy_core_pipeline/src/msaa_writeback.rs index d80bc0fce7bc9..de895ed1987fb 100644 --- a/crates/bevy_core_pipeline/src/msaa_writeback.rs +++ b/crates/bevy_core_pipeline/src/msaa_writeback.rs @@ -1,7 +1,7 @@ use crate::{ blit::{BlitPipeline, BlitPipelineKey}, - core_2d::{self, CORE_2D}, - core_3d::{self, CORE_3D}, + core_2d::{graph::Labels2d, CORE_2D}, + core_3d::{graph::Labels3d, CORE_3D}, }; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; @@ -30,16 +30,14 @@ impl Plugin for MsaaWritebackPlugin { prepare_msaa_writeback_pipelines.in_set(RenderSet::Prepare), ); { - use core_2d::graph::node::*; render_app - .add_render_graph_node::(CORE_2D, MSAA_WRITEBACK) - .add_render_graph_edge(CORE_2D, MSAA_WRITEBACK, MAIN_PASS); + .add_render_graph_node::(CORE_2D, Labels2d::MsaaWriteback) + .add_render_graph_edge(CORE_2D, Labels2d::MsaaWriteback, Labels2d::MainPass); } { - use core_3d::graph::node::*; render_app - .add_render_graph_node::(CORE_3D, MSAA_WRITEBACK) - .add_render_graph_edge(CORE_3D, MSAA_WRITEBACK, START_MAIN_PASS); + .add_render_graph_node::(CORE_3D, Labels3d::MsaaWriteback) + .add_render_graph_edge(CORE_3D, Labels3d::MsaaWriteback, Labels3d::StartMainPass); } } } diff --git a/crates/bevy_core_pipeline/src/taa/mod.rs b/crates/bevy_core_pipeline/src/taa/mod.rs index de4069c9abe7d..5bac68a1b3a37 100644 --- a/crates/bevy_core_pipeline/src/taa/mod.rs +++ b/crates/bevy_core_pipeline/src/taa/mod.rs @@ -1,5 +1,5 @@ use crate::{ - core_3d::{self, CORE_3D}, + core_3d::{graph::Labels3d, CORE_3D}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, prelude::Camera3d, prepass::{DepthPrepass, MotionVectorPrepass, ViewPrepassTextures}, @@ -35,13 +35,6 @@ use bevy_render::{ ExtractSchedule, MainWorld, Render, RenderApp, RenderSet, }; -pub mod draw_3d_graph { - pub mod node { - /// Label for the TAA render node. - pub const TAA: &str = "taa"; - } -} - const TAA_SHADER_HANDLE: Handle = Handle::weak_from_u128(656865235226276); /// Plugin for temporal anti-aliasing. Disables multisample anti-aliasing (MSAA). @@ -71,18 +64,15 @@ impl Plugin for TemporalAntiAliasPlugin { prepare_taa_history_textures.in_set(RenderSet::PrepareResources), ), ) - .add_render_graph_node::>( - CORE_3D, - draw_3d_graph::node::TAA, - ) + .add_render_graph_node::>(CORE_3D, Labels3d::Taa) .add_render_graph_edges( CORE_3D, - &[ - core_3d::graph::node::END_MAIN_PASS, - draw_3d_graph::node::TAA, - core_3d::graph::node::BLOOM, - core_3d::graph::node::TONEMAPPING, - ], + ( + Labels3d::EndMainPass, + Labels3d::Taa, + Labels3d::Bloom, + Labels3d::Tonemapping, + ), ); } diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index f679f638d42ac..e9010f11e7318 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -3,7 +3,7 @@ use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, Handle}; use bevy_core_pipeline::{ clear_color::ClearColorConfig, - core_3d, + core_3d::{self, graph::Labels3d}, deferred::{ copy_lighting_id::DeferredLightingIdDepthTexture, DEFERRED_LIGHTING_PASS_ID_DEPTH_FORMAT, }, @@ -17,7 +17,7 @@ use bevy_render::{ ComponentUniforms, ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin, }, render_asset::RenderAssets, - render_graph::{NodeRunError, RenderGraphContext, ViewNode, ViewNodeRunner}, + render_graph::{NodeRunError, RenderGraphContext, RenderLabel, ViewNode, ViewNodeRunner}, render_resource::{self, Operations, PipelineCache, RenderPassDescriptor}, renderer::{RenderContext, RenderDevice}, texture::Image, @@ -121,15 +121,15 @@ impl Plugin for DeferredPbrLightingPlugin { ) .add_render_graph_node::>( core_3d::graph::NAME, - DEFERRED_LIGHTING_PASS, + DeferredLightingPass3dNode, ) .add_render_graph_edges( core_3d::graph::NAME, - &[ - core_3d::graph::node::START_MAIN_PASS, - DEFERRED_LIGHTING_PASS, - core_3d::graph::node::MAIN_OPAQUE_PASS, - ], + ( + Labels3d::StartMainPass, + DeferredLightingPass3dNode, + Labels3d::MainOpaquePass, + ), ); } @@ -142,7 +142,9 @@ impl Plugin for DeferredPbrLightingPlugin { } } -pub const DEFERRED_LIGHTING_PASS: &str = "deferred_opaque_pbr_lighting_pass_3d"; +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] +pub struct DeferredLightingPass3dNode; + #[derive(Default)] pub struct DeferredOpaquePass3dPbrLightingNode; diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 8e1cfdd41d34b..46296a787da31 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -17,6 +17,7 @@ mod render; mod ssao; pub use alpha::*; +use bevy_core_pipeline::core_3d::graph::Labels3d; pub use bundle::*; pub use environment_map::EnvironmentMapLight; pub use extended_material::*; @@ -47,10 +48,15 @@ pub mod prelude { }; } -pub mod draw_3d_graph { - pub mod node { +pub mod graph { + use bevy_render::render_graph::RenderLabel; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] + pub enum LabelsPbr { /// Label for the shadow pass node. - pub const SHADOW_PASS: &str = "shadow_pass"; + ShadowPass, + /// Label for the screen space ambient occlusion render node. + ScreenSpaceAmbientOcclusion, } } @@ -73,7 +79,7 @@ use bevy_render::{ use bevy_transform::TransformSystem; use environment_map::EnvironmentMapPlugin; -use crate::deferred::DeferredPbrLightingPlugin; +use crate::{deferred::DeferredPbrLightingPlugin, graph::LabelsPbr}; pub const PBR_TYPES_SHADER_HANDLE: Handle = Handle::weak_from_u128(1708015359337029744); pub const PBR_BINDINGS_SHADER_HANDLE: Handle = Handle::weak_from_u128(5635987986427308186); @@ -359,11 +365,8 @@ impl Plugin for PbrPlugin { let draw_3d_graph = graph .get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME) .unwrap(); - draw_3d_graph.add_node(draw_3d_graph::node::SHADOW_PASS, shadow_pass_node); - draw_3d_graph.add_node_edge( - draw_3d_graph::node::SHADOW_PASS, - bevy_core_pipeline::core_3d::graph::node::START_MAIN_PASS, - ); + draw_3d_graph.add_node(LabelsPbr::ShadowPass, shadow_pass_node); + draw_3d_graph.add_node_edge(LabelsPbr::ShadowPass, Labels3d::StartMainPass); } fn finish(&self, app: &mut App) { diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index 62a7d4e5a4a6a..dc40b835beffb 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -1,7 +1,7 @@ use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Handle}; use bevy_core_pipeline::{ - core_3d::CORE_3D, + core_3d::{graph::Labels3d, CORE_3D}, prelude::Camera3d, prepass::{DepthPrepass, NormalPrepass, ViewPrepassTextures}, }; @@ -32,12 +32,7 @@ use bevy_utils::{ }; use std::mem; -pub mod draw_3d_graph { - pub mod node { - /// Label for the screen space ambient occlusion render node. - pub const SCREEN_SPACE_AMBIENT_OCCLUSION: &str = "screen_space_ambient_occlusion"; - } -} +use crate::LabelsPbr; const PREPROCESS_DEPTH_SHADER_HANDLE: Handle = Handle::weak_from_u128(102258915420479); const GTAO_SHADER_HANDLE: Handle = Handle::weak_from_u128(253938746510568); @@ -113,16 +108,16 @@ impl Plugin for ScreenSpaceAmbientOcclusionPlugin { ) .add_render_graph_node::>( CORE_3D, - draw_3d_graph::node::SCREEN_SPACE_AMBIENT_OCCLUSION, + LabelsPbr::ScreenSpaceAmbientOcclusion, ) .add_render_graph_edges( CORE_3D, - &[ + ( // END_PRE_PASSES -> SCREEN_SPACE_AMBIENT_OCCLUSION -> MAIN_PASS - bevy_core_pipeline::core_3d::graph::node::END_PREPASSES, - draw_3d_graph::node::SCREEN_SPACE_AMBIENT_OCCLUSION, - bevy_core_pipeline::core_3d::graph::node::START_MAIN_PASS, - ], + Labels3d::EndPrepasses, + LabelsPbr::ScreenSpaceAmbientOcclusion, + Labels3d::StartMainPass, + ), ); } } diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 97fb405e63659..904a286bbc423 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -2,6 +2,8 @@ mod pipeline; mod render_pass; mod ui_material_pipeline; +use bevy_core_pipeline::core_2d::graph::Labels2d; +use bevy_core_pipeline::core_3d::graph::Labels3d; use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; use bevy_hierarchy::Parent; use bevy_render::render_phase::PhaseItem; @@ -12,6 +14,7 @@ pub use pipeline::*; pub use render_pass::*; pub use ui_material_pipeline::*; +use crate::graph::LabelsUi; use crate::Outline; use crate::{ prelude::UiCameraConfig, BackgroundColor, BorderColor, CalculatedClip, ContentSize, Node, @@ -43,14 +46,16 @@ use bevy_utils::{EntityHashMap, FloatOrd, HashMap}; use bytemuck::{Pod, Zeroable}; use std::ops::Range; -pub mod node { - pub const UI_PASS_DRIVER: &str = "ui_pass_driver"; -} - pub mod draw_ui_graph { pub const NAME: &str = "draw_ui"; - pub mod node { - pub const UI_PASS: &str = "ui_pass"; +} + +pub mod graph { + use bevy_render::render_graph::RenderLabel; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] + pub enum LabelsUi { + UiPass, } } @@ -109,48 +114,30 @@ pub fn build_ui_render(app: &mut App) { if let Some(graph_2d) = graph.get_sub_graph_mut(bevy_core_pipeline::core_2d::graph::NAME) { graph_2d.add_sub_graph(draw_ui_graph::NAME, ui_graph_2d); graph_2d.add_node( - draw_ui_graph::node::UI_PASS, + LabelsUi::UiPass, RunGraphOnViewNode::new(draw_ui_graph::NAME), ); - graph_2d.add_node_edge( - bevy_core_pipeline::core_2d::graph::node::MAIN_PASS, - draw_ui_graph::node::UI_PASS, - ); - graph_2d.add_node_edge( - bevy_core_pipeline::core_2d::graph::node::END_MAIN_PASS_POST_PROCESSING, - draw_ui_graph::node::UI_PASS, - ); - graph_2d.add_node_edge( - draw_ui_graph::node::UI_PASS, - bevy_core_pipeline::core_2d::graph::node::UPSCALING, - ); + graph_2d.add_node_edge(Labels2d::MainPass, LabelsUi::UiPass); + graph_2d.add_node_edge(Labels2d::EndMainPassPostProcessing, LabelsUi::UiPass); + graph_2d.add_node_edge(LabelsUi::UiPass, Labels2d::Upscaling); } if let Some(graph_3d) = graph.get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME) { graph_3d.add_sub_graph(draw_ui_graph::NAME, ui_graph_3d); graph_3d.add_node( - draw_ui_graph::node::UI_PASS, + LabelsUi::UiPass, RunGraphOnViewNode::new(draw_ui_graph::NAME), ); - graph_3d.add_node_edge( - bevy_core_pipeline::core_3d::graph::node::END_MAIN_PASS, - draw_ui_graph::node::UI_PASS, - ); - graph_3d.add_node_edge( - bevy_core_pipeline::core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING, - draw_ui_graph::node::UI_PASS, - ); - graph_3d.add_node_edge( - draw_ui_graph::node::UI_PASS, - bevy_core_pipeline::core_3d::graph::node::UPSCALING, - ); + graph_3d.add_node_edge(Labels3d::EndMainPass, LabelsUi::UiPass); + graph_3d.add_node_edge(Labels3d::EndMainPassPostProcessing, LabelsUi::UiPass); + graph_3d.add_node_edge(LabelsUi::UiPass, Labels3d::Upscaling); } } fn get_ui_graph(render_app: &mut App) -> RenderGraph { let ui_pass_node = UiPassNode::new(&mut render_app.world); let mut ui_graph = RenderGraph::default(); - ui_graph.add_node(draw_ui_graph::node::UI_PASS, ui_pass_node); + ui_graph.add_node(LabelsUi::UiPass, ui_pass_node); ui_graph } diff --git a/examples/shader/compute_shader_game_of_life.rs b/examples/shader/compute_shader_game_of_life.rs index 2f8a269e592b8..a56873078fa80 100644 --- a/examples/shader/compute_shader_game_of_life.rs +++ b/examples/shader/compute_shader_game_of_life.rs @@ -8,7 +8,7 @@ use bevy::{ render::{ extract_resource::{ExtractResource, ExtractResourcePlugin}, render_asset::RenderAssets, - render_graph::{self, RenderGraph}, + render_graph::{self, RenderGraph, RenderLabel}, render_resource::*, renderer::{RenderContext, RenderDevice}, Render, RenderApp, RenderSet, @@ -68,6 +68,9 @@ fn setup(mut commands: Commands, mut images: ResMut>) { pub struct GameOfLifeComputePlugin; +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] +pub struct GameOfLifeLabel; + impl Plugin for GameOfLifeComputePlugin { fn build(&self, app: &mut App) { // Extract the game of life image resource from the main world into the render world @@ -80,10 +83,10 @@ impl Plugin for GameOfLifeComputePlugin { ); let mut render_graph = render_app.world.resource_mut::(); - render_graph.add_node("game_of_life", GameOfLifeNode::default()); + render_graph.add_node(GameOfLifeLabel, GameOfLifeNode::default()); render_graph.add_node_edge( - "game_of_life", - bevy::render::main_graph::node::CAMERA_DRIVER, + GameOfLifeLabel, + bevy::render::main_graph::node::CameraDriver, ); } diff --git a/examples/shader/post_processing.rs b/examples/shader/post_processing.rs index 39a6c46530b54..15b6ffeff33c5 100644 --- a/examples/shader/post_processing.rs +++ b/examples/shader/post_processing.rs @@ -7,7 +7,8 @@ use bevy::{ core_pipeline::{ - clear_color::ClearColorConfig, core_3d, + clear_color::ClearColorConfig, + core_3d::{self, graph::Labels3d}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }, ecs::query::QueryItem, @@ -17,7 +18,7 @@ use bevy::{ ComponentUniforms, ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin, }, render_graph::{ - NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner, + NodeRunError, RenderGraphApp, RenderGraphContext, RenderLabel, ViewNode, ViewNodeRunner, }, render_resource::{ BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, @@ -42,6 +43,9 @@ fn main() { .run(); } +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] +pub struct PostProcessLabel; + /// It is generally encouraged to set up post processing effects as a plugin struct PostProcessPlugin; @@ -83,18 +87,18 @@ impl Plugin for PostProcessPlugin { .add_render_graph_node::>( // Specify the name of the graph, in this case we want the graph for 3d core_3d::graph::NAME, - // It also needs the name of the node - PostProcessNode::NAME, + // It also needs the label of the node + PostProcessLabel, ) .add_render_graph_edges( core_3d::graph::NAME, // Specify the node ordering. // This will automatically create all required node edges to enforce the given ordering. - &[ - core_3d::graph::node::TONEMAPPING, - PostProcessNode::NAME, - core_3d::graph::node::END_MAIN_PASS_POST_PROCESSING, - ], + ( + Labels3d::Tonemapping, + PostProcessLabel, + Labels3d::EndMainPassPostProcessing, + ), ); } @@ -113,9 +117,6 @@ impl Plugin for PostProcessPlugin { // The post process node used for the render graph #[derive(Default)] struct PostProcessNode; -impl PostProcessNode { - pub const NAME: &'static str = "post_process"; -} // The ViewNode trait is required by the ViewNodeRunner impl ViewNode for PostProcessNode { From e7b465a37f3d4da3deae29d7b3383f1ae58204f8 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sat, 18 Nov 2023 20:58:08 +0100 Subject: [PATCH 07/20] Refactor CameraDriverLabel --- crates/bevy_render/src/camera/mod.rs | 2 +- crates/bevy_render/src/lib.rs | 10 ++++------ examples/shader/compute_shader_game_of_life.rs | 5 +---- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index 3bfa6f29972c5..97a521ec844ef 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -42,7 +42,7 @@ impl Plugin for CameraPlugin { .add_systems(Render, sort_cameras.in_set(RenderSet::ManageViews)); let camera_driver_node = CameraDriverNode::new(&mut render_app.world); let mut render_graph = render_app.world.resource_mut::(); - render_graph.add_node(crate::main_graph::node::CameraDriver, camera_driver_node); + render_graph.add_node(crate::graph::CameraDriverLabel, camera_driver_node); } } } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index d9e19d809d2b1..12c0374f72469 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -206,13 +206,11 @@ impl DerefMut for MainWorld { } } -pub mod main_graph { - pub mod node { - use crate::render_graph::RenderLabel; +pub mod graph { + use crate::render_graph::RenderLabel; - #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] - pub struct CameraDriver; - } + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] + pub struct CameraDriverLabel; } #[derive(Resource)] diff --git a/examples/shader/compute_shader_game_of_life.rs b/examples/shader/compute_shader_game_of_life.rs index a56873078fa80..cee169ed96766 100644 --- a/examples/shader/compute_shader_game_of_life.rs +++ b/examples/shader/compute_shader_game_of_life.rs @@ -84,10 +84,7 @@ impl Plugin for GameOfLifeComputePlugin { let mut render_graph = render_app.world.resource_mut::(); render_graph.add_node(GameOfLifeLabel, GameOfLifeNode::default()); - render_graph.add_node_edge( - GameOfLifeLabel, - bevy::render::main_graph::node::CameraDriver, - ); + render_graph.add_node_edge(GameOfLifeLabel, bevy::render::graph::CameraDriverLabel); } fn finish(&self, app: &mut App) { From 3efa7c153bf8efc5270d08ab137b3f2d608309f4 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 19 Nov 2023 16:22:45 +0100 Subject: [PATCH 08/20] Add `RenderSubGraph` label --- crates/bevy_render/macros/src/lib.rs | 18 +++++ crates/bevy_render/src/camera/camera.rs | 18 ++--- crates/bevy_render/src/camera/mod.rs | 1 - crates/bevy_render/src/render_graph/app.rs | 41 ++++++---- .../bevy_render/src/render_graph/context.rs | 28 ++++--- crates/bevy_render/src/render_graph/graph.rs | 79 +++++++++++-------- crates/bevy_render/src/render_graph/node.rs | 16 ++-- .../bevy_render/src/renderer/graph_runner.rs | 16 ++-- 8 files changed, 130 insertions(+), 87 deletions(-) diff --git a/crates/bevy_render/macros/src/lib.rs b/crates/bevy_render/macros/src/lib.rs index b748be7e401ac..b8e036cbe6297 100644 --- a/crates/bevy_render/macros/src/lib.rs +++ b/crates/bevy_render/macros/src/lib.rs @@ -77,3 +77,21 @@ pub fn derive_render_label(input: TokenStream) -> TokenStream { dyn_eq_path.segments.push(format_ident!("DynEq").into()); derive_label(input, "RenderLabel", &trait_path, &dyn_eq_path) } + +/// Derive macro generating an impl of the trait `RenderSubGraph`. +/// +/// This does not work for unions. +#[proc_macro_derive(RenderSubGraph)] +pub fn derive_render_sub_graph(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let mut trait_path = bevy_render_path(); + trait_path + .segments + .push(format_ident!("render_graph").into()); + let mut dyn_eq_path = trait_path.clone(); + trait_path + .segments + .push(format_ident!("RenderSubGraph").into()); + dyn_eq_path.segments.push(format_ident!("DynEq").into()); + derive_label(input, "RenderSubGraph", &trait_path, &dyn_eq_path) +} diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 14f9ae72511fa..2793b53dc26ec 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -4,6 +4,7 @@ use crate::{ prelude::Image, primitives::Frustum, render_asset::RenderAssets, + render_graph::{InternedRenderSubGraph, RenderSubGraph}, render_resource::TextureView, view::{ColorGrading, ExtractedView, ExtractedWindows, RenderLayers, VisibleEntities}, Extract, @@ -27,7 +28,7 @@ use bevy_utils::{HashMap, HashSet}; use bevy_window::{ NormalizedWindowRef, PrimaryWindow, Window, WindowCreated, WindowRef, WindowResized, }; -use std::{borrow::Cow, ops::Range}; +use std::ops::Range; use wgpu::{BlendState, LoadOp, TextureFormat}; use super::Projection; @@ -389,21 +390,20 @@ impl Default for CameraOutputMode { } /// Configures the [`RenderGraph`](crate::render_graph::RenderGraph) name assigned to be run for a given [`Camera`] entity. -#[derive(Component, Deref, DerefMut, Reflect, Default)] -#[reflect(Component)] -pub struct CameraRenderGraph(Cow<'static, str>); +#[derive(Component, Deref, DerefMut)] +pub struct CameraRenderGraph(InternedRenderSubGraph); impl CameraRenderGraph { /// Creates a new [`CameraRenderGraph`] from any string-like type. #[inline] - pub fn new>>(name: T) -> Self { - Self(name.into()) + pub fn new(name: T) -> Self { + Self(name.intern()) } /// Sets the graph name. #[inline] - pub fn set>>(&mut self, name: T) { - self.0 = name.into(); + pub fn set(&mut self, name: T) { + self.0 = name.intern(); } } @@ -624,7 +624,7 @@ pub struct ExtractedCamera { pub physical_viewport_size: Option, pub physical_target_size: Option, pub viewport: Option, - pub render_graph: Cow<'static, str>, + pub render_graph: InternedRenderSubGraph, pub order: isize, pub output_mode: CameraOutputMode, pub msaa_writeback: bool, diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index 97a521ec844ef..3309ef169f023 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -25,7 +25,6 @@ impl Plugin for CameraPlugin { .register_type::() .register_type::>() .register_type::() - .register_type::() .register_type::() .init_resource::() .add_plugins(( diff --git a/crates/bevy_render/src/render_graph/app.rs b/crates/bevy_render/src/render_graph/app.rs index 4b566ac68a401..fedb176d1a4d1 100644 --- a/crates/bevy_render/src/render_graph/app.rs +++ b/crates/bevy_render/src/render_graph/app.rs @@ -2,31 +2,31 @@ use bevy_app::App; use bevy_ecs::world::FromWorld; use bevy_log::warn; -use super::{IntoRenderNodeArray, Node, RenderGraph, RenderLabel}; +use super::{IntoRenderNodeArray, Node, RenderGraph, RenderLabel, RenderSubGraph}; /// 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; + fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self; /// Add a [`Node`] to the [`RenderGraph`]: /// * Create the [`Node`] using the [`FromWorld`] implementation /// * Add it to the graph fn add_render_graph_node( &mut self, - sub_graph_name: &'static str, + sub_graph: impl RenderSubGraph, node_label: impl RenderLabel, ) -> &mut Self; /// Automatically add the required node edges based on the given ordering fn add_render_graph_edges( &mut self, - sub_graph_name: &'static str, + sub_graph: impl RenderSubGraph, edges: impl IntoRenderNodeArray, ) -> &mut Self; /// Add node edge to the specified graph fn add_render_graph_edge( &mut self, - sub_graph_name: &'static str, + sub_graph: impl RenderSubGraph, output_node: impl RenderLabel, input_node: impl RenderLabel, ) -> &mut Self; @@ -35,59 +35,68 @@ pub trait RenderGraphApp { impl RenderGraphApp for App { fn add_render_graph_node( &mut self, - sub_graph_name: &'static str, + sub_graph: impl RenderSubGraph, node_label: impl RenderLabel, ) -> &mut Self { + let sub_graph = sub_graph.intern(); let node = T::from_world(&mut self.world); let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_node on the RenderApp", ); - if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) { + if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph) { graph.add_node(node_label, node); } else { - warn!("Tried adding a render graph node to {sub_graph_name} but the sub graph doesn't exist"); + warn!( + "Tried adding a render graph node to {sub_graph:?} but the sub graph doesn't exist" + ); } self } fn add_render_graph_edges( &mut self, - sub_graph_name: &'static str, + sub_graph: impl RenderSubGraph, edges: impl IntoRenderNodeArray, ) -> &mut Self { + let sub_graph = sub_graph.intern(); let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_edges on the RenderApp", ); - if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) { + if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph) { graph.add_node_edges(edges); } else { - warn!("Tried adding render graph edges to {sub_graph_name} but the sub graph doesn't exist"); + warn!( + "Tried adding render graph edges to {sub_graph:?} but the sub graph doesn't exist" + ); } self } fn add_render_graph_edge( &mut self, - sub_graph_name: &'static str, + sub_graph: impl RenderSubGraph, output_node: impl RenderLabel, input_node: impl RenderLabel, ) -> &mut Self { + let sub_graph = sub_graph.intern(); let mut render_graph = self.world.get_resource_mut::().expect( "RenderGraph not found. Make sure you are using add_render_graph_edge on the RenderApp", ); - if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph_name) { + if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph) { graph.add_node_edge(output_node, input_node); } else { - warn!("Tried adding a render graph edge to {sub_graph_name} but the sub graph doesn't exist"); + warn!( + "Tried adding a render graph edge to {sub_graph:?} but the sub graph doesn't exist" + ); } self } - fn add_render_sub_graph(&mut self, sub_graph_name: &'static str) -> &mut Self { + fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self { let mut render_graph = self.world.get_resource_mut::().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()); + render_graph.add_sub_graph(sub_graph, RenderGraph::default()); self } } diff --git a/crates/bevy_render/src/render_graph/context.rs b/crates/bevy_render/src/render_graph/context.rs index da983fdc7fbae..54c4d2024ad8b 100644 --- a/crates/bevy_render/src/render_graph/context.rs +++ b/crates/bevy_render/src/render_graph/context.rs @@ -6,10 +6,12 @@ use bevy_ecs::entity::Entity; use std::borrow::Cow; use thiserror::Error; -/// A command that signals the graph runner to run the sub graph corresponding to the `name` +use super::{InternedRenderSubGraph, RenderSubGraph}; + +/// A command that signals the graph runner to run the sub graph corresponding to the `sub_graph` /// with the specified `inputs` next. pub struct RunSubGraph { - pub name: Cow<'static, str>, + pub sub_graph: InternedRenderSubGraph, pub inputs: Vec, pub view_entity: Option, } @@ -180,15 +182,15 @@ impl<'a> RenderGraphContext<'a> { /// Queues up a sub graph for execution after the node has finished running. pub fn run_sub_graph( &mut self, - name: impl Into>, + name: impl RenderSubGraph, inputs: Vec, view_entity: Option, ) -> Result<(), RunSubGraphError> { - let name = name.into(); + let name = name.intern(); let sub_graph = self .graph - .get_sub_graph(&name) - .ok_or_else(|| RunSubGraphError::MissingSubGraph(name.clone()))?; + .get_sub_graph(name) + .ok_or_else(|| RunSubGraphError::MissingSubGraph(name))?; if let Some(input_node) = sub_graph.get_input_node() { for (i, input_slot) in input_node.input_slots.iter().enumerate() { if let Some(input_value) = inputs.get(i) { @@ -214,7 +216,7 @@ impl<'a> RenderGraphContext<'a> { } self.run_sub_graphs.push(RunSubGraph { - name, + sub_graph: name, inputs, view_entity, }); @@ -231,19 +233,19 @@ impl<'a> RenderGraphContext<'a> { #[derive(Error, Debug, Eq, PartialEq)] pub enum RunSubGraphError { - #[error("attempted to run sub-graph `{0}`, but it does not exist")] - MissingSubGraph(Cow<'static, str>), - #[error("attempted to pass inputs to sub-graph `{0}`, which has no input slots")] - SubGraphHasNoInputs(Cow<'static, str>), + #[error("attempted to run sub-graph `{0:?}`, but it does not exist")] + MissingSubGraph(InternedRenderSubGraph), + #[error("attempted to pass inputs to sub-graph `{0:?}`, which has no input slots")] + SubGraphHasNoInputs(InternedRenderSubGraph), #[error("sub graph (name: `{graph_name:?}`) could not be run because slot `{slot_name}` at index {slot_index} has no value")] MissingInput { slot_index: usize, slot_name: Cow<'static, str>, - graph_name: Cow<'static, str>, + graph_name: InternedRenderSubGraph, }, #[error("attempted to use the wrong type for input slot")] MismatchedInputSlotType { - graph_name: Cow<'static, str>, + graph_name: InternedRenderSubGraph, slot_index: usize, label: SlotLabel, expected: SlotType, diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 6f2b6b124941c..41aec6a7c8ba8 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -6,11 +6,22 @@ use crate::{ renderer::RenderContext, }; use bevy_ecs::{prelude::World, system::Resource}; -use bevy_utils::HashMap; -use std::{borrow::Cow, fmt::Debug}; +use bevy_utils::{define_label, intern::Interned, HashMap}; +use std::fmt::Debug; use super::{EdgeExistence, InternedRenderLabel, IntoRenderNodeArray}; +pub use bevy_render_macros::RenderSubGraph; + +define_label!( + /// A strongly-typed class of labels used to identify a [`SubGraph`] in a render graph. + RenderSubGraph, + RENDER_SUB_GRAPH_INTERNER +); + +/// A shorthand for `Interned`. +pub type InternedRenderSubGraph = Interned; + /// The render graph configures the modular, parallel and re-usable render logic. /// It is a retained and stateless (nodes themselves may have their own internal state) structure, /// which can not be modified while it is executed by the graph runner. @@ -57,7 +68,7 @@ use super::{EdgeExistence, InternedRenderLabel, IntoRenderNodeArray}; #[derive(Resource, Default)] pub struct RenderGraph { nodes: HashMap, - sub_graphs: HashMap, RenderGraph>, + sub_graphs: HashMap, } /// The label for the input node of a graph. Used to connect other nodes to it. @@ -514,17 +525,17 @@ impl RenderGraph { } /// Returns an iterator over the sub graphs. - pub fn iter_sub_graphs(&self) -> impl Iterator { - self.sub_graphs - .iter() - .map(|(name, graph)| (name.as_ref(), graph)) + pub fn iter_sub_graphs(&self) -> impl Iterator { + self.sub_graphs.iter().map(|(name, graph)| (*name, graph)) } /// Returns an iterator over the sub graphs, that allows modifying each value. - pub fn iter_sub_graphs_mut(&mut self) -> impl Iterator { + pub fn iter_sub_graphs_mut( + &mut self, + ) -> impl Iterator { self.sub_graphs .iter_mut() - .map(|(name, graph)| (name.as_ref(), graph)) + .map(|(name, graph)| (*name, graph)) } /// Returns an iterator over a tuple of the input edges and the corresponding output nodes @@ -557,56 +568,58 @@ impl RenderGraph { .map(move |(edge, input_node)| (edge, self.get_node_state(input_node).unwrap()))) } - /// Adds the `sub_graph` with the `name` to the graph. - /// If the name is already present replaces it instead. - pub fn add_sub_graph(&mut self, name: impl Into>, sub_graph: RenderGraph) { - self.sub_graphs.insert(name.into(), sub_graph); + /// Adds the `sub_graph` with the `label` to the graph. + /// If the label is already present replaces it instead. + pub fn add_sub_graph(&mut self, label: impl RenderSubGraph, sub_graph: RenderGraph) { + self.sub_graphs.insert(label.intern(), sub_graph); } - /// Removes the `sub_graph` with the `name` from the graph. - /// If the name does not exist then nothing happens. - pub fn remove_sub_graph(&mut self, name: impl Into>) { - self.sub_graphs.remove(&name.into()); + /// Removes the `sub_graph` with the `label` from the graph. + /// If the label does not exist then nothing happens. + pub fn remove_sub_graph(&mut self, label: impl RenderSubGraph) { + self.sub_graphs.remove(&label.intern()); } - /// Retrieves the sub graph corresponding to the `name`. - pub fn get_sub_graph(&self, name: impl AsRef) -> Option<&RenderGraph> { - self.sub_graphs.get(name.as_ref()) + /// Retrieves the sub graph corresponding to the `label`. + pub fn get_sub_graph(&self, label: impl RenderSubGraph) -> Option<&RenderGraph> { + self.sub_graphs.get(&label.intern()) } - /// Retrieves the sub graph corresponding to the `name` mutably. - pub fn get_sub_graph_mut(&mut self, name: impl AsRef) -> Option<&mut RenderGraph> { - self.sub_graphs.get_mut(name.as_ref()) + /// Retrieves the sub graph corresponding to the `label` mutably. + pub fn get_sub_graph_mut(&mut self, label: impl RenderSubGraph) -> Option<&mut RenderGraph> { + self.sub_graphs.get_mut(&label.intern()) } - /// Retrieves the sub graph corresponding to the `name`. + /// Retrieves the sub graph corresponding to the `label`. /// /// # Panics /// - /// Panics if any invalid node name is given. + /// Panics if any invalid subgraph label is given. /// /// # See also /// /// - [`get_sub_graph`](Self::get_sub_graph) for a fallible version. - pub fn sub_graph(&self, name: impl AsRef) -> &RenderGraph { + pub fn sub_graph(&self, label: impl RenderSubGraph) -> &RenderGraph { + let label = label.intern(); self.sub_graphs - .get(name.as_ref()) - .unwrap_or_else(|| panic!("Node {} not found in sub_graph", name.as_ref())) + .get(&label) + .unwrap_or_else(|| panic!("Subgraph {label:?} not found")) } - /// Retrieves the sub graph corresponding to the `name` mutably. + /// Retrieves the sub graph corresponding to the `label` mutably. /// /// # Panics /// - /// Panics if any invalid node name is given. + /// Panics if any invalid subgraph label is given. /// /// # See also /// /// - [`get_sub_graph_mut`](Self::get_sub_graph_mut) for a fallible version. - pub fn sub_graph_mut(&mut self, name: impl AsRef) -> &mut RenderGraph { + pub fn sub_graph_mut(&mut self, label: impl RenderSubGraph) -> &mut RenderGraph { + let label = label.intern(); self.sub_graphs - .get_mut(name.as_ref()) - .unwrap_or_else(|| panic!("Node {} not found in sub_graph", name.as_ref())) + .get_mut(&label) + .unwrap_or_else(|| panic!("Subgraph {label:?} not found")) } } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 11edf2e80ba6e..5c8346f1d610a 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -12,13 +12,15 @@ use bevy_ecs::{ pub use bevy_utils::label::DynEq; use bevy_utils::{all_tuples_with_size, define_label, intern::Interned}; use downcast_rs::{impl_downcast, Downcast}; -use std::{borrow::Cow, fmt::Debug}; +use std::fmt::Debug; use thiserror::Error; pub use bevy_render_macros::RenderLabel; +use super::{InternedRenderSubGraph, RenderSubGraph}; + define_label!( - /// A strongly-typed class of labels used to identify an [`Node`] in a render graph. + /// A strongly-typed class of labels used to identify a [`Node`] in a render graph. RenderLabel, RENDER_LABEL_INTERNER ); @@ -304,16 +306,16 @@ impl Node for EmptyNode { } } -/// A [`RenderGraph`](super::RenderGraph) [`Node`] that runs the configured graph name once. +/// A [`RenderGraph`](super::RenderGraph) [`Node`] that runs the configured subgraph once. /// This makes it easier to insert sub-graph runs into a graph. pub struct RunGraphOnViewNode { - graph_name: Cow<'static, str>, + sub_graph: InternedRenderSubGraph, } impl RunGraphOnViewNode { - pub fn new>>(graph_name: T) -> Self { + pub fn new(sub_graph: T) -> Self { Self { - graph_name: graph_name.into(), + sub_graph: sub_graph.intern(), } } } @@ -325,7 +327,7 @@ impl Node for RunGraphOnViewNode { _render_context: &mut RenderContext, _world: &World, ) -> Result<(), NodeRunError> { - graph.run_sub_graph(self.graph_name.clone(), vec![], Some(graph.view_entity()))?; + graph.run_sub_graph(self.sub_graph, vec![], Some(graph.view_entity()))?; Ok(()) } } diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index f76140e1a4695..89c0d260c79c5 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -10,8 +10,8 @@ use thiserror::Error; use crate::{ render_graph::{ - Edge, InternedRenderLabel, NodeRunError, NodeState, RenderGraph, RenderGraphContext, - SlotLabel, SlotType, SlotValue, + Edge, InternedRenderLabel, InternedRenderSubGraph, NodeRunError, NodeState, RenderGraph, + RenderGraphContext, SlotLabel, SlotType, SlotValue, }, renderer::{RenderContext, RenderDevice}, }; @@ -28,11 +28,11 @@ pub enum RenderGraphRunnerError { slot_index: usize, slot_name: Cow<'static, str>, }, - #[error("graph (name: '{graph_name:?}') could not be run because slot '{slot_name}' at index {slot_index} has no value")] + #[error("graph '{sub_graph:?}' could not be run because slot '{slot_name}' at index {slot_index} has no value")] MissingInput { slot_index: usize, slot_name: Cow<'static, str>, - graph_name: Option>, + sub_graph: Option, }, #[error("attempted to use the wrong type for input slot")] MismatchedInputSlotType { @@ -73,7 +73,7 @@ impl RenderGraphRunner { fn run_graph( graph: &RenderGraph, - graph_name: Option>, + sub_graph: Option, render_context: &mut RenderContext, world: &World, inputs: &[SlotValue], @@ -114,7 +114,7 @@ impl RenderGraphRunner { return Err(RenderGraphRunnerError::MissingInput { slot_index: i, slot_name: input_slot.name.clone(), - graph_name, + sub_graph, }); } } @@ -196,11 +196,11 @@ impl RenderGraphRunner { for run_sub_graph in context.finish() { let sub_graph = graph - .get_sub_graph(&run_sub_graph.name) + .get_sub_graph(run_sub_graph.sub_graph) .expect("sub graph exists because it was validated when queued."); Self::run_graph( sub_graph, - Some(run_sub_graph.name), + Some(run_sub_graph.sub_graph), render_context, world, &run_sub_graph.inputs, From c54ba19b1a80d909e39244c0b49297bdfcab1324 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 19 Nov 2023 16:31:39 +0100 Subject: [PATCH 09/20] Use new SubGraphs --- crates/bevy_core_pipeline/src/bloom/mod.rs | 12 +++--- .../src/contrast_adaptive_sharpening/mod.rs | 16 ++++---- .../src/core_2d/camera_2d.rs | 7 +++- crates/bevy_core_pipeline/src/core_2d/mod.rs | 21 +++++------ .../src/core_3d/camera_3d.rs | 4 +- crates/bevy_core_pipeline/src/core_3d/mod.rs | 37 +++++++++---------- crates/bevy_core_pipeline/src/fxaa/mod.rs | 12 +++--- .../bevy_core_pipeline/src/msaa_writeback.rs | 16 +++++--- crates/bevy_core_pipeline/src/taa/mod.rs | 9 +++-- crates/bevy_pbr/src/deferred/mod.rs | 6 +-- crates/bevy_pbr/src/lib.rs | 6 +-- crates/bevy_pbr/src/ssao/mod.rs | 6 +-- crates/bevy_ui/src/render/mod.rs | 33 +++++++---------- examples/shader/post_processing.rs | 16 ++++---- 14 files changed, 101 insertions(+), 100 deletions(-) diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index 08d7da8c86aec..d810e541a932f 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -5,8 +5,8 @@ mod upsampling_pipeline; pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings}; use crate::{ - core_2d::{graph::Labels2d, CORE_2D}, - core_3d::{graph::Labels3d, CORE_3D}, + core_2d::graph::{Labels2d, SubGraph2d}, + core_3d::graph::{Labels3d, SubGraph3d}, }; use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Handle}; @@ -73,9 +73,9 @@ impl Plugin for BloomPlugin { ), ) // Add bloom to the 3d render graph - .add_render_graph_node::>(CORE_3D, Labels3d::Bloom) + .add_render_graph_node::>(SubGraph3d, Labels3d::Bloom) .add_render_graph_edges( - CORE_3D, + SubGraph3d, ( Labels3d::EndMainPass, Labels3d::Bloom, @@ -83,9 +83,9 @@ impl Plugin for BloomPlugin { ), ) // Add bloom to the 2d render graph - .add_render_graph_node::>(CORE_2D, Labels2d::Bloom) + .add_render_graph_node::>(SubGraph2d, Labels2d::Bloom) .add_render_graph_edges( - CORE_2D, + SubGraph2d, (Labels2d::MainPass, Labels2d::Bloom, Labels2d::Tonemapping), ); } diff --git a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs index be71066643cb8..e03aca2ac3e3a 100644 --- a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs +++ b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs @@ -1,6 +1,6 @@ use crate::{ - core_2d::{graph::Labels2d, CORE_2D}, - core_3d::{graph::Labels3d, CORE_3D}, + core_2d::graph::{Labels2d, SubGraph2d}, + core_3d::graph::{Labels3d, SubGraph3d}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }; use bevy_app::prelude::*; @@ -123,14 +123,14 @@ impl Plugin for CASPlugin { { render_app - .add_render_graph_node::(CORE_3D, Labels3d::ContrastAdaptiveSharpening) + .add_render_graph_node::(SubGraph3d, Labels3d::ContrastAdaptiveSharpening) .add_render_graph_edge( - CORE_3D, + SubGraph3d, Labels3d::Tonemapping, Labels3d::ContrastAdaptiveSharpening, ) .add_render_graph_edges( - CORE_3D, + SubGraph3d, ( Labels3d::Fxaa, Labels3d::ContrastAdaptiveSharpening, @@ -140,14 +140,14 @@ impl Plugin for CASPlugin { } { render_app - .add_render_graph_node::(CORE_2D, Labels2d::ConstrastAdaptiveSharpening) + .add_render_graph_node::(SubGraph2d, Labels2d::ConstrastAdaptiveSharpening) .add_render_graph_edge( - CORE_2D, + SubGraph2d, Labels2d::Tonemapping, Labels2d::ConstrastAdaptiveSharpening, ) .add_render_graph_edges( - CORE_2D, + SubGraph2d, ( Labels2d::Fxaa, Labels2d::ConstrastAdaptiveSharpening, diff --git a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs index fcd794029b04f..3e8ea11b6dc9c 100644 --- a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs +++ b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs @@ -1,5 +1,6 @@ use crate::{ clear_color::ClearColorConfig, + core_3d::graph::SubGraph3d, tonemapping::{DebandDither, Tonemapping}, }; use bevy_ecs::prelude::*; @@ -12,6 +13,8 @@ use bevy_render::{ }; use bevy_transform::prelude::{GlobalTransform, Transform}; +use super::graph::SubGraph2d; + #[derive(Component, Default, Reflect, Clone, ExtractComponent)] #[extract_component_filter(With)] #[reflect(Component)] @@ -50,7 +53,7 @@ impl Default for Camera2dBundle { projection.far(), ); Self { - camera_render_graph: CameraRenderGraph::new(crate::core_2d::graph::NAME), + camera_render_graph: CameraRenderGraph::new(SubGraph2d), projection, visible_entities: VisibleEntities::default(), frustum, @@ -88,7 +91,7 @@ impl Camera2dBundle { projection.far(), ); Self { - camera_render_graph: CameraRenderGraph::new(crate::core_2d::graph::NAME), + camera_render_graph: CameraRenderGraph::new(SubGraph3d), projection, visible_entities: VisibleEntities::default(), frustum, diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index f012e2aaa6c5e..3247261afcce2 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -2,9 +2,10 @@ mod camera_2d; mod main_pass_2d_node; pub mod graph { - use bevy_render::render_graph::RenderLabel; + use bevy_render::render_graph::{RenderLabel, RenderSubGraph}; - pub const NAME: &str = "core_2d"; + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderSubGraph)] + pub struct SubGraph2d; pub mod input { pub const VIEW_ENTITY: &str = "view_entity"; @@ -23,8 +24,6 @@ pub mod graph { } } -pub const CORE_2D: &str = graph::NAME; - use std::ops::Range; pub use camera_2d::*; @@ -47,7 +46,7 @@ use bevy_utils::{nonmax::NonMaxU32, FloatOrd}; use crate::{tonemapping::TonemappingNode, upscaling::UpscalingNode}; -use self::graph::Labels2d; +use self::graph::{Labels2d, SubGraph2d}; pub struct Core2dPlugin; @@ -70,16 +69,16 @@ impl Plugin for Core2dPlugin { ); render_app - .add_render_sub_graph(CORE_2D) - .add_render_graph_node::(CORE_2D, Labels2d::MainPass) + .add_render_sub_graph(SubGraph2d) + .add_render_graph_node::(SubGraph2d, Labels2d::MainPass) .add_render_graph_node::>( - CORE_2D, + SubGraph2d, Labels2d::Tonemapping, ) - .add_render_graph_node::(CORE_2D, Labels2d::EndMainPassPostProcessing) - .add_render_graph_node::>(CORE_2D, Labels2d::Upscaling) + .add_render_graph_node::(SubGraph2d, Labels2d::EndMainPassPostProcessing) + .add_render_graph_node::>(SubGraph2d, Labels2d::Upscaling) .add_render_graph_edges( - CORE_2D, + SubGraph2d, ( Labels2d::MainPass, Labels2d::Tonemapping, diff --git a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs index 33579994c9aca..5fa52b52d7ffc 100644 --- a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs +++ b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs @@ -14,6 +14,8 @@ use bevy_render::{ use bevy_transform::prelude::{GlobalTransform, Transform}; use serde::{Deserialize, Serialize}; +use super::graph::SubGraph3d; + /// Configuration for the "main 3d render graph". #[derive(Component, Reflect, Clone, ExtractComponent)] #[extract_component_filter(With)] @@ -154,7 +156,7 @@ pub struct Camera3dBundle { impl Default for Camera3dBundle { fn default() -> Self { Self { - camera_render_graph: CameraRenderGraph::new(crate::core_3d::graph::NAME), + camera_render_graph: CameraRenderGraph::new(SubGraph3d), camera: Default::default(), projection: Default::default(), visible_entities: Default::default(), diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index f890a82646b7b..e8a6070f7aa2b 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -4,9 +4,10 @@ mod main_transmissive_pass_3d_node; mod main_transparent_pass_3d_node; pub mod graph { - use bevy_render::render_graph::RenderLabel; + use bevy_render::render_graph::{RenderLabel, RenderSubGraph}; - pub const NAME: &str = "core_3d"; + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderSubGraph)] + pub struct SubGraph3d; pub mod input { pub const VIEW_ENTITY: &str = "view_entity"; @@ -34,8 +35,6 @@ pub mod graph { } } -pub const CORE_3D: &str = graph::NAME; - // PERF: vulkan docs recommend using 24 bit depth for better performance pub const CORE_3D_DEPTH_FORMAT: TextureFormat = TextureFormat::Depth32Float; @@ -84,7 +83,7 @@ use crate::{ upscaling::UpscalingNode, }; -use self::graph::Labels3d; +use self::graph::{Labels3d, SubGraph3d}; pub struct Core3dPlugin; @@ -129,39 +128,39 @@ impl Plugin for Core3dPlugin { ); render_app - .add_render_sub_graph(CORE_3D) - .add_render_graph_node::>(CORE_3D, Labels3d::Prepass) + .add_render_sub_graph(SubGraph3d) + .add_render_graph_node::>(SubGraph3d, Labels3d::Prepass) .add_render_graph_node::>( - CORE_3D, + SubGraph3d, Labels3d::DeferredPrepass, ) .add_render_graph_node::>( - CORE_3D, + SubGraph3d, Labels3d::CopyDeferredLightingId, ) - .add_render_graph_node::(CORE_3D, Labels3d::EndPrepasses) - .add_render_graph_node::(CORE_3D, Labels3d::StartMainPass) + .add_render_graph_node::(SubGraph3d, Labels3d::EndPrepasses) + .add_render_graph_node::(SubGraph3d, Labels3d::StartMainPass) .add_render_graph_node::>( - CORE_3D, + SubGraph3d, Labels3d::MainOpaquePass, ) .add_render_graph_node::>( - CORE_3D, + SubGraph3d, Labels3d::MainTransmissivePass, ) .add_render_graph_node::>( - CORE_3D, + SubGraph3d, Labels3d::MainTransparentPass, ) - .add_render_graph_node::(CORE_3D, Labels3d::EndMainPass) + .add_render_graph_node::(SubGraph3d, Labels3d::EndMainPass) .add_render_graph_node::>( - CORE_3D, + SubGraph3d, Labels3d::Tonemapping, ) - .add_render_graph_node::(CORE_3D, Labels3d::EndMainPassPostProcessing) - .add_render_graph_node::>(CORE_3D, Labels3d::Upscaling) + .add_render_graph_node::(SubGraph3d, Labels3d::EndMainPassPostProcessing) + .add_render_graph_node::>(SubGraph3d, Labels3d::Upscaling) .add_render_graph_edges( - CORE_3D, + SubGraph3d, ( Labels3d::Prepass, Labels3d::DeferredPrepass, diff --git a/crates/bevy_core_pipeline/src/fxaa/mod.rs b/crates/bevy_core_pipeline/src/fxaa/mod.rs index bfb6fa42b5cd2..2ed3094df1ad6 100644 --- a/crates/bevy_core_pipeline/src/fxaa/mod.rs +++ b/crates/bevy_core_pipeline/src/fxaa/mod.rs @@ -1,6 +1,6 @@ use crate::{ - core_2d::{graph::Labels2d, CORE_2D}, - core_3d::{ graph::Labels3d, CORE_3D}, + core_2d::graph::{Labels2d, SubGraph2d}, + core_3d::graph::{Labels3d, SubGraph3d}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }; use bevy_app::prelude::*; @@ -93,18 +93,18 @@ impl Plugin for FxaaPlugin { render_app .init_resource::>() .add_systems(Render, prepare_fxaa_pipelines.in_set(RenderSet::Prepare)) - .add_render_graph_node::>(CORE_3D, Labels3d::Fxaa) + .add_render_graph_node::>(SubGraph3d, Labels3d::Fxaa) .add_render_graph_edges( - CORE_3D, + SubGraph3d, ( Labels3d::Tonemapping, Labels3d::Fxaa, Labels3d::EndMainPassPostProcessing, ), ) - .add_render_graph_node::>(CORE_2D, Labels2d::Fxaa) + .add_render_graph_node::>(SubGraph2d, Labels2d::Fxaa) .add_render_graph_edges( - CORE_2D, + SubGraph2d, ( Labels2d::Tonemapping, Labels2d::Fxaa, diff --git a/crates/bevy_core_pipeline/src/msaa_writeback.rs b/crates/bevy_core_pipeline/src/msaa_writeback.rs index de895ed1987fb..fa193da73da04 100644 --- a/crates/bevy_core_pipeline/src/msaa_writeback.rs +++ b/crates/bevy_core_pipeline/src/msaa_writeback.rs @@ -1,7 +1,7 @@ use crate::{ blit::{BlitPipeline, BlitPipelineKey}, - core_2d::{graph::Labels2d, CORE_2D}, - core_3d::{graph::Labels3d, CORE_3D}, + core_2d::graph::{Labels2d, SubGraph2d}, + core_3d::graph::{Labels3d, SubGraph3d}, }; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; @@ -31,13 +31,17 @@ impl Plugin for MsaaWritebackPlugin { ); { render_app - .add_render_graph_node::(CORE_2D, Labels2d::MsaaWriteback) - .add_render_graph_edge(CORE_2D, Labels2d::MsaaWriteback, Labels2d::MainPass); + .add_render_graph_node::(SubGraph2d, Labels2d::MsaaWriteback) + .add_render_graph_edge(SubGraph2d, Labels2d::MsaaWriteback, Labels2d::MainPass); } { render_app - .add_render_graph_node::(CORE_3D, Labels3d::MsaaWriteback) - .add_render_graph_edge(CORE_3D, Labels3d::MsaaWriteback, Labels3d::StartMainPass); + .add_render_graph_node::(SubGraph3d, Labels3d::MsaaWriteback) + .add_render_graph_edge( + SubGraph3d, + Labels3d::MsaaWriteback, + Labels3d::StartMainPass, + ); } } } diff --git a/crates/bevy_core_pipeline/src/taa/mod.rs b/crates/bevy_core_pipeline/src/taa/mod.rs index 5bac68a1b3a37..7ed478b947fdb 100644 --- a/crates/bevy_core_pipeline/src/taa/mod.rs +++ b/crates/bevy_core_pipeline/src/taa/mod.rs @@ -1,5 +1,5 @@ use crate::{ - core_3d::{graph::Labels3d, CORE_3D}, + core_3d::graph::{Labels3d, SubGraph3d}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, prelude::Camera3d, prepass::{DepthPrepass, MotionVectorPrepass, ViewPrepassTextures}, @@ -64,9 +64,12 @@ impl Plugin for TemporalAntiAliasPlugin { prepare_taa_history_textures.in_set(RenderSet::PrepareResources), ), ) - .add_render_graph_node::>(CORE_3D, Labels3d::Taa) + .add_render_graph_node::>( + SubGraph3d, + Labels3d::Taa, + ) .add_render_graph_edges( - CORE_3D, + SubGraph3d, ( Labels3d::EndMainPass, Labels3d::Taa, diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index e9010f11e7318..1c107c7d2ba43 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -3,7 +3,7 @@ use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, Handle}; use bevy_core_pipeline::{ clear_color::ClearColorConfig, - core_3d::{self, graph::Labels3d}, + core_3d::graph::{Labels3d, SubGraph3d}, deferred::{ copy_lighting_id::DeferredLightingIdDepthTexture, DEFERRED_LIGHTING_PASS_ID_DEPTH_FORMAT, }, @@ -120,11 +120,11 @@ impl Plugin for DeferredPbrLightingPlugin { (prepare_deferred_lighting_pipelines.in_set(RenderSet::Prepare),), ) .add_render_graph_node::>( - core_3d::graph::NAME, + SubGraph3d, DeferredLightingPass3dNode, ) .add_render_graph_edges( - core_3d::graph::NAME, + SubGraph3d, ( Labels3d::StartMainPass, DeferredLightingPass3dNode, diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 46296a787da31..a3a71a3d9ceb7 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -17,7 +17,7 @@ mod render; mod ssao; pub use alpha::*; -use bevy_core_pipeline::core_3d::graph::Labels3d; +use bevy_core_pipeline::core_3d::graph::{Labels3d, SubGraph3d}; pub use bundle::*; pub use environment_map::EnvironmentMapLight; pub use extended_material::*; @@ -362,9 +362,7 @@ impl Plugin for PbrPlugin { let shadow_pass_node = ShadowPassNode::new(&mut render_app.world); let mut graph = render_app.world.resource_mut::(); - let draw_3d_graph = graph - .get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME) - .unwrap(); + let draw_3d_graph = graph.get_sub_graph_mut(SubGraph3d).unwrap(); draw_3d_graph.add_node(LabelsPbr::ShadowPass, shadow_pass_node); draw_3d_graph.add_node_edge(LabelsPbr::ShadowPass, Labels3d::StartMainPass); } diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index dc40b835beffb..d46fc3181b40f 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -1,7 +1,7 @@ use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Handle}; use bevy_core_pipeline::{ - core_3d::{graph::Labels3d, CORE_3D}, + core_3d::graph::{Labels3d, SubGraph3d}, prelude::Camera3d, prepass::{DepthPrepass, NormalPrepass, ViewPrepassTextures}, }; @@ -107,11 +107,11 @@ impl Plugin for ScreenSpaceAmbientOcclusionPlugin { ), ) .add_render_graph_node::>( - CORE_3D, + SubGraph3d, LabelsPbr::ScreenSpaceAmbientOcclusion, ) .add_render_graph_edges( - CORE_3D, + SubGraph3d, ( // END_PRE_PASSES -> SCREEN_SPACE_AMBIENT_OCCLUSION -> MAIN_PASS Labels3d::EndPrepasses, diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 904a286bbc423..4bcce993d2cb6 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -2,8 +2,8 @@ mod pipeline; mod render_pass; mod ui_material_pipeline; -use bevy_core_pipeline::core_2d::graph::Labels2d; -use bevy_core_pipeline::core_3d::graph::Labels3d; +use bevy_core_pipeline::core_2d::graph::{Labels2d, SubGraph2d}; +use bevy_core_pipeline::core_3d::graph::{Labels3d, SubGraph3d}; use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; use bevy_hierarchy::Parent; use bevy_render::render_phase::PhaseItem; @@ -14,7 +14,7 @@ pub use pipeline::*; pub use render_pass::*; pub use ui_material_pipeline::*; -use crate::graph::LabelsUi; +use crate::graph::{LabelsUi, SubGraphUi}; use crate::Outline; use crate::{ prelude::UiCameraConfig, BackgroundColor, BorderColor, CalculatedClip, ContentSize, Node, @@ -46,12 +46,11 @@ use bevy_utils::{EntityHashMap, FloatOrd, HashMap}; use bytemuck::{Pod, Zeroable}; use std::ops::Range; -pub mod draw_ui_graph { - pub const NAME: &str = "draw_ui"; -} - pub mod graph { - use bevy_render::render_graph::RenderLabel; + use bevy_render::render_graph::{RenderLabel, RenderSubGraph}; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderSubGraph)] + pub struct SubGraphUi; #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] pub enum LabelsUi { @@ -111,23 +110,17 @@ pub fn build_ui_render(app: &mut App) { let ui_graph_3d = get_ui_graph(render_app); let mut graph = render_app.world.resource_mut::(); - if let Some(graph_2d) = graph.get_sub_graph_mut(bevy_core_pipeline::core_2d::graph::NAME) { - graph_2d.add_sub_graph(draw_ui_graph::NAME, ui_graph_2d); - graph_2d.add_node( - LabelsUi::UiPass, - RunGraphOnViewNode::new(draw_ui_graph::NAME), - ); + if let Some(graph_2d) = graph.get_sub_graph_mut(SubGraph2d) { + graph_2d.add_sub_graph(SubGraphUi, ui_graph_2d); + graph_2d.add_node(LabelsUi::UiPass, RunGraphOnViewNode::new(SubGraphUi)); graph_2d.add_node_edge(Labels2d::MainPass, LabelsUi::UiPass); graph_2d.add_node_edge(Labels2d::EndMainPassPostProcessing, LabelsUi::UiPass); graph_2d.add_node_edge(LabelsUi::UiPass, Labels2d::Upscaling); } - if let Some(graph_3d) = graph.get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME) { - graph_3d.add_sub_graph(draw_ui_graph::NAME, ui_graph_3d); - graph_3d.add_node( - LabelsUi::UiPass, - RunGraphOnViewNode::new(draw_ui_graph::NAME), - ); + if let Some(graph_3d) = graph.get_sub_graph_mut(SubGraph3d) { + graph_3d.add_sub_graph(SubGraphUi, ui_graph_3d); + graph_3d.add_node(LabelsUi::UiPass, RunGraphOnViewNode::new(SubGraphUi)); graph_3d.add_node_edge(Labels3d::EndMainPass, LabelsUi::UiPass); graph_3d.add_node_edge(Labels3d::EndMainPassPostProcessing, LabelsUi::UiPass); graph_3d.add_node_edge(LabelsUi::UiPass, Labels3d::Upscaling); diff --git a/examples/shader/post_processing.rs b/examples/shader/post_processing.rs index 15b6ffeff33c5..f586de5ba84dc 100644 --- a/examples/shader/post_processing.rs +++ b/examples/shader/post_processing.rs @@ -7,8 +7,7 @@ use bevy::{ core_pipeline::{ - clear_color::ClearColorConfig, - core_3d::{self, graph::Labels3d}, + clear_color::ClearColorConfig, core_3d::graph::Labels3d, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }, ecs::query::QueryItem, @@ -34,6 +33,7 @@ use bevy::{ RenderApp, }, }; +use bevy_internal::core_pipeline::core_3d::graph::SubGraph3d; fn main() { App::new() @@ -43,9 +43,6 @@ fn main() { .run(); } -#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] -pub struct PostProcessLabel; - /// It is generally encouraged to set up post processing effects as a plugin struct PostProcessPlugin; @@ -85,13 +82,13 @@ impl Plugin for PostProcessPlugin { // The [`ViewNodeRunner`] is a special [`Node`] that will automatically run the node for each view // matching the [`ViewQuery`] .add_render_graph_node::>( - // Specify the name of the graph, in this case we want the graph for 3d - core_3d::graph::NAME, + // Specify the label of the graph, in this case we want the graph for 3d + SubGraph3d, // It also needs the label of the node PostProcessLabel, ) .add_render_graph_edges( - core_3d::graph::NAME, + SubGraph3d, // Specify the node ordering. // This will automatically create all required node edges to enforce the given ordering. ( @@ -114,6 +111,9 @@ impl Plugin for PostProcessPlugin { } } +#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] +pub struct PostProcessLabel; + // The post process node used for the render graph #[derive(Default)] struct PostProcessNode; From 6eadbb44e34579b465808049d31f2cc7a4985b2c Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 19 Nov 2023 17:11:45 +0100 Subject: [PATCH 10/20] Tracing now happy? --- crates/bevy_render/src/renderer/graph_runner.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index 89c0d260c79c5..72f6382e95730 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -3,8 +3,6 @@ use bevy_ecs::{prelude::Entity, world::World}; use bevy_utils::tracing::info_span; use bevy_utils::HashMap; use smallvec::{smallvec, SmallVec}; -#[cfg(feature = "trace")] -use std::ops::Deref; use std::{borrow::Cow, collections::VecDeque}; use thiserror::Error; @@ -82,8 +80,8 @@ impl RenderGraphRunner { let mut node_outputs: HashMap> = HashMap::default(); #[cfg(feature = "trace")] - let span = if let Some(name) = &graph_name { - info_span!("run_graph", name = name.deref()) + let span = if let Some(label) = &sub_graph { + info_span!("run_graph", name = format!("{label:?}")) } else { info_span!("run_graph", name = "main_graph") }; From 5f212bf94e6a90df2da5e304e93b8bbb08a589ed Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 19 Nov 2023 17:15:37 +0100 Subject: [PATCH 11/20] Fix `bevy_internal` use in example --- examples/shader/post_processing.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/shader/post_processing.rs b/examples/shader/post_processing.rs index f586de5ba84dc..bfe69de8c7537 100644 --- a/examples/shader/post_processing.rs +++ b/examples/shader/post_processing.rs @@ -7,7 +7,8 @@ use bevy::{ core_pipeline::{ - clear_color::ClearColorConfig, core_3d::graph::Labels3d, + clear_color::ClearColorConfig, + core_3d::graph::{Labels3d, SubGraph3d}, fullscreen_vertex_shader::fullscreen_shader_vertex_state, }, ecs::query::QueryItem, @@ -33,7 +34,6 @@ use bevy::{ RenderApp, }, }; -use bevy_internal::core_pipeline::core_3d::graph::SubGraph3d; fn main() { App::new() From 0f0ca1348c1fab9aaf90b1a87f752c4cabd92f0d Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 19 Nov 2023 17:17:41 +0100 Subject: [PATCH 12/20] make clippy happy --- crates/bevy_render/src/camera/camera.rs | 2 +- crates/bevy_render/src/camera/camera_driver_node.rs | 6 +----- crates/bevy_render/src/render_graph/context.rs | 2 +- crates/bevy_render/src/render_graph/graph.rs | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 2793b53dc26ec..ed73506601a6a 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -693,7 +693,7 @@ pub fn extract_cameras( viewport: camera.viewport.clone(), physical_viewport_size: Some(viewport_size), physical_target_size: Some(target_size), - render_graph: camera_render_graph.0.clone(), + render_graph: camera_render_graph.0, order: camera.order, output_mode: camera.output_mode, msaa_writeback: camera.msaa_writeback, diff --git a/crates/bevy_render/src/camera/camera_driver_node.rs b/crates/bevy_render/src/camera/camera_driver_node.rs index 38ba4ac185749..9332d7d14662a 100644 --- a/crates/bevy_render/src/camera/camera_driver_node.rs +++ b/crates/bevy_render/src/camera/camera_driver_node.rs @@ -49,11 +49,7 @@ impl Node for CameraDriverNode { } } if run_graph { - graph.run_sub_graph( - camera.render_graph.clone(), - vec![], - Some(sorted_camera.entity), - )?; + graph.run_sub_graph(camera.render_graph, vec![], Some(sorted_camera.entity))?; } } diff --git a/crates/bevy_render/src/render_graph/context.rs b/crates/bevy_render/src/render_graph/context.rs index 54c4d2024ad8b..e62917465d6b5 100644 --- a/crates/bevy_render/src/render_graph/context.rs +++ b/crates/bevy_render/src/render_graph/context.rs @@ -190,7 +190,7 @@ impl<'a> RenderGraphContext<'a> { let sub_graph = self .graph .get_sub_graph(name) - .ok_or_else(|| RunSubGraphError::MissingSubGraph(name))?; + .ok_or(RunSubGraphError::MissingSubGraph(name))?; if let Some(input_node) = sub_graph.get_input_node() { for (i, input_slot) in input_node.input_slots.iter().enumerate() { if let Some(input_value) = inputs.get(i) { diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 41aec6a7c8ba8..45d029c47fa50 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -97,7 +97,7 @@ impl RenderGraph { "Graph already has an input node" ); - self.add_node(GraphInput, GraphInputNode { inputs }) + self.add_node(GraphInput, GraphInputNode { inputs }); } /// Returns the [`NodeState`] of the input node of this graph. From 7aac98df2839d1ea7e04d6fcfdbba1f2b1334ea7 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 19 Nov 2023 19:26:30 +0100 Subject: [PATCH 13/20] Need to ignore --- crates/bevy_render/src/render_graph/graph.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 45d029c47fa50..b7e6bbd44b5a8 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -40,7 +40,8 @@ pub type InternedRenderSubGraph = Interned; /// /// ## Example /// Here is a simple render graph example with two nodes connected by a node edge. -/// ``` +/// ```ignore +/// # TODO: Remove when #10645 is fixed /// # use bevy_app::prelude::*; /// # use bevy_ecs::prelude::World; /// # use bevy_render::render_graph::{RenderGraph, RenderLabel, Node, RenderGraphContext, NodeRunError}; From c6cd0940874330d8a3379424d8c77617c4f748d1 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Sun, 19 Nov 2023 19:52:48 +0100 Subject: [PATCH 14/20] Fix links --- crates/bevy_render/src/render_graph/graph.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index b7e6bbd44b5a8..9f94676917665 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -239,7 +239,7 @@ impl RenderGraph { /// Adds the [`Edge::SlotEdge`] to the graph. This guarantees that the `output_node` /// is run before the `input_node` and also connects the `output_slot` to the `input_slot`. /// - /// Fails if any invalid [`RenderNode`]s or [`SlotLabel`]s are given. + /// Fails if any invalid [`RenderLabel`]s or [`SlotLabel`]s are given. /// /// # See also /// @@ -292,7 +292,7 @@ impl RenderGraph { /// /// # Panics /// - /// Any invalid [`RenderNode`]s or [`SlotLabel`]s are given. + /// Any invalid [`RenderLabel`]s or [`SlotLabel`]s are given. /// /// # See also /// @@ -356,7 +356,7 @@ impl RenderGraph { /// Adds the [`Edge::NodeEdge`] to the graph. This guarantees that the `output_node` /// is run before the `input_node`. /// - /// Fails if any invalid [`RenderNode`] is given. + /// Fails if any invalid [`RenderLabel`] is given. /// /// # See also /// @@ -391,7 +391,7 @@ impl RenderGraph { /// /// # Panics /// - /// Panics if any invalid [`RenderNode`] is given. + /// Panics if any invalid [`RenderLabel`] is given. /// /// # See also /// From 3c861d3bd1b1c348effc8d154c30ad2425795537 Mon Sep 17 00:00:00 2001 From: DasLixou Date: Mon, 20 Nov 2023 15:55:39 +0100 Subject: [PATCH 15/20] Mvoe `DeferredLightingPass` to `LabelsPbr` --- crates/bevy_pbr/src/deferred/mod.rs | 13 ++++++------- crates/bevy_pbr/src/lib.rs | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index 1c107c7d2ba43..bd31d1f8b99cf 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -1,4 +1,6 @@ -use crate::{MeshPipeline, MeshViewBindGroup, ScreenSpaceAmbientOcclusionSettings}; +use crate::{ + graph::LabelsPbr, MeshPipeline, MeshViewBindGroup, ScreenSpaceAmbientOcclusionSettings, +}; use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, Handle}; use bevy_core_pipeline::{ @@ -17,7 +19,7 @@ use bevy_render::{ ComponentUniforms, ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin, }, render_asset::RenderAssets, - render_graph::{NodeRunError, RenderGraphContext, RenderLabel, ViewNode, ViewNodeRunner}, + render_graph::{NodeRunError, RenderGraphContext, ViewNode, ViewNodeRunner}, render_resource::{self, Operations, PipelineCache, RenderPassDescriptor}, renderer::{RenderContext, RenderDevice}, texture::Image, @@ -121,13 +123,13 @@ impl Plugin for DeferredPbrLightingPlugin { ) .add_render_graph_node::>( SubGraph3d, - DeferredLightingPass3dNode, + LabelsPbr::DeferredLightingPass, ) .add_render_graph_edges( SubGraph3d, ( Labels3d::StartMainPass, - DeferredLightingPass3dNode, + LabelsPbr::DeferredLightingPass, Labels3d::MainOpaquePass, ), ); @@ -142,9 +144,6 @@ impl Plugin for DeferredPbrLightingPlugin { } } -#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] -pub struct DeferredLightingPass3dNode; - #[derive(Default)] pub struct DeferredOpaquePass3dPbrLightingNode; diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index a3a71a3d9ceb7..de60ba5b50e22 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -57,6 +57,7 @@ pub mod graph { ShadowPass, /// Label for the screen space ambient occlusion render node. ScreenSpaceAmbientOcclusion, + DeferredLightingPass, } } From 6b6f70ce6aa539e5bdce7f3571e7eafbe95ff023 Mon Sep 17 00:00:00 2001 From: Lixou <82600264+DasLixou@users.noreply.github.com> Date: Wed, 22 Nov 2023 19:03:07 +0100 Subject: [PATCH 16/20] Sort `Labels3d::Taa` right --- crates/bevy_core_pipeline/src/core_3d/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index e8a6070f7aa2b..a9f243967ede7 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -25,10 +25,10 @@ pub mod graph { MainTransmissivePass, MainTransparentPass, EndMainPass, + Taa, Bloom, Tonemapping, Fxaa, - Taa, Upscaling, ContrastAdaptiveSharpening, EndMainPassPostProcessing, From ea40c4171d67bbb5b05a7f5c9148e0bcb56cd4fd Mon Sep 17 00:00:00 2001 From: Lixou <82600264+DasLixou@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:57:02 +0100 Subject: [PATCH 17/20] Update mod.rs --- crates/bevy_pbr/src/deferred/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index 16b088feb225c..67aed41b6a80c 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -1,5 +1,5 @@ use crate::{ - graph::LabelsPbr, environment_map::RenderViewEnvironmentMaps, MeshPipeline, MeshViewBindGroup, + environment_map::RenderViewEnvironmentMaps, graph::LabelsPbr, MeshPipeline, MeshViewBindGroup, ScreenSpaceAmbientOcclusionSettings, ViewLightProbesUniformOffset, }; use bevy_app::prelude::*; From 08cdfacf9cf452d9235857123c2ccec2246d723f Mon Sep 17 00:00:00 2001 From: Lixou <82600264+DasLixou@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:57:43 +0100 Subject: [PATCH 18/20] Update lib.rs --- crates/bevy_pbr/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 341927f18e9cc..c1556c8d360d1 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -363,7 +363,7 @@ impl Plugin for PbrPlugin { let draw_3d_graph = graph.get_sub_graph_mut(SubGraph3d).unwrap(); draw_3d_graph.add_node(LabelsPbr::ShadowPass, shadow_pass_node); draw_3d_graph.add_node_edge(LabelsPbr::ShadowPass, Labels3d::StartMainPass); - + render_app.ignore_ambiguity( bevy_render::Render, bevy_core_pipeline::core_3d::prepare_core_3d_transmission_textures, From ab87bdb4c53cc50f8bea987881670a1e58ed6740 Mon Sep 17 00:00:00 2001 From: Lixou <82600264+DasLixou@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:58:27 +0100 Subject: [PATCH 19/20] Update camera.rs --- crates/bevy_render/src/camera/camera.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index fe6d098eba8f8..a2fff3edf0468 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -32,7 +32,7 @@ use bevy_window::{ NormalizedWindowRef, PrimaryWindow, Window, WindowCreated, WindowRef, WindowResized, WindowScaleFactorChanged, }; -use std::{borrow::Cow, ops::Range}; +use std::ops::Range; use wgpu::{BlendState, LoadOp, TextureFormat, TextureUsages}; use super::{ClearColorConfig, Projection}; From f9824d78219f220bd55fae962eb28afb6a3229e4 Mon Sep 17 00:00:00 2001 From: Lixou <82600264+DasLixou@users.noreply.github.com> Date: Wed, 24 Jan 2024 22:02:27 +0100 Subject: [PATCH 20/20] Update graph_runner.rs --- crates/bevy_render/src/renderer/graph_runner.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index a84d5dd89148c..49319127bd96b 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -6,8 +6,6 @@ use bevy_utils::{ HashMap, }; -#[cfg(feature = "trace")] -use std::ops::Deref; use std::{borrow::Cow, collections::VecDeque}; use thiserror::Error;