diff --git a/lyra-game/src/render/graph/execution_path.rs b/lyra-game/src/render/graph/execution_path.rs index 049b7af..ab080ad 100644 --- a/lyra-game/src/render/graph/execution_path.rs +++ b/lyra-game/src/render/graph/execution_path.rs @@ -38,7 +38,7 @@ impl GraphExecutionPath { let node = Node { id: desc.id, - desc: (*desc).clone(), + desc: (*desc), slot_inputs: inputs }; nodes.insert(node.id, node); @@ -75,12 +75,14 @@ impl GraphExecutionPath { } } +#[allow(dead_code)] #[derive(Debug, Clone, Copy)] struct SlotOwnerPair { pass: u64, slot: u64, } +#[allow(dead_code)] struct Node<'a> { id: u64, desc: &'a RenderGraphPassDesc, diff --git a/lyra-game/src/render/graph/mod.rs b/lyra-game/src/render/graph/mod.rs index bd9b08d..043b742 100644 --- a/lyra-game/src/render/graph/mod.rs +++ b/lyra-game/src/render/graph/mod.rs @@ -121,17 +121,11 @@ impl RenderGraph { self.slot_names.get(name).cloned() } - pub fn slot_value(&self, id: u64) -> Option<&SlotValue> { - self.slots.get(&id).map(|s| &s.value) - } - - pub fn pass(&self, id: u64) -> Option<&RenderGraphPassDesc> { - self.passes.get(&id).map(|s| &*s.desc) - } - + #[instrument(skip(self, pass), level = "debug")] pub fn add_pass(&mut self, mut pass: P) { let mut desc = pass.desc(self); + // collect all the slots of the pass for slot in &mut desc.slots { if let Some((id, other)) = self .slot_names @@ -158,6 +152,7 @@ impl RenderGraph { } } + // get clones of the bind groups and layouts for (name, bg, bgl) in &desc.bind_groups { let bg_id = self.next_id(); self.bind_groups.insert( @@ -211,8 +206,8 @@ impl RenderGraph { inner.prepare(world, &mut context); } - // Queue all buffer writes to the gpu { + // Queue all buffer writes to the gpu let s = debug_span!("queue_buffer_writes"); let _e = s.enter(); @@ -236,7 +231,7 @@ impl RenderGraph { // create the execution path for the graph. This will be executed in `RenderGraph::render` let builtin = { let mut h = FxHashSet::default(); - h.insert(0u64); + h.insert(0u64); // include the base pass h }; let descs = self.passes.values().map(|p| &*p.desc).collect(); @@ -248,7 +243,8 @@ impl RenderGraph { self.exec_path = Some(path); } - pub fn render(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, surface: &wgpu::Surface) { + #[instrument(skip(self, surface))] + pub fn render(&mut self, surface: &wgpu::Surface) { let mut path = self.exec_path.take().unwrap(); let output = surface.get_current_texture().unwrap(); @@ -272,10 +268,13 @@ impl RenderGraph { let pass_desc = pass.desc.clone(); let label = format!("{} Encoder", pass_desc.name); - let encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { - label: Some(&label), - }); - let mut context = RenderGraphContext::new(queue, Some(encoder)); + let encoder = self + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some(&label), + }); + let queue = self.queue.clone(); // clone is required to appease the borrow checker + let mut context = RenderGraphContext::new(&queue, Some(encoder)); let mut inner = pass_inn.borrow_mut(); inner.execute(self, &*pass_desc, &mut context); @@ -283,10 +282,22 @@ impl RenderGraph { encoders.push(context.encoder.unwrap().finish()); } - queue.submit(encoders.into_iter()); + self.queue.submit(encoders.into_iter()); output.present(); } + pub fn slot_value(&self, id: u64) -> Option<&SlotValue> { + self.slots.get(&id).map(|s| &s.value) + } + + pub fn slot_value_mut(&mut self, id: u64) -> Option<&mut SlotValue> { + self.slots.get_mut(&id).map(|s| &mut s.value) + } + + pub fn pass(&self, id: u64) -> Option<&RenderGraphPassDesc> { + self.passes.get(&id).map(|s| &*s.desc) + } + #[inline(always)] pub fn pipeline(&self, id: u64) -> &Pipeline { &self.pipelines.get(&id).unwrap().pipeline @@ -319,7 +330,8 @@ impl RenderGraph { } } -pub(crate) struct BufferWrite { +/// 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: String, offset: u64, @@ -331,7 +343,7 @@ pub struct RenderGraphContext<'a> { /// Becomes None when the encoder is submitted pub(crate) encoder: Option, pub(crate) queue: &'a wgpu::Queue, - pub(crate) buffer_writes: VecDeque, + pub(crate) buffer_writes: VecDeque, renderpass_desc: Vec>, } @@ -373,15 +385,17 @@ impl<'a> RenderGraphContext<'a> { /// 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: &str, offset: u64, bytes: &[u8]) { - self.buffer_writes.push_back(BufferWrite { + self.buffer_writes.push_back(GraphBufferWrite { target_slot: target_slot.to_string(), offset, bytes: bytes.to_vec(), }) } - /// Write + /// 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::()))] pub fn queue_buffer_write_with( &mut self, target_slot: &str, diff --git a/lyra-game/src/render/graph/passes/triangle.rs b/lyra-game/src/render/graph/passes/triangle.rs index 05d4a83..937f03b 100644 --- a/lyra-game/src/render/graph/passes/triangle.rs +++ b/lyra-game/src/render/graph/passes/triangle.rs @@ -12,13 +12,9 @@ use crate::{ DeltaTime, }; -/// Supplies some basic things other passes needs. -/// -/// screen size buffer, camera buffer, +/// A demo pass that renders a triangle that changes colors every frame. #[derive(Default)] pub struct TrianglePass { - //color_bg: Option>, - //color_buf: Option>, acc: f32, } @@ -48,8 +44,6 @@ impl RenderGraphPass for TrianglePass { let color_bgl = Rc::new(color_bgl); let color_bg = Rc::new(color_bg); - //let color_buf = Rc::new(color_buf); - let mut desc = RenderGraphPassDesc::new( graph.next_id(), "TrianglePass", @@ -120,14 +114,9 @@ impl RenderGraphPass for TrianglePass { .slot_value(graph.slot_id("window_texture_view").unwrap()) .unwrap() .as_texture_view(); - let encoder = context.encoder.as_mut().unwrap(); - - //context.queue.write_buffer(buffer, offset, data) - - //let color_bg = graph.bind_group(graph.slot_id("color_buffer").unwrap()); - //let color_bg = self.color_bg.as_ref().unwrap(); let color_bg = graph.bind_group(graph.bind_group_id("color_bg").unwrap()); - + + let encoder = context.encoder.as_mut().unwrap(); let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("TrianglePass"), color_attachments: &[ diff --git a/lyra-game/src/render/renderer.rs b/lyra-game/src/render/renderer.rs index 290bd42..23f4cb6 100755 --- a/lyra-game/src/render/renderer.rs +++ b/lyra-game/src/render/renderer.rs @@ -270,7 +270,7 @@ impl Renderer for BasicRenderer { #[instrument(skip(self))] fn render(&mut self) -> Result<(), wgpu::SurfaceError> { - self.graph.render(&self.device, &self.queue, &self.surface); + self.graph.render(&self.surface); Ok(()) } diff --git a/lyra-game/src/render/resource/compute_pipeline.rs b/lyra-game/src/render/resource/compute_pipeline.rs index d44bde4..43d37d2 100644 --- a/lyra-game/src/render/resource/compute_pipeline.rs +++ b/lyra-game/src/render/resource/compute_pipeline.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, ops::Deref}; +use std::ops::Deref; use wgpu::PipelineLayout;