Skip to content

Commit

Permalink
Toggle Profiling (#486)
Browse files Browse the repository at this point in the history
* Remove resolved workaround

* Disable `wgpu-profiler` by default

Allow it to be toggled by the "G" key, and controlled
by a command line flag

Also properly maintain the vsync state, and
enable it to be toggled with a command line flag

* Fix WASM
  • Loading branch information
DJMcNab authored Mar 4, 2024
1 parent 246c42d commit e8456db
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 12 deletions.
8 changes: 6 additions & 2 deletions examples/simple/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ fn main() -> Result<()> {

// Create a vello Surface
let size = window.inner_size();
let surface_future =
render_cx.create_surface(window.clone(), size.width, size.height);
let surface_future = render_cx.create_surface(
window.clone(),
size.width,
size.height,
wgpu::PresentMode::AutoVsync,
);
let surface = pollster::block_on(surface_future).expect("Error creating surface");

// Create a vello Renderer for the surface (using its device id)
Expand Down
44 changes: 40 additions & 4 deletions examples/with_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use instant::{Duration, Instant};
use std::num::NonZeroUsize;
use std::{collections::HashSet, sync::Arc};
use wgpu_profiler::GpuProfilerSettings;

use anyhow::Result;
use clap::{CommandFactory, Parser};
Expand Down Expand Up @@ -39,6 +40,16 @@ struct Args {
#[arg(long)]
/// Whether to use CPU shaders
use_cpu: bool,
/// Used to disable vsync at startup. Can be toggled with the "V" key.
///
/// This setting is useful for Android, where it might be harder to press this key
#[arg(long)]
startup_vsync_off: bool,
/// Used to enable gpu profiling at startup. Can be toggled with the "G" key
///
/// It is off by default because it has adverse performance characteristics
#[arg(long)]
startup_gpu_profiling_on: bool,
/// Whether to force initialising the shaders serially (rather than spawning threads)
/// This has no effect on wasm, and defaults to 1 on macOS for performance reasons
///
Expand Down Expand Up @@ -116,7 +127,8 @@ fn run(
#[allow(unused_mut)]
let mut scene_complexity: Option<BumpAllocators> = None;
let mut complexity_shown = false;
let mut vsync_on = true;
let mut vsync_on = !args.startup_vsync_off;
let mut gpu_profiling_on = args.startup_gpu_profiling_on;

const AA_CONFIGS: [AaConfig; 3] = [AaConfig::Area, AaConfig::Msaa8, AaConfig::Msaa16];
// We allow cycling through AA configs in either direction, so use a signed index
Expand Down Expand Up @@ -241,6 +253,19 @@ fn run(
},
);
}
"g"=> {
gpu_profiling_on = !gpu_profiling_on;
if let Some(renderer) = &mut renderers[render_state.surface.dev_id] {
renderer
.profiler
.change_settings(GpuProfilerSettings {
enable_timer_queries: gpu_profiling_on,
enable_debug_groups: gpu_profiling_on,
..Default::default()
})
.expect("Not setting max_num_pending_frames");
}
}
_ => {}
}
}
Expand Down Expand Up @@ -528,7 +553,8 @@ fn run(
.take()
.unwrap_or_else(|| create_window(event_loop));
let size = window.inner_size();
let surface_future = render_cx.create_surface(window.clone(), size.width, size.height);
let present_mode = if vsync_on { wgpu::PresentMode::AutoVsync } else { wgpu::PresentMode::AutoNoVsync };
let surface_future = render_cx.create_surface(window.clone(), size.width, size.height, present_mode);
// We need to block here, in case a Suspended event appeared
let surface =
pollster::block_on(surface_future).expect("Error creating surface");
Expand All @@ -538,7 +564,7 @@ fn run(
let id = render_state.surface.dev_id;
renderers[id].get_or_insert_with(|| {
let start = Instant::now();
let renderer = Renderer::new(
let mut renderer = Renderer::new(
&render_cx.devices[id].device,
RendererOptions {
surface_format: Some(render_state.surface.format),
Expand All @@ -549,6 +575,11 @@ fn run(
)
.expect("Could create renderer");
eprintln!("Creating renderer {id} took {:?}", start.elapsed());
renderer.profiler.change_settings(GpuProfilerSettings{
enable_timer_queries: gpu_profiling_on,
enable_debug_groups: gpu_profiling_on,
..Default::default()
}).expect("Not setting max_num_pending_frames");
renderer
});
Some(render_state)
Expand Down Expand Up @@ -651,7 +682,12 @@ pub fn main() -> Result<()> {
winit::dpi::PhysicalSize::from_logical::<_, f64>((width, height), scale_factor);
_ = window.request_inner_size(size);
let surface = render_cx
.create_surface(window.clone(), size.width, size.height)
.create_surface(
window.clone(),
size.width,
size.height,
wgpu::PresentMode::AutoVsync,
)
.await;
if let Ok(surface) = surface {
let render_state = RenderState { window, surface };
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub struct Renderer {
blit: Option<BlitPipeline>,
target: Option<TargetTexture>,
#[cfg(feature = "wgpu-profiler")]
profiler: GpuProfiler,
pub profiler: GpuProfiler,
#[cfg(feature = "wgpu-profiler")]
pub profile_result: Option<Vec<wgpu_profiler::GpuTimerQueryResult>>,
}
Expand Down
7 changes: 2 additions & 5 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl RenderContext {
window: impl Into<SurfaceTarget<'w>>,
width: u32,
height: u32,
present_mode: wgpu::PresentMode,
) -> Result<RenderSurface<'w>> {
let surface = self.instance.create_surface(window.into())?;
let dev_id = self
Expand All @@ -63,7 +64,7 @@ impl RenderContext {
format,
width,
height,
present_mode: wgpu::PresentMode::AutoVsync,
present_mode,
desired_maximum_frame_latency: 2,
alpha_mode: wgpu::CompositeAlphaMode::Auto,
view_formats: vec![],
Expand Down Expand Up @@ -92,10 +93,6 @@ impl RenderContext {

fn configure_surface(&self, surface: &RenderSurface) {
let device = &self.devices[surface.dev_id].device;
// Temporary workaround for https://github.com/gfx-rs/wgpu/issues/4214
// It's still possible for this to panic if the device is being used on another thread
// but this unbreaks most current users
device.poll(wgpu::MaintainBase::Wait);
surface.surface.configure(device, &surface.config);
}

Expand Down

0 comments on commit e8456db

Please sign in to comment.