From a5ab3acb82de6313e06b8def699b1b4d035153c1 Mon Sep 17 00:00:00 2001 From: Marc Pabst <“marcpabst@users.noreply.github.com”> Date: Sun, 23 Mar 2025 13:31:09 +0000 Subject: [PATCH 01/10] initial work to make latency waitable object optional --- deno_webgpu/lib.rs | 1 + tests/src/init.rs | 1 + wgpu-hal/examples/ray-traced-triangle/main.rs | 1 + wgpu-hal/src/dx12/mod.rs | 27 ++++++++++++------- wgpu-types/src/instance.rs | 26 ++++++++++++++++-- 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 44ed02ff06..1b7c421d76 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -151,6 +151,7 @@ impl GPU { backend_options: wgpu_types::BackendOptions { dx12: wgpu_types::Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::Fxc, + ..Default::default() }, gl: wgpu_types::GlBackendOptions::default(), noop: wgpu_types::NoopBackendOptions::default(), diff --git a/tests/src/init.rs b/tests/src/init.rs index 6f93508c20..69cfad5194 100644 --- a/tests/src/init.rs +++ b/tests/src/init.rs @@ -46,6 +46,7 @@ pub fn initialize_instance(backends: wgpu::Backends, params: &TestParameters) -> backend_options: wgpu::BackendOptions { dx12: wgpu::Dx12BackendOptions { shader_compiler: dx12_shader_compiler, + ..Default::default() }, gl: wgpu::GlBackendOptions { fence_behavior: if cfg!(target_family = "wasm") { diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 9e2a7771e1..38086f42cb 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -241,6 +241,7 @@ impl Example { backend_options: wgpu_types::BackendOptions { dx12: Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::default_dynamic_dxc(), + ..Default::default() }, ..Default::default() }, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 48fcbee6eb..35516e85c8 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -519,7 +519,7 @@ struct SwapChain { // when the swapchain is destroyed resources: Vec, /// Handle is freed in [`Self::release_resources()`] - waitable: Foundation::HANDLE, + waitable: Option, acquired_count: usize, present_mode: wgt::PresentMode, format: wgt::TextureFormat, @@ -1118,7 +1118,9 @@ impl crate::DynAccelerationStructure for AccelerationStructure {} impl SwapChain { unsafe fn release_resources(mut self) -> Dxgi::IDXGISwapChain3 { - unsafe { Foundation::HANDLE::free(&mut self.waitable) }; + if let Some(waitable) = self.waitable.take() { + Foundation::HANDLE::free(&mut waitable); + } self.raw } @@ -1130,14 +1132,21 @@ impl SwapChain { Some(duration) => duration.as_millis() as u32, None => Threading::INFINITE, }; - match unsafe { Threading::WaitForSingleObject(self.waitable, timeout_ms) } { - Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => Err(crate::SurfaceError::Lost), - Foundation::WAIT_OBJECT_0 => Ok(true), - Foundation::WAIT_TIMEOUT => Ok(false), - other => { - log::error!("Unexpected wait status: 0x{:x?}", other); - Err(crate::SurfaceError::Lost) + + if let Some(waitable) = self.waitable { + match unsafe { Threading::WaitForSingleObject(waitable, timeout_ms) } { + Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => { + Err(crate::SurfaceError::Lost) + } + Foundation::WAIT_OBJECT_0 => Ok(true), + Foundation::WAIT_TIMEOUT => Ok(false), + other => { + log::error!("Unexpected wait status: 0x{:x?}", other); + Err(crate::SurfaceError::Lost) + } } + } else { + Ok(true) } } } diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 2083049918..7d96992997 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -263,10 +263,21 @@ impl GlBackendOptions { /// Configuration for the DX12 backend. /// /// Part of [`BackendOptions`]. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct Dx12BackendOptions { /// Which DX12 shader compiler to use. pub shader_compiler: Dx12Compiler, + /// Whether to wait for the latency waitable object before acquiring the next swapchain image. + pub use_latency_waitable_object: bool, +} + +impl Default for Dx12BackendOptions { + fn default() -> Self { + Self { + shader_compiler: Dx12Compiler::default(), + use_latency_waitable_object: true, + } + } } impl Dx12BackendOptions { @@ -276,8 +287,12 @@ impl Dx12BackendOptions { #[must_use] pub fn from_env_or_default() -> Self { let compiler = Dx12Compiler::from_env().unwrap_or_default(); + let use_latency_waitable_object = crate::env::var("WGPU_DX12_USE_LATENCY_WAITABLE_OBJECT") + .as_deref() + .map_or(true, |s| s != "0"); Self { shader_compiler: compiler, + use_latency_waitable_object, } } @@ -287,7 +302,14 @@ impl Dx12BackendOptions { #[must_use] pub fn with_env(self) -> Self { let shader_compiler = self.shader_compiler.with_env(); - Self { shader_compiler } + let use_latency_waitable_object = crate::env::var("WGPU_DX12_USE_LATENCY_WAITABLE_OBJECT") + .as_deref() + .map_or(self.use_latency_waitable_object, |s| s != "0"); + + Self { + shader_compiler, + use_latency_waitable_object, + } } } From 075f5eb4d88af1ff23e20e9baab9758f98c4652b Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 14:23:22 +0000 Subject: [PATCH 02/10] add support for use_latency_waitable_object setting for DX12 backend --- wgpu-hal/src/dx12/adapter.rs | 3 +++ wgpu-hal/src/dx12/device.rs | 2 ++ wgpu-hal/src/dx12/instance.rs | 9 ++++++++- wgpu-hal/src/dx12/mod.rs | 12 ++++++++++-- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 50aa80ad28..b0b5c41b2a 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -55,6 +55,7 @@ impl super::Adapter { library: &Arc, instance_flags: wgt::InstanceFlags, dxc_container: Option>, + backend_options: wgt::Dx12BackendOptions, ) -> Option> { // Create the device so that we can get the capabilities. let device = { @@ -519,6 +520,7 @@ impl super::Adapter { presentation_timer, workarounds, dxc_container, + options: backend_options, }, info, features, @@ -656,6 +658,7 @@ impl crate::Adapter for super::Adapter { self.private_caps, &self.library, self.dxc_container.clone(), + self.options.clone(), )?; Ok(crate::OpenDevice { device, diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index cdc6418665..8fdb959270 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -44,6 +44,7 @@ impl super::Device { private_caps: super::PrivateCapabilities, library: &Arc, dxc_container: Option>, + backend_options: wgt::Dx12BackendOptions, ) -> Result { if private_caps .instance_flags @@ -192,6 +193,7 @@ impl super::Device { raw.clone(), Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, )), + options: backend_options, library: Arc::clone(library), #[cfg(feature = "renderdoc")] render_doc: Default::default(), diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index ef02c8aca7..044ab58331 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -112,6 +112,7 @@ impl crate::Instance for super::Instance { supports_allow_tearing, flags: desc.flags, dxc_container, + options: desc.backend_options.dx12.clone(), }) } @@ -144,7 +145,13 @@ impl crate::Instance for super::Instance { adapters .into_iter() .filter_map(|raw| { - super::Adapter::expose(raw, &self.library, self.flags, self.dxc_container.clone()) + super::Adapter::expose( + raw, + &self.library, + self.flags, + self.dxc_container.clone(), + self.options.clone(), + ) }) .collect() } diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 35516e85c8..43463ca562 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -459,6 +459,7 @@ pub struct Instance { supports_allow_tearing: bool, _lib_dxgi: DxgiLib, flags: wgt::InstanceFlags, + options: wgt::Dx12BackendOptions, dxc_container: Option>, } @@ -585,6 +586,7 @@ pub struct Adapter { #[allow(unused)] workarounds: Workarounds, dxc_container: Option>, + options: wgt::Dx12BackendOptions, } unsafe impl Send for Adapter {} @@ -636,6 +638,7 @@ pub struct Device { private_caps: PrivateCapabilities, features: wgt::Features, shared: Arc, + options: wgt::Dx12BackendOptions, // CPU only pools rtv_pool: Mutex, dsv_pool: Mutex, @@ -1118,7 +1121,7 @@ impl crate::DynAccelerationStructure for AccelerationStructure {} impl SwapChain { unsafe fn release_resources(mut self) -> Dxgi::IDXGISwapChain3 { - if let Some(waitable) = self.waitable.take() { + if let Some(mut waitable) = self.waitable.take() { Foundation::HANDLE::free(&mut waitable); } self.raw @@ -1314,7 +1317,12 @@ impl crate::Surface for Surface { unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) } .into_device_result("SetMaximumFrameLatency")?; - let waitable = unsafe { swap_chain.GetFrameLatencyWaitableObject() }; + + let waitable = if device.options.use_latency_waitable_object { + Some(unsafe { swap_chain.GetFrameLatencyWaitableObject() }) + } else { + None + }; let mut resources = Vec::with_capacity(swap_chain_buffer as usize); for i in 0..swap_chain_buffer { From 948b4073b9fc0dff333bd744beca506a48caf9a1 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 14:51:00 +0000 Subject: [PATCH 03/10] add unsafe{} block --- wgpu-hal/src/dx12/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 43463ca562..fede67f505 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -1122,7 +1122,7 @@ impl crate::DynAccelerationStructure for AccelerationStructure {} impl SwapChain { unsafe fn release_resources(mut self) -> Dxgi::IDXGISwapChain3 { if let Some(mut waitable) = self.waitable.take() { - Foundation::HANDLE::free(&mut waitable); + unsafe { Foundation::HANDLE::free(&mut waitable) }; } self.raw } From c2932050b32cfa67a5501e957dfd63d76cc31b96 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 15:15:37 +0000 Subject: [PATCH 04/10] make clippy happy --- wgpu-types/src/instance.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 7d96992997..06425c3040 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -287,9 +287,8 @@ impl Dx12BackendOptions { #[must_use] pub fn from_env_or_default() -> Self { let compiler = Dx12Compiler::from_env().unwrap_or_default(); - let use_latency_waitable_object = crate::env::var("WGPU_DX12_USE_LATENCY_WAITABLE_OBJECT") - .as_deref() - .map_or(true, |s| s != "0"); + let use_latency_waitable_object = + crate::env::var("WGPU_DX12_USE_LATENCY_WAITABLE_OBJECT").as_deref() != Some("0"); Self { shader_compiler: compiler, use_latency_waitable_object, From 84d4b275b5c37a28ceb4700f41a3b0c3cb047907 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 18:10:50 +0000 Subject: [PATCH 05/10] Introduced `Dx12UseFrameLatencyWaitableObject` enum and add a public `wait_for_latency_object` method that allows waiting manually for the waitable handle --- wgpu-types/src/instance.rs | 73 ++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 06425c3040..d20eba8190 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -263,21 +263,12 @@ impl GlBackendOptions { /// Configuration for the DX12 backend. /// /// Part of [`BackendOptions`]. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct Dx12BackendOptions { /// Which DX12 shader compiler to use. pub shader_compiler: Dx12Compiler, /// Whether to wait for the latency waitable object before acquiring the next swapchain image. - pub use_latency_waitable_object: bool, -} - -impl Default for Dx12BackendOptions { - fn default() -> Self { - Self { - shader_compiler: Dx12Compiler::default(), - use_latency_waitable_object: true, - } - } + pub latency_waitable_object: Dx12UseFrameLatencyWaitableObject, } impl Dx12BackendOptions { @@ -287,11 +278,11 @@ impl Dx12BackendOptions { #[must_use] pub fn from_env_or_default() -> Self { let compiler = Dx12Compiler::from_env().unwrap_or_default(); - let use_latency_waitable_object = - crate::env::var("WGPU_DX12_USE_LATENCY_WAITABLE_OBJECT").as_deref() != Some("0"); + let latency_waitable_object = + Dx12UseFrameLatencyWaitableObject::from_env().unwrap_or_default(); Self { shader_compiler: compiler, - use_latency_waitable_object, + latency_waitable_object, } } @@ -301,13 +292,11 @@ impl Dx12BackendOptions { #[must_use] pub fn with_env(self) -> Self { let shader_compiler = self.shader_compiler.with_env(); - let use_latency_waitable_object = crate::env::var("WGPU_DX12_USE_LATENCY_WAITABLE_OBJECT") - .as_deref() - .map_or(self.use_latency_waitable_object, |s| s != "0"); + let latency_waitable_object = self.latency_waitable_object.with_env(); Self { shader_compiler, - use_latency_waitable_object, + latency_waitable_object, } } } @@ -450,6 +439,54 @@ impl Dx12Compiler { } } +/// Whether and how to use a waitable handle obtained from `GetFrameLatencyWaitableObject`. +#[derive(Clone, Debug, Default)] +pub enum Dx12UseFrameLatencyWaitableObject { + /// Do not obtain a waitable handle and do not wait for it. The swapchain will + /// be created without the `DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT` flag. + None, + /// Obtain a waitable handle and wait for it before acquiring the next swapchain image. + #[default] + Wait, + /// Create the swapchain with the `DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT` flag and + /// obtain a waitable handle, but do not wait for it before acquiring the next swapchain image. + /// This is useful if the application wants to wait for the waitable object itself. + DontWait, +} + +impl Dx12UseFrameLatencyWaitableObject { + /// Choose whether to use a frame latency waitable object from the environment variable `WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT`. + /// + /// Valid values, case insensitive: + /// - `None` + /// - `Wait` + /// - `DontWait` + #[must_use] + pub fn from_env() -> Option { + let value = crate::env::var("WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT") + .as_deref()? + .to_lowercase(); + match value.as_str() { + "none" => Some(Self::None), + "wait" => Some(Self::Wait), + "dontwait" => Some(Self::DontWait), + _ => None, + } + } + + /// Takes the given setting, modifies it based on the `WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT` environment variable, and returns the result. + /// + /// See `from_env` for more information. + #[must_use] + pub fn with_env(self) -> Self { + if let Some(compiler) = Self::from_env() { + compiler + } else { + self + } + } +} + /// Selects which OpenGL ES 3 minor version to request. /// /// When using ANGLE as an OpenGL ES/EGL implementation, explicitly requesting `Version1` can provide a non-conformant ES 3.1 on APIs like D3D11. From a15f887bba4f02cbd1ee2a8e29209cc6383921d0 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 18:13:49 +0000 Subject: [PATCH 06/10] fix stupid error --- wgpu-hal/src/dx12/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index fede67f505..3c0781ce4e 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -1318,10 +1318,12 @@ impl crate::Surface for Surface { unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) } .into_device_result("SetMaximumFrameLatency")?; - let waitable = if device.options.use_latency_waitable_object { - Some(unsafe { swap_chain.GetFrameLatencyWaitableObject() }) - } else { - None + let waitable = match device.options.latency_waitable_object { + wgt::Dx12UseFrameLatencyWaitableObject::None => None, + wgt::Dx12UseFrameLatencyWaitableObject::Wait + | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => { + Some(unsafe { swap_chain.GetFrameLatencyWaitableObject() }) + } }; let mut resources = Vec::with_capacity(swap_chain_buffer as usize); From a4e4d03d81d379a16aedf185f1dc28075725a24f Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 18:25:37 +0000 Subject: [PATCH 07/10] make sure we only call wait() when desired --- wgpu-hal/src/dx12/instance.rs | 1 + wgpu-hal/src/dx12/mod.rs | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 044ab58331..90e840c5b3 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -129,6 +129,7 @@ impl crate::Instance for super::Instance { target: SurfaceTarget::WndHandle(Foundation::HWND(handle.hwnd.get() as *mut _)), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), }), _ => Err(crate::InstanceError::new(format!( "window handle {window_handle:?} is not a Win32 handle" diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 3c0781ce4e..f2af581c64 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -473,6 +473,7 @@ impl Instance { target: SurfaceTarget::Visual(visual.to_owned()), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), } } @@ -490,6 +491,7 @@ impl Instance { target: SurfaceTarget::SurfaceHandle(surface_handle), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), } } @@ -506,6 +508,7 @@ impl Instance { target: SurfaceTarget::SwapChainPanel(swap_chain_panel.to_owned()), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), } } } @@ -542,6 +545,7 @@ pub struct Surface { target: SurfaceTarget, supports_allow_tearing: bool, swap_chain: RwLock>, + options: wgt::Dx12BackendOptions, } unsafe impl Send for Surface {} @@ -1371,7 +1375,13 @@ impl crate::Surface for Surface { let mut swapchain = self.swap_chain.write(); let sc = swapchain.as_mut().unwrap(); - unsafe { sc.wait(timeout) }?; + match self.options.latency_waitable_object { + wgt::Dx12UseFrameLatencyWaitableObject::None => {} + wgt::Dx12UseFrameLatencyWaitableObject::Wait + | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => { + unsafe { sc.wait(timeout) }?; + } + } let base_index = unsafe { sc.raw.GetCurrentBackBufferIndex() } as usize; let index = (base_index + sc.acquired_count) % sc.resources.len(); From 0e7457275dc12c0435c35c2436c921bf694b58c1 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 18:38:55 +0000 Subject: [PATCH 08/10] add `wait_for_frame_latency_object` --- wgpu-hal/src/dx12/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index f2af581c64..043c96fd7c 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -551,6 +551,23 @@ pub struct Surface { unsafe impl Send for Surface {} unsafe impl Sync for Surface {} +impl Surface { + pub unsafe fn wait_for_frame_latency_object( + &self, + timeout: Option, + ) -> Result { + match self.options.latency_waitable_object { + wgt::Dx12UseFrameLatencyWaitableObject::None => Ok(false), + wgt::Dx12UseFrameLatencyWaitableObject::Wait + | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => { + let mut swapchain = self.swap_chain.write(); + let sc = swapchain.as_mut().unwrap(); + unsafe { sc.wait(timeout) } + } + } + } +} + #[derive(Debug, Clone, Copy)] enum MemoryArchitecture { Unified { From 4e1b81339e9ea555ef22d1625c0c3fda7355afc3 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Sun, 23 Mar 2025 18:48:25 +0000 Subject: [PATCH 09/10] fix another error --- wgpu-hal/src/dx12/mod.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 043c96fd7c..0bb2edec9e 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -556,15 +556,9 @@ impl Surface { &self, timeout: Option, ) -> Result { - match self.options.latency_waitable_object { - wgt::Dx12UseFrameLatencyWaitableObject::None => Ok(false), - wgt::Dx12UseFrameLatencyWaitableObject::Wait - | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => { - let mut swapchain = self.swap_chain.write(); - let sc = swapchain.as_mut().unwrap(); - unsafe { sc.wait(timeout) } - } - } + let mut swapchain = self.swap_chain.write(); + let sc = swapchain.as_mut().unwrap(); + unsafe { sc.wait(timeout) } } } @@ -1393,9 +1387,9 @@ impl crate::Surface for Surface { let sc = swapchain.as_mut().unwrap(); match self.options.latency_waitable_object { - wgt::Dx12UseFrameLatencyWaitableObject::None => {} - wgt::Dx12UseFrameLatencyWaitableObject::Wait - | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => { + wgt::Dx12UseFrameLatencyWaitableObject::None + | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => {} + wgt::Dx12UseFrameLatencyWaitableObject::Wait => { unsafe { sc.wait(timeout) }?; } } From 2298c4dc2a5ae274f11808731747fd9484fdc037 Mon Sep 17 00:00:00 2001 From: Marc Pabst Date: Wed, 16 Apr 2025 17:24:01 +0100 Subject: [PATCH 10/10] expose waitable handle --- wgpu-hal/src/dx12/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 0bb2edec9e..593ab5f192 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -552,13 +552,13 @@ unsafe impl Send for Surface {} unsafe impl Sync for Surface {} impl Surface { - pub unsafe fn wait_for_frame_latency_object( - &self, - timeout: Option, - ) -> Result { - let mut swapchain = self.swap_chain.write(); - let sc = swapchain.as_mut().unwrap(); - unsafe { sc.wait(timeout) } + /// Returns the waitable handle of the swapchain, if it exists. + pub unsafe fn waitable_handle(&self) -> Option { + let swapchain = self.swap_chain.read(); + if let Some(swap_chain) = swapchain.as_ref() { + return swap_chain.waitable.clone(); + } + None } }