mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
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>
This commit is contained in:
parent
070f760940
commit
685c2133f2
@ -71,6 +71,10 @@ By @teoxoy [#6134](https://github.com/gfx-rs/wgpu/pull/6134).
|
||||
|
||||
* 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 with the `VULKAN_GOOGLE_DISPLAY_TIMING` feature. 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)
|
||||
|
@ -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,6 +1009,11 @@ impl PhysicalDeviceProperties {
|
||||
extensions.push(khr::shader_atomic_int64::NAME);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
extensions
|
||||
}
|
||||
|
||||
|
@ -642,6 +642,7 @@ impl super::Device {
|
||||
view_formats: wgt_view_formats,
|
||||
surface_semaphores,
|
||||
next_semaphore_index: 0,
|
||||
next_present_time: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -355,6 +355,13 @@ 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()).
|
||||
///
|
||||
/// # 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_time: Option<vk::PresentTimeGOOGLE>,
|
||||
}
|
||||
|
||||
impl Swapchain {
|
||||
@ -375,6 +382,47 @@ pub struct Surface {
|
||||
swapchain: RwLock<Option<Swapchain>>,
|
||||
}
|
||||
|
||||
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<vk::SwapchainKHR> {
|
||||
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](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
|
||||
///
|
||||
/// - 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_time(&self, present_timing: vk::PresentTimeGOOGLE) {
|
||||
let mut swapchain = self.swapchain.write();
|
||||
let swapchain = swapchain
|
||||
.as_mut()
|
||||
.expect("Surface should have been configured");
|
||||
let features = wgt::Features::VULKAN_GOOGLE_DISPLAY_TIMING;
|
||||
if swapchain.device.features.contains(features) {
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SurfaceTexture {
|
||||
index: u32,
|
||||
@ -1158,6 +1206,23 @@ impl crate::Queue for Queue {
|
||||
.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_time.take() {
|
||||
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"
|
||||
);
|
||||
present_times = [present_time];
|
||||
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 {
|
||||
vk_info
|
||||
};
|
||||
|
||||
let suboptimal = {
|
||||
profiling::scope!("vkQueuePresentKHR");
|
||||
unsafe { self.swapchain_fn.queue_present(self.raw, &vk_info) }.map_err(|error| {
|
||||
|
@ -952,6 +952,22 @@ 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 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])
|
||||
///
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user