diff --git a/Cargo.lock b/Cargo.lock index be93056fcb3..0c85eaa68a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4219,9 +4219,9 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "wgpu" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b71d2ded29e2161db50ab731d6cb42c037bd7ab94864a98fa66ff36b4721a8" +checksum = "0bfe9a310dcf2e6b85f00c46059aaeaf4184caa8e29a1ecd4b7a704c3482332d" dependencies = [ "arrayvec", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 9fa472ba679..67f0806ed81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ glow = "0.13" puffin = "0.18" raw-window-handle = "0.6.0" thiserror = "1.0.37" -wgpu = { version = "0.19", features = [ +wgpu = { version = "0.19.1", features = [ # Make the renderer `Sync` even on wasm32, because it makes the code simpler: "fragile-send-sync-non-atomic-wasm", ] } diff --git a/crates/egui-wgpu/src/lib.rs b/crates/egui-wgpu/src/lib.rs index 6a43598da86..66caf2616c0 100644 --- a/crates/egui-wgpu/src/lib.rs +++ b/crates/egui-wgpu/src/lib.rs @@ -228,6 +228,15 @@ pub struct WgpuConfiguration { /// Present mode used for the primary surface. pub present_mode: wgpu::PresentMode, + /// Desired maximum number of frames that the presentation engine should queue in advance. + /// + /// Use `1` for low-latency, and `2` for high-throughput. + /// + /// See [`wgpu::SurfaceConfiguration::desired_maximum_frame_latency`] for details. + /// + /// `None` = `wgpu` default. + pub desired_maximum_frame_latency: Option, + /// Power preference for the adapter. pub power_preference: wgpu::PowerPreference, @@ -237,10 +246,22 @@ pub struct WgpuConfiguration { impl std::fmt::Debug for WgpuConfiguration { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { + supported_backends, + device_descriptor: _, + present_mode, + desired_maximum_frame_latency, + power_preference, + on_surface_error: _, + } = self; f.debug_struct("WgpuConfiguration") - .field("supported_backends", &self.supported_backends) - .field("present_mode", &self.present_mode) - .field("power_preference", &self.power_preference) + .field("supported_backends", &supported_backends) + .field("present_mode", &present_mode) + .field( + "desired_maximum_frame_latency", + &desired_maximum_frame_latency, + ) + .field("power_preference", &power_preference) .finish_non_exhaustive() } } @@ -274,6 +295,8 @@ impl Default for WgpuConfiguration { present_mode: wgpu::PresentMode::AutoVsync, + desired_maximum_frame_latency: None, + power_preference: wgpu::util::power_preference_from_env() .unwrap_or(wgpu::PowerPreference::HighPerformance), diff --git a/crates/egui-wgpu/src/winit.rs b/crates/egui-wgpu/src/winit.rs index 15460686205..ca292212a15 100644 --- a/crates/egui-wgpu/src/winit.rs +++ b/crates/egui-wgpu/src/winit.rs @@ -142,7 +142,7 @@ impl Painter { fn configure_surface( surface_state: &SurfaceState, render_state: &RenderState, - present_mode: wgpu::PresentMode, + config: &WgpuConfiguration, ) { crate::profile_function!(); @@ -155,21 +155,25 @@ impl Painter { let width = surface_state.width; let height = surface_state.height; - surface_state.surface.configure( - &render_state.device, - &wgpu::SurfaceConfiguration { - // TODO(emilk): expose `desired_maximum_frame_latency` to eframe users - usage, - format: render_state.target_format, - present_mode, - alpha_mode: surface_state.alpha_mode, - view_formats: vec![render_state.target_format], - ..surface_state - .surface - .get_default_config(&render_state.adapter, width, height) - .expect("The surface isn't supported by this adapter") - }, - ); + let mut surf_config = wgpu::SurfaceConfiguration { + usage, + format: render_state.target_format, + present_mode: config.present_mode, + alpha_mode: surface_state.alpha_mode, + view_formats: vec![render_state.target_format], + ..surface_state + .surface + .get_default_config(&render_state.adapter, width, height) + .expect("The surface isn't supported by this adapter") + }; + + if let Some(desired_maximum_frame_latency) = config.desired_maximum_frame_latency { + surf_config.desired_maximum_frame_latency = desired_maximum_frame_latency; + } + + surface_state + .surface + .configure(&render_state.device, &surf_config); } /// Updates (or clears) the [`winit::window::Window`] associated with the [`Painter`] @@ -328,7 +332,7 @@ impl Painter { surface_state.width = width; surface_state.height = height; - Self::configure_surface(surface_state, render_state, self.configuration.present_mode); + Self::configure_surface(surface_state, render_state, &self.configuration); if let Some(depth_format) = self.depth_format { self.depth_texture_view.insert( @@ -525,11 +529,7 @@ impl Painter { Ok(frame) => frame, Err(err) => match (*self.configuration.on_surface_error)(err) { SurfaceErrorAction::RecreateSurface => { - Self::configure_surface( - surface_state, - render_state, - self.configuration.present_mode, - ); + Self::configure_surface(surface_state, render_state, &self.configuration); return None; } SurfaceErrorAction::SkipFrame => {