Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,13 @@ impl super::Device {
let images =
unsafe { functor.get_swapchain_images(raw) }.map_err(super::map_host_device_oom_err)?;

let fence = unsafe {
self.shared
.raw
.create_fence(&vk::FenceCreateInfo::default(), None)
.map_err(super::map_host_device_oom_err)?
};

// NOTE: It's important that we define the same number of acquire/present semaphores
// as we will need to index into them with the image index.
let acquire_semaphores = (0..=images.len())
Expand All @@ -597,6 +604,7 @@ impl super::Device {
functor,
device: Arc::clone(&self.shared),
images,
fence,
config: config.clone(),
acquire_semaphores,
next_acquire_index: 0,
Expand Down
28 changes: 27 additions & 1 deletion wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ impl super::Swapchain {
};
};

unsafe { device.destroy_fence(self.fence, None) }

// We cannot take this by value, as the function returns `self`.
for semaphore in self.acquire_semaphores.drain(..) {
let arc_removed = Arc::into_inner(semaphore).expect(
Expand Down Expand Up @@ -1115,7 +1117,7 @@ impl crate::Surface for super::Surface {
swapchain.raw,
timeout_ns,
acquire_semaphore_guard.acquire,
vk::Fence::null(),
swapchain.fence,
)
} {
// We treat `VK_SUBOPTIMAL_KHR` as `VK_SUCCESS` on Android.
Expand All @@ -1138,6 +1140,30 @@ impl crate::Surface for super::Surface {
}
};

// Wait for the image was acquired to be fully ready to be rendered too.
//
// This wait is very important on Windows to avoid bad frame pacing on
// Windows where the Vulkan driver is using a DXGI swapchain. See
// https://github.com/gfx-rs/wgpu/issues/8310 and
// https://github.com/gfx-rs/wgpu/issues/8354 for more details.
//
// On other platforms, this wait may serve to slightly decrease frame
// latency, depending on how the platform implements waiting within
// acquire.
unsafe {
swapchain
.device
.raw
.wait_for_fences(&[swapchain.fence], false, timeout_ns)
.map_err(super::map_host_device_oom_and_lost_err)?;

swapchain
.device
.raw
.reset_fences(&[swapchain.fence])
.map_err(super::map_host_device_oom_and_lost_err)?;
}

drop(acquire_semaphore_guard);
// We only advance the surface semaphores if we successfully acquired an image, otherwise
// we should try to re-acquire using the same semaphores.
Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ struct Swapchain {
functor: khr::swapchain::Device,
device: Arc<DeviceShared>,
images: Vec<vk::Image>,
/// Fence used to wait on the acquired image.
fence: vk::Fence,
config: crate::SurfaceConfiguration,

/// Semaphores used between image acquisition and the first submission
Expand Down
Loading