render: rename RenderGraph::add_pass to add_node
This commit is contained in:
parent
5fc1a0f134
commit
f17bf40c77
|
@ -0,0 +1,89 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use tracing::instrument;
|
||||
|
||||
use super::{RenderGraphLabel, RenderGraphLabelValue};
|
||||
|
||||
/// A queued write to a GPU buffer targeting a graph slot.
|
||||
pub(crate) struct GraphBufferWrite {
|
||||
/// The name of the slot that has the resource that will be written
|
||||
pub(crate) target_slot: RenderGraphLabelValue,
|
||||
pub(crate) offset: u64,
|
||||
pub(crate) bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct RenderGraphContext<'a> {
|
||||
/// The [`wgpu::CommandEncoder`] used to encode GPU operations.
|
||||
///
|
||||
/// This is `None` during the `prepare` stage.
|
||||
pub encoder: Option<wgpu::CommandEncoder>,
|
||||
/// The gpu device that is being used.
|
||||
pub device: &'a wgpu::Device,
|
||||
pub queue: &'a wgpu::Queue,
|
||||
pub(crate) buffer_writes: VecDeque<GraphBufferWrite>,
|
||||
renderpass_desc: Vec<wgpu::RenderPassDescriptor<'a, 'a>>,
|
||||
/// The label of this Node.
|
||||
pub label: RenderGraphLabelValue,
|
||||
}
|
||||
|
||||
impl<'a> RenderGraphContext<'a> {
|
||||
pub(crate) fn new(device: &'a wgpu::Device, queue: &'a wgpu::Queue, encoder: Option<wgpu::CommandEncoder>, label: RenderGraphLabelValue) -> Self {
|
||||
Self {
|
||||
encoder,
|
||||
device,
|
||||
queue,
|
||||
buffer_writes: Default::default(),
|
||||
renderpass_desc: vec![],
|
||||
label,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin_render_pass(
|
||||
&'a mut self,
|
||||
desc: wgpu::RenderPassDescriptor<'a, 'a>,
|
||||
) -> wgpu::RenderPass {
|
||||
self.encoder
|
||||
.as_mut()
|
||||
.expect(
|
||||
"RenderGraphContext is missing a command encoder. This is likely \
|
||||
because you are trying to run render commands in the prepare stage.",
|
||||
)
|
||||
.begin_render_pass(&desc)
|
||||
}
|
||||
|
||||
pub fn begin_compute_pass(&mut self, desc: &wgpu::ComputePassDescriptor) -> wgpu::ComputePass {
|
||||
self.encoder
|
||||
.as_mut()
|
||||
.expect(
|
||||
"RenderGraphContext is missing a command encoder. This is likely \
|
||||
because you are trying to run render commands in the prepare stage.",
|
||||
)
|
||||
.begin_compute_pass(desc)
|
||||
}
|
||||
|
||||
/// Queue a data write to a buffer at that is contained in `target_slot`.
|
||||
///
|
||||
/// This does not submit the data to the GPU immediately, or add it to the `wgpu::Queue`. The
|
||||
/// data will be submitted to the GPU queue right after the prepare stage for all passes
|
||||
/// is ran.
|
||||
#[instrument(skip(self, bytes), level="trace", fields(size = bytes.len()))]
|
||||
pub fn queue_buffer_write(&mut self, target_slot: impl RenderGraphLabel, offset: u64, bytes: &[u8]) {
|
||||
self.buffer_writes.push_back(GraphBufferWrite {
|
||||
target_slot: target_slot.into(),
|
||||
offset,
|
||||
bytes: bytes.to_vec(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Queue a data write of a type that to a buffer at that is contained in `target_slot`.
|
||||
#[instrument(skip(self, bytes), level="trace", fields(size = std::mem::size_of::<T>()))]
|
||||
pub fn queue_buffer_write_with<T: bytemuck::NoUninit>(
|
||||
&mut self,
|
||||
target_slot: impl RenderGraphLabel,
|
||||
offset: u64,
|
||||
bytes: T,
|
||||
) {
|
||||
self.queue_buffer_write(target_slot, offset, bytemuck::bytes_of(&bytes));
|
||||
}
|
||||
}
|
|
@ -12,6 +12,9 @@ pub use passes::*;
|
|||
mod slot_desc;
|
||||
pub use slot_desc::*;
|
||||
|
||||
mod context;
|
||||
pub use context::*;
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
use tracing::{debug_span, instrument, trace, warn};
|
||||
use wgpu::ComputePass;
|
||||
|
@ -121,8 +124,8 @@ pub struct RenderGraph {
|
|||
slots: FxHashMap<RenderGraphLabelValue, ResourcedSlot>,
|
||||
nodes: FxHashMap<RenderGraphLabelValue, PassEntry>,
|
||||
bind_groups: FxHashMap<RenderGraphLabelValue, BindGroupEntry>,
|
||||
/// A directed graph describing the execution path of the RenderGraph
|
||||
execution_graph: petgraph::matrix_graph::DiMatrix<RenderGraphLabelValue, (), Option<()>, usize>,
|
||||
/// A directed graph used to determine dependencies of nodes.
|
||||
node_graph: petgraph::matrix_graph::DiMatrix<RenderGraphLabelValue, (), Option<()>, usize>,
|
||||
}
|
||||
|
||||
impl RenderGraph {
|
||||
|
@ -133,7 +136,7 @@ impl RenderGraph {
|
|||
slots: Default::default(),
|
||||
nodes: Default::default(),
|
||||
bind_groups: Default::default(),
|
||||
execution_graph: Default::default(),
|
||||
node_graph: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +155,7 @@ impl RenderGraph {
|
|||
/// not change. The IDs of output slots do stay the same.
|
||||
/// 3. Ensuring that no two slots share the same ID when the names do not match.
|
||||
#[instrument(skip(self, pass), level = "debug")]
|
||||
pub fn add_pass<P: Node>(&mut self, label: impl RenderGraphLabel, mut pass: P) {
|
||||
pub fn add_node<P: Node>(&mut self, label: impl RenderGraphLabel, mut pass: P) {
|
||||
let mut desc = pass.desc(self);
|
||||
|
||||
// collect all the slots of the pass
|
||||
|
@ -203,7 +206,7 @@ impl RenderGraph {
|
|||
}
|
||||
|
||||
let label: RenderGraphLabelValue = label.into();
|
||||
let index = self.execution_graph.add_node(label.clone());
|
||||
let index = self.node_graph.add_node(label.clone());
|
||||
|
||||
self.nodes.insert(
|
||||
label,
|
||||
|
@ -296,10 +299,10 @@ impl RenderGraph {
|
|||
|
||||
#[instrument(skip(self))]
|
||||
pub fn render(&mut self) {
|
||||
let mut sorted: VecDeque<RenderGraphLabelValue> = petgraph::algo::toposort(&self.execution_graph, None)
|
||||
let mut sorted: VecDeque<RenderGraphLabelValue> = petgraph::algo::toposort(&self.node_graph, None)
|
||||
.expect("RenderGraph had cycled!")
|
||||
.iter()
|
||||
.map(|i| self.execution_graph[i.clone()].clone())
|
||||
.map(|i| self.node_graph[i.clone()].clone())
|
||||
.collect();
|
||||
//debug!("Render graph execution order: {:?}", sorted);
|
||||
|
||||
|
@ -422,7 +425,7 @@ impl RenderGraph {
|
|||
|
||||
debug_assert_ne!(from_idx, to_idx, "cannot add edges between the same node");
|
||||
|
||||
self.execution_graph.add_edge(from_idx, to_idx, ());
|
||||
self.node_graph.add_edge(from_idx, to_idx, ());
|
||||
}
|
||||
|
||||
/// Utility method for setting the bind groups for a pass.
|
||||
|
@ -463,87 +466,3 @@ impl RenderGraph {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A queued write to a GPU buffer targeting a graph slot.
|
||||
pub(crate) struct GraphBufferWrite {
|
||||
/// The name of the slot that has the resource that will be written
|
||||
target_slot: RenderGraphLabelValue,
|
||||
offset: u64,
|
||||
bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct RenderGraphContext<'a> {
|
||||
/// The [`wgpu::CommandEncoder`] used to encode GPU operations.
|
||||
///
|
||||
/// This is `None` during the `prepare` stage.
|
||||
pub encoder: Option<wgpu::CommandEncoder>,
|
||||
/// The gpu device that is being used.
|
||||
pub device: &'a wgpu::Device,
|
||||
pub queue: &'a wgpu::Queue,
|
||||
pub(crate) buffer_writes: VecDeque<GraphBufferWrite>,
|
||||
renderpass_desc: Vec<wgpu::RenderPassDescriptor<'a, 'a>>,
|
||||
/// The label of this Node.
|
||||
pub label: RenderGraphLabelValue,
|
||||
}
|
||||
|
||||
impl<'a> RenderGraphContext<'a> {
|
||||
pub(crate) fn new(device: &'a wgpu::Device, queue: &'a wgpu::Queue, encoder: Option<wgpu::CommandEncoder>, label: RenderGraphLabelValue) -> Self {
|
||||
Self {
|
||||
encoder,
|
||||
device,
|
||||
queue,
|
||||
buffer_writes: Default::default(),
|
||||
renderpass_desc: vec![],
|
||||
label,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin_render_pass(
|
||||
&'a mut self,
|
||||
desc: wgpu::RenderPassDescriptor<'a, 'a>,
|
||||
) -> wgpu::RenderPass {
|
||||
self.encoder
|
||||
.as_mut()
|
||||
.expect(
|
||||
"RenderGraphContext is missing a command encoder. This is likely \
|
||||
because you are trying to run render commands in the prepare stage.",
|
||||
)
|
||||
.begin_render_pass(&desc)
|
||||
}
|
||||
|
||||
pub fn begin_compute_pass(&mut self, desc: &wgpu::ComputePassDescriptor) -> wgpu::ComputePass {
|
||||
self.encoder
|
||||
.as_mut()
|
||||
.expect(
|
||||
"RenderGraphContext is missing a command encoder. This is likely \
|
||||
because you are trying to run render commands in the prepare stage.",
|
||||
)
|
||||
.begin_compute_pass(desc)
|
||||
}
|
||||
|
||||
/// Queue a data write to a buffer at that is contained in `target_slot`.
|
||||
///
|
||||
/// This does not submit the data to the GPU immediately, or add it to the `wgpu::Queue`. The
|
||||
/// data will be submitted to the GPU queue right after the prepare stage for all passes
|
||||
/// is ran.
|
||||
#[instrument(skip(self, bytes), level="trace", fields(size = bytes.len()))]
|
||||
pub fn queue_buffer_write(&mut self, target_slot: impl RenderGraphLabel, offset: u64, bytes: &[u8]) {
|
||||
self.buffer_writes.push_back(GraphBufferWrite {
|
||||
target_slot: target_slot.into(),
|
||||
offset,
|
||||
bytes: bytes.to_vec(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Queue a data write of a type that to a buffer at that is contained in `target_slot`.
|
||||
#[instrument(skip(self, bytes), level="trace", fields(size = std::mem::size_of::<T>()))]
|
||||
pub fn queue_buffer_write_with<T: bytemuck::NoUninit>(
|
||||
&mut self,
|
||||
target_slot: impl RenderGraphLabel,
|
||||
offset: u64,
|
||||
bytes: T,
|
||||
) {
|
||||
self.queue_buffer_write(target_slot, offset, bytemuck::bytes_of(&bytes));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,20 +125,20 @@ impl BasicRenderer {
|
|||
let mut g = RenderGraph::new(device.clone(), queue.clone());
|
||||
|
||||
debug!("Adding base pass");
|
||||
g.add_pass(BasePassLabel, BasePass::new(surface, config));
|
||||
g.add_node(BasePassLabel, BasePass::new(surface, config));
|
||||
debug!("Adding light base pass");
|
||||
g.add_pass(LightBasePassLabel, LightBasePass::new());
|
||||
g.add_node(LightBasePassLabel, LightBasePass::new());
|
||||
debug!("Adding light cull compute pass");
|
||||
g.add_pass(LightCullComputePassLabel, LightCullComputePass::new(size));
|
||||
g.add_node(LightCullComputePassLabel, LightCullComputePass::new(size));
|
||||
//debug!("Adding triangle pass");
|
||||
//g.add_pass(TrianglePass::new());
|
||||
//g.add_node(TrianglePass::new());
|
||||
|
||||
debug!("Adding mesh pass");
|
||||
g.add_pass(MeshesPassLabel, MeshPass::new());
|
||||
g.add_node(MeshesPassLabel, MeshPass::new());
|
||||
|
||||
debug!("Adding present pass");
|
||||
let p = PresentPass::new(BasePassSlots::MainRenderTarget);
|
||||
g.add_pass(p.label.clone(), p);
|
||||
g.add_node(p.label.clone(), p);
|
||||
|
||||
g.add_edge(BasePassLabel, LightBasePassLabel);
|
||||
g.add_edge(LightBasePassLabel, LightCullComputePassLabel);
|
||||
|
|
Loading…
Reference in New Issue