diff --git a/Changelog.md b/Changelog.md index 326644902..54d6fe452 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Update Vulkan-Headers to 1.3.210 (#605) +- Added `VK_EXT_image_drm_format_modifier` device extension (#603) ### Removed diff --git a/ash/src/extensions/ext/image_drm_format_modifier.rs b/ash/src/extensions/ext/image_drm_format_modifier.rs new file mode 100644 index 000000000..d1ceac744 --- /dev/null +++ b/ash/src/extensions/ext/image_drm_format_modifier.rs @@ -0,0 +1,126 @@ +use crate::extensions::khr::GetPhysicalDeviceProperties2; +use crate::prelude::*; +use crate::vk; +use crate::{Device, Instance}; +use std::ffi::CStr; +use std::mem; + +/// +#[derive(Clone)] +pub struct ImageDrmFormatModifier { + handle: vk::Device, + fp: vk::ExtImageDrmFormatModifierFn, +} + +impl ImageDrmFormatModifier { + pub fn new(instance: &Instance, device: &Device) -> Self { + let handle = device.handle(); + let fp = vk::ExtImageDrmFormatModifierFn::load(|name| unsafe { + mem::transmute(instance.get_device_proc_addr(handle, name.as_ptr())) + }); + Self { handle, fp } + } + + /// + pub unsafe fn get_image_drm_format_modifier_properties( + &self, + image: vk::Image, + properties: &mut vk::ImageDrmFormatModifierPropertiesEXT, + ) -> VkResult<()> { + (self.fp.get_image_drm_format_modifier_properties_ext)(self.handle, image, properties) + .result() + } + + /// Retrieve a list of DRM format modifiers the supported for a format on the physical device. + /// + /// This is equivalent to calling [`Instance::get_physical_device_format_properties2`] with + /// [`DrmFormatModifierPropertiesListEXT`](vk::DrmFormatModifierPropertiesListEXT) extending [`FormatProperties2`](vk::FormatProperties2). + /// + /// # Safety + /// + /// * This function requires the [`VK_EXT_image_drm_format_modifier`] extension. + /// * This function requires Vulkan 1.1. + /// + /// If you use Vulkan 1.0, use [`GetPhysicalDeviceProperties2::get_drm_format_properties_list`] + /// instead. + /// + /// [`VK_EXT_image_drm_format_modifier`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_EXT_image_drm_format_modifier.html + pub unsafe fn get_drm_format_properties_list( + instance: &Instance, + pdevice: vk::PhysicalDevice, + format: vk::Format, + mut format_properties: &mut vk::FormatProperties2, + ) -> Vec { + let mut list = vk::DrmFormatModifierPropertiesListEXT::default(); + format_properties.push_next(&mut list); + + read_into_uninitialized_vector(|count, data| { + // The data pointer will always be null on the first invocation of the closure. + list.p_drm_format_modifier_properties = data; + + instance.get_physical_device_format_properties2( + pdevice, + format, + &mut format_properties, + ); + + *count = list.drm_format_modifier_count; + + vk::Result::SUCCESS + }) + // The closure always returns SUCCESS + .unwrap() + } + + pub const fn name() -> &'static CStr { + vk::ExtImageDrmFormatModifierFn::name() + } + + pub fn fp(&self) -> &vk::ExtImageDrmFormatModifierFn { + &self.fp + } + + pub fn device(&self) -> vk::Device { + self.handle + } +} + +// Vulkan 1.0 +impl GetPhysicalDeviceProperties2 { + /// Retrieve a list of DRM format modifiers the supported for a format on the physical device. + /// + /// This is equivalent to calling [`GetPhysicalDeviceProperties2::get_physical_device_format_properties2`] with + /// [`DrmFormatModifierPropertiesListEXT`](vk::DrmFormatModifierPropertiesListEXT) extending [`FormatProperties2KHR`](vk::FormatProperties2KHR). + /// + /// # Safety + /// + /// This function requires the [`VK_EXT_image_drm_format_modifier`] extension. + /// + /// [`VK_EXT_image_drm_format_modifier`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_EXT_image_drm_format_modifier.html + pub unsafe fn get_drm_format_properties_list( + &self, + pdevice: vk::PhysicalDevice, + format: vk::Format, + mut format_properties: &mut vk::FormatProperties2KHR, + ) -> Vec { + let mut list = vk::DrmFormatModifierPropertiesListEXT::default(); + format_properties.push_next(&mut list); + + read_into_uninitialized_vector(|count, data| { + // The data pointer will always be null on the first invocation of the closure. + list.p_drm_format_modifier_properties = data; + + self.get_physical_device_format_properties2( + pdevice, + format, + &mut format_properties, + ); + + *count = list.drm_format_modifier_count; + + vk::Result::SUCCESS + }) + // The closure always returns SUCCESS + .unwrap() + } +} diff --git a/ash/src/extensions/ext/mod.rs b/ash/src/extensions/ext/mod.rs index 7151e27b6..0a71ffdc5 100644 --- a/ash/src/extensions/ext/mod.rs +++ b/ash/src/extensions/ext/mod.rs @@ -9,6 +9,7 @@ pub use self::extended_dynamic_state::ExtendedDynamicState; pub use self::extended_dynamic_state2::ExtendedDynamicState2; pub use self::full_screen_exclusive::FullScreenExclusive; pub use self::headless_surface::HeadlessSurface; +pub use self::image_drm_format_modifier::ImageDrmFormatModifier; pub use self::metal_surface::MetalSurface; pub use self::physical_device_drm::PhysicalDeviceDrm; pub use self::private_data::PrivateData; @@ -25,6 +26,7 @@ mod extended_dynamic_state; mod extended_dynamic_state2; mod full_screen_exclusive; mod headless_surface; +mod image_drm_format_modifier; mod metal_surface; mod physical_device_drm; mod private_data; diff --git a/ash/src/prelude.rs b/ash/src/prelude.rs index 218c59bea..8993598e5 100644 --- a/ash/src/prelude.rs +++ b/ash/src/prelude.rs @@ -30,7 +30,7 @@ impl vk::Result { /// /// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html pub(crate) unsafe fn read_into_uninitialized_vector, T>( - f: impl Fn(&mut N, *mut T) -> vk::Result, + mut f: impl FnMut(&mut N, *mut T) -> vk::Result, ) -> VkResult> where >::Error: std::fmt::Debug, @@ -67,7 +67,7 @@ pub(crate) unsafe fn read_into_defaulted_vector< N: Copy + Default + TryInto, T: Default + Clone, >( - f: impl Fn(&mut N, *mut T) -> vk::Result, + mut f: impl FnMut(&mut N, *mut T) -> vk::Result, ) -> VkResult> where >::Error: std::fmt::Debug, diff --git a/generator/Vulkan-Headers b/generator/Vulkan-Headers index 0c5928795..52a76fd0a 160000 --- a/generator/Vulkan-Headers +++ b/generator/Vulkan-Headers @@ -1 +1 @@ -Subproject commit 0c5928795a66e93f65e5e68a36d8daa79a209dc2 +Subproject commit 52a76fd0a693708eb8c25bd0ab7a1008091f64d4