From 573bf91c9325008a9e4b29df901c9cc12fa300e8 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:32:21 +0100 Subject: [PATCH 01/16] Expose the raw swapchain from a vulkan `Surface` --- wgpu-hal/src/vulkan/mod.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 26186d5fa8..3197eea5a9 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -375,6 +375,16 @@ pub struct Surface { swapchain: RwLock>, } +impl Surface { + /// Get the raw Vulkan swapchain associated with this surface. + /// + /// Returns `None` if the surface is not configured. + pub fn raw_swapchain(&self) -> Option { + let read = self.swapchain.read(); + read.as_ref().map(|it| it.raw) + } +} + #[derive(Debug)] pub struct SurfaceTexture { index: u32, From 0189345078b1afd1fea8f439314108c2b145e0b1 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:41:01 +0100 Subject: [PATCH 02/16] Allow setting the present timing information on hal Vulkan --- wgpu-hal/Cargo.toml | 9 ++++-- wgpu-hal/src/vulkan/adapter.rs | 13 +++++++- wgpu-hal/src/vulkan/device.rs | 1 + wgpu-hal/src/vulkan/mod.rs | 56 ++++++++++++++++++++++++++++++++-- 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index ee2808b19d..74b32f0b3f 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -105,6 +105,11 @@ device_lost_panic = [] # Only affects the d3d12 and vulkan backends. internal_error_panic = [] +# Enable the VK_GOOGLE_display_timing Vulkan extension if supported. +# This API has no stability guarantees. +# https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html +unstable_vulkan_google_display_timing = [] + [[example]] name = "halmark" @@ -204,8 +209,8 @@ features = ["wgsl-in"] [dev-dependencies] cfg-if.workspace = true env_logger.workspace = true -glam.workspace = true # for ray-traced-triangle example -winit.workspace = true # for "halmark" example +glam.workspace = true # for ray-traced-triangle example +winit.workspace = true # for "halmark" example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] glutin.workspace = true # for "gles" example diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index f323456eaa..7059eaeec1 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1,6 +1,6 @@ use super::conv; -use ash::{amd, ext, khr, vk}; +use ash::{amd, ext, google, khr, vk}; use parking_lot::Mutex; use std::{collections::BTreeMap, ffi::CStr, sync::Arc}; @@ -1004,6 +1004,12 @@ impl PhysicalDeviceProperties { extensions.push(khr::shader_atomic_int64::NAME); } + #[cfg(feature = "unstable_vulkan_google_display_timing")] + // Support VK_GOOGLE_display_timing if it is requested *and* available. + if self.supports_extension(google::display_timing::NAME) { + extensions.push(google::display_timing::NAME); + } + extensions } @@ -1812,6 +1818,9 @@ impl super::Adapter { 0, 0, 0, 0, ]; + #[cfg(feature = "unstable_vulkan_google_display_timing")] + let has_display_timing = enabled_extensions.contains(&google::display_timing::NAME); + let shared = Arc::new(super::DeviceShared { raw: raw_device, family_index, @@ -1821,6 +1830,8 @@ impl super::Adapter { instance: Arc::clone(&self.instance), physical_device: self.raw, enabled_extensions: enabled_extensions.into(), + #[cfg(feature = "unstable_vulkan_google_display_timing")] + has_google_display_timing_extension: has_display_timing, extension_fns: super::DeviceExtensionFunctions { debug_utils: debug_utils_fn, draw_indirect_count: indirect_count_fn, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 70136bdfb5..9ba50fc46b 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -642,6 +642,7 @@ impl super::Device { view_formats: wgt_view_formats, surface_semaphores, next_semaphore_index: 0, + next_present_times: None, }) } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 3197eea5a9..58c1483e12 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -40,7 +40,10 @@ use std::{ }; use arrayvec::ArrayVec; -use ash::{ext, khr, vk}; +use ash::{ + ext, khr, + vk::{self, PresentTimeGOOGLE}, +}; use parking_lot::{Mutex, RwLock}; use wgt::InternalCounter; @@ -355,6 +358,8 @@ struct Swapchain { /// index as the image index, but we need to specify the semaphore as an argument /// to the acquire_next_image function which is what tells us which image to use. next_semaphore_index: usize, + #[cfg(feature = "unstable_vulkan_google_display_timing")] + next_present_times: Option, } impl Swapchain { @@ -383,6 +388,27 @@ impl Surface { let read = self.swapchain.read(); read.as_ref().map(|it| it.raw) } + + /// Set the present timing information which will be used for the next presentation. + /// + /// Warns if the device doesn't [support present timing](Device::supports_google_display_timing). + /// + /// # Panics + /// + /// If the surface hasn't been configured. + #[cfg(feature = "unstable_vulkan_google_display_timing")] + #[track_caller] + pub fn set_next_present_times(&self, present_timing: PresentTimeGOOGLE) { + let mut swapchain = self.swapchain.write(); + let swapchain = swapchain + .as_mut() + .expect("Surface should have been configured"); + if swapchain.device.has_google_display_timing_extension { + swapchain.next_present_times = Some(present_timing); + } else { + log::warn!("Tried to call set_next_present_times on a device which doesn't support."); + } + } } #[derive(Debug)] @@ -561,6 +587,8 @@ struct DeviceShared { instance: Arc, physical_device: vk::PhysicalDevice, enabled_extensions: Vec<&'static CStr>, + #[cfg(feature = "unstable_vulkan_google_display_timing")] + has_google_display_timing_extension: bool, extension_fns: DeviceExtensionFunctions, vendor_id: u32, pipeline_cache_validation_key: [u8; 16], @@ -585,6 +613,16 @@ pub struct Device { counters: wgt::HalCounters, } +impl Device { + /// Returns true if this device supports [VK_GOOGLE_display_timing]. + /// + /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html + #[cfg(feature = "unstable_vulkan_google_display_timing")] + pub fn supports_google_display_timing(&self) -> bool { + self.shared.has_google_display_timing_extension + } +} + /// Semaphores for forcing queue submissions to run in order. /// /// The [`wgpu_hal::Queue`] trait promises that if two calls to [`submit`] are @@ -1167,7 +1205,21 @@ impl crate::Queue for Queue { .swapchains(&swapchains) .image_indices(&image_indices) .wait_semaphores(swapchain_semaphores.get_present_wait_semaphores()); - + #[cfg(feature = "unstable_vulkan_google_display_timing")] + let mut display_timing; + #[cfg(feature = "unstable_vulkan_google_display_timing")] + let present_times; + #[cfg(feature = "unstable_vulkan_google_display_timing")] + let vk_info = if let Some(present_time) = ssc.next_present_times.take() { + assert!(ssc.device.has_google_display_timing_extension); + display_timing = vk::PresentTimesInfoGOOGLE::default(); + present_times = [present_time]; + display_timing = display_timing.times(&present_times); + // Safety: We know that the display_timing extension is present. + vk_info.push_next(&mut display_timing) + } else { + vk_info + }; let suboptimal = { profiling::scope!("vkQueuePresentKHR"); unsafe { self.swapchain_fn.queue_present(self.raw, &vk_info) }.map_err(|error| { From 8e975d62692284015d48150a96dd0e4088b88b5d Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 23 Aug 2024 20:02:30 +0100 Subject: [PATCH 03/16] Fix clippy without the feature enabled --- wgpu-hal/src/vulkan/adapter.rs | 8 ++++---- wgpu-hal/src/vulkan/device.rs | 1 + wgpu-hal/src/vulkan/mod.rs | 9 +++------ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 7059eaeec1..23039786a8 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1,6 +1,6 @@ use super::conv; -use ash::{amd, ext, google, khr, vk}; +use ash::{amd, ext, khr, vk}; use parking_lot::Mutex; use std::{collections::BTreeMap, ffi::CStr, sync::Arc}; @@ -1006,8 +1006,8 @@ impl PhysicalDeviceProperties { #[cfg(feature = "unstable_vulkan_google_display_timing")] // Support VK_GOOGLE_display_timing if it is requested *and* available. - if self.supports_extension(google::display_timing::NAME) { - extensions.push(google::display_timing::NAME); + if self.supports_extension(ash::google::display_timing::NAME) { + extensions.push(ash::google::display_timing::NAME); } extensions @@ -1819,7 +1819,7 @@ impl super::Adapter { ]; #[cfg(feature = "unstable_vulkan_google_display_timing")] - let has_display_timing = enabled_extensions.contains(&google::display_timing::NAME); + let has_display_timing = enabled_extensions.contains(&ash::google::display_timing::NAME); let shared = Arc::new(super::DeviceShared { raw: raw_device, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 9ba50fc46b..28735ff771 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -642,6 +642,7 @@ impl super::Device { view_formats: wgt_view_formats, surface_semaphores, next_semaphore_index: 0, + #[cfg(feature = "unstable_vulkan_google_display_timing")] next_present_times: None, }) } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 58c1483e12..984ea02f71 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -40,10 +40,7 @@ use std::{ }; use arrayvec::ArrayVec; -use ash::{ - ext, khr, - vk::{self, PresentTimeGOOGLE}, -}; +use ash::{ext, khr, vk}; use parking_lot::{Mutex, RwLock}; use wgt::InternalCounter; @@ -359,7 +356,7 @@ struct Swapchain { /// to the acquire_next_image function which is what tells us which image to use. next_semaphore_index: usize, #[cfg(feature = "unstable_vulkan_google_display_timing")] - next_present_times: Option, + next_present_times: Option, } impl Swapchain { @@ -398,7 +395,7 @@ impl Surface { /// If the surface hasn't been configured. #[cfg(feature = "unstable_vulkan_google_display_timing")] #[track_caller] - pub fn set_next_present_times(&self, present_timing: PresentTimeGOOGLE) { + pub fn set_next_present_times(&self, present_timing: vk::PresentTimeGOOGLE) { let mut swapchain = self.swapchain.write(); let swapchain = swapchain .as_mut() From 5a7a205e58787bc47bae2bea6e29e9d70fb0ed20 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Fri, 23 Aug 2024 20:09:38 +0100 Subject: [PATCH 04/16] CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21ec6bde0c..90117f1056 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,10 @@ By @wumpf in [#6069](https://github.com/gfx-rs/wgpu/pull/6069), [#6099](https:// * Support constant evaluation for `firstLeadingBit` and `firstTrailingBit` numeric built-ins in WGSL. Front-ends that translate to these built-ins also benefit from constant evaluation. By @ErichDonGubler in [#5101](https://github.com/gfx-rs/wgpu/pull/5101). +#### Vulkan + +- Allow using [VK_GOOGLE_display_timing](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html) unsafely. By @DJMcNab in [#6149](https://github.com/gfx-rs/wgpu/pull/6149) + ### Bug Fixes - Fix incorrect hlsl image output type conversion. By @atlv24 in [#6123](https://github.com/gfx-rs/wgpu/pull/6123) From 62cef44a1fa04f9ef811362d2b3fd8f80ee306b6 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sat, 24 Aug 2024 09:07:00 +0100 Subject: [PATCH 05/16] Revert inadvertently formatted Cargo.toml --- wgpu-hal/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 74b32f0b3f..6a3508d4d1 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -209,8 +209,8 @@ features = ["wgsl-in"] [dev-dependencies] cfg-if.workspace = true env_logger.workspace = true -glam.workspace = true # for ray-traced-triangle example -winit.workspace = true # for "halmark" example +glam.workspace = true # for ray-traced-triangle example +winit.workspace = true # for "halmark" example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] glutin.workspace = true # for "gles" example From 064c5f6b301f9d5acf8c04146f2de3d1ac5a6a6d Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:30:23 +0100 Subject: [PATCH 06/16] Move display timing to a feature --- wgpu-hal/Cargo.toml | 4 ---- wgpu-hal/src/vulkan/adapter.rs | 17 +++++++------- wgpu-hal/src/vulkan/device.rs | 1 - wgpu-hal/src/vulkan/mod.rs | 43 ++++++++++++++-------------------- wgpu-types/src/lib.rs | 13 ++++++++++ 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 6a3508d4d1..654ce8a6da 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -105,10 +105,6 @@ device_lost_panic = [] # Only affects the d3d12 and vulkan backends. internal_error_panic = [] -# Enable the VK_GOOGLE_display_timing Vulkan extension if supported. -# This API has no stability guarantees. -# https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html -unstable_vulkan_google_display_timing = [] [[example]] name = "halmark" diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 23039786a8..7b8f3d37c6 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1,6 +1,6 @@ use super::conv; -use ash::{amd, ext, khr, vk}; +use ash::{amd, ext, google, khr, vk}; use parking_lot::Mutex; use std::{collections::BTreeMap, ffi::CStr, sync::Arc}; @@ -771,6 +771,11 @@ impl PhysicalDeviceFeatures { ); } + features.set( + F::VULKAN_GOOGLE_DISPLAY_TIMING, + caps.supports_extension(google::display_timing::NAME), + ); + (features, dl_flags) } @@ -1004,9 +1009,8 @@ impl PhysicalDeviceProperties { extensions.push(khr::shader_atomic_int64::NAME); } - #[cfg(feature = "unstable_vulkan_google_display_timing")] - // Support VK_GOOGLE_display_timing if it is requested *and* available. - if self.supports_extension(ash::google::display_timing::NAME) { + // Require `VK_GOOGLE_display_timing` if the associated feature was requested + if requested_features.contains(wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING) { extensions.push(ash::google::display_timing::NAME); } @@ -1818,9 +1822,6 @@ impl super::Adapter { 0, 0, 0, 0, ]; - #[cfg(feature = "unstable_vulkan_google_display_timing")] - let has_display_timing = enabled_extensions.contains(&ash::google::display_timing::NAME); - let shared = Arc::new(super::DeviceShared { raw: raw_device, family_index, @@ -1830,8 +1831,6 @@ impl super::Adapter { instance: Arc::clone(&self.instance), physical_device: self.raw, enabled_extensions: enabled_extensions.into(), - #[cfg(feature = "unstable_vulkan_google_display_timing")] - has_google_display_timing_extension: has_display_timing, extension_fns: super::DeviceExtensionFunctions { debug_utils: debug_utils_fn, draw_indirect_count: indirect_count_fn, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 28735ff771..9ba50fc46b 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -642,7 +642,6 @@ impl super::Device { view_formats: wgt_view_formats, surface_semaphores, next_semaphore_index: 0, - #[cfg(feature = "unstable_vulkan_google_display_timing")] next_present_times: None, }) } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 984ea02f71..7c866d190c 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -355,7 +355,10 @@ struct Swapchain { /// index as the image index, but we need to specify the semaphore as an argument /// to the acquire_next_image function which is what tells us which image to use. next_semaphore_index: usize, - #[cfg(feature = "unstable_vulkan_google_display_timing")] + /// The times which will be set in the next present times. + /// + /// SAFETY: This is only set if [wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING] is enabled, and + /// so `VK_GOOGLE_display_timing` is set. next_present_times: Option, } @@ -386,24 +389,24 @@ impl Surface { read.as_ref().map(|it| it.raw) } - /// Set the present timing information which will be used for the next presentation. - /// - /// Warns if the device doesn't [support present timing](Device::supports_google_display_timing). + /// Set the present timing information which will be used for the next presentation using `VK_GOOGLE_display_timing`. /// /// # Panics /// - /// If the surface hasn't been configured. - #[cfg(feature = "unstable_vulkan_google_display_timing")] + /// - If the surface hasn't been configured. + /// - If the device doesn't [support present timing](wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING). #[track_caller] pub fn set_next_present_times(&self, present_timing: vk::PresentTimeGOOGLE) { let mut swapchain = self.swapchain.write(); let swapchain = swapchain .as_mut() .expect("Surface should have been configured"); - if swapchain.device.has_google_display_timing_extension { + let features = wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING; + if swapchain.device.features.contains(features) { swapchain.next_present_times = Some(present_timing); } else { - log::warn!("Tried to call set_next_present_times on a device which doesn't support."); + // Ideally we'd use something like `device.required_features` here, but that's in `wgpu-core`, which we are a dependency of + panic!("Tried to set display timing properties without the corresponding feature ({features:?}) enabled."); } } } @@ -584,8 +587,6 @@ struct DeviceShared { instance: Arc, physical_device: vk::PhysicalDevice, enabled_extensions: Vec<&'static CStr>, - #[cfg(feature = "unstable_vulkan_google_display_timing")] - has_google_display_timing_extension: bool, extension_fns: DeviceExtensionFunctions, vendor_id: u32, pipeline_cache_validation_key: [u8; 16], @@ -610,16 +611,6 @@ pub struct Device { counters: wgt::HalCounters, } -impl Device { - /// Returns true if this device supports [VK_GOOGLE_display_timing]. - /// - /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html - #[cfg(feature = "unstable_vulkan_google_display_timing")] - pub fn supports_google_display_timing(&self) -> bool { - self.shared.has_google_display_timing_extension - } -} - /// Semaphores for forcing queue submissions to run in order. /// /// The [`wgpu_hal::Queue`] trait promises that if two calls to [`submit`] are @@ -1202,17 +1193,19 @@ impl crate::Queue for Queue { .swapchains(&swapchains) .image_indices(&image_indices) .wait_semaphores(swapchain_semaphores.get_present_wait_semaphores()); - #[cfg(feature = "unstable_vulkan_google_display_timing")] let mut display_timing; - #[cfg(feature = "unstable_vulkan_google_display_timing")] let present_times; - #[cfg(feature = "unstable_vulkan_google_display_timing")] let vk_info = if let Some(present_time) = ssc.next_present_times.take() { - assert!(ssc.device.has_google_display_timing_extension); + debug_assert!( + ssc.device + .features + .contains(wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING), + "`next_present_times` should only be set if `VULKAN_GOOGLE_DISPLAY_TIMING` is enabled" + ); display_timing = vk::PresentTimesInfoGOOGLE::default(); present_times = [present_time]; display_timing = display_timing.times(&present_times); - // Safety: We know that the display_timing extension is present. + // Safety: We know that VK_GOOGLE_display_timing is present because of the safety contract on `next_present_times`. vk_info.push_next(&mut display_timing) } else { vk_info diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 4f15e68a17..6fa54bbfc6 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -952,6 +952,19 @@ bitflags::bitflags! { /// /// This is a native only feature. const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 61; + /// Allows using the [VK_GOOGLE_display_timing] Vulkan extension. + /// This is used for frame pacing to reduce latency, and is generally only available on Android. + /// + /// This feature does not have a `wgpu`-level API, and must be accessed via `wgpu-hal`, + /// through various `as_hal` functions. + /// + /// Supported platforms: + /// - Vulkan (with [VK_GOOGLE_display_timing]) + /// + /// This is a native only feature. + /// + /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html + const VULKAN_GOOGLE_DISPLAY_TIMING = 1 << 62; } } From 91afed829d79ffc982f909cc5c531b71f725d851 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:32:26 +0100 Subject: [PATCH 07/16] Update the changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90117f1056..48f652969e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,7 +63,7 @@ By @wumpf in [#6069](https://github.com/gfx-rs/wgpu/pull/6069), [#6099](https:// #### Vulkan -- Allow using [VK_GOOGLE_display_timing](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html) unsafely. By @DJMcNab in [#6149](https://github.com/gfx-rs/wgpu/pull/6149) +- Allow using [VK_GOOGLE_display_timing](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html) unsafely with the `VULKAN_GOOGLE_DISPLAY_TIMING` feature. By @DJMcNab in [#6149](https://github.com/gfx-rs/wgpu/pull/6149) ### Bug Fixes From 911178b9e8010dd5cd82271e01900acdda3f2c63 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:41:19 +0100 Subject: [PATCH 08/16] Whitespace and doc wording tweaks --- wgpu-hal/Cargo.toml | 5 ++--- wgpu-hal/src/vulkan/mod.rs | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 654ce8a6da..060d7a0c31 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -105,7 +105,6 @@ device_lost_panic = [] # Only affects the d3d12 and vulkan backends. internal_error_panic = [] - [[example]] name = "halmark" @@ -205,8 +204,8 @@ features = ["wgsl-in"] [dev-dependencies] cfg-if.workspace = true env_logger.workspace = true -glam.workspace = true # for ray-traced-triangle example -winit.workspace = true # for "halmark" example +glam.workspace = true # for ray-traced-triangle example +winit.workspace = true # for "halmark" example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] glutin.workspace = true # for "gles" example diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 7c866d190c..3e01a01047 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -358,7 +358,7 @@ struct Swapchain { /// The times which will be set in the next present times. /// /// SAFETY: This is only set if [wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING] is enabled, and - /// so `VK_GOOGLE_display_timing` is set. + /// so the `VK_GOOGLE_display_timing` extension is present. next_present_times: Option, } @@ -1193,6 +1193,7 @@ impl crate::Queue for Queue { .swapchains(&swapchains) .image_indices(&image_indices) .wait_semaphores(swapchain_semaphores.get_present_wait_semaphores()); + let mut display_timing; let present_times; let vk_info = if let Some(present_time) = ssc.next_present_times.take() { @@ -1210,6 +1211,7 @@ impl crate::Queue for Queue { } else { vk_info }; + let suboptimal = { profiling::scope!("vkQueuePresentKHR"); unsafe { self.swapchain_fn.queue_present(self.raw, &vk_info) }.map_err(|error| { From 1c04a515b318fa8ce50692f75f352422084d25b5 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:52:27 +0100 Subject: [PATCH 09/16] Apply suggestions from code review Co-authored-by: Marijn Suijten --- wgpu-hal/src/vulkan/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 3e01a01047..e4f3b1b3d0 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -357,7 +357,7 @@ struct Swapchain { next_semaphore_index: usize, /// The times which will be set in the next present times. /// - /// SAFETY: This is only set if [wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING] is enabled, and + /// SAFETY: This is only set if [`wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING`] is enabled, and /// so the `VK_GOOGLE_display_timing` extension is present. next_present_times: Option, } @@ -383,7 +383,7 @@ pub struct Surface { impl Surface { /// Get the raw Vulkan swapchain associated with this surface. /// - /// Returns `None` if the surface is not configured. + /// Returns [`None`] if the surface is not configured. pub fn raw_swapchain(&self) -> Option { let read = self.swapchain.read(); read.as_ref().map(|it| it.raw) @@ -1206,7 +1206,7 @@ impl crate::Queue for Queue { display_timing = vk::PresentTimesInfoGOOGLE::default(); present_times = [present_time]; display_timing = display_timing.times(&present_times); - // Safety: We know that VK_GOOGLE_display_timing is present because of the safety contract on `next_present_times`. + // SAFETY: We know that VK_GOOGLE_display_timing is present because of the safety contract on `next_present_times`. vk_info.push_next(&mut display_timing) } else { vk_info From 50ab5d56235ce84128adecbbe614ef48bcfa475f Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:53:08 +0100 Subject: [PATCH 10/16] Revert inadvertent formatting changes again --- wgpu-hal/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 060d7a0c31..ee2808b19d 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -204,8 +204,8 @@ features = ["wgsl-in"] [dev-dependencies] cfg-if.workspace = true env_logger.workspace = true -glam.workspace = true # for ray-traced-triangle example -winit.workspace = true # for "halmark" example +glam.workspace = true # for ray-traced-triangle example +winit.workspace = true # for "halmark" example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] glutin.workspace = true # for "gles" example From 4c5f56b05f887e04ab5f8080d40c193e1729a7fd Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:54:10 +0100 Subject: [PATCH 11/16] Remove unused qualification Co-authored-by: Marijn Suijten --- wgpu-hal/src/vulkan/adapter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 7b8f3d37c6..d7db62364f 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1011,7 +1011,7 @@ impl PhysicalDeviceProperties { // Require `VK_GOOGLE_display_timing` if the associated feature was requested if requested_features.contains(wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING) { - extensions.push(ash::google::display_timing::NAME); + extensions.push(google::display_timing::NAME); } extensions From 354e9a998117d2e144765abdf50ea8a28125aa9e Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:00:55 +0100 Subject: [PATCH 12/16] Address review feedback --- wgpu-hal/src/vulkan/adapter.rs | 2 +- wgpu-hal/src/vulkan/mod.rs | 10 +++++++--- wgpu-types/src/lib.rs | 7 +++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index d7db62364f..edeeca5e91 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1009,7 +1009,7 @@ impl PhysicalDeviceProperties { extensions.push(khr::shader_atomic_int64::NAME); } - // Require `VK_GOOGLE_display_timing` if the associated feature was requested + // Require VK_GOOGLE_display_timing if the associated feature was requested if requested_features.contains(wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING) { extensions.push(google::display_timing::NAME); } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index e4f3b1b3d0..64979acb11 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -357,8 +357,10 @@ struct Swapchain { next_semaphore_index: usize, /// The times which will be set in the next present times. /// - /// SAFETY: This is only set if [`wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING`] is enabled, and - /// so the `VK_GOOGLE_display_timing` extension is present. + /// # SAFETY + /// + /// This must only be set if [`wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING`] is enabled, and + /// so the VK_GOOGLE_display_timing extension is present. next_present_times: Option, } @@ -389,12 +391,14 @@ impl Surface { read.as_ref().map(|it| it.raw) } - /// Set the present timing information which will be used for the next presentation using `VK_GOOGLE_display_timing`. + /// Set the present timing information which will be used for the next presentation using [VK_GOOGLE_display_timing]. /// /// # Panics /// /// - If the surface hasn't been configured. /// - If the device doesn't [support present timing](wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING). + /// + /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html #[track_caller] pub fn set_next_present_times(&self, present_timing: vk::PresentTimeGOOGLE) { let mut swapchain = self.swapchain.write(); diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 6fa54bbfc6..f34a32ea52 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -953,10 +953,12 @@ bitflags::bitflags! { /// This is a native only feature. const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 61; /// Allows using the [VK_GOOGLE_display_timing] Vulkan extension. + /// /// This is used for frame pacing to reduce latency, and is generally only available on Android. /// - /// This feature does not have a `wgpu`-level API, and must be accessed via `wgpu-hal`, - /// through various `as_hal` functions. + /// This feature does not have a `wgpu`-level API, and so users of wgpu wishing + /// to use this functionality must access it using various `as_hal` functions, + /// primarily [`Surface::as_hal`], to then use. /// /// Supported platforms: /// - Vulkan (with [VK_GOOGLE_display_timing]) @@ -964,6 +966,7 @@ bitflags::bitflags! { /// This is a native only feature. /// /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html + /// [`Surface::as_hal`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html#method.as_hal const VULKAN_GOOGLE_DISPLAY_TIMING = 1 << 62; } } From 374b2591b8c82324968377b6df55dd1c2dc417fd Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:03:31 +0100 Subject: [PATCH 13/16] Fix flow of sentence and follow intra-doc-link --- wgpu-hal/src/vulkan/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 64979acb11..7ce3b34ab4 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -355,7 +355,7 @@ struct Swapchain { /// index as the image index, but we need to specify the semaphore as an argument /// to the acquire_next_image function which is what tells us which image to use. next_semaphore_index: usize, - /// The times which will be set in the next present times. + /// The present timing information which will be set in the next call to [`present`](crate::Queue::present). /// /// # SAFETY /// From 7a3d7597f5c54678003016a01238002710bc8d19 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:08:18 +0100 Subject: [PATCH 14/16] Add more docs to `set_next_present_time`, and rename --- wgpu-hal/src/vulkan/mod.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 7ce3b34ab4..b2c95c9f23 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -391,7 +391,15 @@ impl Surface { read.as_ref().map(|it| it.raw) } - /// Set the present timing information which will be used for the next presentation using [VK_GOOGLE_display_timing]. + /// Set the present timing information which will be used for the next [presentation](crate::Queue::present) of this surface, + /// using [VK_GOOGLE_display_timing]. + /// + /// This can be used to give an id to presentations, for future use of `VkPastPresentationTimingGOOGLE`. + /// Note that `wgpu-hal` does *not* provide a way to use that API - you should manually access this through `ash`. + /// + /// This can also be used to add a "not before" timestamp to the presentation. + /// + /// The exact semantics of the fields are also documented in the [specification](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPresentTimeGOOGLE.html) for the extension. /// /// # Panics /// @@ -400,7 +408,7 @@ impl Surface { /// /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html #[track_caller] - pub fn set_next_present_times(&self, present_timing: vk::PresentTimeGOOGLE) { + pub fn set_next_present_time(&self, present_timing: vk::PresentTimeGOOGLE) { let mut swapchain = self.swapchain.write(); let swapchain = swapchain .as_mut() From 53b6826163e4e4531b34adc28f7127d534cb444b Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:09:10 +0100 Subject: [PATCH 15/16] Also rename `next_present_times` --- wgpu-hal/src/vulkan/device.rs | 2 +- wgpu-hal/src/vulkan/mod.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 9ba50fc46b..6c9ddfe807 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -642,7 +642,7 @@ impl super::Device { view_formats: wgt_view_formats, surface_semaphores, next_semaphore_index: 0, - next_present_times: None, + next_present_time: None, }) } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index b2c95c9f23..1d287464f3 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -361,7 +361,7 @@ struct Swapchain { /// /// This must only be set if [`wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING`] is enabled, and /// so the VK_GOOGLE_display_timing extension is present. - next_present_times: Option, + next_present_time: Option, } impl Swapchain { @@ -415,7 +415,7 @@ impl Surface { .expect("Surface should have been configured"); let features = wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING; if swapchain.device.features.contains(features) { - swapchain.next_present_times = Some(present_timing); + swapchain.next_present_time = Some(present_timing); } else { // Ideally we'd use something like `device.required_features` here, but that's in `wgpu-core`, which we are a dependency of panic!("Tried to set display timing properties without the corresponding feature ({features:?}) enabled."); @@ -1208,7 +1208,7 @@ impl crate::Queue for Queue { let mut display_timing; let present_times; - let vk_info = if let Some(present_time) = ssc.next_present_times.take() { + let vk_info = if let Some(present_time) = ssc.next_present_time.take() { debug_assert!( ssc.device .features From e99a2167bfc1d6f6bb24908e04192e2dbcf1fff1 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:11:23 +0100 Subject: [PATCH 16/16] Apply suggestions from code review Co-authored-by: Marijn Suijten --- wgpu-hal/src/vulkan/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 1d287464f3..9e57f77d03 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -355,9 +355,9 @@ struct Swapchain { /// index as the image index, but we need to specify the semaphore as an argument /// to the acquire_next_image function which is what tells us which image to use. next_semaphore_index: usize, - /// The present timing information which will be set in the next call to [`present`](crate::Queue::present). + /// The present timing information which will be set in the next call to [`present()`](crate::Queue::present()). /// - /// # SAFETY + /// # Safety /// /// This must only be set if [`wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING`] is enabled, and /// so the VK_GOOGLE_display_timing extension is present. @@ -1215,9 +1215,8 @@ impl crate::Queue for Queue { .contains(wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING), "`next_present_times` should only be set if `VULKAN_GOOGLE_DISPLAY_TIMING` is enabled" ); - display_timing = vk::PresentTimesInfoGOOGLE::default(); present_times = [present_time]; - display_timing = display_timing.times(&present_times); + display_timing = vk::PresentTimesInfoGOOGLE::default().times(&present_times); // SAFETY: We know that VK_GOOGLE_display_timing is present because of the safety contract on `next_present_times`. vk_info.push_next(&mut display_timing) } else {