render: create a node for sub render graphs, create a graph init node
This commit is contained in:
parent
9d3de88c50
commit
f755a4c53b
|
@ -123,6 +123,7 @@ pub struct RenderGraph {
|
|||
queue: Rc<wgpu::Queue>,
|
||||
slots: FxHashMap<RenderGraphLabelValue, ResourcedSlot>,
|
||||
nodes: FxHashMap<RenderGraphLabelValue, PassEntry>,
|
||||
sub_graphs: FxHashMap<RenderGraphLabelValue, RenderGraph>,
|
||||
bind_groups: FxHashMap<RenderGraphLabelValue, BindGroupEntry>,
|
||||
/// A directed graph used to determine dependencies of nodes.
|
||||
node_graph: petgraph::matrix_graph::DiMatrix<RenderGraphLabelValue, (), Option<()>, usize>,
|
||||
|
@ -135,6 +136,7 @@ impl RenderGraph {
|
|||
queue,
|
||||
slots: Default::default(),
|
||||
nodes: Default::default(),
|
||||
sub_graphs: Default::default(),
|
||||
bind_groups: Default::default(),
|
||||
node_graph: Default::default(),
|
||||
}
|
||||
|
@ -261,16 +263,27 @@ impl RenderGraph {
|
|||
|
||||
#[instrument(skip(self, world))]
|
||||
pub fn prepare(&mut self, world: &mut World) {
|
||||
// prepare all passes
|
||||
let mut buffer_writes = VecDeque::<GraphBufferWrite>::new();
|
||||
// reserve some buffer writes. not all nodes write so half the amount of them is probably
|
||||
// fine.
|
||||
buffer_writes.reserve(self.nodes.len() / 2);
|
||||
|
||||
for (label, pass) in &mut self.nodes {
|
||||
let mut context = RenderGraphContext::new(&self.device, &self.queue, None, label.clone());
|
||||
let mut inner = pass.inner.borrow_mut();
|
||||
inner.prepare(world, &mut context);
|
||||
let mut sorted: VecDeque<RenderGraphLabelValue> = petgraph::algo::toposort(&self.node_graph, None)
|
||||
.expect("RenderGraph had cycled!")
|
||||
.iter()
|
||||
.map(|i| self.node_graph[i.clone()].clone())
|
||||
.collect();
|
||||
|
||||
while let Some(pass_label) = sorted.pop_front() {
|
||||
let pass = self.nodes.get(&pass_label).unwrap();
|
||||
let device = self.device.clone();
|
||||
let queue = self.queue.clone();
|
||||
|
||||
let inner = pass.inner.clone();
|
||||
let mut inner = inner.borrow_mut();
|
||||
|
||||
let mut context = RenderGraphContext::new(&device, &queue, None, pass_label.clone());
|
||||
inner.prepare(self, world, &mut context);
|
||||
buffer_writes.append(&mut context.buffer_writes);
|
||||
}
|
||||
|
||||
|
@ -465,24 +478,33 @@ impl RenderGraph {
|
|||
pass.set_bind_group(*index, bg, &[]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub_graph_mut<L: Into<RenderGraphLabelValue>>(&mut self, label: L) -> Option<&mut RenderGraph> {
|
||||
self.sub_graphs.get_mut(&label.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for RenderGraph {
|
||||
pub struct SubGraphNode(RenderGraphLabelValue);
|
||||
|
||||
impl Node for SubGraphNode {
|
||||
fn desc<'a, 'b>(&'a mut self, _: &'b mut RenderGraph) -> NodeDesc {
|
||||
// TODO: how would bind groups be shared between sub-graphs?
|
||||
NodeDesc::new(NodeType::Graph, None, vec![])
|
||||
}
|
||||
|
||||
fn prepare(&mut self, world: &mut World, _: &mut RenderGraphContext) {
|
||||
self.prepare(world);
|
||||
fn prepare(&mut self, graph: &mut RenderGraph, world: &mut World, _: &mut RenderGraphContext) {
|
||||
let sg = graph.sub_graph_mut(self.0.clone())
|
||||
.unwrap_or_else(|| panic!("failed to find sub graph for SubGraphNode: {:?}", self.0));
|
||||
sg.prepare(world);
|
||||
}
|
||||
|
||||
fn execute(
|
||||
&mut self,
|
||||
_: &mut RenderGraph,
|
||||
graph: &mut RenderGraph,
|
||||
_: &NodeDesc,
|
||||
_: &mut RenderGraphContext,
|
||||
) {
|
||||
self.render();
|
||||
let sg = graph.sub_graph_mut(self.0.clone())
|
||||
.unwrap_or_else(|| panic!("failed to find sub graph for SubGraphNode: {:?}", self.0));
|
||||
sg.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -351,7 +351,7 @@ pub trait Node: 'static {
|
|||
///
|
||||
/// This phase runs before `execute` and is meant to be used to collect data from the World
|
||||
/// and write to GPU buffers.
|
||||
fn prepare(&mut self, world: &mut World, context: &mut RenderGraphContext);
|
||||
fn prepare(&mut self, graph: &mut RenderGraph, world: &mut World, context: &mut RenderGraphContext);
|
||||
|
||||
/// Execute the node.
|
||||
///
|
||||
|
|
|
@ -9,8 +9,7 @@ use crate::{
|
|||
render::{
|
||||
camera::{CameraUniform, RenderCamera},
|
||||
graph::{
|
||||
RenderGraphContext, Node, NodeDesc, NodeSlot,
|
||||
NodeType, RenderTarget, SlotAttribute, SlotType, SlotValue,
|
||||
Node, NodeDesc, NodeSlot, NodeType, RenderGraph, RenderGraphContext, RenderTarget, SlotAttribute, SlotType, SlotValue
|
||||
},
|
||||
render_buffer::BufferWrapper, texture::RenderTexture,
|
||||
},
|
||||
|
@ -147,7 +146,7 @@ impl Node for BasePass {
|
|||
desc
|
||||
}
|
||||
|
||||
fn prepare(&mut self, world: &mut lyra_ecs::World, context: &mut RenderGraphContext) {
|
||||
fn prepare(&mut self, _graph: &mut RenderGraph, world: &mut lyra_ecs::World, context: &mut RenderGraphContext) {
|
||||
if let Some(camera) = world.view_iter::<&mut CameraComponent>().next() {
|
||||
let mut render_cam =
|
||||
RenderCamera::new(PhysicalSize::new(self.screen_size.x, self.screen_size.y));
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
use lyra_game_derive::RenderGraphLabel;
|
||||
|
||||
use crate::render::graph::{Node, NodeDesc, NodeSlot, NodeType};
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Hash, RenderGraphLabel)]
|
||||
pub struct InitNodeLabel;
|
||||
|
||||
pub struct InitNode {
|
||||
slots: Vec<NodeSlot>,
|
||||
}
|
||||
|
||||
impl Node for InitNode {
|
||||
fn desc<'a, 'b>(&'a mut self, _: &'b mut crate::render::graph::RenderGraph) -> crate::render::graph::NodeDesc {
|
||||
let mut desc = NodeDesc::new(NodeType::Node, None, vec![]);
|
||||
// the slots can just be cloned since the slot attribute doesn't really matter much.
|
||||
desc.slots = self.slots.clone();
|
||||
|
||||
desc
|
||||
}
|
||||
|
||||
fn prepare(&mut self, _: &mut crate::render::graph::RenderGraph, _: &mut lyra_ecs::World, _: &mut crate::render::graph::RenderGraphContext) {
|
||||
|
||||
}
|
||||
|
||||
fn execute(
|
||||
&mut self,
|
||||
_: &mut crate::render::graph::RenderGraph,
|
||||
_: &crate::render::graph::NodeDesc,
|
||||
_: &mut crate::render::graph::RenderGraphContext,
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
|
@ -2,8 +2,7 @@ use lyra_game_derive::RenderGraphLabel;
|
|||
|
||||
use crate::render::{
|
||||
graph::{
|
||||
RenderGraphContext, Node, NodeDesc, NodeType, SlotAttribute,
|
||||
SlotValue,
|
||||
Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext, SlotAttribute, SlotValue
|
||||
},
|
||||
light::LightUniformBuffers,
|
||||
};
|
||||
|
@ -58,7 +57,7 @@ impl Node for LightBasePass {
|
|||
desc
|
||||
}
|
||||
|
||||
fn prepare(&mut self, world: &mut lyra_ecs::World, context: &mut RenderGraphContext) {
|
||||
fn prepare(&mut self, _graph: &mut RenderGraph, world: &mut lyra_ecs::World, context: &mut RenderGraphContext) {
|
||||
let tick = world.current_tick();
|
||||
let lights = self.light_buffers.as_mut().unwrap();
|
||||
lights.update_lights(context.queue, tick, world);
|
||||
|
|
|
@ -7,7 +7,7 @@ use wgpu::util::DeviceExt;
|
|||
|
||||
use crate::render::{
|
||||
graph::{
|
||||
Node, NodeDesc, NodeType, RenderGraphContext, SlotAttribute, SlotValue
|
||||
Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext, SlotAttribute, SlotValue
|
||||
}, renderer::ScreenSize, resource::{ComputePipelineDescriptor, PipelineDescriptor, Shader}
|
||||
};
|
||||
|
||||
|
@ -215,7 +215,7 @@ impl Node for LightCullComputePass {
|
|||
desc
|
||||
}
|
||||
|
||||
fn prepare(&mut self, world: &mut World, context: &mut RenderGraphContext) {
|
||||
fn prepare(&mut self, _graph: &mut RenderGraph, world: &mut World, context: &mut RenderGraphContext) {
|
||||
context.queue_buffer_write_with(LightCullComputePassSlots::IndexCounterBuffer, 0, 0);
|
||||
|
||||
let screen_size = world.get_resource::<ScreenSize>();
|
||||
|
|
|
@ -15,8 +15,7 @@ use wgpu::util::DeviceExt;
|
|||
use crate::{
|
||||
render::{
|
||||
desc_buf_lay::DescVertexBufferLayout, graph::{
|
||||
RenderGraphContext, Node, NodeDesc,
|
||||
NodeType,
|
||||
Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext
|
||||
}, material::{Material, MaterialUniform}, render_buffer::{BufferStorage, BufferWrapper}, render_job::RenderJob, resource::{FragmentState, PipelineDescriptor, RenderPipelineDescriptor, Shader, VertexState}, texture::RenderTexture, transform_buffer_storage::{TransformBuffers, TransformGroup}, vertex::Vertex
|
||||
},
|
||||
DeltaTime,
|
||||
|
@ -297,8 +296,8 @@ impl Node for MeshPass {
|
|||
desc
|
||||
}
|
||||
|
||||
#[instrument(skip(self, world, context))]
|
||||
fn prepare(&mut self, world: &mut lyra_ecs::World, context: &mut RenderGraphContext) {
|
||||
#[instrument(skip(self, _graph, world, context))]
|
||||
fn prepare(&mut self, _graph: &mut RenderGraph, world: &mut lyra_ecs::World, context: &mut RenderGraphContext) {
|
||||
let device = context.device;
|
||||
let queue = context.queue;
|
||||
let render_limits = device.limits();
|
||||
|
|
|
@ -11,4 +11,7 @@ mod light_base;
|
|||
pub use light_base::*;
|
||||
|
||||
mod present_pass;
|
||||
pub use present_pass::*;
|
||||
pub use present_pass::*;
|
||||
|
||||
mod init;
|
||||
pub use init::*;
|
|
@ -2,7 +2,7 @@ use std::hash::Hash;
|
|||
|
||||
use lyra_game_derive::RenderGraphLabel;
|
||||
|
||||
use crate::render::graph::{RenderGraphContext, RenderGraphLabel, RenderGraphLabelValue, Node, NodeDesc, NodeSlot, NodeType, SlotAttribute, SlotType};
|
||||
use crate::render::graph::{Node, NodeDesc, NodeSlot, NodeType, RenderGraph, RenderGraphContext, RenderGraphLabel, RenderGraphLabelValue, SlotAttribute, SlotType};
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, RenderGraphLabel)]
|
||||
pub struct PresentPassLabel(RenderGraphLabelValue);
|
||||
|
@ -50,7 +50,7 @@ impl Node for PresentPass {
|
|||
desc
|
||||
}
|
||||
|
||||
fn prepare(&mut self, _world: &mut lyra_ecs::World, _context: &mut RenderGraphContext) {
|
||||
fn prepare(&mut self, _graph: &mut RenderGraph, _world: &mut lyra_ecs::World, _context: &mut RenderGraphContext) {
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue