@@ -257,12 +257,21 @@ impl Surface for NativeSurface {
257257 let images = unsafe { functor. get_swapchain_images ( raw) }
258258 . map_err ( crate :: vulkan:: map_host_device_oom_err) ?;
259259
260- let fence = unsafe {
261- device
262- . shared
263- . raw
264- . create_fence ( & vk:: FenceCreateInfo :: default ( ) , None )
265- . map_err ( crate :: vulkan:: map_host_device_oom_err) ?
260+ // This fence is only used to throttle acquisition on Windows. It is very important to
261+ // avoid bad frame pacing when the Vulkan driver is using a DXGI swapchain. See
262+ // https://github.com/gfx-rs/wgpu/issues/8310 and
263+ // https://github.com/gfx-rs/wgpu/issues/8354 for more details.
264+ let fence = if cfg ! ( target_os = "windows" ) {
265+ let raw = unsafe {
266+ device
267+ . shared
268+ . raw
269+ . create_fence ( & vk:: FenceCreateInfo :: default ( ) , None )
270+ . map_err ( crate :: vulkan:: map_host_device_oom_err) ?
271+ } ;
272+ Some ( raw)
273+ } else {
274+ None
266275 } ;
267276
268277 // NOTE: It's important that we define the same number of acquire/present semaphores
@@ -309,7 +318,7 @@ pub(crate) struct NativeSwapchain {
309318 device : Arc < DeviceShared > ,
310319 images : Vec < vk:: Image > ,
311320 /// Fence used to wait on the acquired image.
312- fence : vk:: Fence ,
321+ fence : Option < vk:: Fence > ,
313322 config : crate :: SurfaceConfiguration ,
314323
315324 /// Semaphores used between image acquisition and the first submission
@@ -382,7 +391,9 @@ impl Swapchain for NativeSwapchain {
382391 } ;
383392 } ;
384393
385- unsafe { device. shared . raw . destroy_fence ( self . fence , None ) }
394+ if let Some ( fence) = self . fence {
395+ unsafe { device. shared . raw . destroy_fence ( fence, None ) }
396+ }
386397
387398 // We cannot take this by value, as the function returns `self`.
388399 for semaphore in self . acquire_semaphores . drain ( ..) {
@@ -455,14 +466,16 @@ impl Swapchain for NativeSwapchain {
455466 return Err ( crate :: SurfaceError :: Timeout ) ;
456467 }
457468
469+ let acquire_fence = self . fence . unwrap_or_else ( vk:: Fence :: null) ;
470+
458471 // will block if no image is available
459472 let ( index, suboptimal) = match unsafe {
460473 profiling:: scope!( "vkAcquireNextImageKHR" ) ;
461474 self . functor . acquire_next_image (
462475 self . raw ,
463476 timeout_ns,
464477 acquire_semaphore_guard. acquire ,
465- self . fence ,
478+ acquire_fence ,
466479 )
467480 } {
468481 // We treat `VK_SUBOPTIMAL_KHR` as `VK_SUCCESS` on Android.
@@ -485,24 +498,19 @@ impl Swapchain for NativeSwapchain {
485498 }
486499 } ;
487500
488- // Wait for the image was acquired to be fully ready to be rendered too.
489- //
490- // This wait is very important on Windows to avoid bad frame pacing on
491- // Windows where the Vulkan driver is using a DXGI swapchain. See
492- // https://github.com/gfx-rs/wgpu/issues/8310 and
493- // https://github.com/gfx-rs/wgpu/issues/8354 for more details.
494- #[ cfg( target_os = "windows" ) ]
495- unsafe {
496- // The `wait_all` argument must be `true` to avoid crash on some Android devices. See https://github.com/gfx-rs/wgpu/pull/8769
497- self . device
498- . raw
499- . wait_for_fences ( & [ self . fence ] , true , timeout_ns)
500- . map_err ( map_host_device_oom_and_lost_err) ?;
501-
502- self . device
503- . raw
504- . reset_fences ( & [ self . fence ] )
505- . map_err ( map_host_device_oom_and_lost_err) ?;
501+ if let Some ( fence) = self . fence {
502+ unsafe {
503+ // The `wait_all` argument must be `true` to avoid crash on some Android devices. See https://github.com/gfx-rs/wgpu/pull/8769
504+ self . device
505+ . raw
506+ . wait_for_fences ( & [ fence] , true , timeout_ns)
507+ . map_err ( map_host_device_oom_and_lost_err) ?;
508+
509+ self . device
510+ . raw
511+ . reset_fences ( & [ fence] )
512+ . map_err ( map_host_device_oom_and_lost_err) ?;
513+ }
506514 }
507515
508516 drop ( acquire_semaphore_guard) ;
0 commit comments