From a7efd1b0f6883afa8b9fdec87ee659c5c4ee6fcb Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 29 Oct 2023 00:49:03 -0700 Subject: [PATCH] Better profiling integration for the renderer, make hot reload optional --- blade-asset/Cargo.toml | 1 + blade-asset/src/lib.rs | 1 + blade-egui/Cargo.toml | 1 + blade-egui/src/lib.rs | 5 +++++ blade-graphics/src/lib.rs | 2 +- blade-render/src/asset_hub.rs | 2 ++ blade-render/src/render/mod.rs | 9 +++++++++ examples/scene/main.rs | 22 ++++++++++++++++------ 8 files changed, 36 insertions(+), 7 deletions(-) diff --git a/blade-asset/Cargo.toml b/blade-asset/Cargo.toml index 20abfdfb..b1bc5cee 100644 --- a/blade-asset/Cargo.toml +++ b/blade-asset/Cargo.toml @@ -14,3 +14,4 @@ base64 = { workspace = true } bytemuck = { workspace = true } choir = { workspace = true } log = { workspace = true } +profiling = { workspace = true } diff --git a/blade-asset/src/lib.rs b/blade-asset/src/lib.rs index 1a1fdf1f..f588d04e 100644 --- a/blade-asset/src/lib.rs +++ b/blade-asset/src/lib.rs @@ -224,6 +224,7 @@ enum CookReason { WrongDataOffset, } +#[profiling::function] #[allow(clippy::read_zero_byte_vec)] // bad warning? fn check_target_relevancy( target_path: &Path, diff --git a/blade-egui/Cargo.toml b/blade-egui/Cargo.toml index 2c26cd9b..d0e687e5 100644 --- a/blade-egui/Cargo.toml +++ b/blade-egui/Cargo.toml @@ -14,3 +14,4 @@ blade-graphics = { version = "0.2", path = "../blade-graphics"} blade-macros = { version = "0.2", path = "../blade-macros"} bytemuck = { workspace = true } egui = { workspace = true, features = ["bytemuck"] } +profiling = { workspace = true } diff --git a/blade-egui/src/lib.rs b/blade-egui/src/lib.rs index 08d28c17..e7c7cbc5 100644 --- a/blade-egui/src/lib.rs +++ b/blade-egui/src/lib.rs @@ -116,6 +116,7 @@ impl GuiPainter { /// /// It supports renderpasses with only a color attachment, /// and this attachment format must be The `output_format`. + #[profiling::function] pub fn new( context: &blade_graphics::Context, output_format: blade_graphics::TextureFormat, @@ -167,6 +168,7 @@ impl GuiPainter { } } + #[profiling::function] fn triage_deletions(&mut self, context: &blade_graphics::Context) { let valid_pos = self .textures_to_delete @@ -182,6 +184,7 @@ impl GuiPainter { /// Updates the texture used by egui for the fonts etc. /// New textures should be added before the call to `execute()`, /// and old textures should be removed after. + #[profiling::function] pub fn update_textures( &mut self, command_encoder: &mut blade_graphics::CommandEncoder, @@ -270,6 +273,7 @@ impl GuiPainter { /// Render the set of clipped primitives into a render pass. /// The `sd` must contain dimensions of the render target. + #[profiling::function] pub fn paint( &mut self, pass: &mut blade_graphics::RenderCommandEncoder, @@ -344,6 +348,7 @@ impl GuiPainter { } /// Call this after submitting work at the given `sync_point`. + #[profiling::function] pub fn after_submit(&mut self, sync_point: blade_graphics::SyncPoint) { self.textures_to_delete.extend( self.textures_dropped diff --git a/blade-graphics/src/lib.rs b/blade-graphics/src/lib.rs index 01defa90..096ba671 100644 --- a/blade-graphics/src/lib.rs +++ b/blade-graphics/src/lib.rs @@ -531,7 +531,7 @@ pub struct ShaderDataLayout { } impl ShaderDataLayout { - pub const EMPTY: &Self = &Self { + pub const EMPTY: &'static Self = &Self { bindings: Vec::new(), }; } diff --git a/blade-render/src/asset_hub.rs b/blade-render/src/asset_hub.rs index aa297e52..4245d5d3 100644 --- a/blade-render/src/asset_hub.rs +++ b/blade-render/src/asset_hub.rs @@ -50,6 +50,7 @@ impl AssetHub { /// /// Populates the list of temporary buffers that can be freed when the /// relevant submission is completely retired. + #[profiling::function] pub fn flush( &self, command_encoder: &mut blade_graphics::CommandEncoder, @@ -78,6 +79,7 @@ impl AssetHub { } } + #[profiling::function] pub fn list_running_tasks(&self) -> Vec { let mut list = Vec::new(); self.textures.list_running_tasks(&mut list); diff --git a/blade-render/src/render/mod.rs b/blade-render/src/render/mod.rs index 6b8d14fd..59314c32 100644 --- a/blade-render/src/render/mod.rs +++ b/blade-render/src/render/mod.rs @@ -728,6 +728,7 @@ impl Renderer { /// /// Panics if the system is not compatible. /// Records initialization routines into the given command encoder. + #[profiling::function] pub fn new( encoder: &mut blade_graphics::CommandEncoder, gpu: &blade_graphics::Context, @@ -876,6 +877,7 @@ impl Renderer { self.is_tlas_dirty = true; } + #[profiling::function] pub fn hot_reload( &mut self, asset_hub: &crate::AssetHub, @@ -964,6 +966,7 @@ impl Renderer { self.env_map.weight_view } + #[profiling::function] pub fn resize_screen( &mut self, size: blade_graphics::Extent, @@ -998,6 +1001,7 @@ impl Renderer { } /// Prepare to render a frame. + #[profiling::function] #[allow(clippy::too_many_arguments)] pub fn prepare( &mut self, @@ -1258,6 +1262,7 @@ impl Renderer { /// Ray trace the scene. /// /// The result is stored internally in an HDR render target. + #[profiling::function] pub fn ray_trace( &self, command_encoder: &mut blade_graphics::CommandEncoder, @@ -1335,6 +1340,8 @@ impl Renderer { } } + /// Perform noise reduction using SVGF. + #[profiling::function] pub fn denoise( &mut self, //TODO: borrow immutably command_encoder: &mut blade_graphics::CommandEncoder, @@ -1405,6 +1412,7 @@ impl Renderer { } /// Blit the rendering result into a specified render pass. + #[profiling::function] pub fn post_proc( &self, pass: &mut blade_graphics::RenderCommandEncoder, @@ -1469,6 +1477,7 @@ impl Renderer { } } + #[profiling::function] pub fn read_debug_selection_info(&self) -> SelectionInfo { let db_v = unsafe { &*(self.debug.variance_buffer.data() as *const DebugVariance) }; let db_e = unsafe { &*(self.debug.entry_buffer.data() as *const DebugEntry) }; diff --git a/examples/scene/main.rs b/examples/scene/main.rs index 9a574660..c8d5a1e7 100644 --- a/examples/scene/main.rs +++ b/examples/scene/main.rs @@ -79,6 +79,7 @@ struct Example { camera: blade_render::Camera, fly_speed: f32, debug: blade_render::DebugConfig, + track_hot_reloads: bool, need_accumulation_reset: bool, is_debug_drawing: bool, last_render_time: time::Instant, @@ -106,9 +107,9 @@ impl Example { } } + #[profiling::function] fn new(window: &winit::window::Window, scene_path: &Path) -> Self { log::info!("Initializing"); - //let _ = profiling::tracy_client::Client::start(); let context = Arc::new(unsafe { gpu::Context::init_windowed( @@ -220,6 +221,7 @@ impl Example { camera, fly_speed: config_scene.camera.speed, debug: blade_render::DebugConfig::default(), + track_hot_reloads: false, need_accumulation_reset: true, is_debug_drawing: false, last_render_time: time::Instant::now(), @@ -253,6 +255,7 @@ impl Example { .destroy_command_encoder(self.command_encoder.take().unwrap()); } + #[profiling::function] fn wait_for_previous_frame(&mut self) { if let Some(sp) = self.prev_sync_point.take() { self.context.wait_for(&sp, !0); @@ -265,6 +268,7 @@ impl Example { } } + #[profiling::function] fn render( &mut self, gui_primitives: &[egui::ClippedPrimitive], @@ -280,11 +284,13 @@ impl Example { } } - self.need_accumulation_reset |= self.renderer.hot_reload( - &self.asset_hub, - &self.context, - self.prev_sync_point.as_ref().unwrap(), - ); + if self.track_hot_reloads { + self.need_accumulation_reset |= self.renderer.hot_reload( + &self.asset_hub, + &self.context, + self.prev_sync_point.as_ref().unwrap(), + ); + } // Note: the resize is split in 2 parts because `wait_for_previous_frame` // wants to borrow `self` mutably, and `command_encoder` blocks that. @@ -374,6 +380,7 @@ impl Example { .extend(temp_acceleration_structures); } + #[profiling::function] fn add_gui(&mut self, ui: &mut egui::Ui) { use strum::IntoEnumIterator as _; @@ -421,6 +428,7 @@ impl Example { egui::CollapsingHeader::new("Debug") .default_open(true) .show(ui, |ui| { + ui.checkbox(&mut self.track_hot_reloads, "Hot reloading"); // debug mode egui::ComboBox::from_label("View mode") .selected_text(format!("{:?}", self.debug.view_mode)) @@ -667,6 +675,7 @@ impl Example { fn main() { env_logger::init(); + //let _ = profiling::tracy_client::Client::start(); let event_loop = winit::event_loop::EventLoop::new(); let window = winit::window::WindowBuilder::new() @@ -851,6 +860,7 @@ fn main() { window.inner_size(), egui_ctx.pixels_per_point(), ); + profiling::finish_frame!(); } winit::event::Event::LoopDestroyed => { example.destroy();