Skip to content

Commit 685c213

Browse files
DJMcNabMarijnS95
andauthored
hal: cargo feature to allow using VK_GOOGLE_display_timing unsafely (#6149)
* Expose the raw swapchain from a vulkan `Surface` * Allow setting the present timing information on hal Vulkan * Fix clippy without the feature enabled * CHANGELOG * Revert inadvertently formatted Cargo.toml * Move display timing to a feature * Update the changelog * Whitespace and doc wording tweaks * Apply suggestions from code review Co-authored-by: Marijn Suijten <marijns95@gmail.com> * Revert inadvertent formatting changes again * Remove unused qualification Co-authored-by: Marijn Suijten <marijns95@gmail.com> * Address review feedback * Fix flow of sentence and follow intra-doc-link * Add more docs to `set_next_present_time`, and rename * Also rename `next_present_times` * Apply suggestions from code review Co-authored-by: Marijn Suijten <marijns95@gmail.com> --------- Co-authored-by: Marijn Suijten <marijns95@gmail.com>
1 parent 070f760 commit 685c213

File tree

5 files changed

+97
-1
lines changed

5 files changed

+97
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ By @teoxoy [#6134](https://github.com/gfx-rs/wgpu/pull/6134).
7171

7272
* 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).
7373

74+
#### Vulkan
75+
76+
- 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)
77+
7478
### Bug Fixes
7579

7680
- Fix incorrect hlsl image output type conversion. By @atlv24 in [#6123](https://github.com/gfx-rs/wgpu/pull/6123)

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::conv;
22

3-
use ash::{amd, ext, khr, vk};
3+
use ash::{amd, ext, google, khr, vk};
44
use parking_lot::Mutex;
55

66
use std::{collections::BTreeMap, ffi::CStr, sync::Arc};
@@ -771,6 +771,11 @@ impl PhysicalDeviceFeatures {
771771
);
772772
}
773773

774+
features.set(
775+
F::VULKAN_GOOGLE_DISPLAY_TIMING,
776+
caps.supports_extension(google::display_timing::NAME),
777+
);
778+
774779
(features, dl_flags)
775780
}
776781

@@ -1004,6 +1009,11 @@ impl PhysicalDeviceProperties {
10041009
extensions.push(khr::shader_atomic_int64::NAME);
10051010
}
10061011

1012+
// Require VK_GOOGLE_display_timing if the associated feature was requested
1013+
if requested_features.contains(wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING) {
1014+
extensions.push(google::display_timing::NAME);
1015+
}
1016+
10071017
extensions
10081018
}
10091019

wgpu-hal/src/vulkan/device.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ impl super::Device {
642642
view_formats: wgt_view_formats,
643643
surface_semaphores,
644644
next_semaphore_index: 0,
645+
next_present_time: None,
645646
})
646647
}
647648

wgpu-hal/src/vulkan/mod.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,13 @@ struct Swapchain {
355355
/// index as the image index, but we need to specify the semaphore as an argument
356356
/// to the acquire_next_image function which is what tells us which image to use.
357357
next_semaphore_index: usize,
358+
/// The present timing information which will be set in the next call to [`present()`](crate::Queue::present()).
359+
///
360+
/// # Safety
361+
///
362+
/// This must only be set if [`wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING`] is enabled, and
363+
/// so the VK_GOOGLE_display_timing extension is present.
364+
next_present_time: Option<vk::PresentTimeGOOGLE>,
358365
}
359366

360367
impl Swapchain {
@@ -375,6 +382,47 @@ pub struct Surface {
375382
swapchain: RwLock<Option<Swapchain>>,
376383
}
377384

385+
impl Surface {
386+
/// Get the raw Vulkan swapchain associated with this surface.
387+
///
388+
/// Returns [`None`] if the surface is not configured.
389+
pub fn raw_swapchain(&self) -> Option<vk::SwapchainKHR> {
390+
let read = self.swapchain.read();
391+
read.as_ref().map(|it| it.raw)
392+
}
393+
394+
/// Set the present timing information which will be used for the next [presentation](crate::Queue::present) of this surface,
395+
/// using [VK_GOOGLE_display_timing].
396+
///
397+
/// This can be used to give an id to presentations, for future use of `VkPastPresentationTimingGOOGLE`.
398+
/// Note that `wgpu-hal` does *not* provide a way to use that API - you should manually access this through `ash`.
399+
///
400+
/// This can also be used to add a "not before" timestamp to the presentation.
401+
///
402+
/// 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.
403+
///
404+
/// # Panics
405+
///
406+
/// - If the surface hasn't been configured.
407+
/// - If the device doesn't [support present timing](wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING).
408+
///
409+
/// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html
410+
#[track_caller]
411+
pub fn set_next_present_time(&self, present_timing: vk::PresentTimeGOOGLE) {
412+
let mut swapchain = self.swapchain.write();
413+
let swapchain = swapchain
414+
.as_mut()
415+
.expect("Surface should have been configured");
416+
let features = wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING;
417+
if swapchain.device.features.contains(features) {
418+
swapchain.next_present_time = Some(present_timing);
419+
} else {
420+
// Ideally we'd use something like `device.required_features` here, but that's in `wgpu-core`, which we are a dependency of
421+
panic!("Tried to set display timing properties without the corresponding feature ({features:?}) enabled.");
422+
}
423+
}
424+
}
425+
378426
#[derive(Debug)]
379427
pub struct SurfaceTexture {
380428
index: u32,
@@ -1158,6 +1206,23 @@ impl crate::Queue for Queue {
11581206
.image_indices(&image_indices)
11591207
.wait_semaphores(swapchain_semaphores.get_present_wait_semaphores());
11601208

1209+
let mut display_timing;
1210+
let present_times;
1211+
let vk_info = if let Some(present_time) = ssc.next_present_time.take() {
1212+
debug_assert!(
1213+
ssc.device
1214+
.features
1215+
.contains(wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING),
1216+
"`next_present_times` should only be set if `VULKAN_GOOGLE_DISPLAY_TIMING` is enabled"
1217+
);
1218+
present_times = [present_time];
1219+
display_timing = vk::PresentTimesInfoGOOGLE::default().times(&present_times);
1220+
// SAFETY: We know that VK_GOOGLE_display_timing is present because of the safety contract on `next_present_times`.
1221+
vk_info.push_next(&mut display_timing)
1222+
} else {
1223+
vk_info
1224+
};
1225+
11611226
let suboptimal = {
11621227
profiling::scope!("vkQueuePresentKHR");
11631228
unsafe { self.swapchain_fn.queue_present(self.raw, &vk_info) }.map_err(|error| {

wgpu-types/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,22 @@ bitflags::bitflags! {
952952
///
953953
/// This is a native only feature.
954954
const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 61;
955+
/// Allows using the [VK_GOOGLE_display_timing] Vulkan extension.
956+
///
957+
/// This is used for frame pacing to reduce latency, and is generally only available on Android.
958+
///
959+
/// This feature does not have a `wgpu`-level API, and so users of wgpu wishing
960+
/// to use this functionality must access it using various `as_hal` functions,
961+
/// primarily [`Surface::as_hal`], to then use.
962+
///
963+
/// Supported platforms:
964+
/// - Vulkan (with [VK_GOOGLE_display_timing])
965+
///
966+
/// This is a native only feature.
967+
///
968+
/// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html
969+
/// [`Surface::as_hal`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html#method.as_hal
970+
const VULKAN_GOOGLE_DISPLAY_TIMING = 1 << 62;
955971
}
956972
}
957973

0 commit comments

Comments
 (0)