diff --git a/Cargo.toml b/Cargo.toml index cb59c15..a4afe80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,8 @@ tracy = ["lyra-game/tracy"] lyra-game = { path = "lyra-game" } lyra-scripting = { path = "lyra-scripting", optional = true } -[profile.dev] -opt-level = 1 +#[profile.dev] +#opt-level = 1 [profile.release] debug = true \ No newline at end of file diff --git a/lyra-game/src/render/graph/context.rs b/lyra-game/src/render/graph/context.rs index fea0dc0..696ce57 100644 --- a/lyra-game/src/render/graph/context.rs +++ b/lyra-game/src/render/graph/context.rs @@ -1,8 +1,8 @@ -use std::collections::VecDeque; +use std::{collections::VecDeque, sync::Arc}; use tracing::instrument; -use super::{RenderGraphLabel, RenderGraphLabelValue}; +use super::{Frame, RenderGraphLabel, RenderGraphLabelValue, RenderTarget}; /// A queued write to a GPU buffer targeting a graph slot. pub(crate) struct GraphBufferWrite { @@ -19,8 +19,8 @@ pub struct RenderGraphContext<'a> { /// This is `None` during the `prepare` stage. pub encoder: Option, /// The gpu device that is being used. - pub device: &'a wgpu::Device, - pub queue: &'a wgpu::Queue, + pub device: Arc, + pub queue: Arc, pub(crate) buffer_writes: VecDeque, renderpass_desc: Vec>, /// The label of this Node. @@ -28,7 +28,7 @@ pub struct RenderGraphContext<'a> { } impl<'a> RenderGraphContext<'a> { - pub(crate) fn new(device: &'a wgpu::Device, queue: &'a wgpu::Queue, encoder: Option, label: RenderGraphLabelValue) -> Self { + pub(crate) fn new(device: Arc, queue: Arc, encoder: Option, label: RenderGraphLabelValue) -> Self { Self { encoder, device, @@ -86,4 +86,15 @@ impl<'a> RenderGraphContext<'a> { ) { self.queue_buffer_write(target_slot, offset, bytemuck::bytes_of(&bytes)); } + + pub fn get_frame(&self, render_target: &RenderTarget) -> super::Frame { + let texture = render_target.frame_texture() + .expect("failed to create frame texture"); // should this be returned to the user? + + Frame { + device: self.device.clone(), + queue: self.queue.clone(), + texture, + } + } } diff --git a/lyra-game/src/render/graph/mod.rs b/lyra-game/src/render/graph/mod.rs index 255917e..9504bec 100644 --- a/lyra-game/src/render/graph/mod.rs +++ b/lyra-game/src/render/graph/mod.rs @@ -15,6 +15,9 @@ pub use slot_desc::*; mod context; pub use context::*; +mod render_target; +pub use render_target::*; + use rustc_hash::FxHashMap; use tracing::{debug_span, instrument, trace, warn}; use wgpu::ComputePass; @@ -111,16 +114,9 @@ pub struct PipelineResource { pub bg_layout_name_lookup: HashMap, } -#[derive(Debug)] -pub struct RenderTarget { - pub surface: wgpu::Surface, - pub surface_config: wgpu::SurfaceConfiguration, - pub current_texture: Option, -} - pub struct RenderGraph { - device: Rc, - queue: Rc, + device: Arc, + queue: Arc, slots: FxHashMap, nodes: FxHashMap, sub_graphs: FxHashMap, @@ -130,7 +126,7 @@ pub struct RenderGraph { } impl RenderGraph { - pub fn new(device: Rc, queue: Rc) -> Self { + pub fn new(device: Arc, queue: Arc) -> Self { Self { device, queue, @@ -282,7 +278,7 @@ impl RenderGraph { let inner = pass.inner.clone(); let mut inner = inner.borrow_mut(); - let mut context = RenderGraphContext::new(&device, &queue, None, pass_label.clone()); + let mut context = RenderGraphContext::new(device, queue, None, pass_label.clone()); inner.prepare(self, world, &mut context); buffer_writes.append(&mut context.buffer_writes); } @@ -344,7 +340,7 @@ impl RenderGraph { // clone of the Rc's is required to appease the borrow checker let device = self.device.clone(); let queue = self.queue.clone(); - let mut context = RenderGraphContext::new(&device, &queue, encoder, pass_label.clone()); + let mut context = RenderGraphContext::new(device, queue, encoder, pass_label.clone()); // all encoders need to be submitted before a presenter node is executed. if pass_desc.ty == NodeType::Presenter { @@ -428,23 +424,23 @@ impl RenderGraph { .iter() .find(|p| *p.0 == from) .map(|p| p.1.graph_index) - .expect("Failed to find from pass"); + .expect("Failed to find from node"); let to_idx = self .nodes .iter() .find(|p| *p.0 == to) .map(|p| p.1.graph_index) - .expect("Failed to find to pass"); + .expect("Failed to find to node"); debug_assert_ne!(from_idx, to_idx, "cannot add edges between the same node"); self.node_graph.add_edge(from_idx, to_idx, ()); } - /// Utility method for setting the bind groups for a pass. + /// Utility method for setting the bind groups for a node. /// /// The parameter `bind_groups` can be used to specify the labels of a bind group, and the - /// index of the bind group in the pipeline for the pass. If a bind group of the provided + /// index of the bind group in the pipeline for the node. If a bind group of the provided /// name is not found in the graph, a panic will occur. /// /// # Example: diff --git a/lyra-game/src/render/graph/node.rs b/lyra-game/src/render/graph/node.rs index 069a6a0..1437205 100644 --- a/lyra-game/src/render/graph/node.rs +++ b/lyra-game/src/render/graph/node.rs @@ -5,7 +5,7 @@ use lyra_ecs::World; use crate::render::resource::PipelineDescriptor; -use super::{RenderGraph, RenderGraphContext, RenderGraphLabel, RenderGraphLabelValue, RenderTarget}; +use super::{Frame, RenderGraph, RenderGraphContext, RenderGraphLabel, RenderGraphLabelValue, RenderTarget}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] pub enum NodeType { @@ -43,10 +43,11 @@ pub enum SlotType { Texture, Buffer, RenderTarget, + Frame, } /// The value of a slot in a [`Node`]. -#[derive(Debug, Clone)] +#[derive(Clone)] pub enum SlotValue { /// This slot doesn't have any value None, @@ -58,6 +59,7 @@ pub enum SlotValue { Texture(Rc), Buffer(Rc), RenderTarget(Rc>), + Frame(Rc>>), } impl SlotValue { @@ -84,6 +86,14 @@ impl SlotValue { pub fn as_render_target_mut(&mut self) -> Option> { bind_match!(self, Self::RenderTarget(v) => v.borrow_mut()) } + + pub fn as_frame(&self) -> Option>> { + bind_match!(self, Self::Frame(v) => v.borrow()) + } + + pub fn as_frame_mut(&mut self) -> Option>> { + bind_match!(self, Self::Frame(v) => v.borrow_mut()) + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum SlotAttribute { diff --git a/lyra-game/src/render/graph/passes/base.rs b/lyra-game/src/render/graph/passes/base.rs index 3316c0d..33b989c 100644 --- a/lyra-game/src/render/graph/passes/base.rs +++ b/lyra-game/src/render/graph/passes/base.rs @@ -1,6 +1,5 @@ use std::{cell::RefCell, rc::Rc}; -use glam::UVec2; use lyra_game_derive::RenderGraphLabel; use tracing::warn; use winit::dpi::PhysicalSize; @@ -27,6 +26,7 @@ pub enum BasePassSlots { MainRenderTarget, WindowTextureView, DepthTextureView, + Frame, } /// Supplies some basic things other passes needs. @@ -43,15 +43,11 @@ pub struct BasePass { } impl BasePass { - pub fn new(surface: wgpu::Surface, surface_config: wgpu::SurfaceConfiguration) -> Self { - let size = glam::UVec2::new(surface_config.width, surface_config.height); + pub fn new(render_target: RenderTarget) -> Self { + let size = render_target.size(); Self { - temp_render_target: Some(RenderTarget { - surface, - surface_config, - current_texture: None, - }), + temp_render_target: Some(render_target), screen_size: size, ..Default::default() } @@ -64,10 +60,7 @@ impl Node for BasePass { graph: &mut crate::render::graph::RenderGraph, ) -> crate::render::graph::NodeDesc { let render_target = self.temp_render_target.take().unwrap(); - self.screen_size = UVec2::new( - render_target.surface_config.width, - render_target.surface_config.height, - ); + self.screen_size = render_target.size(); let (screen_size_bgl, screen_size_bg, screen_size_buf, _) = BufferWrapper::builder() .buffer_usage(wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST) @@ -90,7 +83,7 @@ impl Node for BasePass { let camera_bg = Rc::new(camera_bg); // create the depth texture using the utility struct, then take all the required fields - let mut depth_texture = RenderTexture::create_depth_texture(&graph.device(), &render_target.surface_config, "depth_texture"); + let mut depth_texture = RenderTexture::create_depth_texture(&graph.device(), self.screen_size, "depth_texture"); depth_texture.create_bind_group(&graph.device); let dt_bg_pair = depth_texture.bindgroup_pair.unwrap(); @@ -122,6 +115,12 @@ impl Node for BasePass { render_target, )))), }); + desc.add_slot(NodeSlot { + ty: SlotType::Frame, + attribute: SlotAttribute::Output, + label: BasePassSlots::Frame.into(), + value: Some(SlotValue::Lazy), + }); desc.add_texture_view_slot( BasePassSlots::WindowTextureView, SlotAttribute::Output, @@ -167,28 +166,31 @@ impl Node for BasePass { let tv_slot = graph .slot_value_mut(BasePassSlots::MainRenderTarget) .expect("somehow the main render target slot is missing"); - let mut rt = tv_slot.as_render_target_mut().unwrap(); - debug_assert!( + let rt = tv_slot.as_render_target().unwrap(); + let rt_size = rt.size(); + let frame = context.get_frame(&rt); + /* debug_assert!( !rt.current_texture.is_some(), "main render target surface was not presented!" - ); + ); */ // update the screen size buffer if the size changed. - if rt.surface_config.width != self.screen_size.x - || rt.surface_config.height != self.screen_size.y - { - self.screen_size = UVec2::new(rt.surface_config.width, rt.surface_config.height); + if rt_size != self.screen_size { + self.screen_size = rt_size; context.queue_buffer_write_with(BasePassSlots::ScreenSize, 0, self.screen_size) } - let surface_tex = rt.surface.get_current_texture().unwrap(); + let surface_tex = frame.texture(); let view = surface_tex - .texture .create_view(&wgpu::TextureViewDescriptor::default()); - rt.current_texture = Some(surface_tex); drop(rt); // must be manually dropped for borrow checker when getting texture view slot + let frame_slot = graph + .slot_value_mut(BasePassSlots::Frame) + .expect("somehow the frame slot is missing"); + *frame_slot = SlotValue::Frame(Rc::new(RefCell::new(Some(frame)))); + // store the surface texture to the slot let tv_slot = graph .slot_value_mut(BasePassSlots::WindowTextureView) diff --git a/lyra-game/src/render/graph/passes/light_base.rs b/lyra-game/src/render/graph/passes/light_base.rs index 3e78401..60844ed 100644 --- a/lyra-game/src/render/graph/passes/light_base.rs +++ b/lyra-game/src/render/graph/passes/light_base.rs @@ -60,7 +60,7 @@ impl Node for LightBasePass { 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); + lights.update_lights(&context.queue, tick, world); } fn execute( diff --git a/lyra-game/src/render/graph/passes/light_cull_compute.rs b/lyra-game/src/render/graph/passes/light_cull_compute.rs index 9dbc88d..3eef02f 100644 --- a/lyra-game/src/render/graph/passes/light_cull_compute.rs +++ b/lyra-game/src/render/graph/passes/light_cull_compute.rs @@ -51,8 +51,7 @@ impl Node for LightCullComputePass { .slot_value(BasePassSlots::MainRenderTarget) .and_then(|s| s.as_render_target()) .expect("missing main render target"); - self.workgroup_size = - glam::UVec2::new(main_rt.surface_config.width, main_rt.surface_config.height); + self.workgroup_size = main_rt.size(); // initialize some buffers with empty data let mut contents = Vec::::new(); diff --git a/lyra-game/src/render/graph/passes/meshes.rs b/lyra-game/src/render/graph/passes/meshes.rs index 1a06255..e1f17e7 100644 --- a/lyra-game/src/render/graph/passes/meshes.rs +++ b/lyra-game/src/render/graph/passes/meshes.rs @@ -234,7 +234,7 @@ impl Node for MeshPass { let main_rt = graph.slot_value(BasePassSlots::MainRenderTarget) .and_then(|s| s.as_render_target()) .expect("missing main render target"); - let surface_config_format = main_rt.surface_config.format; + let surface_config_format = main_rt.format(); drop(main_rt); let camera_bgl = graph.bind_group_layout(BasePassSlots::Camera); @@ -298,8 +298,8 @@ impl Node for MeshPass { #[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 device = &context.device; + let queue = &context.queue; let render_limits = device.limits(); let last_epoch = world.current_tick(); @@ -363,7 +363,7 @@ impl Node for MeshPass { let transforms = self.transforms.as_mut().unwrap(); if transforms.needs_expand() { debug!("Expanding transform buffers"); - transforms.expand_buffers(device); + transforms.expand_buffers(&device); } } @@ -372,14 +372,14 @@ impl Node for MeshPass { // if process mesh did not just create a new mesh, and the epoch // shows that the scene has changed, verify that the mesh buffers // dont need to be resent to the gpu. - if !self.process_mesh(device, queue, entity, &*mesh, mesh_han.uuid()) + if !self.process_mesh(&device, &queue, entity, &*mesh, mesh_han.uuid()) && mesh_epoch == last_epoch { - self.check_mesh_buffers(device, queue, &mesh_han); + self.check_mesh_buffers(&device, &queue, &mesh_han); } let transforms = self.transforms.as_mut().unwrap(); let group = TransformGroup::EntityRes(entity, mesh_han.uuid()); - let transform_id = transforms.update_or_push(device, queue, &render_limits, + let transform_id = transforms.update_or_push(&device, &queue, &render_limits, group, interp_transform.calculate_mat4(), glam::Mat3::from_quat(interp_transform.rotation)); let material = mesh.material.as_ref().unwrap() @@ -404,15 +404,15 @@ impl Node for MeshPass { // if process mesh did not just create a new mesh, and the epoch // shows that the scene has changed, verify that the mesh buffers // dont need to be resent to the gpu. - if !self.process_mesh(device, queue, entity, &*mesh, mesh_han.uuid()) + if !self.process_mesh(&device, &queue, entity, &*mesh, mesh_han.uuid()) && scene_epoch == last_epoch { - self.check_mesh_buffers(device, queue, &mesh_han); + self.check_mesh_buffers(&device, &queue, &mesh_han); } let transforms = self.transforms.as_mut().unwrap(); let scene_mesh_group = TransformGroup::Res(scene_han.uuid(), mesh_han.uuid()); let group = TransformGroup::OwnedGroup(entity, scene_mesh_group.into()); - let transform_id = transforms.update_or_push(device, queue, &render_limits, + let transform_id = transforms.update_or_push(&device, &queue, &render_limits, group, mesh_interpo.calculate_mat4(), glam::Mat3::from_quat(mesh_interpo.rotation) ); let material = mesh.material.as_ref().unwrap() @@ -431,7 +431,7 @@ impl Node for MeshPass { } let transforms = self.transforms.as_mut().unwrap(); - transforms.send_to_gpu(queue); + transforms.send_to_gpu(&queue); } fn execute( diff --git a/lyra-game/src/render/graph/passes/present_pass.rs b/lyra-game/src/render/graph/passes/present_pass.rs index ad6e513..b5d356d 100644 --- a/lyra-game/src/render/graph/passes/present_pass.rs +++ b/lyra-game/src/render/graph/passes/present_pass.rs @@ -8,8 +8,8 @@ use crate::render::graph::{Node, NodeDesc, NodeSlot, NodeType, RenderGraph, Rend pub struct PresentPassLabel(RenderGraphLabelValue); impl PresentPassLabel { - pub fn new(label: impl RenderGraphLabel) -> Self { - Self(label.into()) + pub fn new(frame_label: impl RenderGraphLabel) -> Self { + Self(frame_label.into()) } } @@ -22,10 +22,17 @@ pub struct PresentPass { } impl PresentPass { - pub fn new(render_target_slot: impl RenderGraphLabel) -> Self { + /// Create a new PresentNode, presenting the frame at `frame_label` + pub fn new(frame_label: impl RenderGraphLabel) -> Self { Self { //render_target_slot: render_target_slot.rc_clone(), - label: PresentPassLabel::new(render_target_slot), + label: PresentPassLabel::new(frame_label), + } + } + + pub fn from_node_label(present_pass_label: PresentPassLabel) -> Self { + Self { + label: present_pass_label, } } } @@ -40,7 +47,7 @@ impl Node for PresentPass { desc.add_slot( NodeSlot { - ty: SlotType::RenderTarget, + ty: SlotType::Frame, attribute: SlotAttribute::Input, label: self.label.0.clone(), value: None, @@ -55,10 +62,12 @@ impl Node for PresentPass { } fn execute(&mut self, graph: &mut crate::render::graph::RenderGraph, _desc: &crate::render::graph::NodeDesc, _context: &mut crate::render::graph::RenderGraphContext) { - let mut slot = graph.slot_value_mut(self.label.0.clone()) - .expect(&format!("render target slot '{:?}' for PresentPass is missing", self.label.0)) - .as_render_target_mut().unwrap(); - let surf_tex = slot.current_texture.take().unwrap(); - surf_tex.present(); + let slot = graph.slot_value_mut(self.label.0.clone()) + .unwrap_or_else(|| panic!("frame slot '{:?}' for PresentPass is missing", self.label.0)) + .as_frame_mut() + .unwrap() + .take() + .unwrap_or_else(|| panic!("frame '{:?}' was already presented", self.label.0)); + slot.present(); } } \ No newline at end of file diff --git a/lyra-game/src/render/graph/render_target.rs b/lyra-game/src/render/graph/render_target.rs new file mode 100644 index 0000000..84461c9 --- /dev/null +++ b/lyra-game/src/render/graph/render_target.rs @@ -0,0 +1,102 @@ +use std::sync::Arc; + +use crate::math; + +enum RenderTargetInner { + Surface { + surface: wgpu::Surface, + config: wgpu::SurfaceConfiguration, + }, + Texture { + texture: Arc, + } +} + +/// A render target that is a surface or a texture. +#[repr(transparent)] +pub struct RenderTarget(RenderTargetInner); + +impl From for RenderTarget { + fn from(value: wgpu::Texture) -> Self { + Self(RenderTargetInner::Texture { texture: Arc::new(value) }) + } +} + +impl RenderTarget { + pub fn from_surface(surface: wgpu::Surface, config: wgpu::SurfaceConfiguration) -> Self { + Self(RenderTargetInner::Surface { surface, config }) + } + + pub fn format(&self) -> wgpu::TextureFormat { + match &self.0 { + RenderTargetInner::Surface { config, .. } => config.format, + RenderTargetInner::Texture { texture } => texture.format(), + } + } + + pub fn size(&self) -> math::UVec2 { + match &self.0 { + RenderTargetInner::Surface { config, .. } => math::UVec2::new(config.width, config.height), + RenderTargetInner::Texture { texture } => { + let s = texture.size(); + math::UVec2::new(s.width, s.height) + }, + } + } + + /// Get the frame texture of the [`RenderTarget`] + /// + /// If this is target is a surface and the frame texture was already retrieved from the swap + /// chain, a [`wgpu::SurfaceError`] error will be returned. + pub fn frame_texture(&self) -> Result { + match &self.0 { + RenderTargetInner::Surface { surface, .. } => Ok(FrameTexture::Surface(surface.get_current_texture()?)), + RenderTargetInner::Texture { texture } => Ok(FrameTexture::Texture(texture.clone())), + } + } + + pub fn resize(&mut self, device: &wgpu::Device, new_size: math::UVec2) { + match &mut self.0 { + RenderTargetInner::Surface { surface, config } => { + config.width = new_size.x; + config.height = new_size.y; + surface.configure(device, config); + }, + RenderTargetInner::Texture { texture } => { + let _ = texture; + todo!() + }, + } + } +} + +pub enum FrameTexture { + Surface(wgpu::SurfaceTexture), + Texture(Arc), +} + +#[allow(dead_code)] +pub struct Frame { + pub(crate) device: Arc, + pub(crate) queue: Arc, + pub(crate) texture: FrameTexture, +} + +impl Frame { + pub fn texture(&self) -> &wgpu::Texture { + match &self.texture { + FrameTexture::Surface(s) => &s.texture, + FrameTexture::Texture(t) => t, + } + } + + /// Present the frame + /// + /// If this frame is from a surface, it will be present, else nothing will happen. + pub fn present(self) { + match self.texture { + FrameTexture::Surface(s) => s.present(), + FrameTexture::Texture(_) => {}, + } + } +} \ No newline at end of file diff --git a/lyra-game/src/render/light_cull_compute.rs b/lyra-game/src/render/light_cull_compute.rs index f8a6a95..3975e1d 100644 --- a/lyra-game/src/render/light_cull_compute.rs +++ b/lyra-game/src/render/light_cull_compute.rs @@ -17,8 +17,8 @@ pub(crate) struct LightIndicesGridBuffer { } pub(crate) struct LightCullCompute { - device: Rc, - queue: Rc, + device: Arc, + queue: Arc, pipeline: ComputePipeline, pub light_indices_grid: LightIndicesGridBuffer, screen_size_buffer: BufferWrapper, @@ -153,7 +153,7 @@ impl LightCullCompute { } } - pub fn new(device: Rc, queue: Rc, screen_size: PhysicalSize, lights_buffers: &LightUniformBuffers, camera_buffers: &BufferWrapper, depth_texture: &mut RenderTexture) -> Self { + pub fn new(device: Arc, queue: Arc, screen_size: PhysicalSize, lights_buffers: &LightUniformBuffers, camera_buffers: &BufferWrapper, depth_texture: &mut RenderTexture) -> Self { let screen_size_buffer = BufferWrapper::builder() .buffer_usage(wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST) .label_prefix("ScreenSize") diff --git a/lyra-game/src/render/renderer.rs b/lyra-game/src/render/renderer.rs index b2fda3f..d492fd3 100755 --- a/lyra-game/src/render/renderer.rs +++ b/lyra-game/src/render/renderer.rs @@ -1,17 +1,18 @@ use std::collections::VecDeque; use std::ops::{Deref, DerefMut}; -use std::rc::Rc; use std::sync::Arc; use lyra_ecs::World; use tracing::{debug, instrument, warn}; use winit::window::Window; -use crate::render::graph::{BasePass, BasePassLabel, BasePassSlots, LightBasePass, LightBasePassLabel, LightCullComputePass, LightCullComputePassLabel, MeshPass, MeshesPassLabel, PresentPass, PresentPassLabel}; +use crate::render::graph::{BasePass, BasePassLabel, BasePassSlots, LightBasePass, LightBasePassLabel, LightCullComputePass, LightCullComputePassLabel, MeshPass, MeshesPassLabel, PresentPass, PresentPassLabel, RenderTarget}; use super::graph::RenderGraph; use super::{resource::RenderPipeline, render_job::RenderJob}; +use crate::math; + #[derive(Clone, Copy, Debug)] pub struct ScreenSize(glam::UVec2); @@ -45,8 +46,8 @@ pub trait RenderPass { } pub struct BasicRenderer { - pub device: Rc, // device does not need to be mutable, no need for refcell - pub queue: Rc, + pub device: Arc, // device does not need to be mutable, no need for refcell + pub queue: Arc, pub size: winit::dpi::PhysicalSize, pub window: Arc, @@ -119,13 +120,15 @@ impl BasicRenderer { }; surface.configure(&device, &config); - let device = Rc::new(device); - let queue = Rc::new(queue); + let device = Arc::new(device); + let queue = Arc::new(queue); let mut g = RenderGraph::new(device.clone(), queue.clone()); + let surface_target = RenderTarget::from_surface(surface, config); + debug!("Adding base pass"); - g.add_node(BasePassLabel, BasePass::new(surface, config)); + g.add_node(BasePassLabel, BasePass::new(surface_target)); debug!("Adding light base pass"); g.add_node(LightBasePassLabel, LightBasePass::new()); debug!("Adding light cull compute pass"); @@ -137,7 +140,8 @@ impl BasicRenderer { g.add_node(MeshesPassLabel, MeshPass::new()); debug!("Adding present pass"); - let p = PresentPass::new(BasePassSlots::MainRenderTarget); + let present_pass_label = PresentPassLabel::new(BasePassSlots::Frame); + let p = PresentPass::from_node_label(present_pass_label.clone()); g.add_node(p.label.clone(), p); g.add_edge(BasePassLabel, LightBasePassLabel); @@ -145,9 +149,9 @@ impl BasicRenderer { g.add_edge(BasePassLabel, MeshesPassLabel); // make sure that present runs last - g.add_edge(BasePassLabel, PresentPassLabel::new(BasePassSlots::MainRenderTarget)); - g.add_edge(LightCullComputePassLabel, PresentPassLabel::new(BasePassSlots::MainRenderTarget)); - g.add_edge(MeshesPassLabel, PresentPassLabel::new(BasePassSlots::MainRenderTarget)); + g.add_edge(BasePassLabel, present_pass_label.clone()); + g.add_edge(LightCullComputePassLabel, present_pass_label.clone()); + g.add_edge(MeshesPassLabel, present_pass_label.clone()); g.setup(&device); @@ -191,9 +195,10 @@ impl Renderer for BasicRenderer { // update surface config and the surface let mut rt = self.graph.slot_value_mut(BasePassSlots::MainRenderTarget) .unwrap().as_render_target_mut().unwrap(); - rt.surface_config.width = new_size.width; + rt.resize(&self.device, math::UVec2::new(new_size.width, new_size.height)); + /* rt.surface_config.width = new_size.width; rt.surface_config.height = new_size.height; - rt.surface.configure(&self.device, &rt.surface_config); + rt.surface.configure(&self.device, &rt.surface_config); */ // update screen size resource in ecs let mut world_ss = world.get_resource_mut::(); diff --git a/lyra-game/src/render/texture.rs b/lyra-game/src/render/texture.rs index c3927dd..b51ccef 100755 --- a/lyra-game/src/render/texture.rs +++ b/lyra-game/src/render/texture.rs @@ -254,10 +254,10 @@ impl RenderTexture { ); } - pub fn create_depth_texture(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration, label: &str) -> Self { + pub fn create_depth_texture(device: &wgpu::Device, size: crate::math::UVec2, label: &str) -> Self { let size = wgpu::Extent3d { - width: config.width, - height: config.height, + width: size.x, + height: size.y, depth_or_array_layers: 1, }; let desc = wgpu::TextureDescriptor {