bedrock/
base.rs

1//! Vulkan Base Objects(Instance/PhysicalDevice)
2
3use crate::ffi_helper::{CStrFFIRef, slice_as_ptr_empty_null};
4use crate::*;
5use derives::implements;
6
7#[cfg(feature = "Multithreaded")]
8struct LazyCellReadRef<'d, T>(::std::sync::RwLockReadGuard<'d, Option<T>>);
9#[cfg(feature = "Multithreaded")]
10impl<'d, T> ::std::ops::Deref for LazyCellReadRef<'d, T> {
11    type Target = T;
12    fn deref(&self) -> &T {
13        self.0.as_ref().unwrap()
14    }
15}
16
17/// A Value Object represents the Vulkan version number
18// Note: (MSB) major | minor | patch (LSB) の順でビットが割り当てられているので合成した状態の比較で正しい順序になる
19#[repr(transparent)]
20#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
21pub struct Version(u32);
22impl Version {
23    /// Version 1.0.0
24    pub const V1: Self = Self::new(0, 1, 0, 0);
25
26    /// Construct an object from discrete values
27    pub const fn new(variant: u8, major: u16, minor: u16, patch: u16) -> Self {
28        Self(crate::vk::VK_MAKE_VERSION(variant, major, minor, patch))
29    }
30
31    /// Construct an object from a raw value
32    pub const fn from_raw(v: u32) -> Self {
33        Self(v)
34    }
35
36    /// Gets a raw value from this object
37    pub const fn raw(&self) -> u32 {
38        self.0
39    }
40
41    /// Version variant number
42    pub const fn variant(&self) -> u8 {
43        crate::vk::VK_VARIANT_VERSION(self.0)
44    }
45
46    /// Major version number
47    pub const fn major(&self) -> u16 {
48        crate::vk::VK_MAJOR_VERSION(self.0)
49    }
50
51    /// Minor version number
52    pub const fn minor(&self) -> u16 {
53        crate::vk::VK_MINOR_VERSION(self.0)
54    }
55
56    /// Patch version number
57    pub const fn patch(&self) -> u16 {
58        crate::vk::VK_PATCH_VERSION(self.0)
59    }
60}
61impl core::fmt::Display for Version {
62    #[inline]
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        // TODO: Variantを含めたバージョン表示
65        write!(f, "{}.{}.{}", self.major(), self.minor(), self.patch())
66    }
67}
68
69/// Query instance-level version before instance creation
70/// # Failures
71/// On failure, this command returns
72///
73/// * `VK_ERROR_OUT_OF_HOST_MEMORY`
74#[inline]
75#[implements]
76pub fn instance_version() -> crate::Result<Version> {
77    #[cfg(feature = "Allow1_1APIs")]
78    unsafe {
79        let mut sink = 0;
80        crate::vkfn::enumerate_instance_version(&mut sink).into_result()?;
81        Ok(Version(sink))
82    }
83    #[cfg(not(feature = "Allow1_1APIs"))]
84    {
85        // fixed to v1.0.0
86        Ok(Version::V1)
87    }
88}
89
90#[implements]
91type InstanceResolvedFn<F> = crate::resolver::ResolvedFnCell<F, VkInstance>;
92#[implements]
93impl crate::resolver::ResolverInterface for VkInstance {
94    #[inline(always)]
95    unsafe fn load_symbol_unconstrainted<T: crate::resolver::FromPtr>(&self, name: &core::ffi::CStr) -> T {
96        unsafe {
97            T::from_ptr(core::mem::transmute(crate::vkfn::get_instance_proc_addr(
98                *self,
99                name.as_ptr() as _,
100            )))
101        }
102    }
103
104    #[tracing::instrument(name = "<VkInstance as ResolverInterface>::load_function_unconstrainted", skip(self), fields(name = ?F::NAME_CSTR))]
105    unsafe fn load_function_unconstrainted<F: crate::resolver::PFN>(&self) -> F {
106        match unsafe { crate::vkfn::get_instance_proc_addr(*self, F::NAME_CSTR.as_ptr() as _) } {
107            Some(x) => unsafe { F::from_void_fn(x) },
108            None => {
109                tracing::error!("instance function not found, bedrock could not continue");
110                std::process::abort();
111            }
112        }
113    }
114}
115
116/// Opaque handle to a physical device object
117///
118/// ## Platform Dependent Methods: Presentation Support checking functions
119///
120/// * `xlib_presentation_support(&self, queue_family: u32, display: *mut x11::xlib::Display, visual: x11::xlib::VisualID) -> bool`: VK_KHR_xlib_surface
121/// * `xcb_presentation_support(&self, queue_family: u32, connection: *mut xcb::ffi::xcb_connection_t, visual: xcb::ffi::xcb_visualid_t) -> bool`: VK_KHR_xcb_surface
122/// * `wayland_presentation_support(&self, queue_family: u32, display: *mut wayland_client::sys::wl_display) -> bool`: VK_KHR_wayland_surface
123/// * `win32_presentation_support(&self, queue_family: u32) -> bool`: VK_KHR_win32_surface
124/// * Methods for Android and Mir surfaces are not implemented
125#[derive(VkHandle, VkObject, crate::InstanceChild, crate::InstanceChildTransferrable, Clone)]
126#[VkObject(type = VK_OBJECT_TYPE_PHYSICAL_DEVICE)]
127pub struct PhysicalDeviceObject<Owner: Instance>(VkPhysicalDevice, #[parent] Owner);
128unsafe impl<Owner: Instance + Sync> Sync for PhysicalDeviceObject<Owner> {}
129unsafe impl<Owner: Instance + Send> Send for PhysicalDeviceObject<Owner> {}
130impl<Owner: Instance> PhysicalDevice for PhysicalDeviceObject<Owner> {}
131impl<Owner: Instance> PhysicalDeviceObject<Owner> {
132    pub const unsafe fn manage(handle: VkPhysicalDevice, owner: Owner) -> Self {
133        Self(handle, owner)
134    }
135
136    pub const fn unmanage(self) -> (VkPhysicalDevice, Owner) {
137        let handle = self.0;
138        let owner = unsafe { core::ptr::read(&self.1) };
139        core::mem::forget(self);
140
141        (handle, owner)
142    }
143}
144impl<Owner: Instance + Clone> PhysicalDeviceObject<&'_ Owner> {
145    /// Split the lifetime from owner by cloning it.
146    #[inline(always)]
147    pub fn clone_parent(&self) -> PhysicalDeviceObject<Owner> {
148        PhysicalDeviceObject(self.0, self.1.clone())
149    }
150}
151
152pub struct IterPhysicalDevices<'i, Source: Instance + 'i + ?Sized>(Vec<VkPhysicalDevice>, usize, &'i Source);
153impl<'i, Source: Instance + 'i + ?Sized> Iterator for IterPhysicalDevices<'i, Source> {
154    type Item = PhysicalDeviceObject<&'i Source>;
155
156    #[inline(always)]
157    fn next(&mut self) -> Option<PhysicalDeviceObject<&'i Source>> {
158        if self.0.len() <= self.1 {
159            None
160        } else {
161            self.1 += 1;
162            Some(PhysicalDeviceObject(self.0[self.1 - 1], self.2))
163        }
164    }
165    #[inline(always)]
166    fn size_hint(&self) -> (usize, Option<usize>) {
167        (self.0.len(), Some(self.0.len()))
168    }
169}
170impl<'i, Source: Instance + 'i + ?Sized> ExactSizeIterator for IterPhysicalDevices<'i, Source> {
171    #[inline(always)]
172    fn len(&self) -> usize {
173        self.0.len()
174    }
175}
176impl<'i, Source: Instance + 'i + ?Sized> DoubleEndedIterator for IterPhysicalDevices<'i, Source> {
177    #[inline(always)]
178    fn next_back(&mut self) -> Option<PhysicalDeviceObject<&'i Source>> {
179        if self.0.len() <= self.1 {
180            None
181        } else {
182            self.0.pop().map(|p| PhysicalDeviceObject(p, self.2))
183        }
184    }
185}
186
187#[repr(transparent)]
188pub struct ApplicationInfo<'d>(VkApplicationInfo, core::marker::PhantomData<&'d core::ffi::CStr>);
189impl<'d> ApplicationInfo<'d> {
190    #[inline(always)]
191    pub const fn new(
192        app_name: &'d core::ffi::CStr,
193        app_version: Version,
194        engine_name: &'d core::ffi::CStr,
195        engine_version: Version,
196    ) -> Self {
197        Self(
198            VkApplicationInfo {
199                sType: VkApplicationInfo::TYPE,
200                pNext: core::ptr::null(),
201                apiVersion: VK_API_VERSION_1_0,
202                pApplicationName: app_name.as_ptr(),
203                applicationVersion: app_version.0,
204                pEngineName: engine_name.as_ptr(),
205                engineVersion: engine_version.0,
206            },
207            core::marker::PhantomData,
208        )
209    }
210
211    #[inline(always)]
212    pub const fn api_version(mut self, version: Version) -> Self {
213        self.0.apiVersion = version.0;
214        self
215    }
216}
217
218#[derive(Debug, Clone, Copy, PartialEq, Eq)]
219#[bitflags_newtype]
220pub struct InstanceCreateFlags(VkInstanceCreateFlags);
221impl InstanceCreateFlags {
222    /// Empty bits.
223    pub const EMPTY: Self = Self(0);
224
225    #[cfg(feature = "VK_KHR_portability_enumeration")]
226    /// The instance will enumerate available Vulkan Portability-compliant physical devices and groups
227    /// in addition to the Vulkan physical devices and groups that are enumerated by default.
228    pub const ENUMERATE_PORTABILITY: Self = Self(VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR);
229}
230
231#[repr(transparent)]
232#[derive(Clone)]
233pub struct InstanceCreateInfo<'d>(
234    VkInstanceCreateInfo,
235    core::marker::PhantomData<(
236        Option<&'d dyn VulkanStructure>,
237        &'d ApplicationInfo<'d>,
238        &'d [CStrFFIRef<'d>],
239    )>,
240);
241impl<'d> InstanceCreateInfo<'d> {
242    pub const fn new(
243        application_info: &'d ApplicationInfo<'d>,
244        layers: &'d [CStrFFIRef<'d>],
245        extensions: &'d [CStrFFIRef<'d>],
246    ) -> Self {
247        Self(
248            VkInstanceCreateInfo {
249                sType: VkInstanceCreateInfo::TYPE,
250                pNext: core::ptr::null(),
251                flags: 0,
252                pApplicationInfo: &application_info.0 as *const _,
253                enabledLayerCount: layers.len() as _,
254                ppEnabledLayerNames: slice_as_ptr_empty_null(layers) as _,
255                enabledExtensionCount: extensions.len() as _,
256                ppEnabledExtensionNames: slice_as_ptr_empty_null(extensions) as _,
257            },
258            core::marker::PhantomData,
259        )
260    }
261
262    pub const unsafe fn from_raw(raw: VkInstanceCreateInfo) -> Self {
263        Self(raw, core::marker::PhantomData)
264    }
265
266    pub const fn into_raw(self) -> VkInstanceCreateInfo {
267        self.0
268    }
269
270    #[inline(always)]
271    pub fn with_next(mut self, next: &'d (impl VulkanStructure + ?Sized)) -> Self {
272        self.0.pNext = next.as_generic() as *const _ as _;
273        self
274    }
275
276    pub const fn flags(mut self, flags: InstanceCreateFlags) -> Self {
277        self.0.flags = flags.bits();
278        self
279    }
280}
281
282/// Create a new Vulkan instance
283/// # Failures
284/// On failure, this command returns
285///
286/// * `VK_ERROR_OUT_OF_HOST_MEMORY`
287/// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
288/// * `VK_ERROR_INITIALIZATION_FAILED`
289/// * `VK_ERROR_LAYER_NOT_PRESENT`
290/// * `VK_ERROR_EXTENSION_NOT_PRESENT`
291/// * `VK_ERROR_INCOMPATIBLE_DRIVER`
292///
293/// # Safety
294/// no guarantees will be provided (simply calls under api)
295#[implements]
296pub unsafe fn new_instance_raw(
297    info: &InstanceCreateInfo,
298    allocation_callbacks: Option<&VkAllocationCallbacks>,
299) -> crate::Result<VkInstance> {
300    let mut h = core::mem::MaybeUninit::uninit();
301
302    unsafe {
303        crate::vkfn::create_instance(
304            &info.0,
305            crate::ffi_helper::opt_pointer(allocation_callbacks),
306            h.as_mut_ptr(),
307        )
308        .into_result()?;
309    }
310    Ok(unsafe { h.assume_init() })
311}
312
313/// Returns a count of all of global layer properties
314/// # Failures
315/// On failure, this command returns
316///
317/// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
318/// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
319#[implements]
320#[inline]
321pub fn instance_layer_property_count() -> crate::Result<u32> {
322    let mut n = 0;
323    unsafe {
324        crate::vkfn::enumerate_instance_layer_properties(&mut n, core::ptr::null_mut()).into_result()?;
325    }
326
327    Ok(n)
328}
329
330/// Returns up to all of global layer properties
331/// # Failures
332/// On failure, this command returns
333///
334/// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
335/// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
336#[implements]
337#[inline]
338pub fn instance_layer_properties(sink: &mut [core::mem::MaybeUninit<VkLayerProperties>]) -> crate::Result<u32> {
339    let mut n = sink.len() as _;
340    unsafe {
341        crate::vkfn::enumerate_instance_layer_properties(&mut n, sink.as_mut_ptr() as _).into_result()?;
342    }
343
344    Ok(n)
345}
346
347/// Returns up to all of global layer properties
348/// # Failures
349/// On failure, this command returns
350///
351/// * `VK_ERROR_OUT_OF_HOST_MEMORY`
352/// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
353#[implements("alloc")]
354pub fn enumerate_layer_properties_alloc() -> crate::Result<Vec<VkLayerProperties>> {
355    let n = instance_layer_property_count()?;
356    if n == 0 {
357        // no items
358        return Ok(crate::alloc::empty_sink_buffer());
359    }
360
361    let mut xs = Vec::with_capacity(n as _);
362    instance_layer_properties(xs.spare_capacity_mut())?;
363    unsafe {
364        xs.set_len(n as _);
365    }
366
367    Ok(xs)
368}
369
370/// Returns a count up to all of global extension properties
371/// # Failures
372/// On failure, this command returns
373///
374/// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
375/// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
376/// * [`VK_ERROR_LAYER_NOT_PRESENT`]
377#[implements]
378#[inline]
379pub fn instance_extension_property_count_cstr(layer_name: Option<&core::ffi::CStr>) -> crate::Result<u32> {
380    let mut n = 0;
381    unsafe {
382        crate::vkfn::enumerate_instance_extension_properties(
383            crate::ffi_helper::opt_cstr_ptr(layer_name),
384            &mut n,
385            core::ptr::null_mut(),
386        )
387        .into_result()?;
388    }
389
390    Ok(n)
391}
392
393/// Returns up to all of global extension properties
394/// # Failures
395/// On failure, this command returns
396///
397/// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
398/// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
399/// * [`VK_ERROR_LAYER_NOT_PRESENT`]
400#[implements]
401#[inline]
402pub fn instance_extension_properties_cstr(
403    layer_name: Option<&core::ffi::CStr>,
404    sink: &mut [core::mem::MaybeUninit<VkExtensionProperties>],
405) -> crate::Result<u32> {
406    let mut n = sink.len() as _;
407    unsafe {
408        crate::vkfn::enumerate_instance_extension_properties(
409            crate::ffi_helper::opt_cstr_ptr(layer_name),
410            &mut n,
411            sink.as_mut_ptr() as _,
412        )
413        .into_result()?;
414    }
415
416    Ok(n)
417}
418
419/// Returns up to all of global extension properties
420/// # Failures
421/// On failure, this command returns
422///
423/// * `VK_ERROR_OUT_OF_HOST_MEMORY`
424/// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
425/// * `VK_ERROR_LAYER_NOT_PRESENT`
426#[implements("alloc")]
427pub fn instance_extension_properties_cstr_alloc(
428    layer_name: Option<&core::ffi::CStr>,
429) -> crate::Result<Vec<VkExtensionProperties>> {
430    let n = instance_extension_property_count_cstr(layer_name)? as usize;
431    if n == 0 {
432        // no items
433        return Ok(crate::alloc::empty_sink_buffer());
434    }
435
436    let mut xs = Vec::with_capacity(n);
437    instance_extension_properties_cstr(layer_name, xs.spare_capacity_mut())?;
438    unsafe {
439        xs.set_len(n);
440    }
441
442    Ok(xs)
443}
444
445/// Returns up to all of global extension properties
446/// # Failures
447/// On failure, this command returns
448///
449/// * `VK_ERROR_OUT_OF_HOST_MEMORY`
450/// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
451/// * `VK_ERROR_LAYER_NOT_PRESENT`
452#[implements("alloc")]
453pub fn instance_extension_properties(layer_name: Option<&str>) -> crate::Result<Vec<VkExtensionProperties>> {
454    instance_extension_properties_cstr_alloc(layer_name.map(|s| crate::alloc::str_to_cstr(s).unwrap()).as_deref())
455}
456/// Opaque handle to a instance object
457#[derive(VkHandle, VkObject)]
458#[VkObject(type = VK_OBJECT_TYPE_INSTANCE)]
459pub struct InstanceObject {
460    #[handle]
461    handle: VkInstance,
462    #[cfg(feature = "Implements")]
463    ext: InstanceExtFunctions,
464}
465unsafe impl Sync for InstanceObject {}
466unsafe impl Send for InstanceObject {}
467#[implements]
468impl Drop for InstanceObject {
469    fn drop(&mut self) {
470        unsafe {
471            crate::vkfn::destroy_instance(self.handle, core::ptr::null());
472        }
473    }
474}
475impl Instance for InstanceObject {}
476impl InstanceObject {
477    /// Create a new Vulkan instance
478    /// # Failures
479    /// On failure, this command returns
480    ///
481    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
482    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
483    /// * `VK_ERROR_INITIALIZATION_FAILED`
484    /// * `VK_ERROR_LAYER_NOT_PRESENT`
485    /// * `VK_ERROR_EXTENSION_NOT_PRESENT`
486    /// * `VK_ERROR_INCOMPATIBLE_DRIVER`
487    #[implements]
488    #[inline]
489    pub fn new(info: &InstanceCreateInfo) -> crate::Result<Self> {
490        unsafe { Ok(Self::manage(new_instance_raw(info, None)?)) }
491    }
492
493    /// Constructs from raw handle
494    /// # Safety
495    /// the handle must be valid and not freed
496    pub const unsafe fn manage(handle: VkInstance) -> Self {
497        Self {
498            handle,
499            #[cfg(feature = "Implements")]
500            ext: InstanceExtFunctions::new(handle),
501        }
502    }
503
504    /// Purges internal values (Drop will not be called for this resource)
505    pub const fn unmanage(self) -> VkInstance {
506        let v = self.handle;
507        core::mem::forget(self);
508
509        v
510    }
511}
512
513/// A Vulkan Instance interface
514pub trait Instance: VkHandle<Handle = VkInstance> {
515    /// Return a function pointer for a command
516    #[deprecated = "do not use this directly(this does not provide caching!)"]
517    #[implements]
518    #[inline]
519    fn extra_procedure(&self, name: &core::ffi::CStr) -> Option<PFN_vkVoidFunction> {
520        unsafe { crate::vkfn::get_instance_proc_addr(self.native_ptr(), name.as_ptr()) }
521    }
522
523    /// Counts the physical devices accessible to a Vulkan instance
524    /// # Failures
525    /// On failure, this command returns
526    ///
527    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
528    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
529    /// * [`VK_ERROR_INITIALIZATION_FAILED`]
530    #[implements]
531    #[inline]
532    fn physical_device_count(&self) -> crate::Result<u32> {
533        let mut n = 0;
534        unsafe {
535            crate::vkfn::enumerate_physical_devices(self.native_ptr(), &mut n, core::ptr::null_mut()).into_result()?;
536        }
537
538        Ok(n)
539    }
540
541    /// Enumerates the physical devices accessible to a Vulkan instance
542    /// # Failures
543    /// On failure, this command returns
544    ///
545    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
546    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
547    /// * [`VK_ERROR_INITIALIZATION_FAILED`]
548    #[implements]
549    #[inline]
550    fn enumerate_physical_devices(&self, sink: &mut [core::mem::MaybeUninit<VkPhysicalDevice>]) -> crate::Result<u32> {
551        let mut n = sink.len() as _;
552        unsafe {
553            crate::vkfn::enumerate_physical_devices(self.native_ptr(), &mut n, sink.as_mut_ptr() as _).into_result()?;
554        }
555
556        Ok(n)
557    }
558
559    /// Lazyly enumerates the physical devices accessible to a Vulkan instance
560    ///
561    /// # Failures
562    ///
563    /// On failure, this command returns
564    ///
565    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
566    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
567    /// * `VK_ERROR_INITIALIZATION_FAILED`
568    #[implements("alloc")]
569    fn iter_physical_devices(&self) -> crate::Result<IterPhysicalDevices<Self>> {
570        let n = self.physical_device_count()? as usize;
571        if n == 0 {
572            // no items
573            return Ok(IterPhysicalDevices(crate::alloc::empty_sink_buffer(), 0, self));
574        }
575
576        let mut xs = Vec::with_capacity(n);
577        self.enumerate_physical_devices(xs.spare_capacity_mut())?;
578        unsafe {
579            xs.set_len(n);
580        }
581
582        Ok(IterPhysicalDevices(xs, 0, self))
583    }
584
585    /// Enumerates the physical devices accessible to a Vulkan instance
586    /// # Failures
587    /// On failure, this command returns
588    ///
589    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
590    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
591    /// * `VK_ERROR_INITIALIZATION_FAILED`
592    #[implements("alloc")]
593    fn enumerate_physical_devices_alloc(&self) -> crate::Result<Vec<PhysicalDeviceObject<&Self>>> {
594        self.iter_physical_devices().map(crate::alloc::collect_vec)
595    }
596}
597DerefContainerWithGuardsBracketImpl!(for Instance {});
598
599/// Extension function caches
600#[implements]
601struct InstanceExtFunctions {
602    #[cfg(feature = "VK_KHR_get_physical_device_properties2")]
603    get_physical_device_properties2_khr: InstanceResolvedFn<PFN_vkGetPhysicalDeviceProperties2KHR>,
604    #[cfg(feature = "VK_KHR_get_physical_device_properties2")]
605    get_physical_device_features2_khr: InstanceResolvedFn<PFN_vkGetPhysicalDeviceFeatures2KHR>,
606    #[cfg(feature = "VK_KHR_get_physical_device_properties2")]
607    get_physical_device_format_properties2_khr: InstanceResolvedFn<PFN_vkGetPhysicalDeviceFormatProperties2KHR>,
608    #[cfg(feature = "VK_EXT_debug_report")]
609    create_debug_report_callback_ext: InstanceResolvedFn<PFN_vkCreateDebugReportCallbackEXT>,
610    #[cfg(feature = "VK_EXT_debug_report")]
611    destroy_debug_report_callback_ext: InstanceResolvedFn<PFN_vkDestroyDebugReportCallbackEXT>,
612    #[cfg(feature = "VK_EXT_debug_report")]
613    debug_report_message_ext: InstanceResolvedFn<PFN_vkDebugReportMessageEXT>,
614    #[cfg(feature = "VK_EXT_debug_utils")]
615    create_debug_utils_messenger_ext: InstanceResolvedFn<PFN_vkCreateDebugUtilsMessengerEXT>,
616    #[cfg(feature = "VK_EXT_debug_utils")]
617    destroy_debug_utils_messenger_ext: InstanceResolvedFn<PFN_vkDestroyDebugUtilsMessengerEXT>,
618    #[cfg(feature = "VK_EXT_debug_utils")]
619    set_debug_utils_object_name_ext: InstanceResolvedFn<PFN_vkSetDebugUtilsObjectNameEXT>,
620    #[cfg(feature = "VK_KHR_external_fence_capabilities")]
621    get_physical_device_external_fence_properties_khr:
622        InstanceResolvedFn<PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR>,
623    #[cfg(feature = "VK_EXT_acquire_xlib_display")]
624    get_randr_output_display_ext: InstanceResolvedFn<PFN_vkGetRandROutputDisplayEXT>,
625    #[cfg(feature = "VK_EXT_acquire_xlib_display")]
626    acquire_xlib_display_ext: InstanceResolvedFn<PFN_vkAcquireXlibDisplayEXT>,
627    #[cfg(feature = "VK_EXT_full_screen_exclusive")]
628    get_physical_device_surface_present_modes_2_ext: InstanceResolvedFn<PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT>,
629    #[cfg(feature = "VK_KHR_get_surface_capabilities2")]
630    get_physical_device_surface_capabilities_2_khr: InstanceResolvedFn<PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR>,
631    #[cfg(feature = "VK_EXT_direct_mode_display")]
632    release_display_ext: InstanceResolvedFn<PFN_vkReleaseDisplayEXT>,
633    #[cfg(feature = "VK_EXT_sample_locations")]
634    get_physical_device_multisample_properties_ext: InstanceResolvedFn<PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT>,
635}
636#[implements]
637impl InstanceExtFunctions {
638    const fn new(r: VkInstance) -> Self {
639        Self {
640            #[cfg(feature = "VK_KHR_get_physical_device_properties2")]
641            get_physical_device_properties2_khr: InstanceResolvedFn::new(r),
642            #[cfg(feature = "VK_KHR_get_physical_device_properties2")]
643            get_physical_device_features2_khr: InstanceResolvedFn::new(r),
644            #[cfg(feature = "VK_KHR_get_physical_device_properties2")]
645            get_physical_device_format_properties2_khr: InstanceResolvedFn::new(r),
646            #[cfg(feature = "VK_EXT_debug_report")]
647            create_debug_report_callback_ext: InstanceResolvedFn::new(r),
648            #[cfg(feature = "VK_EXT_debug_report")]
649            destroy_debug_report_callback_ext: InstanceResolvedFn::new(r),
650            #[cfg(feature = "VK_EXT_debug_report")]
651            debug_report_message_ext: InstanceResolvedFn::new(r),
652            #[cfg(feature = "VK_EXT_debug_utils")]
653            create_debug_utils_messenger_ext: InstanceResolvedFn::new(r),
654            #[cfg(feature = "VK_EXT_debug_utils")]
655            destroy_debug_utils_messenger_ext: InstanceResolvedFn::new(r),
656            #[cfg(feature = "VK_EXT_debug_utils")]
657            set_debug_utils_object_name_ext: InstanceResolvedFn::new(r),
658            #[cfg(feature = "VK_KHR_external_fence_capabilities")]
659            get_physical_device_external_fence_properties_khr: InstanceResolvedFn::new(r),
660            #[cfg(feature = "VK_EXT_acquire_xlib_display")]
661            get_randr_output_display_ext: InstanceResolvedFn::new(r),
662            #[cfg(feature = "VK_EXT_acquire_xlib_display")]
663            acquire_xlib_display_ext: InstanceResolvedFn::new(r),
664            #[cfg(feature = "VK_EXT_full_screen_exclusive")]
665            get_physical_device_surface_present_modes_2_ext: InstanceResolvedFn::new(r),
666            #[cfg(feature = "VK_KHR_get_surface_capabilities2")]
667            get_physical_device_surface_capabilities_2_khr: InstanceResolvedFn::new(r),
668            #[cfg(feature = "VK_EXT_direct_mode_display")]
669            release_display_ext: InstanceResolvedFn::new(r),
670            #[cfg(feature = "VK_EXT_sample_locations")]
671            get_physical_device_multisample_properties_ext: InstanceResolvedFn::new(r),
672        }
673    }
674}
675
676#[cfg(feature = "VK_KHR_get_physical_device_properties2")]
677pub trait InstanceGetPhysicalDeviceProperties2Extension: Instance {
678    #[implements]
679    fn get_physical_device_properties2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceProperties2KHR;
680    #[implements]
681    fn get_physical_device_features2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceFeatures2KHR;
682    #[implements]
683    fn get_physical_device_format_properties2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceFormatProperties2KHR;
684}
685#[cfg(feature = "VK_KHR_get_physical_device_properties2")]
686DerefContainerWithGuardsBracketImpl!(for InstanceGetPhysicalDeviceProperties2Extension {
687    #[implements]
688    ForwardFnPtr!(deref get_physical_device_properties2_khr_fn -> PFN_vkGetPhysicalDeviceProperties2KHR);
689    #[implements]
690    ForwardFnPtr!(deref get_physical_device_features2_khr_fn -> PFN_vkGetPhysicalDeviceFeatures2KHR);
691    #[implements]
692    ForwardFnPtr!(deref get_physical_device_format_properties2_khr_fn -> PFN_vkGetPhysicalDeviceFormatProperties2KHR);
693});
694#[cfg(feature = "VK_KHR_get_physical_device_properties2")]
695impl InstanceGetPhysicalDeviceProperties2Extension for InstanceObject {
696    #[implements]
697    #[inline(always)]
698    fn get_physical_device_properties2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceProperties2KHR {
699        *self.ext.get_physical_device_properties2_khr.resolve()
700    }
701    #[implements]
702    #[inline(always)]
703    fn get_physical_device_features2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceFeatures2KHR {
704        *self.ext.get_physical_device_features2_khr.resolve()
705    }
706    #[implements]
707    #[inline(always)]
708    fn get_physical_device_format_properties2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceFormatProperties2KHR {
709        *self.ext.get_physical_device_format_properties2_khr.resolve()
710    }
711}
712
713#[cfg(feature = "VK_EXT_debug_report")]
714pub trait InstanceDebugReportExtension: Instance {
715    #[implements]
716    fn create_debug_report_callback_ext_fn(&self) -> PFN_vkCreateDebugReportCallbackEXT;
717    #[implements]
718    fn destroy_debug_report_callback_ext_fn(&self) -> PFN_vkDestroyDebugReportCallbackEXT;
719    #[implements]
720    fn debug_report_message_ext_fn(&self) -> PFN_vkDebugReportMessageEXT;
721
722    /// Register a debug report callback
723    /// # Failures
724    /// On failure, this command returns
725    ///
726    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
727    ///
728    /// # Safety
729    /// must not execute in parallel with any Vulkan commands
730    #[implements]
731    #[inline]
732    unsafe fn new_debug_report_callback_raw(
733        &self,
734        info: &crate::DebugReportCallbackCreateInfo,
735        allocation_callbacks: Option<&VkAllocationCallbacks>,
736    ) -> crate::Result<VkDebugReportCallbackEXT> {
737        let mut h = core::mem::MaybeUninit::uninit();
738        unsafe {
739            self.create_debug_report_callback_ext_fn().0(
740                self.native_ptr(),
741                info.as_raw_ref(),
742                crate::ffi_helper::opt_pointer(allocation_callbacks),
743                h.as_mut_ptr(),
744            )
745            .into_result()?;
746        }
747
748        Ok(unsafe { h.assume_init() })
749    }
750
751    /// Inject its own messages into the debug stream
752    #[implements]
753    #[inline]
754    fn debug_message(
755        &self,
756        flags: VkDebugReportFlagsEXT,
757        object_type: crate::DebugReportObjectType,
758        object: u64,
759        location: usize,
760        message_count: i32,
761        layer_prefix: &core::ffi::CStr,
762        message: &core::ffi::CStr,
763    ) {
764        unsafe {
765            self.debug_report_message_ext_fn().0(
766                self.native_ptr(),
767                flags,
768                object_type as _,
769                object,
770                location,
771                message_count,
772                layer_prefix.as_ptr(),
773                message.as_ptr(),
774            );
775        }
776    }
777
778    /// Destroy a debug report callback object
779    /// # Safety
780    /// * must be created from this Instance object
781    /// * must not execute in parallel with any Vulkan commands
782    #[implements]
783    #[inline]
784    unsafe fn destroy_debug_report_callback_raw(
785        &self,
786        obj: VkDebugReportCallbackEXT,
787        allocation_callbacks: Option<&VkAllocationCallbacks>,
788    ) {
789        unsafe {
790            self.destroy_debug_report_callback_ext_fn().0(
791                self.native_ptr(),
792                obj,
793                crate::ffi_helper::opt_pointer(allocation_callbacks),
794            );
795        }
796    }
797}
798#[cfg(feature = "VK_EXT_debug_report")]
799DerefContainerWithGuardsBracketImpl!(for InstanceDebugReportExtension {
800    #[implements]
801    ForwardFnPtr!(deref create_debug_report_callback_ext_fn -> PFN_vkCreateDebugReportCallbackEXT);
802    #[implements]
803    ForwardFnPtr!(deref destroy_debug_report_callback_ext_fn -> PFN_vkDestroyDebugReportCallbackEXT);
804    #[implements]
805    ForwardFnPtr!(deref debug_report_message_ext_fn -> PFN_vkDebugReportMessageEXT);
806});
807#[cfg(feature = "VK_EXT_debug_report")]
808impl InstanceDebugReportExtension for InstanceObject {
809    #[implements]
810    #[inline(always)]
811    fn create_debug_report_callback_ext_fn(&self) -> PFN_vkCreateDebugReportCallbackEXT {
812        *self.ext.create_debug_report_callback_ext.resolve()
813    }
814    #[implements]
815    #[inline(always)]
816    fn destroy_debug_report_callback_ext_fn(&self) -> PFN_vkDestroyDebugReportCallbackEXT {
817        *self.ext.destroy_debug_report_callback_ext.resolve()
818    }
819    #[implements]
820    #[inline(always)]
821    fn debug_report_message_ext_fn(&self) -> PFN_vkDebugReportMessageEXT {
822        *self.ext.debug_report_message_ext.resolve()
823    }
824}
825
826#[cfg(feature = "VK_EXT_debug_utils")]
827pub trait InstanceDebugUtilsExtension: Instance {
828    #[implements]
829    fn create_debug_utils_messenger_ext_fn(&self) -> PFN_vkCreateDebugUtilsMessengerEXT;
830    #[implements]
831    fn destroy_debug_utils_messenger_ext_fn(&self) -> PFN_vkDestroyDebugUtilsMessengerEXT;
832    #[implements]
833    fn set_debug_utils_object_name_ext_fn(&self) -> PFN_vkSetDebugUtilsObjectNameEXT;
834
835    /// Create a debug messenger object
836    /// # Failures
837    /// On failure, this command returns
838    ///
839    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
840    ///
841    /// # Safety
842    /// must not be executed in parallel with any Vulkan commands
843    #[implements]
844    #[inline]
845    unsafe fn new_debug_utils_messenger_raw(
846        &self,
847        info: &crate::DebugUtilsMessengerCreateInfo,
848        allocation_callbacks: Option<&VkAllocationCallbacks>,
849    ) -> crate::Result<VkDebugUtilsMessengerEXT> {
850        let mut h = core::mem::MaybeUninit::uninit();
851        unsafe {
852            self.create_debug_utils_messenger_ext_fn().0(
853                self.native_ptr(),
854                info,
855                crate::ffi_helper::opt_pointer(allocation_callbacks),
856                h.as_mut_ptr(),
857            )
858            .into_result()?;
859        }
860
861        Ok(unsafe { h.assume_init() })
862    }
863
864    /// Destroy a debug messenger object
865    /// # Safety
866    /// * must be created from this Instance object
867    /// * must not execute in parallel with any Vulkan commands
868    #[implements]
869    #[inline]
870    unsafe fn destroy_debug_utils_messenger_raw(
871        &self,
872        obj: VkDebugUtilsMessengerEXT,
873        allocation_callbacks: Option<&VkAllocationCallbacks>,
874    ) {
875        unsafe {
876            self.destroy_debug_utils_messenger_ext_fn().0(
877                self.native_ptr(),
878                obj,
879                crate::ffi_helper::opt_pointer(allocation_callbacks),
880            );
881        }
882    }
883}
884#[cfg(feature = "VK_EXT_debug_utils")]
885DerefContainerWithGuardsBracketImpl!(for InstanceDebugUtilsExtension {
886    #[implements]
887    ForwardFnPtr!(deref create_debug_utils_messenger_ext_fn -> PFN_vkCreateDebugUtilsMessengerEXT);
888    #[implements]
889    ForwardFnPtr!(deref destroy_debug_utils_messenger_ext_fn -> PFN_vkDestroyDebugUtilsMessengerEXT);
890    #[implements]
891    ForwardFnPtr!(deref set_debug_utils_object_name_ext_fn -> PFN_vkSetDebugUtilsObjectNameEXT);
892});
893#[cfg(feature = "VK_EXT_debug_utils")]
894impl InstanceDebugUtilsExtension for InstanceObject {
895    #[implements]
896    #[inline(always)]
897    fn create_debug_utils_messenger_ext_fn(&self) -> PFN_vkCreateDebugUtilsMessengerEXT {
898        *self.ext.create_debug_utils_messenger_ext.resolve()
899    }
900    #[implements]
901    #[inline(always)]
902    fn destroy_debug_utils_messenger_ext_fn(&self) -> PFN_vkDestroyDebugUtilsMessengerEXT {
903        *self.ext.destroy_debug_utils_messenger_ext.resolve()
904    }
905    #[implements]
906    #[inline(always)]
907    fn set_debug_utils_object_name_ext_fn(&self) -> PFN_vkSetDebugUtilsObjectNameEXT {
908        *self.ext.set_debug_utils_object_name_ext.resolve()
909    }
910}
911
912#[cfg(feature = "VK_KHR_external_fence_capabilities")]
913pub trait InstanceExternalFenceCapabilitiesExtension: Instance {
914    #[implements]
915    fn get_physical_device_external_fence_properties_khr_fn(&self)
916    -> PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR;
917}
918#[cfg(feature = "VK_KHR_external_fence_capabilities")]
919DerefContainerWithGuardsBracketImpl!(for InstanceExternalFenceCapabilitiesExtension {
920    #[implements]
921    ForwardFnPtr!(deref get_physical_device_external_fence_properties_khr_fn -> PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR);
922});
923#[cfg(feature = "VK_KHR_external_fence_capabilities")]
924impl InstanceExternalFenceCapabilitiesExtension for InstanceObject {
925    #[implements]
926    #[inline(always)]
927    fn get_physical_device_external_fence_properties_khr_fn(
928        &self,
929    ) -> PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR {
930        *self.ext.get_physical_device_external_fence_properties_khr.resolve()
931    }
932}
933
934#[cfg(feature = "VK_EXT_acquire_xlib_display")]
935pub trait InstanceAcquireXlibDisplayExtension: Instance {
936    #[implements]
937    fn get_randr_output_display_ext_fn(&self) -> PFN_vkGetRandROutputDisplayEXT;
938    #[implements]
939    fn acquire_xlib_display_ext_fn(&self) -> PFN_vkAcquireXlibDisplayEXT;
940}
941#[cfg(feature = "VK_EXT_acquire_xlib_display")]
942DerefContainerWithGuardsBracketImpl!(for InstanceAcquireXlibDisplayExtension {
943    #[implements]
944    ForwardFnPtr!(deref get_randr_output_display_ext_fn -> PFN_vkGetRandROutputDisplayEXT);
945    #[implements]
946    ForwardFnPtr!(deref acquire_xlib_display_ext_fn -> PFN_vkAcquireXlibDisplayEXT);
947});
948#[cfg(feature = "VK_EXT_acquire_xlib_display")]
949impl InstanceAcquireXlibDisplayExtension for InstanceObject {
950    #[implements]
951    #[inline(always)]
952    fn get_randr_output_display_ext_fn(&self) -> PFN_vkGetRandROutputDisplayEXT {
953        *self.ext.get_randr_output_display_ext.resolve()
954    }
955    #[implements]
956    #[inline(always)]
957    fn acquire_xlib_display_ext_fn(&self) -> PFN_vkAcquireXlibDisplayEXT {
958        *self.ext.acquire_xlib_display_ext.resolve()
959    }
960}
961
962#[cfg(feature = "VK_EXT_full_screen_exclusive")]
963pub trait InstanceFullScreenExclusiveExtension: Instance {
964    #[implements]
965    fn get_physical_device_surface_present_modes_2_ext_fn(&self) -> PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT;
966}
967#[cfg(feature = "VK_EXT_full_screen_exclusive")]
968DerefContainerWithGuardsBracketImpl!(for InstanceFullScreenExclusiveExtension {
969    #[implements]
970    ForwardFnPtr!(deref get_physical_device_surface_present_modes_2_ext_fn -> PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT);
971});
972#[cfg(feature = "VK_EXT_full_screen_exclusive")]
973impl InstanceFullScreenExclusiveExtension for InstanceObject {
974    #[implements]
975    #[inline(always)]
976    fn get_physical_device_surface_present_modes_2_ext_fn(&self) -> PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT {
977        *self.ext.get_physical_device_surface_present_modes_2_ext.resolve()
978    }
979}
980
981#[cfg(feature = "VK_KHR_get_surface_capabilities2")]
982pub trait InstanceGetSurfaceCapabilities2Extension: Instance {
983    #[implements]
984    fn get_physical_device_surface_capabilities_2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR;
985}
986#[cfg(feature = "VK_KHR_get_surface_capabilities2")]
987DerefContainerWithGuardsBracketImpl!(for InstanceGetSurfaceCapabilities2Extension {
988    #[implements]
989    ForwardFnPtr!(deref get_physical_device_surface_capabilities_2_khr_fn -> PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR);
990});
991#[cfg(feature = "VK_KHR_get_surface_capabilities2")]
992impl InstanceGetSurfaceCapabilities2Extension for InstanceObject {
993    #[implements]
994    #[inline(always)]
995    fn get_physical_device_surface_capabilities_2_khr_fn(&self) -> PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR {
996        *self.ext.get_physical_device_surface_capabilities_2_khr.resolve()
997    }
998}
999
1000#[cfg(feature = "VK_EXT_direct_mode_display")]
1001pub trait InstanceDirectModeDisplayExtension: Instance {
1002    #[implements]
1003    fn release_display_ext_fn(&self) -> PFN_vkReleaseDisplayEXT;
1004}
1005#[cfg(feature = "VK_EXT_direct_mode_display")]
1006DerefContainerWithGuardsBracketImpl!(for InstanceDirectModeDisplayExtension {
1007    #[implements]
1008    ForwardFnPtr!(deref release_display_ext_fn -> PFN_vkReleaseDisplayEXT);
1009});
1010#[cfg(feature = "VK_EXT_direct_mode_display")]
1011impl InstanceDirectModeDisplayExtension for InstanceObject {
1012    #[implements]
1013    #[inline(always)]
1014    fn release_display_ext_fn(&self) -> PFN_vkReleaseDisplayEXT {
1015        *self.ext.release_display_ext.resolve()
1016    }
1017}
1018
1019#[cfg(feature = "VK_EXT_sample_locations")]
1020pub trait InstanceSampleLocationsExtension: Instance {
1021    #[implements]
1022    fn get_physical_device_multisample_properties_ext_fn(&self) -> PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT;
1023}
1024#[cfg(feature = "VK_EXT_sample_locations")]
1025DerefContainerWithGuardsBracketImpl!(for InstanceSampleLocationsExtension {
1026    #[implements]
1027    ForwardFnPtr!(deref get_physical_device_multisample_properties_ext_fn -> PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT);
1028});
1029#[cfg(feature = "VK_EXT_sample_locations")]
1030impl InstanceSampleLocationsExtension for InstanceObject {
1031    #[implements]
1032    #[inline(always)]
1033    fn get_physical_device_multisample_properties_ext_fn(&self) -> PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT {
1034        *self.ext.get_physical_device_multisample_properties_ext.resolve()
1035    }
1036}
1037
1038/// A PhysicalDevice interface
1039pub trait PhysicalDevice: VkHandle<Handle = VkPhysicalDevice> + InstanceChild {
1040    /// Returns a count of properties of available physical device layers
1041    /// # Failures
1042    /// On failure, this command returns
1043    ///
1044    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1045    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1046    #[implements]
1047    #[inline]
1048    fn layer_property_count(&self) -> crate::Result<u32> {
1049        let mut n = 0;
1050        unsafe {
1051            crate::vkfn::enumerate_device_layer_properties(self.native_ptr(), &mut n, core::ptr::null_mut())
1052                .into_result()?;
1053        }
1054
1055        Ok(n)
1056    }
1057
1058    /// Returns properties of available physical device layers
1059    /// # Failures
1060    /// On failure, this command returns
1061    ///
1062    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1063    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1064    #[implements]
1065    #[inline]
1066    fn enumerate_layer_properties(&self, sink: &mut [core::mem::MaybeUninit<VkLayerProperties>]) -> crate::Result<u32> {
1067        let mut n = sink.len() as _;
1068        unsafe {
1069            crate::vkfn::enumerate_device_layer_properties(self.native_ptr(), &mut n, sink.as_mut_ptr() as _)
1070                .into_result()?;
1071        }
1072
1073        Ok(n)
1074    }
1075
1076    /// Returns properties of available physical device layers
1077    /// # Failures
1078    /// On failure, this command returns
1079    ///
1080    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1081    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1082    #[implements("alloc")]
1083    fn enumerate_layer_properties_alloc(&self) -> crate::Result<Vec<VkLayerProperties>> {
1084        let count = self.layer_property_count()? as usize;
1085        if count == 0 {
1086            // no items
1087            return Ok(crate::alloc::empty_sink_buffer());
1088        }
1089
1090        let mut xs = Vec::with_capacity(count);
1091        self.enumerate_layer_properties(xs.spare_capacity_mut())?;
1092        unsafe {
1093            xs.set_len(count);
1094        }
1095
1096        Ok(xs)
1097    }
1098
1099    /// Returns a count of properties of available physical device extensions
1100    /// # Failures
1101    /// On failure, this command returns
1102    ///
1103    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1104    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1105    /// * [`VK_ERROR_LAYER_NOT_PRESENT`]
1106    #[implements]
1107    #[inline]
1108    fn extension_property_count_cstr(&self, layer_name: Option<&core::ffi::CStr>) -> crate::Result<u32> {
1109        let mut n = 0;
1110        unsafe {
1111            crate::vkfn::enumerate_device_extension_properties(
1112                self.native_ptr(),
1113                crate::ffi_helper::opt_cstr_ptr(layer_name),
1114                &mut n,
1115                core::ptr::null_mut(),
1116            )
1117            .into_result()?;
1118        }
1119
1120        Ok(n)
1121    }
1122
1123    /// Returns properties of available physical device extensions
1124    /// # Failures
1125    /// On failure, this command returns
1126    ///
1127    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1128    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1129    /// * [`VK_ERROR_LAYER_NOT_PRESENT`]
1130    #[implements]
1131    #[inline]
1132    fn enumerate_extension_properties_cstr(
1133        &self,
1134        layer_name: Option<&core::ffi::CStr>,
1135        sink: &mut [core::mem::MaybeUninit<VkExtensionProperties>],
1136    ) -> crate::Result<u32> {
1137        let mut n = sink.len() as _;
1138        unsafe {
1139            crate::vkfn::enumerate_device_extension_properties(
1140                self.native_ptr(),
1141                crate::ffi_helper::opt_cstr_ptr(layer_name),
1142                &mut n,
1143                sink.as_mut_ptr() as _,
1144            )
1145            .into_result()?;
1146        }
1147
1148        Ok(n)
1149    }
1150
1151    /// Returns properties of available physical device extensions
1152    /// # Failures
1153    /// On failure, this command returns
1154    ///
1155    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1156    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1157    /// * `VK_ERROR_LAYER_NOT_PRESENT`
1158    #[implements("alloc")]
1159    fn enumerate_extension_properties_cstr_alloc(
1160        &self,
1161        layer_name: Option<&core::ffi::CStr>,
1162    ) -> crate::Result<Vec<VkExtensionProperties>> {
1163        let n = self.extension_property_count_cstr(layer_name)? as usize;
1164        if n == 0 {
1165            // no items
1166            return Ok(crate::alloc::empty_sink_buffer());
1167        }
1168
1169        let mut xs = Vec::with_capacity(n);
1170        self.enumerate_extension_properties_cstr(layer_name, xs.spare_capacity_mut())?;
1171        unsafe {
1172            xs.set_len(n);
1173        }
1174
1175        Ok(xs)
1176    }
1177
1178    /// Returns properties of available physical device extensions
1179    /// # Failures
1180    /// On failure, this command returns
1181    ///
1182    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1183    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1184    /// * `VK_ERROR_LAYER_NOT_PRESENT`
1185    #[implements("alloc")]
1186    #[inline]
1187    fn enumerate_extension_properties(&self, layer_name: Option<&str>) -> crate::Result<Vec<VkExtensionProperties>> {
1188        self.enumerate_extension_properties_cstr_alloc(
1189            layer_name.map(|s| crate::alloc::str_to_cstr(s).unwrap()).as_deref(),
1190        )
1191    }
1192
1193    /// Reports capabilities of a physical device.
1194    #[implements]
1195    #[inline]
1196    fn features(&self) -> VkPhysicalDeviceFeatures {
1197        let mut p = std::mem::MaybeUninit::uninit();
1198        unsafe {
1199            crate::vkfn::get_physical_device_features(self.native_ptr(), p.as_mut_ptr());
1200
1201            p.assume_init()
1202        }
1203    }
1204
1205    /// Reports capabilities of a physical device
1206    /// # Safety
1207    /// Caller must guarantee that all write operations to `sink` and its `pNext` fields are safe
1208    #[implements("Allow1_1APIs")]
1209    #[inline]
1210    unsafe fn features2(&self, sink: &mut core::mem::MaybeUninit<VkPhysicalDeviceFeatures2KHR>) {
1211        unsafe {
1212            crate::vkfn::get_physical_device_features2(self.native_ptr(), sink.as_mut_ptr());
1213        }
1214    }
1215
1216    /// Reports capabilities of a physical device
1217    /// # Safety
1218    /// Caller must guarantee that all write operations to `sink` and its `pNext` fields are safe
1219    #[implements("VK_KHR_get_physical_device_properties2")]
1220    #[inline]
1221    unsafe fn features2_khr(&self, sink: &mut core::mem::MaybeUninit<VkPhysicalDeviceFeatures2KHR>)
1222    where
1223        Self::ConcreteInstance: InstanceGetPhysicalDeviceProperties2Extension,
1224    {
1225        unsafe {
1226            self.instance().get_physical_device_features2_khr_fn().0(self.native_ptr(), sink.as_mut_ptr());
1227        }
1228    }
1229
1230    /// Returns properties of a physical device
1231    #[implements]
1232    #[inline]
1233    fn properties(&self) -> VkPhysicalDeviceProperties {
1234        let mut p = std::mem::MaybeUninit::uninit();
1235        unsafe {
1236            crate::vkfn::get_physical_device_properties(self.native_ptr(), p.as_mut_ptr());
1237
1238            p.assume_init()
1239        }
1240    }
1241
1242    /// Returns properties of a physical device
1243    /// # Safety
1244    /// Caller must guarantee that all write operations to `sink` and its `pNext` fields are safe
1245    #[implements("Allow1_1APIs")]
1246    #[inline]
1247    unsafe fn properties2(&self, sink: &mut core::mem::MaybeUninit<VkPhysicalDeviceProperties2KHR>) {
1248        unsafe {
1249            crate::vkfn::get_physical_device_properties2(self.native_ptr(), sink.as_mut_ptr());
1250        }
1251    }
1252
1253    /// Returns properties of a physical device
1254    /// # Safety
1255    /// Caller must guarantee that all write operations to `sink` and its `pNext` fields are safe
1256    #[implements("VK_KHR_get_physical_device_properties2")]
1257    #[inline]
1258    unsafe fn properties2_khr(&self, sink: &mut core::mem::MaybeUninit<VkPhysicalDeviceProperties2KHR>)
1259    where
1260        Self::ConcreteInstance: InstanceGetPhysicalDeviceProperties2Extension,
1261    {
1262        unsafe {
1263            self.instance().get_physical_device_properties2_khr_fn().0(self.native_ptr(), sink.as_mut_ptr());
1264        }
1265    }
1266
1267    /// Lists physical device's format capabilities
1268    #[implements]
1269    #[inline]
1270    fn format_properties(&self, format: VkFormat) -> VkFormatProperties {
1271        let mut p = std::mem::MaybeUninit::uninit();
1272        unsafe {
1273            crate::vkfn::get_physical_device_format_properties(self.native_ptr(), format, p.as_mut_ptr());
1274
1275            p.assume_init()
1276        }
1277    }
1278
1279    /// Lists physical device's format capabilities
1280    /// # Safety
1281    /// Caller must guarantee that all write operations to `out` are safe.
1282    #[implements("Allow1_1APIs")]
1283    #[inline]
1284    unsafe fn format_properties2(&self, format: VkFormat, out: &mut core::mem::MaybeUninit<VkFormatProperties2KHR>) {
1285        unsafe {
1286            crate::vkfn::get_physical_device_format_properties2(self.native_ptr(), format, out.as_mut_ptr());
1287        }
1288    }
1289
1290    /// Lists physical device's format capabilities
1291    /// # Safety
1292    /// Caller must guarantee that all write operations to `out` are safe.
1293    #[implements("VK_KHR_get_physical_device_properties2")]
1294    #[inline]
1295    unsafe fn format_properties2_khr(&self, format: VkFormat, out: &mut core::mem::MaybeUninit<VkFormatProperties2KHR>)
1296    where
1297        Self::ConcreteInstance: InstanceGetPhysicalDeviceProperties2Extension,
1298    {
1299        unsafe {
1300            self.instance().get_physical_device_format_properties2_khr_fn().0(
1301                self.native_ptr(),
1302                format,
1303                out.as_mut_ptr(),
1304            );
1305        }
1306    }
1307
1308    /// Lists physical device's image format capabilities
1309    /// # Failures
1310    /// On failure, this command returns
1311    ///
1312    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1313    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1314    /// * `VK_ERROR_FORMAT_NOT_SUPPORTED`
1315    #[implements]
1316    #[inline]
1317    fn image_format_properties(
1318        &self,
1319        format: VkFormat,
1320        itype: VkImageType,
1321        tiling: VkImageTiling,
1322        usage: ImageUsageFlags,
1323        flags: ImageFlags,
1324    ) -> crate::Result<VkImageFormatProperties> {
1325        let mut p = std::mem::MaybeUninit::uninit();
1326        unsafe {
1327            crate::vkfn::get_physical_device_image_format_properties(
1328                self.native_ptr(),
1329                format,
1330                itype,
1331                tiling,
1332                usage.bits(),
1333                flags.bits(),
1334                p.as_mut_ptr(),
1335            )
1336            .into_result()?;
1337        }
1338
1339        Ok(unsafe { p.assume_init() })
1340    }
1341
1342    /// Reports a count of properties of the queues of the specified physical device
1343    #[implements]
1344    #[inline]
1345    fn queue_family_property_count(&self) -> u32 {
1346        let mut n = 0;
1347        unsafe {
1348            crate::vkfn::get_physical_device_queue_family_properties(self.native_ptr(), &mut n, core::ptr::null_mut());
1349        }
1350
1351        n
1352    }
1353
1354    /// Reports properties of the queues of the specified physical device
1355    #[implements]
1356    #[inline]
1357    fn queue_family_properties(&self, sink: &mut [core::mem::MaybeUninit<VkQueueFamilyProperties>]) -> u32 {
1358        let mut n = sink.len() as _;
1359        unsafe {
1360            crate::vkfn::get_physical_device_queue_family_properties(self.native_ptr(), &mut n, sink.as_mut_ptr() as _);
1361        }
1362
1363        n
1364    }
1365
1366    /// Reports properties of the queues of the specified physical device
1367    #[implements]
1368    #[cfg(feature = "alloc")]
1369    fn queue_family_properties_alloc(&self) -> QueueFamilies {
1370        let n = self.queue_family_property_count() as usize;
1371        if n == 0 {
1372            // no items
1373            return QueueFamilies(crate::alloc::empty_sink_buffer());
1374        }
1375
1376        let mut xs = Vec::with_capacity(n);
1377        self.queue_family_properties(xs.spare_capacity_mut());
1378        unsafe {
1379            xs.set_len(n);
1380        }
1381
1382        QueueFamilies(xs)
1383    }
1384
1385    /// Reports memory information for the specified physical device
1386    #[implements]
1387    #[inline]
1388    fn memory_properties(&self) -> MemoryProperties {
1389        let mut p = core::mem::MaybeUninit::uninit();
1390        unsafe {
1391            crate::vkfn::get_physical_device_memory_properties(self.native_ptr(), p.as_mut_ptr());
1392
1393            MemoryProperties(p.assume_init())
1394        }
1395    }
1396
1397    /// Retrieve a count of properties of an image format spplied to sparse images
1398    #[implements]
1399    #[inline]
1400    fn sparse_image_format_property_count(
1401        &self,
1402        format: VkFormat,
1403        image_type: VkImageType,
1404        samples: VkSampleCountFlags,
1405        usage: ImageUsageFlags,
1406        tiling: VkImageTiling,
1407    ) -> u32 {
1408        let mut n = 0;
1409        unsafe {
1410            crate::vkfn::get_physical_device_sparse_image_format_properties(
1411                self.native_ptr(),
1412                format,
1413                image_type,
1414                samples,
1415                usage.bits(),
1416                tiling,
1417                &mut n,
1418                core::ptr::null_mut(),
1419            );
1420        }
1421
1422        n
1423    }
1424
1425    /// Retrieve properties of an image format applied to sparse images
1426    #[implements]
1427    #[inline]
1428    fn sparse_image_format_properties(
1429        &self,
1430        format: VkFormat,
1431        image_type: VkImageType,
1432        samples: VkSampleCountFlags,
1433        usage: ImageUsageFlags,
1434        tiling: VkImageTiling,
1435        sink: &mut [core::mem::MaybeUninit<VkSparseImageFormatProperties>],
1436    ) -> u32 {
1437        let mut n = sink.len() as _;
1438        unsafe {
1439            crate::vkfn::get_physical_device_sparse_image_format_properties(
1440                self.native_ptr(),
1441                format,
1442                image_type,
1443                samples,
1444                usage.bits(),
1445                tiling,
1446                &mut n,
1447                sink.as_mut_ptr() as _,
1448            );
1449        }
1450
1451        n
1452    }
1453
1454    /// Retrieve properties of an image format applied to sparse images
1455    #[implements]
1456    #[cfg(feature = "alloc")]
1457    fn sparse_image_format_properties_alloc(
1458        &self,
1459        format: VkFormat,
1460        itype: VkImageType,
1461        samples: VkSampleCountFlags,
1462        usage: ImageUsageFlags,
1463        tiling: VkImageTiling,
1464    ) -> Vec<VkSparseImageFormatProperties> {
1465        let n = self.sparse_image_format_property_count(format, itype, samples, usage, tiling);
1466        if n == 0 {
1467            // no items
1468            return crate::alloc::empty_sink_buffer();
1469        }
1470
1471        let mut xs = Vec::with_capacity(n as _);
1472        self.sparse_image_format_properties(format, itype, samples, usage, tiling, xs.spare_capacity_mut());
1473        unsafe {
1474            xs.set_len(n as _);
1475        }
1476
1477        xs
1478    }
1479
1480    /// # Safety
1481    /// Caller must guarantee that all write operations to `sink` and its `pNext` fields are safe
1482    #[implements("VK_EXT_sample_locations")]
1483    unsafe fn multisample_properties(
1484        &self,
1485        samples: VkSampleCountFlags,
1486        sink: &mut core::mem::MaybeUninit<VkMultisamplePropertiesEXT>,
1487    ) where
1488        Self::ConcreteInstance: InstanceSampleLocationsExtension,
1489    {
1490        self.instance().get_physical_device_multisample_properties_ext_fn().0(
1491            self.native_ptr(),
1492            samples,
1493            sink.as_mut_ptr(),
1494        );
1495    }
1496
1497    /// Function for querying external fence handle capabilities
1498    /// # Safety
1499    /// Caller must guarantee that all write operations to `sink` and its `pNext` fields are safe
1500    #[implements("VK_KHR_external_fence_capabilities")]
1501    #[inline]
1502    unsafe fn external_fence_properties(
1503        &self,
1504        info: &VkPhysicalDeviceExternalFenceInfoKHR,
1505        sink: &mut core::mem::MaybeUninit<VkExternalFencePropertiesKHR>,
1506    ) where
1507        Self::ConcreteInstance: InstanceExternalFenceCapabilitiesExtension,
1508    {
1509        unsafe {
1510            self.instance().get_physical_device_external_fence_properties_khr_fn().0(
1511                self.native_ptr(),
1512                info,
1513                sink.as_mut_ptr(),
1514            );
1515        }
1516    }
1517
1518    /// Query if presentation is supported
1519    /// # Failures
1520    /// On failure, this command returns
1521    ///
1522    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1523    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1524    /// * `VK_ERROR_SURFACE_LOST_KHR`
1525    #[implements("VK_KHR_surface")]
1526    #[inline]
1527    fn surface_support(&self, queue_family: u32, surface: &(impl Surface + ?Sized)) -> crate::Result<bool> {
1528        let mut f = 0;
1529
1530        unsafe {
1531            crate::vkfn::get_physical_device_surface_support_khr(
1532                self.native_ptr(),
1533                queue_family,
1534                surface.native_ptr(),
1535                &mut f,
1536            )
1537            .into_result()?;
1538
1539            Ok(f != 0)
1540        }
1541    }
1542
1543    /// Query surface capabilities
1544    /// # Failures
1545    /// On failure, this command returns
1546    ///
1547    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1548    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1549    /// * `VK_ERROR_SURFACE_LOST_KHR`
1550    #[implements("VK_KHR_surface")]
1551    #[inline]
1552    fn surface_capabilities(&self, surface: &(impl Surface + ?Sized)) -> crate::Result<VkSurfaceCapabilitiesKHR> {
1553        let mut s = std::mem::MaybeUninit::uninit();
1554
1555        unsafe {
1556            crate::vkfn::get_physical_device_surface_capabilities_khr(
1557                self.native_ptr(),
1558                surface.native_ptr(),
1559                s.as_mut_ptr(),
1560            )
1561            .into_result()?;
1562
1563            Ok(s.assume_init())
1564        }
1565    }
1566
1567    /// Query a count of color formats supported by surface
1568    /// # Failures
1569    /// On failure, this command returns
1570    ///
1571    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1572    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1573    /// * `VK_ERROR_SURFACE_LOST_KHR`
1574    #[implements("VK_KHR_surface")]
1575    #[inline]
1576    fn surface_format_count(&self, surface: &(impl VkHandle<Handle = VkSurfaceKHR> + ?Sized)) -> crate::Result<u32> {
1577        let mut n = 0;
1578        unsafe {
1579            crate::vkfn::get_physical_device_surface_formats_khr(
1580                self.native_ptr(),
1581                surface.native_ptr(),
1582                &mut n,
1583                core::ptr::null_mut(),
1584            )
1585            .into_result()?;
1586        }
1587
1588        Ok(n)
1589    }
1590
1591    /// Query a count of color formats supported by surface
1592    /// # Failures
1593    /// On failure, this command returns
1594    ///
1595    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1596    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1597    /// * `VK_ERROR_SURFACE_LOST_KHR`
1598    #[implements("VK_KHR_surface")]
1599    #[inline]
1600    fn surface_formats(
1601        &self,
1602        surface: &(impl VkHandle<Handle = VkSurfaceKHR> + ?Sized),
1603        sink: &mut [core::mem::MaybeUninit<VkSurfaceFormatKHR>],
1604    ) -> crate::Result<u32> {
1605        let mut n = sink.len() as _;
1606        unsafe {
1607            crate::vkfn::get_physical_device_surface_formats_khr(
1608                self.native_ptr(),
1609                surface.native_ptr(),
1610                &mut n,
1611                sink.as_mut_ptr() as _,
1612            )
1613            .into_result()?;
1614        }
1615
1616        Ok(n)
1617    }
1618
1619    /// Query color formats supported by surface
1620    /// # Failures
1621    /// On failure, this command returns
1622    ///
1623    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1624    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1625    /// * `VK_ERROR_SURFACE_LOST_KHR`
1626    #[implements("VK_KHR_surface", "alloc")]
1627    fn surface_formats_alloc(&self, surface: &(impl Surface + ?Sized)) -> crate::Result<Vec<VkSurfaceFormatKHR>> {
1628        let n = self.surface_format_count(surface)?;
1629        if n == 0 {
1630            // no items
1631            return Ok(crate::alloc::empty_sink_buffer());
1632        }
1633
1634        let mut xs = Vec::with_capacity(n as _);
1635        self.surface_formats(surface, xs.spare_capacity_mut())?;
1636        unsafe {
1637            xs.set_len(n as _);
1638        }
1639
1640        Ok(xs)
1641    }
1642
1643    /// Query a count of supported presentation modes
1644    /// # Failures
1645    /// On failure, this command returns
1646    ///
1647    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1648    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1649    /// * `VK_ERROR_SURFACE_LOST_KHR`
1650    #[implements("VK_KHR_surface")]
1651    #[inline]
1652    fn surface_present_mode_count(
1653        &self,
1654        surface: &(impl VkHandle<Handle = VkSurfaceKHR> + ?Sized),
1655    ) -> crate::Result<u32> {
1656        let mut n = 0;
1657        unsafe {
1658            crate::vkfn::get_physical_device_surface_present_modes_khr(
1659                self.native_ptr(),
1660                surface.native_ptr(),
1661                &mut n,
1662                core::ptr::null_mut(),
1663            )
1664            .into_result()?;
1665        }
1666
1667        Ok(n)
1668    }
1669
1670    /// Query supported presentation modes
1671    /// # Failures
1672    /// On failure, this command returns
1673    ///
1674    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1675    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1676    /// * `VK_ERROR_SURFACE_LOST_KHR`
1677    #[implements("VK_KHR_surface")]
1678    #[inline]
1679    fn surface_present_modes(
1680        &self,
1681        surface: &(impl VkHandle<Handle = VkSurfaceKHR> + ?Sized),
1682        sink: &mut [core::mem::MaybeUninit<PresentMode>],
1683    ) -> crate::Result<u32> {
1684        let mut n = sink.len() as _;
1685        unsafe {
1686            crate::vkfn::get_physical_device_surface_present_modes_khr(
1687                self.native_ptr(),
1688                surface.native_ptr(),
1689                &mut n,
1690                sink.as_mut_ptr() as _,
1691            )
1692            .into_result()?;
1693        }
1694
1695        Ok(n)
1696    }
1697
1698    /// Query supported presentation modes
1699    /// # Failures
1700    /// On failure, this command returns
1701    ///
1702    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1703    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1704    /// * `VK_ERROR_SURFACE_LOST_KHR`
1705    #[implements("VK_KHR_surface", "alloc")]
1706    fn surface_present_modes_alloc(&self, surface: &(impl Surface + ?Sized)) -> crate::Result<Vec<PresentMode>> {
1707        let n = self.surface_present_mode_count(surface)?;
1708        if n == 0 {
1709            // no items
1710            return Ok(crate::alloc::empty_sink_buffer());
1711        }
1712
1713        let mut xs = Vec::with_capacity(n as _);
1714        self.surface_present_modes(surface, xs.spare_capacity_mut())?;
1715        unsafe {
1716            xs.set_len(n as _);
1717        }
1718
1719        Ok(xs)
1720    }
1721
1722    /// Query physical device for presentation to X11 server using Xlib
1723    /// # Safety
1724    /// Provided `display` must be a valid reference
1725    #[implements("VK_KHR_xlib_surface")]
1726    #[inline]
1727    unsafe fn xlib_presentation_support(
1728        &self,
1729        queue_family: u32,
1730        display: *mut x11::xlib::Display,
1731        visual: x11::xlib::VisualID,
1732    ) -> bool {
1733        unsafe {
1734            crate::vkfn::get_physical_device_xlib_presentation_support_khr(
1735                self.native_ptr(),
1736                queue_family,
1737                display,
1738                visual,
1739            ) != 0
1740        }
1741    }
1742
1743    /// Query physical device for presentation to X11 server using XCB
1744    /// # Safety
1745    /// Provided `connection` must be a valid reference
1746    #[implements("VK_KHR_xcb_surface")]
1747    #[inline]
1748    unsafe fn xcb_presentation_support(
1749        &self,
1750        queue_family: u32,
1751        connection: *mut xcb::ffi::xcb_connection_t,
1752        visual: xcb::x::Visualid,
1753    ) -> bool {
1754        unsafe {
1755            crate::vkfn::get_physical_device_xcb_presentation_support_khr(
1756                self.native_ptr(),
1757                queue_family,
1758                connection,
1759                visual,
1760            ) != 0
1761        }
1762    }
1763
1764    /// Query physical device for presentation to Wayland
1765    /// # Safety
1766    /// Provided `display` must be a valid reference
1767    #[implements("VK_KHR_wayland_surface")]
1768    #[inline]
1769    unsafe fn wayland_presentation_support(&self, queue_family: u32, display: *mut core::ffi::c_void) -> bool {
1770        unsafe {
1771            crate::vkfn::get_physical_device_wayland_presentation_support_khr(self.native_ptr(), queue_family, display)
1772                != 0
1773        }
1774    }
1775
1776    /// Query queue family support for presentation on a Win32 display
1777    #[implements("VK_KHR_win32_surface")]
1778    #[inline]
1779    fn win32_presentation_support(&self, queue_family: u32) -> bool {
1780        unsafe { crate::vkfn::get_physical_device_win32_presentation_support_khr(self.native_ptr(), queue_family) != 0 }
1781    }
1782
1783    /// Query a count of the set of mode properties supported by the display
1784    /// # Failures
1785    /// On failure, this command returns
1786    ///
1787    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1788    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1789    #[implements("VK_KHR_display")]
1790    #[inline]
1791    fn display_mode_property_count(&self, display: VkDisplayKHR) -> crate::Result<u32> {
1792        let mut n = 0;
1793        unsafe {
1794            crate::vkfn::get_display_mode_properties_khr(self.native_ptr(), display, &mut n, core::ptr::null_mut())
1795                .into_result()?;
1796        }
1797
1798        Ok(n)
1799    }
1800
1801    /// Query the set of mode properties supported by the display
1802    /// # Failures
1803    /// On failure, this command returns
1804    ///
1805    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1806    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1807    #[implements("VK_KHR_display")]
1808    #[inline]
1809    fn display_mode_properties(
1810        &self,
1811        display: VkDisplayKHR,
1812        sink: &mut [core::mem::MaybeUninit<VkDisplayModePropertiesKHR>],
1813    ) -> crate::Result<u32> {
1814        let mut n = sink.len() as _;
1815        unsafe {
1816            crate::vkfn::get_display_mode_properties_khr(self.native_ptr(), display, &mut n, sink.as_mut_ptr() as _)
1817                .into_result()?;
1818        }
1819
1820        Ok(n)
1821    }
1822
1823    /// Query the set of mode properties supported by the display
1824    /// # Failures
1825    /// On failure, this command returns
1826    ///
1827    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1828    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1829    #[implements("VK_KHR_display", "alloc")]
1830    fn display_mode_properties_alloc(&self, display: VkDisplayKHR) -> crate::Result<Vec<VkDisplayModePropertiesKHR>> {
1831        let n = self.display_mode_property_count(display)?;
1832        if n == 0 {
1833            // no items
1834            return Ok(crate::alloc::empty_sink_buffer());
1835        }
1836
1837        let mut xs = Vec::with_capacity(n as _);
1838        self.display_mode_properties(display, xs.spare_capacity_mut())?;
1839        unsafe {
1840            xs.set_len(n as _);
1841        }
1842
1843        Ok(xs)
1844    }
1845
1846    /// Create a display mode
1847    /// # Failures
1848    /// On failure, this command returns
1849    ///
1850    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1851    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1852    /// * `VK_ERROR_INITIALIZATION_FAILED`
1853    ///
1854    /// # Safety
1855    /// no guarantee will be provided (simply calls under api)
1856    #[implements("VK_KHR_display")]
1857    #[inline]
1858    unsafe fn new_display_mode_raw(
1859        &self,
1860        display: VkDisplayKHR,
1861        info: &VkDisplayModeCreateInfoKHR,
1862        allocation_callbacks: Option<&VkAllocationCallbacks>,
1863    ) -> crate::Result<VkDisplayModeKHR> {
1864        let mut h = core::mem::MaybeUninit::uninit();
1865
1866        unsafe {
1867            crate::vkfn::create_display_mode_khr(
1868                self.native_ptr(),
1869                display,
1870                info,
1871                crate::ffi_helper::opt_pointer(allocation_callbacks),
1872                h.as_mut_ptr(),
1873            )
1874            .into_result()?;
1875        }
1876
1877        Ok(unsafe { h.assume_init() })
1878    }
1879
1880    /// Query capabilities of a mode and plane combination
1881    /// # Failures
1882    /// On failure, this command returns
1883    ///
1884    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1885    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1886    #[implements("VK_KHR_display")]
1887    #[inline]
1888    fn display_plane_capabilities(
1889        &self,
1890        mode: VkDisplayModeKHR,
1891        plane_index: u32,
1892    ) -> crate::Result<VkDisplayPlaneCapabilitiesKHR> {
1893        let mut s = core::mem::MaybeUninit::uninit();
1894        unsafe {
1895            crate::vkfn::get_display_plane_capabilities_khr(self.native_ptr(), mode, plane_index, s.as_mut_ptr())
1896                .into_result()?;
1897
1898            Ok(s.assume_init())
1899        }
1900    }
1901
1902    /// Query a count of information about the available displays
1903    /// # Failures
1904    /// On failure, this command returns
1905    ///
1906    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1907    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1908    #[implements("VK_KHR_display")]
1909    #[inline]
1910    fn display_property_count(&self) -> crate::Result<u32> {
1911        let mut n = 0;
1912        unsafe {
1913            crate::vkfn::get_physical_device_display_properties_khr(self.native_ptr(), &mut n, core::ptr::null_mut())
1914                .into_result()?;
1915        }
1916
1917        Ok(n)
1918    }
1919
1920    /// Query information about the available displays
1921    /// # Failures
1922    /// On failure, this command returns
1923    ///
1924    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1925    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1926    #[implements("VK_KHR_display")]
1927    #[inline]
1928    fn display_properties(&self, sink: &mut [core::mem::MaybeUninit<VkDisplayPropertiesKHR>]) -> crate::Result<u32> {
1929        let mut n = sink.len() as _;
1930        unsafe {
1931            crate::vkfn::get_physical_device_display_properties_khr(self.native_ptr(), &mut n, sink.as_mut_ptr() as _)
1932                .into_result()?;
1933        }
1934
1935        Ok(n)
1936    }
1937
1938    /// Query information about the available displays.
1939    /// # Failures
1940    /// On failure, this command returns
1941    ///
1942    /// * VK_ERROR_OUT_OF_HOST_MEMORY
1943    /// * VK_ERROR_OUT_OF_DEVICE_MEMORY
1944    #[implements("VK_KHR_display", "alloc")]
1945    fn display_properties_alloc(&self) -> crate::Result<Vec<DisplayPropertiesWithPhysicalDeviceRef<&Self>>> {
1946        let n = self.display_property_count()?;
1947        if n == 0 {
1948            // no items
1949            return Ok(crate::alloc::empty_sink_buffer());
1950        }
1951
1952        let mut xs = Vec::with_capacity(n as _);
1953        self.display_properties(xs.spare_capacity_mut())?;
1954        unsafe {
1955            xs.set_len(n as _);
1956        }
1957
1958        Ok(crate::alloc::collect_vec(
1959            xs.into_iter()
1960                .map(move |x| DisplayPropertiesWithPhysicalDeviceRef(x, self)),
1961        ))
1962    }
1963
1964    /// Query a count of the plane properties
1965    /// # Failures
1966    /// On failure, this command returns
1967    ///
1968    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1969    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1970    #[implements("VK_KHR_display")]
1971    #[inline]
1972    fn display_plane_property_count(&self) -> crate::Result<u32> {
1973        let mut n = 0;
1974        unsafe {
1975            crate::vkfn::get_physical_device_display_plane_properties_khr(
1976                self.native_ptr(),
1977                &mut n,
1978                core::ptr::null_mut(),
1979            )
1980            .into_result()?;
1981        }
1982
1983        Ok(n)
1984    }
1985
1986    /// Query the plane properties
1987    /// # Failures
1988    /// On failure, this command returns
1989    ///
1990    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1991    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1992    #[implements("VK_KHR_display")]
1993    #[inline]
1994    fn display_plane_properties(
1995        &self,
1996        sink: &mut [core::mem::MaybeUninit<VkDisplayPlanePropertiesKHR>],
1997    ) -> crate::Result<u32> {
1998        let mut n = sink.len() as _;
1999        unsafe {
2000            crate::vkfn::get_physical_device_display_plane_properties_khr(
2001                self.native_ptr(),
2002                &mut n,
2003                sink.as_mut_ptr() as _,
2004            )
2005            .into_result()?;
2006        }
2007
2008        Ok(n)
2009    }
2010
2011    /// Query the plane properties.
2012    /// # Failures
2013    /// On failure, this command returns
2014    ///
2015    /// * VK_ERROR_OUT_OF_HOST_MEMORY
2016    /// * VK_ERROR_OUT_OF_DEVICE_MEMORY
2017    #[implements("VK_KHR_display", "alloc")]
2018    fn display_plane_properties_alloc(&self) -> crate::Result<Vec<DisplayPlanePropertiesWithPhysicalDeviceRef<&Self>>> {
2019        let n = self.display_plane_property_count()?;
2020        if n == 0 {
2021            // no items
2022            return Ok(crate::alloc::empty_sink_buffer());
2023        }
2024
2025        let mut xs = Vec::with_capacity(n as _);
2026        self.display_plane_properties(xs.spare_capacity_mut())?;
2027        unsafe {
2028            xs.set_len(n as _);
2029        }
2030
2031        Ok(crate::alloc::collect_vec(
2032            xs.into_iter()
2033                .map(move |x| DisplayPlanePropertiesWithPhysicalDeviceRef(x, self)),
2034        ))
2035    }
2036
2037    /// Query a count of the list of displays a plane supports
2038    /// # Failures
2039    /// On failure, this command returns
2040    ///
2041    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2042    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
2043    #[implements("VK_KHR_display")]
2044    #[inline]
2045    fn display_plane_supported_display_count(&self, plane_index: u32) -> crate::Result<u32> {
2046        let mut n = 0;
2047        unsafe {
2048            crate::vkfn::get_display_plane_supported_displays_khr(
2049                self.native_ptr(),
2050                plane_index,
2051                &mut n,
2052                core::ptr::null_mut(),
2053            )
2054            .into_result()?;
2055        }
2056
2057        Ok(n)
2058    }
2059
2060    /// Query the list of displays a plane supports
2061    /// # Failures
2062    /// On failure, this command returns
2063    ///
2064    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2065    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
2066    #[implements("VK_KHR_display")]
2067    #[inline]
2068    fn display_plane_supported_displays(
2069        &self,
2070        plane_index: u32,
2071        sink: &mut [core::mem::MaybeUninit<VkDisplayKHR>],
2072    ) -> crate::Result<u32> {
2073        let mut n = sink.len() as _;
2074        unsafe {
2075            crate::vkfn::get_display_plane_supported_displays_khr(
2076                self.native_ptr(),
2077                plane_index,
2078                &mut n,
2079                sink.as_mut_ptr() as _,
2080            )
2081            .into_result()?;
2082        }
2083
2084        Ok(n)
2085    }
2086
2087    /// Query the list of displays a plane supports.
2088    /// # Failures
2089    /// On failure, this command returns
2090    ///
2091    /// * VK_ERROR_OUT_OF_HOST_MEMORY
2092    /// * VK_ERROR_OUT_OF_DEVICE_MEMORY
2093    #[implements("VK_KHR_display", "alloc")]
2094    fn display_plane_supported_displays_alloc(&self, plane_index: u32) -> crate::Result<Vec<Display<&Self>>> {
2095        let n = self.display_plane_supported_display_count(plane_index)?;
2096        if n == 0 {
2097            // no items
2098            return Ok(crate::alloc::empty_sink_buffer());
2099        }
2100
2101        let mut xs = Vec::with_capacity(n as _);
2102        self.display_plane_supported_displays(plane_index, xs.spare_capacity_mut())?;
2103        unsafe {
2104            xs.set_len(n as _);
2105        }
2106
2107        Ok(crate::alloc::collect_vec(xs.into_iter().map(move |x| Display(x, self))))
2108    }
2109
2110    /// Create a `Surface` object representing a display plane and mode
2111    /// # Failures
2112    /// On failure, this command returns
2113    ///
2114    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2115    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
2116    ///
2117    /// # Safety
2118    /// no guarantee will be provided (simply calls under api)
2119    #[implements("VK_KHR_display", "VK_KHR_surface")]
2120    #[inline]
2121    unsafe fn new_surface_for_display_plane_raw(
2122        &self,
2123        info: &VkDisplaySurfaceCreateInfoKHR,
2124        allocation_callbacks: Option<&VkAllocationCallbacks>,
2125    ) -> crate::Result<VkSurfaceKHR> {
2126        let mut h = core::mem::MaybeUninit::uninit();
2127
2128        unsafe {
2129            crate::vkfn::create_display_plane_surface_khr(
2130                self.instance().native_ptr(),
2131                info,
2132                crate::ffi_helper::opt_pointer(allocation_callbacks),
2133                h.as_mut_ptr(),
2134            )
2135            .into_result()?;
2136        }
2137
2138        Ok(unsafe { h.assume_init() })
2139    }
2140
2141    /// Query the VkDisplayKHR corresponding to an X11 RandR Output
2142    /// # Failures
2143    /// On failure, this command returns
2144    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2145    ///
2146    /// # Safety
2147    /// Provided `dpy` must be a valid reference
2148    #[implements("VK_EXT_acquire_xlib_display")]
2149    #[inline]
2150    unsafe fn get_randr_output_display(
2151        self,
2152        dpy: *mut x11::xlib::Display,
2153        rr_output: x11::xrandr::RROutput,
2154    ) -> crate::Result<Display<Self>>
2155    where
2156        Self: Sized,
2157        Self::ConcreteInstance: InstanceAcquireXlibDisplayExtension,
2158    {
2159        let mut d = core::mem::MaybeUninit::uninit();
2160
2161        self.instance().get_randr_output_display_ext_fn().0(self.native_ptr(), dpy, rr_output, d.as_mut_ptr())
2162            .into_result()?;
2163
2164        Ok(Display(d.assume_init(), self))
2165    }
2166
2167    /// Reports capabilities of a surface on a physical device
2168    ///
2169    /// # Failures
2170    ///
2171    /// On failure, this command returns
2172    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2173    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2174    /// * [`VK_ERROR_SURFACE_LOST_KHR`]
2175    ///
2176    /// # Safety
2177    /// Caller must guarantee that all write operations to `sink` and its `pNext` fields are safe
2178    #[implements("VK_KHR_get_surface_capabilities2")]
2179    #[inline]
2180    unsafe fn surface_capabilities2(
2181        &self,
2182        surface_info: &VkPhysicalDeviceSurfaceInfo2KHR,
2183        sink: &mut core::mem::MaybeUninit<VkSurfaceCapabilities2KHR>,
2184    ) -> crate::Result<()>
2185    where
2186        Self::ConcreteInstance: InstanceGetSurfaceCapabilities2Extension,
2187    {
2188        unsafe {
2189            self.instance().get_physical_device_surface_capabilities_2_khr_fn().0(
2190                self.native_ptr(),
2191                surface_info,
2192                sink.as_mut_ptr(),
2193            )
2194            .into_result()
2195            .map(drop)
2196        }
2197    }
2198
2199    /// Query a count of supported presentation modes
2200    /// # Failures
2201    /// On failure, this command returns
2202    ///
2203    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2204    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2205    /// * [`VK_ERROR_SURFACE_LOST_KHR`]
2206    #[implements("VK_EXT_full_screen_exclusive")]
2207    #[inline]
2208    fn surface_present_mode2_count(&self, surface_info: &VkPhysicalDeviceSurfaceInfo2KHR) -> crate::Result<u32>
2209    where
2210        Self::ConcreteInstance: InstanceFullScreenExclusiveExtension,
2211    {
2212        let mut n = 0;
2213        unsafe {
2214            self.instance().get_physical_device_surface_present_modes_2_ext_fn().0(
2215                self.native_ptr(),
2216                surface_info,
2217                &mut n,
2218                core::ptr::null_mut(),
2219            )
2220            .into_result()?;
2221        }
2222
2223        Ok(n)
2224    }
2225
2226    /// Query supported presentation modes
2227    /// # Failures
2228    /// On failure, this command returns
2229    ///
2230    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2231    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2232    /// * [`VK_ERROR_SURFACE_LOST_KHR`]
2233    #[implements("VK_EXT_full_screen_exclusive")]
2234    #[inline]
2235    fn surface_present_modes2(
2236        &self,
2237        surface_info: &VkPhysicalDeviceSurfaceInfo2KHR,
2238        sink: &mut [core::mem::MaybeUninit<VkPresentModeKHR>],
2239    ) -> crate::Result<u32>
2240    where
2241        Self::ConcreteInstance: InstanceFullScreenExclusiveExtension,
2242    {
2243        let mut n = sink.len() as _;
2244        unsafe {
2245            self.instance().get_physical_device_surface_present_modes_2_ext_fn().0(
2246                self.native_ptr(),
2247                surface_info,
2248                &mut n,
2249                sink.as_mut_ptr() as _,
2250            )
2251            .into_result()?;
2252        }
2253
2254        Ok(n)
2255    }
2256
2257    /// Query supported presentation modes.
2258    ///
2259    /// # Failures
2260    ///
2261    /// On failure, this command returns
2262    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2263    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2264    /// * [`VK_ERROR_SURFACE_LOST_KHR`]
2265    #[implements("VK_EXT_full_screen_exclusive", "alloc")]
2266    fn surface_present_modes2_alloc(
2267        &self,
2268        surface_info: &VkPhysicalDeviceSurfaceInfo2KHR,
2269    ) -> crate::Result<Vec<VkPresentModeKHR>>
2270    where
2271        Self::ConcreteInstance: InstanceFullScreenExclusiveExtension,
2272    {
2273        let n = self.surface_present_mode2_count(surface_info)?;
2274        if n == 0 {
2275            // no items
2276            return Ok(crate::alloc::empty_sink_buffer());
2277        }
2278
2279        let mut xs = Vec::with_capacity(n as _);
2280        self.surface_present_modes2(surface_info, xs.spare_capacity_mut())?;
2281        unsafe {
2282            xs.set_len(n as _);
2283        }
2284
2285        Ok(xs)
2286    }
2287}
2288DerefContainerBracketImpl!(for PhysicalDevice {});
2289GuardsImpl!(for PhysicalDevice {});
2290
2291pub trait InstanceChild {
2292    type ConcreteInstance: Instance;
2293
2294    fn instance(&self) -> &Self::ConcreteInstance;
2295}
2296DerefContainerBracketImpl!(for InstanceChild {
2297    type ConcreteInstance = T::ConcreteInstance;
2298
2299    #[inline(always)]
2300    fn instance(&self) -> &Self::ConcreteInstance { T::instance(self) }
2301});
2302GuardsImpl!(for InstanceChild {
2303    type ConcreteInstance = T::ConcreteInstance;
2304
2305    #[inline(always)]
2306    fn instance(&self) -> &Self::ConcreteInstance { T::instance(&self) }
2307});
2308
2309pub trait InstanceChildTransferrable: InstanceChild {
2310    fn transfer_instance(self) -> Self::ConcreteInstance;
2311}
2312impl<T> InstanceChildTransferrable for &'_ T
2313where
2314    T: InstanceChild,
2315    T::ConcreteInstance: Clone,
2316{
2317    #[inline(always)]
2318    fn transfer_instance(self) -> Self::ConcreteInstance {
2319        self.instance().clone()
2320    }
2321}
2322
2323#[cfg(feature = "VK_KHR_external_fence_capabilities")]
2324impl VkExternalFencePropertiesKHR {
2325    pub const fn is_exportable(&self) -> bool {
2326        (self.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) != 0
2327    }
2328
2329    pub const fn is_importable(&self) -> bool {
2330        (self.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR) != 0
2331    }
2332}
2333
2334pub type PhysicalDeviceFeatures = VkPhysicalDeviceFeatures;
2335pub type PhysicalDeviceProperties = VkPhysicalDeviceProperties;
2336pub type PhysicalDeviceMemoryProperties = VkPhysicalDeviceMemoryProperties;
2337impl PhysicalDeviceMemoryProperties {
2338    #[inline(always)]
2339    pub fn types(&self) -> &[MemoryType] {
2340        &self.memoryTypes[..self.memoryTypeCount as _]
2341    }
2342
2343    #[inline(always)]
2344    pub fn heaps(&self) -> &[MemoryHeap] {
2345        &self.memoryHeaps[..self.memoryHeapCount as _]
2346    }
2347}
2348
2349pub type MemoryType = VkMemoryType;
2350impl MemoryType {
2351    pub const fn property_flags(&self) -> MemoryPropertyFlags {
2352        MemoryPropertyFlags(self.propertyFlags)
2353    }
2354}
2355
2356pub type MemoryHeap = VkMemoryHeap;
2357impl MemoryHeap {
2358    pub const fn flags(&self) -> MemoryHeapFlags {
2359        MemoryHeapFlags(self.flags)
2360    }
2361}
2362
2363/// Device memory properties
2364#[repr(transparent)]
2365pub struct MemoryProperties(VkPhysicalDeviceMemoryProperties);
2366impl MemoryProperties {
2367    #[inline(always)]
2368    pub fn types(&self) -> &[MemoryType] {
2369        &self.0.memoryTypes[..self.0.memoryTypeCount as _]
2370    }
2371    #[inline(always)]
2372    pub fn heaps(&self) -> &[MemoryHeap] {
2373        &self.0.memoryHeaps[..self.0.memoryHeapCount as _]
2374    }
2375
2376    #[inline]
2377    pub fn find_type_index(
2378        &self,
2379        mask: MemoryPropertyFlags,
2380        exclude: MemoryPropertyFlags,
2381        index_mask: u32,
2382    ) -> Option<u32> {
2383        self.types().iter().enumerate().find_map(|(i, mt)| {
2384            (index_mask & (1u32 << i) != 0
2385                && mt.property_flags().has_all(mask)
2386                && !mt.property_flags().has_any(exclude))
2387            .then_some(i as _)
2388        })
2389    }
2390
2391    pub fn find_device_local_index(&self, index_mask: u32) -> Option<u32> {
2392        self.find_type_index(
2393            MemoryPropertyFlags::DEVICE_LOCAL,
2394            MemoryPropertyFlags::LAZILY_ALLOCATED,
2395            index_mask,
2396        )
2397    }
2398    pub fn find_lazily_allocated_device_local_index(&self, index_mask: u32) -> Option<u32> {
2399        self.find_type_index(
2400            MemoryPropertyFlags::DEVICE_LOCAL | MemoryPropertyFlags::LAZILY_ALLOCATED,
2401            MemoryPropertyFlags::EMPTY,
2402            index_mask,
2403        )
2404    }
2405    pub fn find_host_visible_index(&self, index_mask: u32) -> Option<u32> {
2406        self.find_type_index(
2407            MemoryPropertyFlags::HOST_VISIBLE,
2408            MemoryPropertyFlags::EMPTY,
2409            index_mask,
2410        )
2411    }
2412
2413    pub fn is_coherent(&self, index: u32) -> bool {
2414        self.0.memoryTypes[index as usize]
2415            .property_flags()
2416            .has_any(MemoryPropertyFlags::HOST_COHERENT)
2417    }
2418    pub fn is_cached(&self, index: u32) -> bool {
2419        self.0.memoryTypes[index as usize]
2420            .property_flags()
2421            .has_any(MemoryPropertyFlags::HOST_CACHED)
2422    }
2423}
2424
2425/// Bitmask specifying properties for a memory type
2426#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2427#[bitflags_newtype]
2428pub struct MemoryPropertyFlags(VkMemoryPropertyFlags);
2429impl MemoryPropertyFlags {
2430    /// Empty set
2431    pub const EMPTY: Self = MemoryPropertyFlags(0);
2432
2433    /// Memory allocated with this type is the most efficient for device access
2434    pub const DEVICE_LOCAL: Self = MemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
2435    /// Memory allocated with this type can be mapped for host access using `vkMapMemory`
2436    pub const HOST_VISIBLE: Self = MemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2437    /// The host cache management commands `vkFlushMappedMemoryRanges` and `vkInvalidateMappedMemoryRanges`
2438    /// are not needed to flush host writes to the device or make device writes visible to the host, respectively.
2439    pub const HOST_COHERENT: Self = MemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
2440    /// Memory allocated with this type is cached on the host.
2441    /// Host memory accesses to uncached memory are slower than to cached memory, however uncached memory is always host coherent
2442    pub const HOST_CACHED: Self = MemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
2443    /// The memory type only allows device access to the memory.
2444    pub const LAZILY_ALLOCATED: Self = MemoryPropertyFlags(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT);
2445
2446    #[cfg(feature = "Allow1_1APIs")]
2447    /// The memory type only allows device access to the memory, and allows protected queue operations to access the memory.
2448    pub const PROTECTED: Self = Self(VK_MEMORY_PROPERTY_PROTECTED_BIT);
2449}
2450
2451/// Bitmask specifying attribute flags for a heap
2452#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2453#[bitflags_newtype]
2454pub struct MemoryHeapFlags(VkMemoryHeapFlags);
2455impl MemoryHeapFlags {
2456    /// Empty set
2457    pub const EMPTY: Self = Self(0);
2458
2459    /// The heap corresponds to device-local memory.
2460    /// Device-local memory may have different performance characteristics than host-local memory,
2461    /// and may support different memory property flags.
2462    pub const DEVICE_LOCAL: Self = Self(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT);
2463
2464    #[cfg(feature = "Allow1_1APIs")]
2465    /// In a logical device representing more than one physical device,
2466    /// there is a per-physical device instance of the heap memory.
2467    /// By default, an allocation from such a heap will be replicated to each physical device's instance of the heap.
2468    pub const MULTI_INSTANCE: Self = Self(VK_MEMORY_HEAP_MULTI_INSTANCE_BIT);
2469}
2470
2471/// List of queue families
2472pub struct QueueFamilies(pub Vec<QueueFamilyProperties>);
2473impl QueueFamilies {
2474    /// Find a queue family index containing specified bitflags
2475    pub fn find_matching_index(&self, flags: QueueFlags) -> Option<u32> {
2476        self.0
2477            .iter()
2478            .position(|q| (q.queueFlags & flags.0) != 0)
2479            .map(|x| x as _)
2480    }
2481
2482    /// Find a queue family index containing specified bitflags
2483    pub fn find_another_matching_index(&self, flags: QueueFlags, exclude: u32) -> Option<u32> {
2484        self.0
2485            .iter()
2486            .enumerate()
2487            .find_map(|(n, &QueueFamilyProperties { queueFlags, .. })| {
2488                ((queueFlags & flags.0) != 0 && exclude != n as u32).then_some(n as _)
2489            })
2490    }
2491
2492    /// Number of queue families
2493    pub fn count(&self) -> u32 {
2494        self.0.len() as _
2495    }
2496
2497    #[inline(always)]
2498    pub fn iter(&self) -> impl Iterator<Item = &QueueFamilyProperties> {
2499        self.0.iter()
2500    }
2501
2502    /// Number of queues in selected queue family
2503    pub fn queue_count(&self, family_index: u32) -> u32 {
2504        self.0[family_index as usize].queueCount
2505    }
2506
2507    /// Unsigned integer count of meaningful bits in the timestamps written via `vkCmdWriteTimestamp`
2508    pub fn timestamp_valid_bits(&self, family_index: u32) -> u32 {
2509        self.0[family_index as usize].timestampValidBits
2510    }
2511
2512    /// Minimum granularity supported for image transfer operations on the queues in selected queue family
2513    pub fn minimum_image_transfer_granularity(&self, family_index: u32) -> &Extent3D {
2514        &self.0[family_index as usize].minImageTransferGranularity
2515    }
2516}
2517
2518pub type QueueFamilyProperties = VkQueueFamilyProperties;
2519impl QueueFamilyProperties {
2520    pub const fn queue_flags(&self) -> QueueFlags {
2521        QueueFlags(self.queueFlags)
2522    }
2523}
2524
2525/// Set of bit of queue flags
2526#[derive(Debug, Clone, PartialEq, Eq, Copy)]
2527#[bitflags_newtype]
2528pub struct QueueFlags(VkQueueFlags);
2529impl QueueFlags {
2530    /// Empty bits
2531    pub const EMPTY: Self = QueueFlags(0);
2532    /// Supports only graphics operations
2533    pub const GRAPHICS: Self = QueueFlags(VK_QUEUE_GRAPHICS_BIT);
2534    /// Supports only compute operations
2535    pub const COMPUTE: Self = QueueFlags(VK_QUEUE_COMPUTE_BIT);
2536    /// Supports only transfer operations
2537    pub const TRANSFER: Self = QueueFlags(VK_QUEUE_TRANSFER_BIT);
2538    /// Supports only sparse memory management operations
2539    pub const SPARSE_BINDING: Self = QueueFlags(VK_QUEUE_SPARSE_BINDING_BIT);
2540}
2541
2542#[cfg(feature = "VK_KHR_display")]
2543mod display;
2544#[cfg(feature = "VK_KHR_display")]
2545pub use self::display::*;