bedrock/
device.rs

1//! Vulkan Device and Queues
2
3use crate::ffi_helper::{CStrFFIRef, slice_as_ptr_empty_null};
4use crate::*;
5use derives::implements;
6
7#[implements]
8#[allow(dead_code)]
9type DeviceResolvedFn<F> = crate::resolver::ResolvedFnCell<F, VkDevice>;
10#[implements]
11impl crate::resolver::ResolverInterface for VkDevice {
12    #[inline(always)]
13    unsafe fn load_symbol_unconstrainted<T: crate::resolver::FromPtr>(&self, name: &core::ffi::CStr) -> T {
14        unsafe {
15            T::from_ptr(core::mem::transmute(crate::vkfn::get_device_proc_addr(
16                *self,
17                name.as_ptr() as _,
18            )))
19        }
20    }
21
22    #[tracing::instrument(name = "<VkDevice as ResolverInterface>::load_function_unconstrainted", skip(self), fields(name = ?F::NAME_CSTR))]
23    unsafe fn load_function_unconstrainted<F: crate::resolver::PFN>(&self) -> F {
24        match unsafe { crate::vkfn::get_device_proc_addr(*self, F::NAME_CSTR.as_ptr() as _) } {
25            Some(x) => unsafe { F::from_void_fn(x) },
26            None => {
27                tracing::error!("device function not found, bedrock could not continue");
28                std::process::abort();
29            }
30        }
31    }
32}
33
34/// Opaque handle to a device object
35#[derive(VkHandle, VkObject)]
36#[VkObject(type = VK_OBJECT_TYPE_DEVICE)]
37pub struct DeviceObject<Instance> {
38    #[handle]
39    handle: VkDevice,
40    parent: Instance,
41    #[cfg(feature = "Implements")]
42    ext: DeviceExtFunctions,
43}
44impl<Instance> DeviceObject<Instance> {
45    pub const fn wrap_handle(handle: VkDevice, parent: Instance) -> Self {
46        Self {
47            handle,
48            parent,
49            #[cfg(feature = "Implements")]
50            ext: DeviceExtFunctions::new(handle),
51        }
52    }
53}
54unsafe impl<Instance: Sync> Sync for DeviceObject<Instance> {}
55unsafe impl<Instance: Send> Send for DeviceObject<Instance> {}
56#[implements]
57impl<Instance> Drop for DeviceObject<Instance> {
58    #[inline(always)]
59    fn drop(&mut self) {
60        unsafe {
61            crate::vkfn::destroy_device(self.handle, std::ptr::null());
62        }
63    }
64}
65impl<Instance: crate::Instance> InstanceChild for DeviceObject<Instance> {
66    type ConcreteInstance = Instance;
67
68    #[inline(always)]
69    fn instance(&self) -> &Self::ConcreteInstance {
70        &self.parent
71    }
72}
73impl<Instance: crate::Instance> Device for DeviceObject<Instance> {}
74impl<Instance: crate::Instance + Clone> DeviceObject<&'_ Instance> {
75    /// Clones parent reference
76    #[inline]
77    pub fn clone_parent(self) -> DeviceObject<Instance> {
78        let r = DeviceObject {
79            handle: self.handle,
80            parent: self.parent.clone(),
81            #[cfg(feature = "Implements")]
82            ext: unsafe { core::ptr::read(&self.ext) },
83        };
84        // disable running VkDevice destruction
85        std::mem::forget(self);
86
87        r
88    }
89}
90impl<Instance: crate::Instance> DeviceObject<Instance> {
91    /// Create a new device instance
92    /// # Failures
93    /// On failure, this command returns
94    ///
95    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
96    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
97    /// * `VK_ERROR_INITIALIZATION_FAILED`
98    /// * `VK_ERROR_EXTENSION_NOT_PRESENT`
99    /// * `VK_ERROR_FEATURE_NOT_PRESENT`
100    /// * `VK_ERROR_TOO_MANY_OBJECTS`
101    /// * `VK_ERROR_DEVICE_LOST`
102    #[implements]
103    pub fn new<
104        PhysicalDevice: crate::PhysicalDevice + crate::InstanceChildTransferrable<ConcreteInstance = Instance>,
105    >(
106        physical_device: PhysicalDevice,
107        info: &DeviceCreateInfo,
108    ) -> crate::Result<Self> {
109        let mut h = core::mem::MaybeUninit::uninit();
110
111        unsafe {
112            crate::vkfn::create_device(physical_device.native_ptr(), &info.0, core::ptr::null(), h.as_mut_ptr())
113                .into_result()?;
114
115            Ok(Self::wrap_handle(h.assume_init(), physical_device.transfer_instance()))
116        }
117    }
118
119    /// Constructs from raw handle
120    /// # Safety
121    /// the handle must be valid and not freed
122    pub const unsafe fn manage(handle: VkDevice, parent: Instance) -> Self {
123        Self::wrap_handle(handle, parent)
124    }
125
126    /// Purges the construct (Drop will not be called for this resource)
127    pub fn unmanage(mut self) -> (VkDevice, Instance) {
128        let h = self.handle;
129        let p = unsafe { core::ptr::read(&self.parent) };
130        #[cfg(feature = "Implements")]
131        unsafe {
132            core::ptr::drop_in_place(&mut self.ext);
133        }
134        core::mem::forget(self);
135
136        (h, p)
137    }
138}
139
140/// Opaque handle to a queue object
141#[derive(Clone, VkHandle, VkObject)]
142#[VkObject(type = VK_OBJECT_TYPE_QUEUE)]
143pub struct QueueObject<Device>(VkQueue, Device);
144unsafe impl<Device: Sync> Sync for QueueObject<Device> {}
145unsafe impl<Device: Send> Send for QueueObject<Device> {}
146impl<Device: crate::Device> Queue for QueueObject<Device> {}
147impl<Device: crate::Device> QueueMut for QueueObject<Device> {}
148impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for QueueObject<Device> {
149    #[inline(always)]
150    fn device_handle(&self) -> VkDevice {
151        self.1.native_ptr()
152    }
153}
154impl<Device: crate::Device> DeviceChild for QueueObject<Device> {
155    type ConcreteDevice = Device;
156
157    #[inline(always)]
158    fn device(&self) -> &Self::ConcreteDevice {
159        &self.1
160    }
161}
162impl<Device: Clone> QueueObject<&'_ Device> {
163    #[inline(always)]
164    pub fn clone_parent(self) -> QueueObject<Device> {
165        let r = QueueObject(self.0, self.1.clone());
166        core::mem::forget(self);
167
168        r
169    }
170}
171impl<Device> QueueObject<Device> {
172    /// Constructs from raw values
173    /// # Safety
174    /// the resource must be created from the device and not freed anywhere
175    pub const unsafe fn manage(handle: VkQueue, parent: Device) -> Self {
176        Self(handle, parent)
177    }
178
179    /// Purges the construct (Drop will not be called for this resource)
180    pub const fn unmanage(self) -> (VkQueue, Device) {
181        let h = self.0;
182        let p = unsafe { core::ptr::read(&self.1) };
183        core::mem::forget(self);
184
185        (h, p)
186    }
187}
188
189/// Family Index, Queue Priorities
190#[repr(transparent)]
191pub struct DeviceQueueCreateInfo<'d>(VkDeviceQueueCreateInfo, core::marker::PhantomData<&'d [f32]>);
192impl<'d> DeviceQueueCreateInfo<'d> {
193    pub const fn new(family_index: u32, priorities: &'d [f32]) -> Self {
194        Self(
195            VkDeviceQueueCreateInfo {
196                sType: VkDeviceQueueCreateInfo::TYPE,
197                pNext: std::ptr::null(),
198                flags: 0,
199                queueFamilyIndex: family_index,
200                queueCount: priorities.len() as _,
201                pQueuePriorities: slice_as_ptr_empty_null(priorities),
202            },
203            core::marker::PhantomData,
204        )
205    }
206}
207
208#[repr(transparent)]
209#[derive(Clone)]
210pub struct DeviceCreateInfo<'d>(
211    VkDeviceCreateInfo,
212    core::marker::PhantomData<(
213        Option<&'d dyn VulkanStructure>,
214        &'d [DeviceQueueCreateInfo<'d>],
215        &'d [CStrFFIRef<'d>],
216        &'d [CStrFFIRef<'d>],
217        Option<&'d VkPhysicalDeviceFeatures>,
218    )>,
219);
220impl<'d> DeviceCreateInfo<'d> {
221    pub const fn new(
222        queue_infos: &'d [DeviceQueueCreateInfo<'d>],
223        layers: &'d [CStrFFIRef<'d>],
224        extensions: &'d [CStrFFIRef<'d>],
225    ) -> Self {
226        Self(
227            VkDeviceCreateInfo {
228                sType: VkDeviceCreateInfo::TYPE,
229                pNext: core::ptr::null(),
230                flags: 0,
231                queueCreateInfoCount: queue_infos.len() as _,
232                pQueueCreateInfos: slice_as_ptr_empty_null(queue_infos) as _,
233                enabledLayerCount: layers.len() as _,
234                ppEnabledLayerNames: slice_as_ptr_empty_null(layers) as _,
235                enabledExtensionCount: extensions.len() as _,
236                ppEnabledExtensionNames: slice_as_ptr_empty_null(extensions) as _,
237                pEnabledFeatures: core::ptr::null(),
238            },
239            core::marker::PhantomData,
240        )
241    }
242
243    pub const unsafe fn from_raw(raw: VkDeviceCreateInfo) -> Self {
244        Self(raw, core::marker::PhantomData)
245    }
246
247    pub const fn into_raw(self) -> VkDeviceCreateInfo {
248        self.0
249    }
250
251    pub const fn with_features(mut self, features: &'d VkPhysicalDeviceFeatures) -> Self {
252        self.0.pEnabledFeatures = features as *const _ as _;
253        self
254    }
255
256    pub fn with_next(mut self, next: &'d (impl VulkanStructure + ?Sized)) -> Self {
257        self.0.pNext = next.as_generic() as *const _ as _;
258        self
259    }
260}
261
262#[cfg(feature = "VK_KHR_get_physical_device_properties2")]
263#[repr(transparent)]
264#[derive(Clone)]
265pub struct PhysicalDeviceFeatures2<'r>(
266    VkPhysicalDeviceFeatures2KHR,
267    core::marker::PhantomData<Option<&'r mut dyn VulkanStructure>>,
268);
269#[cfg(feature = "VK_KHR_get_physical_device_properties2")]
270impl<'r> PhysicalDeviceFeatures2<'r> {
271    pub const fn new(old_features: VkPhysicalDeviceFeatures) -> Self {
272        Self(
273            VkPhysicalDeviceFeatures2KHR {
274                sType: <VkPhysicalDeviceFeatures2KHR as TypedVulkanStructure>::TYPE,
275                pNext: core::ptr::null_mut(),
276                features: old_features,
277            },
278            core::marker::PhantomData,
279        )
280    }
281
282    #[inline(always)]
283    pub fn with_next(mut self, next: &'r mut (impl VulkanStructure + ?Sized)) -> Self {
284        self.0.pNext = next.as_generic_mut() as *mut _ as _;
285        self
286    }
287}
288#[cfg(feature = "VK_KHR_get_physical_device_properties2")]
289unsafe impl VulkanStructure for PhysicalDeviceFeatures2<'_> {
290    #[inline(always)]
291    fn as_generic(&self) -> &GenericVulkanStructure {
292        VulkanStructure::as_generic(&self.0)
293    }
294
295    #[inline(always)]
296    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
297        VulkanStructure::as_generic_mut(&mut self.0)
298    }
299}
300#[cfg(feature = "VK_KHR_get_physical_device_properties2")]
301unsafe impl VulkanSinkStructure for PhysicalDeviceFeatures2<'_> {
302    #[inline(always)]
303    fn as_generic(&self) -> &GenericVulkanSinkStructure {
304        VulkanSinkStructure::as_generic(&self.0)
305    }
306
307    #[inline(always)]
308    fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure {
309        VulkanSinkStructure::as_generic_mut(&mut self.0)
310    }
311}
312
313#[cfg(feature = "VK_KHR_synchronization2")]
314#[repr(transparent)]
315#[derive(Debug, Clone)]
316pub struct PhysicalDeviceSynchronization2Features<'r>(
317    VkPhysicalDeviceSynchronization2FeaturesKHR,
318    core::marker::PhantomData<Option<&'r mut dyn VulkanStructure>>,
319);
320#[cfg(feature = "VK_KHR_synchronization2")]
321impl<'r> PhysicalDeviceSynchronization2Features<'r> {
322    pub const fn new(enabled: bool) -> Self {
323        Self(
324            VkPhysicalDeviceSynchronization2FeaturesKHR {
325                sType: <VkPhysicalDeviceSynchronization2FeaturesKHR as TypedVulkanStructure>::TYPE,
326                pNext: core::ptr::null_mut(),
327                synchronization2: enabled as _,
328            },
329            core::marker::PhantomData,
330        )
331    }
332
333    #[inline(always)]
334    pub fn with_next(mut self, next: &'r mut (impl VulkanStructure + ?Sized)) -> Self {
335        self.0.pNext = next.as_generic_mut() as *mut _ as _;
336        self
337    }
338}
339#[cfg(feature = "VK_KHR_synchronization2")]
340unsafe impl VulkanStructure for PhysicalDeviceSynchronization2Features<'_> {
341    #[inline(always)]
342    fn as_generic(&self) -> &GenericVulkanStructure {
343        VulkanStructure::as_generic(&self.0)
344    }
345
346    #[inline(always)]
347    fn as_generic_mut(&mut self) -> &mut GenericVulkanStructure {
348        VulkanStructure::as_generic_mut(&mut self.0)
349    }
350}
351#[cfg(feature = "VK_KHR_synchronization2")]
352unsafe impl VulkanSinkStructure for PhysicalDeviceSynchronization2Features<'_> {
353    #[inline(always)]
354    fn as_generic(&self) -> &GenericVulkanSinkStructure {
355        VulkanSinkStructure::as_generic(&self.0)
356    }
357
358    #[inline(always)]
359    fn as_generic_mut(&mut self) -> &mut GenericVulkanSinkStructure {
360        VulkanSinkStructure::as_generic_mut(&mut self.0)
361    }
362}
363
364pub trait Device: VkHandle<Handle = VkDevice> + InstanceChild {
365    /// Get a queue handle from a device
366    #[implements]
367    fn queue<'s>(&'s self, family_index: u32, queue_index: u32) -> QueueObject<&'s Self> {
368        let mut h = std::mem::MaybeUninit::uninit();
369        unsafe {
370            crate::vkfn::get_device_queue(self.native_ptr(), family_index, queue_index, h.as_mut_ptr());
371            QueueObject(h.assume_init(), self)
372        }
373    }
374
375    /// Create a new fence object
376    /// # Failure
377    /// On failure, this command returns
378    ///
379    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
380    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
381    #[implements]
382    #[inline]
383    fn new_fence_raw(
384        &self,
385        info: &FenceCreateInfo,
386        allocation_callbacks: Option<&VkAllocationCallbacks>,
387    ) -> crate::Result<VkFence> {
388        let mut h = core::mem::MaybeUninit::uninit();
389        unsafe {
390            crate::vkfn::create_fence(
391                self.native_ptr(),
392                info as *const _ as _,
393                crate::ffi_helper::opt_pointer(allocation_callbacks),
394                h.as_mut_ptr(),
395            )
396            .into_result()?;
397        }
398
399        Ok(unsafe { h.assume_init() })
400    }
401
402    /// Create a new queue semaphore object
403    /// # Failure
404    /// On failure, this command returns
405    ///
406    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
407    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
408    #[implements]
409    #[inline]
410    fn new_semaphore_raw(
411        &self,
412        info: &SemaphoreCreateInfo,
413        allocation_callbacks: Option<&VkAllocationCallbacks>,
414    ) -> crate::Result<VkSemaphore> {
415        let mut h = core::mem::MaybeUninit::uninit();
416        unsafe {
417            crate::vkfn::create_semaphore(
418                self.native_ptr(),
419                info as *const _ as _,
420                crate::ffi_helper::opt_pointer(allocation_callbacks),
421                h.as_mut_ptr(),
422            )
423            .into_result()?;
424        }
425
426        Ok(unsafe { h.assume_init() })
427    }
428
429    /// Create a new event object
430    /// # Failure
431    /// On failure, this command returns
432    ///
433    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
434    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
435    #[implements]
436    #[inline]
437    fn new_event_raw(
438        &self,
439        info: &EventCreateInfo,
440        allocation_callbacks: Option<&VkAllocationCallbacks>,
441    ) -> crate::Result<VkEvent> {
442        let mut h = core::mem::MaybeUninit::uninit();
443        unsafe {
444            crate::vkfn::create_event(
445                self.native_ptr(),
446                info as *const _ as _,
447                crate::ffi_helper::opt_pointer(allocation_callbacks),
448                h.as_mut_ptr(),
449            )
450            .into_result()?;
451        }
452
453        Ok(unsafe { h.assume_init() })
454    }
455
456    /// Allocate device memory
457    /// # Failure
458    /// On failure, this command returns
459    ///
460    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
461    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
462    /// * [`VK_ERROR_INVALID_EXTERNAL_HANDLE`]
463    /// * [`VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`]
464    #[implements]
465    #[inline]
466    fn allocate_memory(
467        &self,
468        info: &MemoryAllocateInfo,
469        allocation_callbacks: Option<&VkAllocationCallbacks>,
470    ) -> crate::Result<VkDeviceMemory> {
471        let mut h = core::mem::MaybeUninit::uninit();
472        unsafe {
473            crate::vkfn::allocate_memory(
474                self.native_ptr(),
475                info as *const _ as _,
476                crate::ffi_helper::opt_pointer(allocation_callbacks),
477                h.as_mut_ptr(),
478            )
479            .into_result()?;
480        }
481
482        Ok(unsafe { h.assume_init() })
483    }
484
485    /// Create a new buffer object
486    /// # Failure
487    /// On failure, this command returns
488    ///
489    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
490    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
491    #[implements]
492    #[inline]
493    fn new_buffer_raw(
494        &self,
495        info: &BufferCreateInfo,
496        allocation_callbacks: Option<&VkAllocationCallbacks>,
497    ) -> crate::Result<VkBuffer> {
498        let mut h = core::mem::MaybeUninit::uninit();
499        unsafe {
500            crate::vkfn::create_buffer(
501                self.native_ptr(),
502                info as *const _ as _,
503                crate::ffi_helper::opt_pointer(allocation_callbacks),
504                h.as_mut_ptr(),
505            )
506            .into_result()?;
507        }
508
509        Ok(unsafe { h.assume_init() })
510    }
511
512    /// Create a new buffer view object
513    /// # Failure
514    /// On failure, this command returns
515    ///
516    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
517    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
518    #[implements]
519    #[inline]
520    fn new_buffer_view_raw(
521        &self,
522        info: &BufferViewCreateInfo,
523        allocation_callbacks: Option<&VkAllocationCallbacks>,
524    ) -> crate::Result<VkBufferView> {
525        let mut h = core::mem::MaybeUninit::uninit();
526        unsafe {
527            crate::vkfn::create_buffer_view(
528                self.native_ptr(),
529                info as *const _ as _,
530                crate::ffi_helper::opt_pointer(allocation_callbacks),
531                h.as_mut_ptr(),
532            )
533            .into_result()?;
534        }
535
536        Ok(unsafe { h.assume_init() })
537    }
538
539    /// Create a new sampler object
540    /// # Failures
541    /// On failure, this command returns
542    ///
543    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
544    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
545    /// * [`VK_ERROR_TOO_MANY_OBJECTS`]
546    #[implements]
547    #[inline]
548    fn new_sampler_raw(
549        &self,
550        info: &SamplerCreateInfo,
551        allocation_callbacks: Option<&VkAllocationCallbacks>,
552    ) -> crate::Result<VkSampler> {
553        let mut h = core::mem::MaybeUninit::uninit();
554        unsafe {
555            crate::vkfn::create_sampler(
556                self.native_ptr(),
557                info as *const _ as _,
558                crate::ffi_helper::opt_pointer(allocation_callbacks),
559                h.as_mut_ptr(),
560            )
561            .into_result()?;
562        }
563
564        Ok(unsafe { h.assume_init() })
565    }
566
567    /// Create a new image object
568    /// # Failure
569    /// On failure, this command returns
570    ///
571    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
572    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
573    /// * [`VK_ERROR_COMPRESSION_EXHAUSTED_EXT`]
574    /// * [`VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`]
575    #[implements]
576    #[inline]
577    fn new_image_raw(
578        &self,
579        info: &ImageCreateInfo,
580        allocation_callbacks: Option<&VkAllocationCallbacks>,
581    ) -> crate::Result<VkImage> {
582        let mut h = core::mem::MaybeUninit::uninit();
583
584        unsafe {
585            crate::vkfn::create_image(
586                self.native_ptr(),
587                info as *const _ as _,
588                crate::ffi_helper::opt_pointer(allocation_callbacks),
589                h.as_mut_ptr(),
590            )
591            .into_result()?;
592        }
593
594        Ok(unsafe { h.assume_init() })
595    }
596
597    /// Create a new image view from an existing image
598    /// # Failure
599    /// On failure, this command returns
600    ///
601    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
602    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
603    /// * [`VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR`]
604    #[implements]
605    #[inline]
606    fn new_image_view_raw(
607        &self,
608        info: &ImageViewCreateInfo,
609        allocation_callbacks: Option<&VkAllocationCallbacks>,
610    ) -> crate::Result<VkImageView> {
611        let mut h = core::mem::MaybeUninit::uninit();
612        unsafe {
613            crate::vkfn::create_image_view(
614                self.native_ptr(),
615                info as *const _ as _,
616                crate::ffi_helper::opt_pointer(allocation_callbacks),
617                h.as_mut_ptr(),
618            )
619            .into_result()?;
620        }
621
622        Ok(unsafe { h.assume_init() })
623    }
624
625    /// Create a new render pass object
626    /// # Failures
627    /// On failure, this command returns
628    ///
629    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
630    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
631    #[implements]
632    #[inline]
633    fn new_render_pass(
634        &self,
635        info: &RenderPassCreateInfo,
636        allocation_callbacks: Option<&VkAllocationCallbacks>,
637    ) -> crate::Result<VkRenderPass> {
638        let mut h = core::mem::MaybeUninit::uninit();
639        unsafe {
640            crate::vkfn::create_render_pass(
641                self.native_ptr(),
642                info as *const _ as _,
643                crate::ffi_helper::opt_pointer(allocation_callbacks),
644                h.as_mut_ptr(),
645            )
646            .into_result()?;
647        }
648
649        Ok(unsafe { h.assume_init() })
650    }
651
652    /// Create a new render pass object
653    /// # Failures
654    /// On failure, this command returns
655    ///
656    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
657    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
658    #[implements("Allow1_2APIs")]
659    #[inline]
660    fn new_render_pass2(
661        &self,
662        info: &RenderPassCreateInfo2,
663        allocation_callbacks: Option<&VkAllocationCallbacks>,
664    ) -> crate::Result<VkRenderPass> {
665        let mut h = core::mem::MaybeUninit::uninit();
666
667        unsafe {
668            crate::vkfn::create_render_pass2(
669                self.native_ptr(),
670                info as *const _ as _,
671                crate::ffi_helper::opt_pointer(allocation_callbacks),
672                h.as_mut_ptr(),
673            )
674            .into_result()?;
675        }
676
677        Ok(unsafe { h.assume_init() })
678    }
679
680    /// Create a new framebuffer object
681    /// # Failures
682    /// On failure, this command returns
683    ///
684    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
685    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
686    #[implements]
687    #[inline]
688    fn new_framebuffer_raw(
689        &self,
690        info: &FramebufferCreateInfo,
691        allocation_callbacks: Option<&VkAllocationCallbacks>,
692    ) -> crate::Result<VkFramebuffer> {
693        let mut h = core::mem::MaybeUninit::uninit();
694        unsafe {
695            crate::vkfn::create_framebuffer(
696                self.native_ptr(),
697                info as *const _ as _,
698                crate::ffi_helper::opt_pointer(allocation_callbacks),
699                h.as_mut_ptr(),
700            )
701            .into_result()?;
702        }
703
704        Ok(unsafe { h.assume_init() })
705    }
706
707    /// Creates a new shader module object
708    /// # Failures
709    /// On failure, this command returns
710    ///
711    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
712    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
713    /// * [`VK_ERROR_INVALID_SHADER_NV`]
714    #[implements]
715    #[inline]
716    fn new_shader_module_raw(
717        &self,
718        info: &ShaderModuleCreateInfo,
719        allocation_callbacks: Option<&VkAllocationCallbacks>,
720    ) -> crate::Result<VkShaderModule> {
721        let mut h = core::mem::MaybeUninit::uninit();
722        unsafe {
723            crate::vkfn::create_shader_module(
724                self.native_ptr(),
725                info as *const _ as _,
726                crate::ffi_helper::opt_pointer(allocation_callbacks),
727                h.as_mut_ptr(),
728            )
729            .into_result()?;
730        }
731
732        Ok(unsafe { h.assume_init() })
733    }
734
735    /// Create a new pipeline cache
736    /// # Failures
737    /// On failure, this command returns
738    ///
739    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
740    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
741    #[implements]
742    #[inline]
743    fn new_pipeline_cache_raw(
744        &self,
745        info: &PipelineCacheCreateInfo,
746        allocation_callbacks: Option<&VkAllocationCallbacks>,
747    ) -> crate::Result<VkPipelineCache> {
748        let mut h = core::mem::MaybeUninit::uninit();
749        unsafe {
750            crate::vkfn::create_pipeline_cache(
751                self.native_ptr(),
752                info as *const _ as _,
753                crate::ffi_helper::opt_pointer(allocation_callbacks),
754                h.as_mut_ptr(),
755            )
756            .into_result()?;
757        }
758
759        Ok(unsafe { h.assume_init() })
760    }
761
762    /// Create a new pipeline layout object
763    /// # Failures
764    /// On failure, this command returns
765    ///
766    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
767    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
768    #[implements]
769    #[inline]
770    fn new_pipeline_layout_raw(
771        &self,
772        info: &PipelineLayoutCreateInfo,
773        allocation_callbacks: Option<&VkAllocationCallbacks>,
774    ) -> crate::Result<VkPipelineLayout> {
775        let mut h = core::mem::MaybeUninit::uninit();
776        unsafe {
777            crate::vkfn::create_pipeline_layout(
778                self.native_ptr(),
779                info as *const _ as _,
780                crate::ffi_helper::opt_pointer(allocation_callbacks),
781                h.as_mut_ptr(),
782            )
783            .into_result()?;
784        }
785
786        Ok(unsafe { h.assume_init() })
787    }
788
789    /// Create graphics pipelines
790    /// # Failures
791    /// On failure, this command returns
792    ///
793    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
794    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
795    ///
796    /// # Safety
797    /// no guarantees will be provided (simply calls under api)
798    #[implements]
799    unsafe fn new_graphics_pipelines_raw(
800        &self,
801        infos: &[GraphicsPipelineCreateInfo],
802        cache: Option<VkPipelineCache>,
803        allocation_callbacks: Option<&VkAllocationCallbacks>,
804        objects: &mut [VkPipeline],
805    ) -> crate::Result<()> {
806        unsafe {
807            crate::vkfn::create_graphics_pipelines(
808                self.native_ptr(),
809                cache.unwrap_or(VkPipelineCache::NULL),
810                infos.len() as _,
811                crate::ffi_helper::slice_as_ptr_empty_null(infos) as _,
812                crate::ffi_helper::opt_pointer(allocation_callbacks),
813                objects.as_mut_ptr(),
814            )
815            .into_result()
816            .map(drop)
817        }
818    }
819
820    /// Create graphics pipelines
821    /// # Failures
822    /// On failure, this command returns
823    ///
824    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
825    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
826    #[implements("alloc")]
827    fn new_graphics_pipelines<'s>(
828        &'s self,
829        infos: &[GraphicsPipelineCreateInfo],
830        cache: Option<&(impl crate::VkHandle<Handle = VkPipelineCache> + ?Sized)>,
831    ) -> crate::Result<Vec<crate::PipelineObject<&'s Self>>> {
832        let mut hs = vec![VkPipeline::NULL; infos.len()];
833
834        unsafe {
835            self.new_graphics_pipelines_raw(infos, cache.map(VkHandle::native_ptr), None, &mut hs)?;
836        }
837
838        Ok(crate::alloc::collect_vec(
839            hs.into_iter()
840                .map(move |h| unsafe { crate::PipelineObject::manage(h, self) }),
841        ))
842    }
843
844    /// Create graphics pipelines
845    /// # Failures
846    /// On failure, this command returns
847    ///
848    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
849    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
850    #[implements]
851    fn new_graphics_pipeline_array<'s, const N: usize>(
852        &'s self,
853        infos: &[GraphicsPipelineCreateInfo; N],
854        cache: Option<&(impl crate::VkHandle<Handle = VkPipelineCache> + ?Sized)>,
855    ) -> crate::Result<[crate::PipelineObject<&'s Self>; N]> {
856        let mut hs = [VkPipeline::NULL; N];
857
858        unsafe {
859            self.new_graphics_pipelines_raw(infos, cache.map(VkHandle::native_ptr), None, &mut hs)?;
860        }
861
862        Ok(core::array::from_fn(move |n| unsafe {
863            crate::PipelineObject::manage(hs[n], self)
864        }))
865    }
866
867    /// Create compute pipelines
868    /// # Failures
869    /// On failure, this command returns
870    ///
871    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
872    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
873    ///
874    /// # Safety
875    /// no guarantees will be provided (simply calls under api)
876    #[implements]
877    unsafe fn new_compute_pipelines_raw(
878        &self,
879        infos: &[ComputePipelineCreateInfo],
880        cache: Option<VkPipelineCache>,
881        allocation_callbacks: Option<&VkAllocationCallbacks>,
882        objects: &mut [VkPipeline],
883    ) -> crate::Result<()> {
884        unsafe {
885            crate::vkfn::create_compute_pipelines(
886                self.native_ptr(),
887                cache.unwrap_or(VkPipelineCache::NULL),
888                infos.len() as _,
889                crate::ffi_helper::slice_as_ptr_empty_null(infos) as _,
890                crate::ffi_helper::opt_pointer(allocation_callbacks),
891                objects.as_mut_ptr(),
892            )
893            .into_result()
894            .map(drop)
895        }
896    }
897
898    /// Create compute pipelines
899    /// # Failures
900    /// On failure, this command returns
901    ///
902    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
903    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
904    #[implements("alloc")]
905    fn new_compute_pipelines<'s>(
906        &'s self,
907        infos: &[ComputePipelineCreateInfo],
908        cache: Option<&(impl crate::VkHandle<Handle = VkPipelineCache> + ?Sized)>,
909    ) -> crate::Result<Vec<crate::PipelineObject<&'s Self>>> {
910        let mut pipelines = vec![VkPipeline::NULL; infos.len()];
911
912        unsafe {
913            self.new_compute_pipelines_raw(infos, cache.map(VkHandle::native_ptr), None, &mut pipelines)?;
914        }
915
916        Ok(crate::alloc::collect_vec(
917            pipelines
918                .into_iter()
919                .map(move |h| unsafe { crate::PipelineObject::manage(h, self) }),
920        ))
921    }
922
923    /// Create compute pipelines
924    /// # Failures
925    /// On failure, this command returns
926    ///
927    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
928    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
929    #[implements]
930    fn new_compute_pipeline_array<'s, const N: usize>(
931        &'s self,
932        infos: &[ComputePipelineCreateInfo; N],
933        cache: Option<&(impl crate::VkHandle<Handle = VkPipelineCache> + ?Sized)>,
934    ) -> crate::Result<[crate::PipelineObject<&'s Self>; N]> {
935        let mut pipelines = [VkPipeline::NULL; N];
936
937        unsafe {
938            self.new_compute_pipelines_raw(infos, cache.map(VkHandle::native_ptr), None, &mut pipelines)?;
939        }
940
941        Ok(core::array::from_fn(move |n| unsafe {
942            crate::PipelineObject::manage(pipelines[n], self)
943        }))
944    }
945
946    /// Create a new command pool object
947    /// # Failures
948    /// On failure, this command returns
949    ///
950    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
951    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
952    #[implements]
953    #[inline]
954    fn new_command_pool_raw(
955        &self,
956        info: &CommandPoolCreateInfo,
957        allocation_callbacks: Option<&VkAllocationCallbacks>,
958    ) -> crate::Result<VkCommandPool> {
959        let mut h = core::mem::MaybeUninit::uninit();
960        unsafe {
961            crate::vkfn::create_command_pool(
962                self.native_ptr(),
963                info as *const _ as _,
964                crate::ffi_helper::opt_pointer(allocation_callbacks),
965                h.as_mut_ptr(),
966            )
967            .into_result()?;
968        }
969
970        Ok(unsafe { h.assume_init() })
971    }
972
973    /// Create a new query pool object
974    /// # Failures
975    /// On failure, this command returns
976    ///
977    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
978    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
979    #[implements]
980    #[inline]
981    fn new_query_pool_raw(
982        &self,
983        info: &QueryPoolCreateInfo,
984        allocation_callbacks: Option<&VkAllocationCallbacks>,
985    ) -> crate::Result<VkQueryPool> {
986        let mut h = core::mem::MaybeUninit::uninit();
987        unsafe {
988            crate::vkfn::create_query_pool(
989                self.native_ptr(),
990                info as *const _ as _,
991                crate::ffi_helper::opt_pointer(allocation_callbacks),
992                h.as_mut_ptr(),
993            )
994            .into_result()?;
995        }
996
997        Ok(unsafe { h.assume_init() })
998    }
999
1000    /// Allocate command buffers from an existing command pool
1001    /// # Failures
1002    /// On failure, this command returns
1003    ///
1004    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1005    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1006    ///
1007    /// # Safety
1008    /// A `VkCommandPool` specified in the `info` argument must be created from this device
1009    #[implements]
1010    #[inline]
1011    unsafe fn allocate_command_buffers<'s>(
1012        &'s self,
1013        info: &CommandBufferAllocateInfo,
1014        sink: &mut [core::mem::MaybeUninit<CommandBufferObject<&'s Self>>],
1015    ) -> crate::Result<()> {
1016        assert_eq!(info.0.commandBufferCount as usize, sink.len());
1017
1018        unsafe {
1019            crate::vkfn::allocate_command_buffers(self.native_ptr(), info as *const _ as _, sink.as_mut_ptr() as _)
1020                .into_result()
1021                .map(drop)
1022        }
1023    }
1024
1025    /// Allocate command buffers from an existing command pool
1026    /// # Failures
1027    /// On failure, this command returns
1028    ///
1029    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1030    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1031    ///
1032    /// # Safety
1033    /// A `VkCommandPool` specified in the `info` argument must be created from this device
1034    #[implements("alloc")]
1035    unsafe fn allocate_command_buffers_alloc<'s>(
1036        &'s self,
1037        info: &CommandBufferAllocateInfo,
1038    ) -> crate::Result<Vec<CommandBufferObject<&'s Self>>> {
1039        let mut sink = Vec::with_capacity(info.0.commandBufferCount as _);
1040        unsafe {
1041            self.allocate_command_buffers(info, sink.spare_capacity_mut())?;
1042            sink.set_len(info.0.commandBufferCount as _);
1043        }
1044
1045        Ok(sink)
1046    }
1047
1048    /// Allocate command buffers from an existing command pool
1049    /// # Failures
1050    /// On failure, this command returns
1051    ///
1052    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1053    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1054    ///
1055    /// # Safety
1056    /// A `VkCommandPool` specified in the `info` argument must be created from this device
1057    #[implements]
1058    #[inline]
1059    unsafe fn allocate_command_buffer_array<'s, const N: usize>(
1060        &'s self,
1061        info: &CommandBufferFixedCountAllocateInfo<N>,
1062    ) -> crate::Result<[CommandBufferObject<&'s Self>; N]> {
1063        let mut sink =
1064            [const { unsafe { core::mem::MaybeUninit::<CommandBufferObject<&'s Self>>::zeroed().assume_init() } }; N];
1065        unsafe {
1066            crate::vkfn::allocate_command_buffers(self.native_ptr(), info as *const _ as _, sink.as_mut_ptr() as _)
1067                .into_result()?;
1068        }
1069
1070        Ok(sink)
1071    }
1072
1073    /// Invalidate `MappedMemoryRange`s
1074    /// Invalidating the memory range allows that device writes to the memory ranges
1075    /// which have been made visible to the `VK_ACCESS_HOST_WRITE_BIT` and `VK_ACCESS_HOST_READ_BIT`
1076    /// are made visible to the host
1077    /// # Safety
1078    /// Memory object in `ranges` must be currently host mapped
1079    #[implements]
1080    #[inline]
1081    unsafe fn invalidate_memory_range(&self, ranges: &[MappedMemoryRange]) -> crate::Result<()> {
1082        unsafe {
1083            crate::vkfn::invalidate_mapped_memory_ranges(
1084                self.native_ptr(),
1085                ranges.len() as _,
1086                crate::ffi_helper::slice_as_ptr_empty_null(ranges) as _,
1087            )
1088            .into_result()
1089            .map(drop)
1090        }
1091    }
1092
1093    /// Flush `MappedMemoryRange`s
1094    /// Flushing the memory range allows that host writes to the memory ranges can
1095    /// be made available to device access
1096    /// # Safety
1097    /// Memory object in `ranges` must be currently host mapped
1098    #[implements]
1099    #[inline]
1100    unsafe fn flush_mapped_memory_ranges(&self, ranges: &[MappedMemoryRange]) -> crate::Result<()> {
1101        unsafe {
1102            crate::vkfn::flush_mapped_memory_ranges(
1103                self.native_ptr(),
1104                ranges.len() as _,
1105                crate::ffi_helper::slice_as_ptr_empty_null(ranges) as _,
1106            )
1107            .into_result()
1108            .map(drop)
1109        }
1110    }
1111
1112    /// Update the contents of descriptor set objects
1113    #[implements]
1114    #[inline]
1115    unsafe fn update_descriptor_sets_raw(&self, writes: &[VkWriteDescriptorSet], copies: &[VkCopyDescriptorSet]) {
1116        unsafe {
1117            crate::vkfn::update_descriptor_sets(
1118                self.native_ptr(),
1119                writes.len() as _,
1120                slice_as_ptr_empty_null(writes),
1121                copies.len() as _,
1122                slice_as_ptr_empty_null(copies),
1123            )
1124        }
1125    }
1126
1127    /// Update the contents of descriptor set objects
1128    #[implements("alloc")]
1129    fn update_descriptor_sets(&self, writes: &[DescriptorSetWriteInfo], copies: &[DescriptorSetCopyInfo]) {
1130        unsafe {
1131            self.update_descriptor_sets_raw(
1132                &crate::alloc::collect_vec(writes.iter().map(DescriptorSetWriteInfo::make_structure)),
1133                &crate::alloc::collect_vec(copies.iter().map(DescriptorSetCopyInfo::make_structure)),
1134            );
1135        }
1136    }
1137
1138    /// Wait for a object to become idle
1139    /// # Safety
1140    /// All VkQueue objects created from this device must be externally synchronized.
1141    #[implements]
1142    #[inline]
1143    unsafe fn wait(&self) -> crate::Result<()> {
1144        unsafe { crate::vkfn::device_wait_idle(self.native_ptr()).into_result().map(drop) }
1145    }
1146
1147    /// Query the memory requirements for a sparse image
1148    /// # Safety
1149    /// `sink_head_ptr` must be a valid pointer for read/write operations.
1150    #[implements("Allow1_1APIs")]
1151    #[inline]
1152    unsafe fn get_image_sparse_memory_requirements2_count(
1153        &self,
1154        info: &ImageSparseMemoryRequirementsInfo2,
1155        count_sink: &mut core::mem::MaybeUninit<u32>,
1156        sink_head_ptr: *mut VkSparseImageMemoryRequirements2KHR,
1157    ) {
1158        unsafe {
1159            crate::vkfn::get_image_sparse_memory_requirements2(
1160                self.native_ptr(),
1161                &info.0,
1162                count_sink.as_mut_ptr(),
1163                sink_head_ptr,
1164            )
1165        }
1166    }
1167
1168    /// Single binding for a buffer
1169    /// # Safety
1170    /// `VkBuffer` and `VkDeviceMemory` must be valid and created from this device object
1171    #[implements]
1172    #[inline]
1173    unsafe fn bind_buffer_raw(
1174        &self,
1175        buffer: VkBuffer,
1176        memory: VkDeviceMemory,
1177        offset: VkDeviceSize,
1178    ) -> crate::Result<()> {
1179        unsafe {
1180            crate::vkfn::bind_buffer_memory(self.native_ptr(), buffer, memory, offset)
1181                .into_result()
1182                .map(drop)
1183        }
1184    }
1185
1186    /// Multiple Binding for Buffers
1187    #[implements("Allow1_1APIs")]
1188    #[inline]
1189    unsafe fn bind_buffers_raw(&self, bounds: &[VkBindBufferMemoryInfoKHR]) -> crate::Result<()> {
1190        unsafe {
1191            crate::vkfn::bind_buffer_memory2(
1192                self.native_ptr(),
1193                bounds.len() as _,
1194                crate::ffi_helper::slice_as_ptr_empty_null(bounds),
1195            )
1196            .into_result()
1197            .map(drop)
1198        }
1199    }
1200
1201    /// Single binding for an image
1202    /// # Safety
1203    /// `VkImage` and `VkDeviceMemory` must be valid and created from this device object
1204    #[implements]
1205    #[inline]
1206    unsafe fn bind_image_raw(&self, image: VkImage, memory: VkDeviceMemory, offset: VkDeviceSize) -> crate::Result<()> {
1207        unsafe {
1208            crate::vkfn::bind_image_memory(self.native_ptr(), image, memory, offset)
1209                .into_result()
1210                .map(drop)
1211        }
1212    }
1213
1214    /// Multiple Binding for Images
1215    #[implements("Allow1_1APIs")]
1216    #[inline]
1217    unsafe fn bind_images_raw(&self, bounds: &[VkBindImageMemoryInfoKHR]) -> crate::Result<()> {
1218        unsafe {
1219            crate::vkfn::bind_image_memory2(
1220                self.native_ptr(),
1221                bounds.len() as _,
1222                crate::ffi_helper::slice_as_ptr_empty_null(bounds),
1223            )
1224            .into_result()
1225            .map(drop)
1226        }
1227    }
1228
1229    /// Wait for one or more fences to become signaled, returns `Ok(true)` if operation is timed out
1230    /// # Failures
1231    /// On failure, this command returns
1232    ///
1233    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1234    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1235    /// * `VK_ERROR_DEVICE_LOST`
1236    #[implements]
1237    fn wait_multiple_fences(
1238        &self,
1239        objects: &[VkHandleRef<VkFence>],
1240        wait_all: bool,
1241        timeout: Option<u64>,
1242    ) -> crate::Result<bool> {
1243        let vr = unsafe {
1244            crate::vkfn::wait_for_fences(
1245                self.native_ptr(),
1246                objects.len() as _,
1247                crate::ffi_helper::slice_as_ptr_empty_null(objects) as _,
1248                wait_all as _,
1249                timeout.unwrap_or(std::u64::MAX),
1250            )
1251        };
1252
1253        match vr {
1254            VK_SUCCESS => Ok(false),
1255            VK_TIMEOUT => Ok(true),
1256            _ => Err(vr),
1257        }
1258    }
1259
1260    /// Resets one or more fence objects
1261    /// # Failures
1262    /// On failure, this command returns
1263    ///
1264    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1265    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1266    #[implements]
1267    #[inline]
1268    fn reset_multiple_fences(&self, objects: &[VkHandleRefMut<VkFence>]) -> crate::Result<()> {
1269        unsafe {
1270            crate::vkfn::reset_fences(
1271                self.native_ptr(),
1272                objects.len() as _,
1273                crate::ffi_helper::slice_as_ptr_empty_null(objects) as _,
1274            )
1275            .into_result()
1276            .map(drop)
1277        }
1278    }
1279
1280    /// Create a swapchain
1281    /// # Failures
1282    /// On failure, this command returns
1283    ///
1284    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1285    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1286    /// * [`VK_ERROR_DEVICE_LOST`]
1287    /// * [`VK_ERROR_SURFACE_LOST_KHR`]
1288    /// * [`VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`]
1289    /// * [`VK_ERROR_INITIALIZATION_FAILED`]
1290    /// * [`VK_ERROR_COMPRESSION_EXHAUSTED_EXT`]
1291    #[implements("VK_KHR_swapchain")]
1292    #[inline]
1293    fn new_swapchain_raw(
1294        &self,
1295        info: &SwapchainCreateInfo,
1296        allocation_callbacks: Option<&VkAllocationCallbacks>,
1297    ) -> crate::Result<VkSwapchainKHR> {
1298        let mut h = core::mem::MaybeUninit::uninit();
1299        unsafe {
1300            crate::vkfn::create_swapchain_khr(
1301                self.native_ptr(),
1302                info as *const _ as _,
1303                crate::ffi_helper::opt_pointer(allocation_callbacks),
1304                h.as_mut_ptr(),
1305            )
1306            .into_result()?;
1307        }
1308
1309        Ok(unsafe { h.assume_init() })
1310    }
1311
1312    /// Give a user-friendly name to an object.
1313    /// # Failures
1314    /// On failure, this command returns
1315    ///
1316    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1317    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1318    #[implements("VK_EXT_debug_utils")]
1319    fn set_object_name(&self, info: &crate::DebugUtilsObjectNameInfo) -> crate::Result<()>
1320    where
1321        Self::ConcreteInstance: InstanceDebugUtilsExtension,
1322    {
1323        unsafe {
1324            self.instance().set_debug_utils_object_name_ext_fn().0(self.native_ptr(), &info.0)
1325                .into_result()
1326                .map(drop)
1327        }
1328    }
1329
1330    /// Create a new descriptor update template
1331    /// # Failure
1332    /// On failure, this command returns
1333    ///
1334    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1335    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1336    ///
1337    /// # Safety
1338    /// no guarantees will be provided (simply calls under api)
1339    #[implements("Allow1_1APIs")]
1340    unsafe fn new_descriptor_update_template_raw(
1341        &self,
1342        info: &VkDescriptorUpdateTemplateCreateInfoKHR,
1343        allocation_callbacks: Option<&VkAllocationCallbacks>,
1344    ) -> crate::Result<VkDescriptorUpdateTemplateKHR> {
1345        let mut h = core::mem::MaybeUninit::uninit();
1346        unsafe {
1347            crate::vkfn::create_descriptor_update_template(
1348                self.native_ptr(),
1349                info,
1350                crate::ffi_helper::opt_pointer(allocation_callbacks),
1351                h.as_mut_ptr(),
1352            )
1353            .into_result()?;
1354        }
1355        Ok(unsafe { h.assume_init() })
1356    }
1357
1358    /// Query the current state of a timeline semaphore
1359    /// # Failure
1360    ///
1361    /// * [`VK_ERROR_DEVICE_LOST`]
1362    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1363    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1364    /// * [`VK_ERROR_UNKNOWN`]
1365    /// * [`VK_ERROR_VALIDATION_FAILED`]
1366    #[implements("Allow1_2APIs")]
1367    fn get_semaphore_counter_value(
1368        &self,
1369        semaphore: &(impl VkHandle<Handle = VkSemaphore> + ?Sized),
1370    ) -> crate::Result<u64> {
1371        let mut sink = core::mem::MaybeUninit::uninit();
1372
1373        unsafe {
1374            crate::vkfn::get_semaphore_counter_value(self.native_ptr(), semaphore.native_ptr(), sink.as_mut_ptr())
1375                .into_result()?;
1376        }
1377
1378        Ok(unsafe { sink.assume_init() })
1379    }
1380
1381    /// Signal a timeline semaphore on the host
1382    /// # Failure
1383    ///
1384    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1385    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1386    /// * [`VK_ERROR_UNKNOWN`]
1387    /// * [`VK_ERROR_VALIDATION_FAILED`]
1388    #[implements("Allow1_2APIs")]
1389    fn signal_semaphore(&self, info: &SemaphoreSignalInfo) -> crate::Result<()> {
1390        unsafe {
1391            crate::vkfn::signal_semaphore(self.native_ptr(), info as *const _ as _)
1392                .into_result()
1393                .map(drop)
1394        }
1395    }
1396
1397    /// Wait for timeline semaphores on the host
1398    ///
1399    /// Returns `false` if timed out
1400    /// # Failure
1401    ///
1402    /// * [`VK_ERROR_DEVICE_LOST`]
1403    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
1404    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
1405    /// * [`VK_ERROR_UNKNOWN`]
1406    /// * [`VK_ERROR_VALIDATION_FAILED`]
1407    #[implements("Allow1_2APIs")]
1408    fn wait_semaphores(&self, info: &SemaphoreWaitInfo, timeout: u64) -> crate::Result<bool> {
1409        match unsafe { crate::vkfn::wait_semaphores(self.native_ptr(), info as *const _ as _, timeout) } {
1410            r if r == VK_SUCCESS => Ok(true),
1411            r if r == VK_TIMEOUT => Ok(false),
1412            r => Err(r),
1413        }
1414    }
1415}
1416DerefContainerWithGuardsBracketImpl!(for Device {});
1417
1418/// Extension function caches
1419#[implements]
1420struct DeviceExtFunctions {
1421    #[cfg(feature = "VK_KHR_maintenance1")]
1422    trim_command_pool_khr: DeviceResolvedFn<PFN_vkTrimCommandPoolKHR>,
1423    #[cfg(feature = "VK_KHR_descriptor_update_template")]
1424    create_descriptor_update_template_khr: DeviceResolvedFn<PFN_vkCreateDescriptorUpdateTemplateKHR>,
1425    #[cfg(feature = "VK_KHR_descriptor_update_template")]
1426    destroy_descriptor_update_template_khr: DeviceResolvedFn<PFN_vkDestroyDescriptorUpdateTemplateKHR>,
1427    #[cfg(feature = "VK_KHR_descriptor_update_template")]
1428    update_descriptor_set_with_template_khr: DeviceResolvedFn<PFN_vkUpdateDescriptorSetWithTemplateKHR>,
1429    #[cfg(feature = "VK_KHR_bind_memory2")]
1430    bind_buffer_memory2_khr: DeviceResolvedFn<PFN_vkBindBufferMemory2KHR>,
1431    #[cfg(feature = "VK_KHR_bind_memory2")]
1432    bind_image_memory2_khr: DeviceResolvedFn<PFN_vkBindImageMemory2KHR>,
1433    #[cfg(all(feature = "VK_EXT_image_drm_format_modifier"))]
1434    get_image_drm_format_modifier_properties_ext: DeviceResolvedFn<PFN_vkGetImageDrmFormatModifierPropertiesEXT>,
1435    #[cfg(all(feature = "VK_KHR_external_fence_fd"))]
1436    get_fence_fd_khr: DeviceResolvedFn<PFN_vkGetFenceFdKHR>,
1437    #[cfg(all(feature = "VK_KHR_external_fence_fd"))]
1438    import_fence_fd_khr: DeviceResolvedFn<PFN_vkImportFenceFdKHR>,
1439    #[cfg(all(feature = "VK_EXT_full_screen_exclusive"))]
1440    acquire_full_screen_exclusive_mode_ext: DeviceResolvedFn<PFN_vkAcquireFullScreenExclusiveModeEXT>,
1441    #[cfg(all(feature = "VK_EXT_full_screen_exclusive"))]
1442    release_full_screen_exclusive_mode_ext: DeviceResolvedFn<PFN_vkReleaseFullScreenExclusiveModeEXT>,
1443    #[cfg(all(feature = "VK_KHR_external_memory_fd"))]
1444    get_memory_fd_khr: DeviceResolvedFn<PFN_vkGetMemoryFdKHR>,
1445    #[cfg(all(feature = "VK_KHR_external_memory_fd"))]
1446    get_memory_fd_properties_khr: DeviceResolvedFn<PFN_vkGetMemoryFdPropertiesKHR>,
1447    #[cfg(all(feature = "VK_EXT_external_memory_host"))]
1448    get_memory_host_pointer_properties_ext: DeviceResolvedFn<PFN_vkGetMemoryHostPointerPropertiesEXT>,
1449    #[cfg(all(feature = "VK_KHR_external_semaphore_win32"))]
1450    import_semaphore_win32_handle_khr: DeviceResolvedFn<PFN_vkImportSemaphoreWin32HandleKHR>,
1451    #[cfg(all(feature = "VK_KHR_external_semaphore_win32"))]
1452    get_semaphore_win32_handle_khr: DeviceResolvedFn<PFN_vkGetSemaphoreWin32HandleKHR>,
1453    #[cfg(all(feature = "VK_KHR_external_memory_win32"))]
1454    get_memory_win32_handle_khr: DeviceResolvedFn<PFN_vkGetMemoryWin32HandleKHR>,
1455    #[cfg(all(feature = "VK_KHR_external_memory_win32"))]
1456    get_memory_win32_handle_properties_khr: DeviceResolvedFn<PFN_vkGetMemoryWin32HandlePropertiesKHR>,
1457    #[cfg(feature = "VK_KHR_get_memory_requirements2")]
1458    get_buffer_memory_requirements_2_khr: DeviceResolvedFn<PFN_vkGetBufferMemoryRequirements2KHR>,
1459    #[cfg(feature = "VK_KHR_get_memory_requirements2")]
1460    get_image_memory_requirements_2_khr: DeviceResolvedFn<PFN_vkGetImageMemoryRequirements2KHR>,
1461    #[cfg(feature = "VK_KHR_get_memory_requirements2")]
1462    get_image_sparse_memory_requirements_2_khr: DeviceResolvedFn<PFN_vkGetImageSparseMemoryRequirements2KHR>,
1463    #[cfg(feature = "VK_KHR_create_renderpass2")]
1464    create_render_pass_2_khr: DeviceResolvedFn<PFN_vkCreateRenderPass2KHR>,
1465    #[cfg(feature = "VK_KHR_create_renderpass2")]
1466    cmd_begin_render_pass_2_khr: DeviceResolvedFn<PFN_vkCmdBeginRenderPass2KHR>,
1467    #[cfg(feature = "VK_KHR_create_renderpass2")]
1468    cmd_end_render_pass_2_khr: DeviceResolvedFn<PFN_vkCmdEndRenderPass2KHR>,
1469    #[cfg(feature = "VK_KHR_create_renderpass2")]
1470    cmd_next_subpass_2_khr: DeviceResolvedFn<PFN_vkCmdNextSubpass2KHR>,
1471    #[cfg(feature = "VK_KHR_synchronization2")]
1472    queue_submit2_khr: DeviceResolvedFn<PFN_vkQueueSubmit2KHR>,
1473    #[cfg(feature = "VK_KHR_synchronization2")]
1474    cmd_pipeline_barrier_2_khr: DeviceResolvedFn<PFN_vkCmdPipelineBarrier2KHR>,
1475    #[cfg(feature = "VK_KHR_push_descriptor")]
1476    cmd_push_descriptor_set_khr: DeviceResolvedFn<PFN_vkCmdPushDescriptorSetKHR>,
1477    #[cfg(feature = "VK_EXT_sample_locations")]
1478    cmd_set_sample_locations_ext: DeviceResolvedFn<PFN_vkCmdSetSampleLocationsEXT>,
1479    #[cfg(feature = "VK_KHR_timeline_semaphore")]
1480    get_semaphore_counter_value_ext: DeviceResolvedFn<PFN_vkGetSemaphoreCounterValueKHR>,
1481    #[cfg(feature = "VK_KHR_timeline_semaphore")]
1482    signal_semaphore_ext: DeviceResolvedFn<PFN_vkSignalSemaphoreKHR>,
1483    #[cfg(feature = "VK_KHR_timeline_semaphore")]
1484    wait_semaphores_ext: DeviceResolvedFn<PFN_vkWaitSemaphoresKHR>,
1485}
1486#[implements]
1487impl DeviceExtFunctions {
1488    const fn new(handle: VkDevice) -> Self {
1489        Self {
1490            #[cfg(feature = "VK_KHR_maintenance1")]
1491            trim_command_pool_khr: DeviceResolvedFn::new(handle),
1492            #[cfg(feature = "VK_KHR_descriptor_update_template")]
1493            create_descriptor_update_template_khr: DeviceResolvedFn::new(handle),
1494            #[cfg(feature = "VK_KHR_descriptor_update_template")]
1495            destroy_descriptor_update_template_khr: DeviceResolvedFn::new(handle),
1496            #[cfg(feature = "VK_KHR_descriptor_update_template")]
1497            update_descriptor_set_with_template_khr: DeviceResolvedFn::new(handle),
1498            #[cfg(feature = "VK_KHR_bind_memory2")]
1499            bind_buffer_memory2_khr: DeviceResolvedFn::new(handle),
1500            #[cfg(feature = "VK_KHR_bind_memory2")]
1501            bind_image_memory2_khr: DeviceResolvedFn::new(handle),
1502            #[cfg(all(feature = "VK_EXT_image_drm_format_modifier"))]
1503            get_image_drm_format_modifier_properties_ext: DeviceResolvedFn::new(handle),
1504            #[cfg(all(feature = "VK_KHR_external_fence_fd"))]
1505            get_fence_fd_khr: DeviceResolvedFn::new(handle),
1506            #[cfg(all(feature = "VK_KHR_external_fence_fd"))]
1507            import_fence_fd_khr: DeviceResolvedFn::new(handle),
1508            #[cfg(all(feature = "VK_EXT_full_screen_exclusive"))]
1509            acquire_full_screen_exclusive_mode_ext: DeviceResolvedFn::new(handle),
1510            #[cfg(all(feature = "VK_EXT_full_screen_exclusive"))]
1511            release_full_screen_exclusive_mode_ext: DeviceResolvedFn::new(handle),
1512            #[cfg(all(feature = "VK_KHR_external_memory_fd"))]
1513            get_memory_fd_khr: DeviceResolvedFn::new(handle),
1514            #[cfg(all(feature = "VK_KHR_external_memory_fd"))]
1515            get_memory_fd_properties_khr: DeviceResolvedFn::new(handle),
1516            #[cfg(all(feature = "VK_EXT_external_memory_host"))]
1517            get_memory_host_pointer_properties_ext: DeviceResolvedFn::new(handle),
1518            #[cfg(all(feature = "VK_KHR_external_semaphore_win32"))]
1519            import_semaphore_win32_handle_khr: DeviceResolvedFn::new(handle),
1520            #[cfg(all(feature = "VK_KHR_external_semaphore_win32"))]
1521            get_semaphore_win32_handle_khr: DeviceResolvedFn::new(handle),
1522            #[cfg(all(feature = "VK_KHR_external_memory_win32"))]
1523            get_memory_win32_handle_khr: DeviceResolvedFn::new(handle),
1524            #[cfg(all(feature = "VK_KHR_external_memory_win32"))]
1525            get_memory_win32_handle_properties_khr: DeviceResolvedFn::new(handle),
1526            #[cfg(feature = "VK_KHR_get_memory_requirements2")]
1527            get_buffer_memory_requirements_2_khr: DeviceResolvedFn::new(handle),
1528            #[cfg(feature = "VK_KHR_get_memory_requirements2")]
1529            get_image_memory_requirements_2_khr: DeviceResolvedFn::new(handle),
1530            #[cfg(feature = "VK_KHR_get_memory_requirements2")]
1531            get_image_sparse_memory_requirements_2_khr: DeviceResolvedFn::new(handle),
1532            #[cfg(feature = "VK_KHR_create_renderpass2")]
1533            create_render_pass_2_khr: DeviceResolvedFn::new(handle),
1534            #[cfg(feature = "VK_KHR_create_renderpass2")]
1535            cmd_begin_render_pass_2_khr: DeviceResolvedFn::new(handle),
1536            #[cfg(feature = "VK_KHR_create_renderpass2")]
1537            cmd_end_render_pass_2_khr: DeviceResolvedFn::new(handle),
1538            #[cfg(feature = "VK_KHR_create_renderpass2")]
1539            cmd_next_subpass_2_khr: DeviceResolvedFn::new(handle),
1540            #[cfg(feature = "VK_KHR_synchronization2")]
1541            queue_submit2_khr: DeviceResolvedFn::new(handle),
1542            #[cfg(feature = "VK_KHR_synchronization2")]
1543            cmd_pipeline_barrier_2_khr: DeviceResolvedFn::new(handle),
1544            #[cfg(feature = "VK_KHR_push_descriptor")]
1545            cmd_push_descriptor_set_khr: DeviceResolvedFn::new(handle),
1546            #[cfg(feature = "VK_EXT_sample_locations")]
1547            cmd_set_sample_locations_ext: DeviceResolvedFn::new(handle),
1548            #[cfg(feature = "VK_KHR_timeline_semaphore")]
1549            get_semaphore_counter_value_ext: DeviceResolvedFn::new(handle),
1550            #[cfg(feature = "VK_KHR_timeline_semaphore")]
1551            signal_semaphore_ext: DeviceResolvedFn::new(handle),
1552            #[cfg(feature = "VK_KHR_timeline_semaphore")]
1553            wait_semaphores_ext: DeviceResolvedFn::new(handle),
1554        }
1555    }
1556}
1557
1558#[cfg(feature = "VK_KHR_maintenance1")]
1559pub trait DeviceMaintenance1Extension: Device {
1560    #[implements]
1561    fn trim_command_pool_khr_fn(&self) -> PFN_vkTrimCommandPoolKHR;
1562
1563    /// Trim a command pool.
1564    #[implements]
1565    #[inline]
1566    unsafe fn trim_command_pool_khr(
1567        &self,
1568        command_pool: &mut (impl VkHandleMut<Handle = VkCommandPool> + ?Sized),
1569        flags: CommandPoolTrimFlags,
1570    ) {
1571        unsafe { self.trim_command_pool_khr_fn().0(self.native_ptr(), command_pool.native_ptr_mut(), flags.bits()) }
1572    }
1573}
1574#[cfg(feature = "VK_KHR_maintenance1")]
1575DerefContainerWithGuardsBracketImpl!(for DeviceMaintenance1Extension {
1576    #[implements]
1577    ForwardFnPtr!(deref trim_command_pool_khr_fn -> PFN_vkTrimCommandPoolKHR);
1578});
1579#[cfg(feature = "VK_KHR_maintenance1")]
1580impl<Instance: crate::Instance> DeviceMaintenance1Extension for DeviceObject<Instance> {
1581    #[implements]
1582    #[inline(always)]
1583    fn trim_command_pool_khr_fn(&self) -> PFN_vkTrimCommandPoolKHR {
1584        *self.ext.trim_command_pool_khr.resolve()
1585    }
1586}
1587
1588#[cfg(feature = "VK_KHR_descriptor_update_template")]
1589pub trait DeviceDescriptorUpdateTemplateExtension: Device {
1590    #[implements]
1591    fn create_descriptor_update_template_khr_fn(&self) -> PFN_vkCreateDescriptorUpdateTemplateKHR;
1592    #[implements]
1593    fn destroy_descriptor_update_template_khr_fn(&self) -> PFN_vkDestroyDescriptorUpdateTemplateKHR;
1594    #[implements]
1595    fn update_descriptor_set_with_template_khr_fn(&self) -> PFN_vkUpdateDescriptorSetWithTemplateKHR;
1596
1597    /// Create a new descriptor update template
1598    /// # Failure
1599    /// On failure, this command returns
1600    ///
1601    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1602    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
1603    ///
1604    /// # Safety
1605    /// no guarantees will be provided (simply calls under api)
1606    #[implements]
1607    #[inline]
1608    unsafe fn new_descriptor_update_template_raw_khr(
1609        &self,
1610        create_info: &VkDescriptorUpdateTemplateCreateInfoKHR,
1611        allocation_callbacks: Option<&VkAllocationCallbacks>,
1612    ) -> crate::Result<VkDescriptorUpdateTemplateKHR> {
1613        let mut h = core::mem::MaybeUninit::uninit();
1614        unsafe {
1615            self.create_descriptor_update_template_khr_fn().0(
1616                self.native_ptr(),
1617                create_info,
1618                crate::ffi_helper::opt_pointer(allocation_callbacks),
1619                h.as_mut_ptr(),
1620            )
1621            .into_result()?;
1622        }
1623        Ok(unsafe { h.assume_init() })
1624    }
1625}
1626#[cfg(feature = "VK_KHR_descriptor_update_template")]
1627DerefContainerWithGuardsBracketImpl!(for DeviceDescriptorUpdateTemplateExtension {
1628    #[implements]
1629    ForwardFnPtr!(deref create_descriptor_update_template_khr_fn -> PFN_vkCreateDescriptorUpdateTemplateKHR);
1630    #[implements]
1631    ForwardFnPtr!(deref destroy_descriptor_update_template_khr_fn -> PFN_vkDestroyDescriptorUpdateTemplateKHR);
1632    #[implements]
1633    ForwardFnPtr!(deref update_descriptor_set_with_template_khr_fn -> PFN_vkUpdateDescriptorSetWithTemplateKHR);
1634});
1635#[cfg(feature = "VK_KHR_descriptor_update_template")]
1636impl<Instance: crate::Instance> DeviceDescriptorUpdateTemplateExtension for DeviceObject<Instance> {
1637    #[implements]
1638    #[inline(always)]
1639    fn create_descriptor_update_template_khr_fn(&self) -> PFN_vkCreateDescriptorUpdateTemplateKHR {
1640        *self.ext.create_descriptor_update_template_khr.resolve()
1641    }
1642    #[implements]
1643    #[inline(always)]
1644    fn destroy_descriptor_update_template_khr_fn(&self) -> PFN_vkDestroyDescriptorUpdateTemplateKHR {
1645        *self.ext.destroy_descriptor_update_template_khr.resolve()
1646    }
1647    #[implements]
1648    #[inline(always)]
1649    fn update_descriptor_set_with_template_khr_fn(&self) -> PFN_vkUpdateDescriptorSetWithTemplateKHR {
1650        *self.ext.update_descriptor_set_with_template_khr.resolve()
1651    }
1652}
1653
1654#[cfg(feature = "VK_KHR_get_memory_requirements2")]
1655pub trait DeviceGetMemoryRequirements2Extension: Device {
1656    #[implements]
1657    fn get_buffer_memory_requirements_2_khr_fn(&self) -> PFN_vkGetBufferMemoryRequirements2KHR;
1658    #[implements]
1659    fn get_image_memory_requirements_2_khr_fn(&self) -> PFN_vkGetImageMemoryRequirements2KHR;
1660    #[implements]
1661    fn get_image_sparse_memory_requirements_2_khr_fn(&self) -> PFN_vkGetImageSparseMemoryRequirements2KHR;
1662
1663    /// Returns the memory requirements for specified Vulkan object.
1664    #[implements]
1665    #[inline]
1666    unsafe fn get_buffer_memory_requirements2_khr(
1667        &self,
1668        info: &crate::BufferMemoryRequirementsInfo2<'_, impl crate::VkHandle<Handle = VkBuffer>>,
1669        sink: &mut core::mem::MaybeUninit<VkMemoryRequirements2KHR>,
1670    ) {
1671        unsafe {
1672            self.get_buffer_memory_requirements_2_khr_fn().0(
1673                self.native_ptr(),
1674                info as *const _ as _,
1675                sink.as_mut_ptr(),
1676            )
1677        }
1678    }
1679
1680    /// Returns the memory requirements for specified Vulkan object.
1681    #[implements]
1682    #[inline]
1683    unsafe fn get_image_memory_requirements2_khr(
1684        &self,
1685        info: &crate::ImageMemoryRequirementsInfo2<'_, impl crate::VkHandle<Handle = VkImage>>,
1686        sink: &mut core::mem::MaybeUninit<VkMemoryRequirements2KHR>,
1687    ) {
1688        unsafe {
1689            self.get_image_memory_requirements_2_khr_fn().0(self.native_ptr(), info as *const _ as _, sink.as_mut_ptr())
1690        }
1691    }
1692
1693    /// Query the memory requirements for a sparse image
1694    /// # Safety
1695    /// `sink_head_ptr` must be a valid pointer for read/write operations.
1696    #[implements]
1697    #[inline]
1698    unsafe fn get_image_sparse_memory_requirements2_count_khr(
1699        &self,
1700        info: &ImageSparseMemoryRequirementsInfo2,
1701        count_sink: &mut core::mem::MaybeUninit<u32>,
1702        sink_head_ptr: *mut VkSparseImageMemoryRequirements2KHR,
1703    ) {
1704        unsafe {
1705            self.get_image_sparse_memory_requirements_2_khr_fn().0(
1706                self.native_ptr(),
1707                &info.0,
1708                count_sink.as_mut_ptr(),
1709                sink_head_ptr,
1710            )
1711        }
1712    }
1713}
1714#[cfg(feature = "VK_KHR_get_memory_requirements2")]
1715DerefContainerWithGuardsBracketImpl!(for DeviceGetMemoryRequirements2Extension {
1716    #[implements]
1717    ForwardFnPtr!(deref get_buffer_memory_requirements_2_khr_fn -> PFN_vkGetBufferMemoryRequirements2KHR);
1718    #[implements]
1719    ForwardFnPtr!(deref get_image_memory_requirements_2_khr_fn -> PFN_vkGetImageMemoryRequirements2KHR);
1720    #[implements]
1721    ForwardFnPtr!(deref get_image_sparse_memory_requirements_2_khr_fn -> PFN_vkGetImageSparseMemoryRequirements2KHR);
1722});
1723#[cfg(feature = "VK_KHR_get_memory_requirements2")]
1724impl<Instance: crate::Instance> DeviceGetMemoryRequirements2Extension for DeviceObject<Instance> {
1725    #[implements]
1726    #[inline(always)]
1727    fn get_buffer_memory_requirements_2_khr_fn(&self) -> PFN_vkGetBufferMemoryRequirements2KHR {
1728        *self.ext.get_buffer_memory_requirements_2_khr.resolve()
1729    }
1730    #[implements]
1731    #[inline(always)]
1732    fn get_image_memory_requirements_2_khr_fn(&self) -> PFN_vkGetImageMemoryRequirements2KHR {
1733        *self.ext.get_image_memory_requirements_2_khr.resolve()
1734    }
1735    #[implements]
1736    #[inline(always)]
1737    fn get_image_sparse_memory_requirements_2_khr_fn(&self) -> PFN_vkGetImageSparseMemoryRequirements2KHR {
1738        *self.ext.get_image_sparse_memory_requirements_2_khr.resolve()
1739    }
1740}
1741
1742#[cfg(feature = "VK_KHR_bind_memory2")]
1743pub trait DeviceBindMemory2Extension: Device {
1744    #[implements]
1745    fn bind_buffer_memory2_khr_fn(&self) -> PFN_vkBindBufferMemory2KHR;
1746    #[implements]
1747    fn bind_image_memory2_khr_fn(&self) -> PFN_vkBindImageMemory2KHR;
1748
1749    /// Multiple Binding for Buffers
1750    #[implements]
1751    #[inline]
1752    unsafe fn bind_buffer_memory2_khr(&self, bounds: &[VkBindBufferMemoryInfoKHR]) -> crate::Result<()> {
1753        unsafe {
1754            self.bind_buffer_memory2_khr_fn().0(
1755                self.native_ptr(),
1756                bounds.len() as _,
1757                crate::ffi_helper::slice_as_ptr_empty_null(bounds),
1758            )
1759            .into_result()
1760            .map(drop)
1761        }
1762    }
1763
1764    /// Multiple Binding for Images
1765    #[implements]
1766    #[inline]
1767    unsafe fn bind_image_memory2_khr(&self, bounds: &[VkBindImageMemoryInfoKHR]) -> crate::Result<()> {
1768        unsafe {
1769            self.bind_image_memory2_khr_fn().0(
1770                self.native_ptr(),
1771                bounds.len() as _,
1772                crate::ffi_helper::slice_as_ptr_empty_null(bounds),
1773            )
1774            .into_result()
1775            .map(drop)
1776        }
1777    }
1778}
1779#[cfg(feature = "VK_KHR_bind_memory2")]
1780DerefContainerWithGuardsBracketImpl!(for DeviceBindMemory2Extension {
1781    #[implements]
1782    ForwardFnPtr!(deref bind_buffer_memory2_khr_fn -> PFN_vkBindBufferMemory2KHR);
1783    #[implements]
1784    ForwardFnPtr!(deref bind_image_memory2_khr_fn -> PFN_vkBindImageMemory2KHR);
1785});
1786#[cfg(feature = "VK_KHR_bind_memory2")]
1787impl<Instance: crate::Instance> DeviceBindMemory2Extension for DeviceObject<Instance> {
1788    #[implements]
1789    fn bind_buffer_memory2_khr_fn(&self) -> PFN_vkBindBufferMemory2KHR {
1790        *self.ext.bind_buffer_memory2_khr.resolve()
1791    }
1792    #[implements]
1793    fn bind_image_memory2_khr_fn(&self) -> PFN_vkBindImageMemory2KHR {
1794        *self.ext.bind_image_memory2_khr.resolve()
1795    }
1796}
1797
1798#[cfg(feature = "VK_KHR_external_fence_fd")]
1799pub trait DeviceExternalFenceFdExtension: Device {
1800    #[implements]
1801    fn get_fence_fd_khr_fn(&self) -> PFN_vkGetFenceFdKHR;
1802    #[implements]
1803    fn import_fence_fd_khr_fn(&self) -> PFN_vkImportFenceFdKHR;
1804
1805    /// Get a POSIX file descriptor handle for a type
1806    /// # Failures
1807    /// On failure, this command returns
1808    ///
1809    /// * `VK_ERROR_TOO_MANY_OBJECTS`
1810    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1811    #[implements]
1812    #[inline]
1813    fn get_fence_fd(&self, info: &crate::FenceFdGetInfo) -> crate::Result<std::os::unix::io::RawFd> {
1814        let mut fd = core::mem::MaybeUninit::uninit();
1815
1816        unsafe {
1817            self.get_fence_fd_khr_fn().0(self.native_ptr(), &info.0, fd.as_mut_ptr()).into_result()?;
1818
1819            Ok(fd.assume_init())
1820        }
1821    }
1822
1823    /// Import a fence from a POSIX file descriptor
1824    /// # Failures
1825    /// On failure, this command returns
1826    ///
1827    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1828    /// * `VK_ERROR_INVALID_EXTERNAL_HANDLE`
1829    #[implements]
1830    #[inline]
1831    fn import_fence_fd(&self, info: &crate::ImportFenceFdInfo) -> crate::Result<()> {
1832        unsafe {
1833            self.import_fence_fd_khr_fn().0(self.native_ptr(), &info.0)
1834                .into_result()
1835                .map(drop)
1836        }
1837    }
1838}
1839#[cfg(feature = "VK_KHR_external_fence_fd")]
1840DerefContainerBracketImpl!(for DeviceExternalFenceFdExtension {
1841    #[implements]
1842    ForwardFnPtr!(deref get_fence_fd_khr_fn -> PFN_vkGetFenceFdKHR);
1843    #[implements]
1844    ForwardFnPtr!(deref import_fence_fd_khr_fn -> PFN_vkImportFenceFdKHR);
1845});
1846#[cfg(feature = "VK_KHR_external_fence_fd")]
1847impl<Instance: crate::Instance> DeviceExternalFenceFdExtension for DeviceObject<Instance> {
1848    #[implements]
1849    #[inline(always)]
1850    fn get_fence_fd_khr_fn(&self) -> PFN_vkGetFenceFdKHR {
1851        *self.ext.get_fence_fd_khr.resolve()
1852    }
1853    #[implements]
1854    #[inline(always)]
1855    fn import_fence_fd_khr_fn(&self) -> PFN_vkImportFenceFdKHR {
1856        *self.ext.import_fence_fd_khr.resolve()
1857    }
1858}
1859
1860#[cfg(feature = "VK_KHR_external_semaphore_win32")]
1861pub trait DeviceExternalSemaphoreWin32Extension: Device {
1862    #[implements]
1863    fn import_semaphore_win32_handle_khr_fn(&self) -> PFN_vkImportSemaphoreWin32HandleKHR;
1864    #[implements]
1865    fn get_semaphore_win32_handle_khr_fn(&self) -> PFN_vkGetSemaphoreWin32HandleKHR;
1866
1867    /// Import a semaphore from a Windows HANDLE
1868    /// # Failures
1869    /// On failure, this command returns
1870    ///
1871    /// * VK_ERROR_OUT_OF_HOST_MEMORY
1872    /// * VK_ERROR_INVALID_EXTERNAL_HANDLE
1873    #[implements]
1874    #[inline]
1875    fn import_semaphore_win32_handle(&self, info: &crate::ImportSemaphoreWin32HandleInfo) -> crate::Result<()> {
1876        unsafe {
1877            self.import_semaphore_win32_handle_khr_fn().0(self.native_ptr(), &info.0)
1878                .into_result()
1879                .map(drop)
1880        }
1881    }
1882
1883    /// Get a Windows HANDLE for a semaphore
1884    ///
1885    /// A returned handle needs to be closed by caller
1886    /// # Failures
1887    /// On failure, this command returns
1888    ///
1889    /// * VK_ERROR_TOO_MANY_OBJECTS
1890    /// * VK_ERROR_OUT_OF_HOST_MEMORY
1891    #[implements]
1892    #[inline]
1893    fn get_semaphore_win32_handle(
1894        &self,
1895        info: &crate::SemaphoreGetWin32HandleInfo,
1896    ) -> crate::Result<windows::Win32::Foundation::HANDLE> {
1897        let mut handle = core::mem::MaybeUninit::uninit();
1898
1899        unsafe {
1900            self.get_semaphore_win32_handle_khr_fn().0(self.native_ptr(), &info.0, handle.as_mut_ptr())
1901                .into_result()?;
1902
1903            Ok(handle.assume_init())
1904        }
1905    }
1906}
1907#[cfg(feature = "VK_KHR_external_semaphore_win32")]
1908DerefContainerWithGuardsBracketImpl!(for DeviceExternalSemaphoreWin32Extension {
1909    #[implements]
1910    ForwardFnPtr!(deref import_semaphore_win32_handle_khr_fn -> PFN_vkImportSemaphoreWin32HandleKHR);
1911    #[implements]
1912    ForwardFnPtr!(deref get_semaphore_win32_handle_khr_fn -> PFN_vkGetSemaphoreWin32HandleKHR);
1913});
1914#[cfg(feature = "VK_KHR_external_semaphore_win32")]
1915impl<Instance: crate::Instance> DeviceExternalSemaphoreWin32Extension for DeviceObject<Instance> {
1916    #[implements]
1917    #[inline(always)]
1918    fn import_semaphore_win32_handle_khr_fn(&self) -> PFN_vkImportSemaphoreWin32HandleKHR {
1919        *self.ext.import_semaphore_win32_handle_khr.resolve()
1920    }
1921
1922    #[implements]
1923    #[inline(always)]
1924    fn get_semaphore_win32_handle_khr_fn(&self) -> PFN_vkGetSemaphoreWin32HandleKHR {
1925        *self.ext.get_semaphore_win32_handle_khr.resolve()
1926    }
1927}
1928
1929#[cfg(feature = "VK_KHR_external_memory_fd")]
1930pub trait DeviceExternalMemoryFdExtension: Device {
1931    #[implements]
1932    fn get_memory_fd_khr_fn(&self) -> PFN_vkGetMemoryFdKHR;
1933    #[implements]
1934    fn get_memory_fd_properties_khr_fn(&self) -> PFN_vkGetMemoryFdPropertiesKHR;
1935
1936    /// Get a POSIX file descriptor for a memory object
1937    /// # Failures
1938    /// On failure, this command returns
1939    ///
1940    /// * `VK_ERROR_TOO_MANY_OBJECTS`
1941    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1942    #[implements]
1943    #[inline]
1944    fn get_memory_fd(&self, info: &crate::MemoryGetFdInfo) -> crate::Result<std::os::unix::io::RawFd> {
1945        let mut fd = core::mem::MaybeUninit::uninit();
1946
1947        unsafe {
1948            self.get_memory_fd_khr_fn().0(self.native_ptr(), &info.0, fd.as_mut_ptr()).into_result()?;
1949
1950            Ok(fd.assume_init())
1951        }
1952    }
1953
1954    /// Get Properties of External Memory File Descriptors
1955    /// # Safety
1956    /// sink must be constructed correctly
1957    /// # Failures
1958    /// On failure, this command returns
1959    ///
1960    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
1961    /// * `VK_ERROR_INVALID_EXTERNAL_HANDLE`
1962    #[implements]
1963    #[inline]
1964    unsafe fn memory_fd_properties(
1965        &self,
1966        handle_type: crate::ExternalMemoryHandleTypeFd,
1967        handle: std::os::unix::io::RawFd,
1968        sink: &mut core::mem::MaybeUninit<VkMemoryFdPropertiesKHR>,
1969    ) -> crate::Result<()> {
1970        unsafe {
1971            self.get_memory_fd_properties_khr_fn().0(self.native_ptr(), handle_type as _, handle, sink.as_mut_ptr())
1972                .into_result()
1973                .map(drop)
1974        }
1975    }
1976}
1977#[cfg(feature = "VK_KHR_external_memory_fd")]
1978DerefContainerWithGuardsBracketImpl!(for DeviceExternalMemoryFdExtension {
1979    #[implements]
1980    ForwardFnPtr!(deref get_memory_fd_khr_fn -> PFN_vkGetMemoryFdKHR);
1981    #[implements]
1982    ForwardFnPtr!(deref get_memory_fd_properties_khr_fn -> PFN_vkGetMemoryFdPropertiesKHR);
1983});
1984#[cfg(feature = "VK_KHR_external_memory_fd")]
1985impl<Instance: crate::Instance> DeviceExternalMemoryFdExtension for DeviceObject<Instance> {
1986    #[implements]
1987    #[inline(always)]
1988    fn get_memory_fd_khr_fn(&self) -> PFN_vkGetMemoryFdKHR {
1989        *self.ext.get_memory_fd_khr.resolve()
1990    }
1991
1992    #[implements]
1993    #[inline(always)]
1994    fn get_memory_fd_properties_khr_fn(&self) -> PFN_vkGetMemoryFdPropertiesKHR {
1995        *self.ext.get_memory_fd_properties_khr.resolve()
1996    }
1997}
1998
1999#[cfg(feature = "VK_EXT_external_memory_host")]
2000pub trait DeviceExternalMemoryHostExtension: Device {
2001    #[implements]
2002    fn get_memory_host_pointer_properties_ext_fn(&self) -> PFN_vkGetMemoryHostPointerPropertiesEXT;
2003
2004    /// Get Properties of external memory host pointer
2005    /// # Safety
2006    /// sink must be constructed correctly
2007    /// # Failures
2008    /// On failure, this command returns
2009    ///
2010    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2011    /// * `VK_ERROR_INVALID_EXTERNAL_HANDLE`
2012    #[implements]
2013    #[inline]
2014    unsafe fn memory_host_pointer_properties(
2015        &self,
2016        handle_type: crate::ExternalMemoryHandleTypeHost,
2017        ptr: *mut core::ffi::c_void,
2018        sink: &mut core::mem::MaybeUninit<VkMemoryHostPointerPropertiesEXT>,
2019    ) -> crate::Result<()> {
2020        unsafe {
2021            self.get_memory_host_pointer_properties_ext_fn().0(
2022                self.native_ptr(),
2023                handle_type as _,
2024                ptr,
2025                sink.as_mut_ptr(),
2026            )
2027            .into_result()
2028            .map(drop)
2029        }
2030    }
2031}
2032#[cfg(feature = "VK_EXT_external_memory_host")]
2033DerefContainerWithGuardsBracketImpl!(for DeviceExternalMemoryHostExtension {
2034    #[implements]
2035    ForwardFnPtr!(deref get_memory_host_pointer_properties_ext_fn -> PFN_vkGetMemoryHostPointerPropertiesEXT);
2036});
2037#[cfg(feature = "VK_EXT_external_memory_host")]
2038impl<Instance: crate::Instance> DeviceExternalMemoryHostExtension for DeviceObject<Instance> {
2039    #[implements]
2040    #[inline(always)]
2041    fn get_memory_host_pointer_properties_ext_fn(&self) -> PFN_vkGetMemoryHostPointerPropertiesEXT {
2042        *self.ext.get_memory_host_pointer_properties_ext.resolve()
2043    }
2044}
2045
2046#[cfg(feature = "VK_KHR_external_memory_win32")]
2047pub trait DeviceExternalMemoryWin32Extension: Device {
2048    #[implements]
2049    fn get_memory_win32_handle_khr_fn(&self) -> PFN_vkGetMemoryWin32HandleKHR;
2050    #[implements]
2051    fn get_memory_win32_handle_properties_khr_fn(&self) -> PFN_vkGetMemoryWin32HandlePropertiesKHR;
2052
2053    /// Get Properties of External Memory Win32 Handles
2054    /// # Safety
2055    /// sink must be constructed correctly
2056    /// # Failures
2057    /// On failure, this command returns
2058    ///
2059    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2060    /// * `VK_ERROR_INVALID_EXTERNAL_HANDLE`
2061    #[implements]
2062    #[inline]
2063    unsafe fn memory_win32_handle_properties(
2064        &self,
2065        handle_type: crate::ExternalMemoryHandleTypeWin32,
2066        handle: windows::Win32::Foundation::HANDLE,
2067        sink: &mut core::mem::MaybeUninit<VkMemoryWin32HandlePropertiesKHR>,
2068    ) -> crate::Result<()> {
2069        unsafe {
2070            self.get_memory_win32_handle_properties_khr_fn().0(
2071                self.native_ptr(),
2072                handle_type as _,
2073                handle,
2074                sink.as_mut_ptr(),
2075            )
2076            .into_result()
2077            .map(drop)
2078        }
2079    }
2080
2081    /// Get a Windows HANDLE for a memory object
2082    ///
2083    /// A returned handle needs to be closed by caller
2084    /// # Failures
2085    /// On failure, this command returns
2086    ///
2087    /// * `VK_ERROR_TOO_MANY_OBJECTS`
2088    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2089    #[implements]
2090    #[inline]
2091    fn get_memory_win32_handle(
2092        &self,
2093        info: &crate::MemoryGetWin32HandleInfo,
2094    ) -> crate::Result<windows::Win32::Foundation::HANDLE> {
2095        let mut handle = core::mem::MaybeUninit::uninit();
2096
2097        unsafe {
2098            self.get_memory_win32_handle_khr_fn().0(self.native_ptr(), &info.0, handle.as_mut_ptr()).into_result()?;
2099
2100            Ok(handle.assume_init())
2101        }
2102    }
2103}
2104#[cfg(feature = "VK_KHR_external_memory_win32")]
2105DerefContainerWithGuardsBracketImpl!(for DeviceExternalMemoryWin32Extension {
2106    #[implements]
2107    ForwardFnPtr!(deref get_memory_win32_handle_khr_fn -> PFN_vkGetMemoryWin32HandleKHR);
2108    #[implements]
2109    ForwardFnPtr!(deref get_memory_win32_handle_properties_khr_fn -> PFN_vkGetMemoryWin32HandlePropertiesKHR);
2110});
2111#[cfg(feature = "VK_KHR_external_memory_win32")]
2112impl<Instance: crate::Instance> DeviceExternalMemoryWin32Extension for DeviceObject<Instance> {
2113    #[implements]
2114    #[inline(always)]
2115    fn get_memory_win32_handle_khr_fn(&self) -> PFN_vkGetMemoryWin32HandleKHR {
2116        *self.ext.get_memory_win32_handle_khr.resolve()
2117    }
2118
2119    #[implements]
2120    #[inline(always)]
2121    fn get_memory_win32_handle_properties_khr_fn(&self) -> PFN_vkGetMemoryWin32HandlePropertiesKHR {
2122        *self.ext.get_memory_win32_handle_properties_khr.resolve()
2123    }
2124}
2125
2126#[cfg(feature = "VK_EXT_full_screen_exclusive")]
2127pub trait DeviceFullScreenExclusiveExtension: Device {
2128    #[implements]
2129    fn acquire_full_screen_exclusive_mode_ext_fn(&self) -> PFN_vkAcquireFullScreenExclusiveModeEXT;
2130    #[implements]
2131    fn release_full_screen_exclusive_mode_ext_fn(&self) -> PFN_vkReleaseFullScreenExclusiveModeEXT;
2132}
2133#[cfg(feature = "VK_EXT_full_screen_exclusive")]
2134DerefContainerWithGuardsBracketImpl!(for DeviceFullScreenExclusiveExtension {
2135    #[implements]
2136    ForwardFnPtr!(deref acquire_full_screen_exclusive_mode_ext_fn -> PFN_vkAcquireFullScreenExclusiveModeEXT);
2137    #[implements]
2138    ForwardFnPtr!(deref release_full_screen_exclusive_mode_ext_fn -> PFN_vkReleaseFullScreenExclusiveModeEXT);
2139});
2140#[cfg(feature = "VK_EXT_full_screen_exclusive")]
2141impl<Instance: crate::Instance> DeviceFullScreenExclusiveExtension for DeviceObject<Instance> {
2142    #[implements]
2143    #[inline(always)]
2144    fn acquire_full_screen_exclusive_mode_ext_fn(&self) -> PFN_vkAcquireFullScreenExclusiveModeEXT {
2145        *self.ext.acquire_full_screen_exclusive_mode_ext.resolve()
2146    }
2147
2148    #[implements]
2149    #[inline(always)]
2150    fn release_full_screen_exclusive_mode_ext_fn(&self) -> PFN_vkReleaseFullScreenExclusiveModeEXT {
2151        *self.ext.release_full_screen_exclusive_mode_ext.resolve()
2152    }
2153}
2154
2155#[cfg(feature = "VK_KHR_create_renderpass2")]
2156pub trait DeviceCreateRenderPass2Extension: Device {
2157    #[implements]
2158    fn create_render_pass_2_khr_fn(&self) -> PFN_vkCreateRenderPass2KHR;
2159    #[implements]
2160    fn cmd_begin_render_pass_2_khr_fn(&self) -> PFN_vkCmdBeginRenderPass2KHR;
2161    #[implements]
2162    fn cmd_end_render_pass_2_khr_fn(&self) -> PFN_vkCmdEndRenderPass2KHR;
2163    #[implements]
2164    fn cmd_next_subpass_2_khr_fn(&self) -> PFN_vkCmdNextSubpass2KHR;
2165
2166    /// Create a new render pass object
2167    /// # Failures
2168    /// On failure, this command returns
2169    ///
2170    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2171    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2172    #[implements]
2173    #[inline]
2174    fn new_render_pass2_khr(
2175        &self,
2176        info: &RenderPassCreateInfo2,
2177        allocation_callbacks: Option<&VkAllocationCallbacks>,
2178    ) -> crate::Result<VkRenderPass> {
2179        let mut h = core::mem::MaybeUninit::uninit();
2180
2181        unsafe {
2182            (self.create_render_pass_2_khr_fn().0)(
2183                self.native_ptr(),
2184                info as *const _ as _,
2185                crate::ffi_helper::opt_pointer(allocation_callbacks),
2186                h.as_mut_ptr(),
2187            )
2188            .into_result()?;
2189        }
2190
2191        Ok(unsafe { h.assume_init() })
2192    }
2193}
2194#[cfg(feature = "VK_KHR_create_renderpass2")]
2195DerefContainerWithGuardsBracketImpl!(for DeviceCreateRenderPass2Extension {
2196    #[implements]
2197    ForwardFnPtr!(deref create_render_pass_2_khr_fn -> PFN_vkCreateRenderPass2KHR);
2198    #[implements]
2199    ForwardFnPtr!(deref cmd_begin_render_pass_2_khr_fn -> PFN_vkCmdBeginRenderPass2KHR);
2200    #[implements]
2201    ForwardFnPtr!(deref cmd_end_render_pass_2_khr_fn -> PFN_vkCmdEndRenderPass2KHR);
2202    #[implements]
2203    ForwardFnPtr!(deref cmd_next_subpass_2_khr_fn -> PFN_vkCmdNextSubpass2KHR);
2204});
2205#[cfg(feature = "VK_KHR_create_renderpass2")]
2206impl<Instance: crate::Instance> DeviceCreateRenderPass2Extension for DeviceObject<Instance> {
2207    #[implements]
2208    #[inline(always)]
2209    fn create_render_pass_2_khr_fn(&self) -> PFN_vkCreateRenderPass2KHR {
2210        *self.ext.create_render_pass_2_khr.resolve()
2211    }
2212    #[implements]
2213    #[inline(always)]
2214    fn cmd_begin_render_pass_2_khr_fn(&self) -> PFN_vkCmdBeginRenderPass2KHR {
2215        *self.ext.cmd_begin_render_pass_2_khr.resolve()
2216    }
2217    #[implements]
2218    #[inline(always)]
2219    fn cmd_end_render_pass_2_khr_fn(&self) -> PFN_vkCmdEndRenderPass2KHR {
2220        *self.ext.cmd_end_render_pass_2_khr.resolve()
2221    }
2222    #[implements]
2223    #[inline(always)]
2224    fn cmd_next_subpass_2_khr_fn(&self) -> PFN_vkCmdNextSubpass2KHR {
2225        *self.ext.cmd_next_subpass_2_khr.resolve()
2226    }
2227}
2228
2229#[cfg(feature = "VK_KHR_synchronization2")]
2230pub trait DeviceSynchronization2Extension: Device {
2231    #[implements]
2232    fn queue_submit2_khr_fn(&self) -> PFN_vkQueueSubmit2KHR;
2233    #[implements]
2234    fn cmd_pipeline_barrier_2_khr_fn(&self) -> PFN_vkCmdPipelineBarrier2KHR;
2235}
2236#[cfg(feature = "VK_KHR_synchronization2")]
2237DerefContainerWithGuardsBracketImpl!(for DeviceSynchronization2Extension {
2238    #[implements]
2239    ForwardFnPtr!(deref queue_submit2_khr_fn -> PFN_vkQueueSubmit2KHR);
2240    #[implements]
2241    ForwardFnPtr!(deref cmd_pipeline_barrier_2_khr_fn -> PFN_vkCmdPipelineBarrier2KHR);
2242});
2243#[cfg(feature = "VK_KHR_synchronization2")]
2244impl<Instance: crate::Instance> DeviceSynchronization2Extension for DeviceObject<Instance> {
2245    #[implements]
2246    #[inline(always)]
2247    fn queue_submit2_khr_fn(&self) -> PFN_vkQueueSubmit2KHR {
2248        *self.ext.queue_submit2_khr.resolve()
2249    }
2250    #[implements]
2251    #[inline(always)]
2252    fn cmd_pipeline_barrier_2_khr_fn(&self) -> PFN_vkCmdPipelineBarrier2KHR {
2253        *self.ext.cmd_pipeline_barrier_2_khr.resolve()
2254    }
2255}
2256
2257#[cfg(feature = "VK_EXT_image_drm_format_modifier")]
2258pub trait DeviceImageDrmFormatModifierExtension: Device {
2259    #[implements]
2260    fn get_image_drm_format_modifier_properties_ext_fn(&self) -> PFN_vkGetImageDrmFormatModifierPropertiesEXT;
2261}
2262#[cfg(feature = "VK_EXT_image_drm_format_modifier")]
2263DerefContainerWithGuardsBracketImpl!(for DeviceImageDrmFormatModifierExtension {
2264    #[implements]
2265    ForwardFnPtr!(deref get_image_drm_format_modifier_properties_ext_fn -> PFN_vkGetImageDrmFormatModifierPropertiesEXT);
2266});
2267#[cfg(feature = "VK_EXT_image_drm_format_modifier")]
2268impl<Instance: crate::Instance> DeviceImageDrmFormatModifierExtension for DeviceObject<Instance> {
2269    #[implements]
2270    #[inline(always)]
2271    fn get_image_drm_format_modifier_properties_ext_fn(&self) -> PFN_vkGetImageDrmFormatModifierPropertiesEXT {
2272        *self.ext.get_image_drm_format_modifier_properties_ext.resolve()
2273    }
2274}
2275
2276#[cfg(feature = "VK_KHR_push_descriptor")]
2277pub trait DevicePushDescriptorExtension: Device {
2278    #[implements]
2279    fn cmd_push_descriptor_set_khr_fn(&self) -> PFN_vkCmdPushDescriptorSetKHR;
2280}
2281#[cfg(feature = "VK_KHR_push_descriptor")]
2282DerefContainerWithGuardsBracketImpl!(for DevicePushDescriptorExtension {
2283    #[implements("VK_KHR_push_descriptor")]
2284    ForwardFnPtr!(deref cmd_push_descriptor_set_khr_fn -> PFN_vkCmdPushDescriptorSetKHR);
2285});
2286#[cfg(feature = "VK_KHR_push_descriptor")]
2287impl<Instance: crate::Instance> DevicePushDescriptorExtension for DeviceObject<Instance> {
2288    #[implements]
2289    #[inline(always)]
2290    fn cmd_push_descriptor_set_khr_fn(&self) -> PFN_vkCmdPushDescriptorSetKHR {
2291        *self.ext.cmd_push_descriptor_set_khr.resolve()
2292    }
2293}
2294
2295#[cfg(feature = "VK_EXT_sample_locations")]
2296pub trait DeviceSampleLocationsExtension: Device {
2297    #[implements]
2298    fn cmd_set_sample_locations_ext_fn(&self) -> PFN_vkCmdSetSampleLocationsEXT;
2299}
2300#[cfg(feature = "VK_EXT_sample_locations")]
2301DerefContainerWithGuardsBracketImpl!(for DeviceSampleLocationsExtension {
2302    #[implements]
2303    ForwardFnPtr!(deref cmd_set_sample_locations_ext_fn -> PFN_vkCmdSetSampleLocationsEXT);
2304});
2305#[cfg(feature = "VK_EXT_sample_locations")]
2306impl<Instance: crate::Instance> DeviceSampleLocationsExtension for DeviceObject<Instance> {
2307    #[implements]
2308    #[inline(always)]
2309    fn cmd_set_sample_locations_ext_fn(&self) -> PFN_vkCmdSetSampleLocationsEXT {
2310        *self.ext.cmd_set_sample_locations_ext.resolve()
2311    }
2312}
2313
2314#[cfg(feature = "VK_KHR_timeline_semaphore")]
2315pub trait DeviceTimelineSemaphoreExtension: Device {
2316    #[implements]
2317    fn get_semaphore_counter_value_ext_fn(&self) -> PFN_vkGetSemaphoreCounterValueKHR;
2318    #[implements]
2319    fn signal_semaphore_ext_fn(&self) -> PFN_vkSignalSemaphoreKHR;
2320    #[implements]
2321    fn wait_semaphores_ext_fn(&self) -> PFN_vkWaitSemaphoresKHR;
2322
2323    /// Query the current state of a timeline semaphore
2324    /// # Failure
2325    ///
2326    /// * [`VK_ERROR_DEVICE_LOST`]
2327    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2328    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2329    /// * [`VK_ERROR_UNKNOWN`]
2330    /// * [`VK_ERROR_VALIDATION_FAILED`]
2331    #[implements]
2332    fn get_semaphore_counter_value_khr(
2333        &self,
2334        semaphore: &(impl VkHandle<Handle = VkSemaphore> + ?Sized),
2335    ) -> crate::Result<u64> {
2336        let mut sink = core::mem::MaybeUninit::uninit();
2337
2338        unsafe {
2339            (self.get_semaphore_counter_value_ext_fn().0)(self.native_ptr(), semaphore.native_ptr(), sink.as_mut_ptr())
2340                .into_result()?;
2341        }
2342
2343        Ok(unsafe { sink.assume_init() })
2344    }
2345
2346    /// Signal a timeline semaphore on the host
2347    /// # Failure
2348    ///
2349    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2350    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2351    /// * [`VK_ERROR_UNKNOWN`]
2352    /// * [`VK_ERROR_VALIDATION_FAILED`]
2353    #[implements]
2354    fn signal_semaphore_khr(&self, info: &SemaphoreSignalInfo) -> crate::Result<()> {
2355        unsafe {
2356            (self.signal_semaphore_ext_fn().0)(self.native_ptr(), info as *const _ as _)
2357                .into_result()
2358                .map(drop)
2359        }
2360    }
2361
2362    /// Wait for timeline semaphores on the host
2363    ///
2364    /// Returns `false` if timed out
2365    /// # Failure
2366    ///
2367    /// * [`VK_ERROR_DEVICE_LOST`]
2368    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2369    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2370    /// * [`VK_ERROR_UNKNOWN`]
2371    /// * [`VK_ERROR_VALIDATION_FAILED`]
2372    #[implements]
2373    fn wait_semaphores_khr(&self, info: &SemaphoreWaitInfo, timeout: u64) -> crate::Result<bool> {
2374        match unsafe { (self.wait_semaphores_ext_fn().0)(self.native_ptr(), info as *const _ as _, timeout) } {
2375            r if r == VK_SUCCESS => Ok(true),
2376            r if r == VK_TIMEOUT => Ok(false),
2377            r => Err(r),
2378        }
2379    }
2380}
2381#[cfg(feature = "VK_KHR_timeline_semaphore")]
2382DerefContainerWithGuardsBracketImpl!(for DeviceTimelineSemaphoreExtension {
2383    #[implements]
2384    ForwardFnPtr!(deref get_semaphore_counter_value_ext_fn -> PFN_vkGetSemaphoreCounterValueKHR);
2385    #[implements]
2386    ForwardFnPtr!(deref signal_semaphore_ext_fn -> PFN_vkSignalSemaphoreKHR);
2387    #[implements]
2388    ForwardFnPtr!(deref wait_semaphores_ext_fn -> PFN_vkWaitSemaphoresKHR);
2389});
2390#[cfg(feature = "VK_KHR_timeline_semaphore")]
2391impl<Instance: crate::Instance> DeviceTimelineSemaphoreExtension for DeviceObject<Instance> {
2392    #[implements]
2393    #[inline(always)]
2394    fn get_semaphore_counter_value_ext_fn(&self) -> PFN_vkGetSemaphoreCounterValueKHR {
2395        *self.ext.get_semaphore_counter_value_ext.resolve()
2396    }
2397
2398    #[implements]
2399    #[inline(always)]
2400    fn signal_semaphore_ext_fn(&self) -> PFN_vkSignalSemaphoreKHR {
2401        *self.ext.signal_semaphore_ext.resolve()
2402    }
2403
2404    #[implements]
2405    #[inline(always)]
2406    fn wait_semaphores_ext_fn(&self) -> PFN_vkWaitSemaphoresKHR {
2407        *self.ext.wait_semaphores_ext.resolve()
2408    }
2409}
2410
2411/// Child of a device object(raw handle)
2412pub trait DeviceChildHandle {
2413    /// Retrieve a reference to a device handle that creates this objecs
2414    fn device_handle(&self) -> VkDevice;
2415}
2416DerefContainerBracketImpl!(for DeviceChildHandle {
2417    #[inline(always)]
2418    fn device_handle(&self) -> VkDevice { T::device_handle(self) }
2419});
2420GuardsImpl!(for DeviceChildHandle {
2421    #[inline(always)]
2422    fn device_handle(&self) -> VkDevice { T::device_handle(&self) }
2423});
2424
2425/// Child of a device object
2426pub trait DeviceChild: DeviceChildHandle {
2427    /// A concrete type of the parent device object.
2428    type ConcreteDevice: Device;
2429
2430    /// Retrieve a reference to a device object that creates this object
2431    fn device(&self) -> &Self::ConcreteDevice;
2432}
2433DerefContainerBracketImpl!(for DeviceChild {
2434    type ConcreteDevice = T::ConcreteDevice;
2435
2436    fn device(&self) -> &Self::ConcreteDevice { T::device(self) }
2437});
2438GuardsImpl!(for DeviceChild {
2439    type ConcreteDevice = T::ConcreteDevice;
2440
2441    fn device(&self) -> &Self::ConcreteDevice { T::device(&self) }
2442});
2443
2444pub trait DeviceChildTransferrable: DeviceChild {
2445    fn transfer_device(self) -> Self::ConcreteDevice;
2446}
2447impl<T> DeviceChildTransferrable for &'_ T
2448where
2449    T: DeviceChild + ?Sized,
2450    T::ConcreteDevice: Clone,
2451{
2452    fn transfer_device(self) -> Self::ConcreteDevice {
2453        self.device().clone()
2454    }
2455}
2456
2457pub trait Queue: VkHandle<Handle = VkQueue> + DeviceChild {}
2458DerefContainerBracketImpl!(for Queue {});
2459GuardsImpl!(for Queue {});
2460
2461pub trait QueueMut: Queue + VkHandleMut {
2462    /// Wait for a object to become idle
2463    #[implements]
2464    #[inline(always)]
2465    fn wait(&mut self) -> crate::Result<()> {
2466        unsafe {
2467            crate::vkfn::queue_wait_idle(self.native_ptr_mut())
2468                .into_result()
2469                .map(drop)
2470        }
2471    }
2472
2473    /// Bind device memory to a sparse resource object
2474    /// # Failure
2475    /// On failure, this command returns
2476    ///
2477    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2478    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
2479    /// * `VK_ERROR_DEVICE_LOST`
2480    #[implements("alloc")]
2481    fn bind_sparse(
2482        &mut self,
2483        batches: &[impl SparseBindingOpBatch],
2484        fence: Option<VkHandleRefMut<VkFence>>,
2485    ) -> crate::Result<()> {
2486        let batches: Vec<_> = crate::alloc::collect_vec(batches.iter().map(SparseBindingOpBatch::make_info_struct));
2487
2488        unsafe { self.bind_sparse_raw(&batches, fence) }
2489    }
2490
2491    /// Bind device memory to a sparse resource object
2492    /// # Failure
2493    /// On failure, this command returns
2494    ///
2495    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2496    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
2497    /// * `VK_ERROR_DEVICE_LOST`
2498    ///
2499    /// # Safety
2500    /// no guarantees will be provided (simply calls under api)
2501    #[implements]
2502    unsafe fn bind_sparse_raw(
2503        &mut self,
2504        batches: &[VkBindSparseInfo],
2505        fence: Option<VkHandleRefMut<VkFence>>,
2506    ) -> crate::Result<()> {
2507        unsafe {
2508            crate::vkfn::queue_bind_sparse(
2509                self.native_ptr_mut(),
2510                batches.len() as _,
2511                crate::ffi_helper::slice_as_ptr_empty_null(batches),
2512                fence.map_or(VkFence::NULL, |x| x.0),
2513            )
2514            .into_result()
2515            .map(drop)
2516        }
2517    }
2518
2519    /// Submits a sequence of semaphores or command buffers to a queue
2520    /// # Failure
2521    /// On failure, this command returns
2522    ///
2523    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
2524    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
2525    /// * `VK_ERROR_DEVICE_LOST`
2526    #[implements("alloc")]
2527    #[allow(deprecated)]
2528    fn submit(
2529        &mut self,
2530        batches: &[impl SubmissionBatch],
2531        fence: Option<VkHandleRefMut<VkFence>>,
2532    ) -> crate::Result<()> {
2533        let batch_resources: Vec<_> = crate::alloc::collect_vec(batches.iter().map(|b| {
2534            let mut resources = TemporalSubmissionBatchResources::new();
2535            b.collect_resources(&mut resources);
2536            resources
2537        }));
2538        let batches: Vec<_> = crate::alloc::collect_vec(
2539            batch_resources
2540                .iter()
2541                .map(TemporalSubmissionBatchResources::make_info_struct),
2542        );
2543
2544        unsafe { self.submit_raw(&batches, fence) }
2545    }
2546
2547    /// Submits a sequence of semaphores or command buffers to a queue
2548    /// # Failure
2549    /// On failure, this command returns
2550    ///
2551    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2552    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2553    /// * [`VK_ERROR_DEVICE_LOST`]
2554    ///
2555    /// # Safety
2556    /// no guarantees will be provided (simply calls under api)
2557    #[implements]
2558    unsafe fn submit_raw(
2559        &mut self,
2560        batches: &[SubmitInfo],
2561        fence: Option<VkHandleRefMut<VkFence>>,
2562    ) -> crate::Result<()> {
2563        unsafe {
2564            crate::vkfn::queue_submit(
2565                self.native_ptr_mut(),
2566                batches.len() as _,
2567                crate::ffi_helper::slice_as_ptr_empty_null(batches) as _,
2568                fence.map_or(VkFence::NULL, |x| x.0),
2569            )
2570            .into_result()
2571            .map(drop)
2572        }
2573    }
2574
2575    /// Submits command buffers to a queue
2576    /// # Failure
2577    /// On failure, this command returns
2578    ///
2579    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2580    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2581    /// * [`VK_ERROR_DEVICE_LOST`]
2582    #[implements("VK_KHR_synchronization2")]
2583    fn submit2_khr(
2584        &mut self,
2585        device: &(impl DeviceSynchronization2Extension + ?Sized),
2586        batches: &[SubmitInfo2],
2587        fence: Option<VkHandleRefMut<VkFence>>,
2588    ) -> crate::Result<()> {
2589        unsafe {
2590            (device.queue_submit2_khr_fn().0)(
2591                self.native_ptr_mut(),
2592                batches.len() as _,
2593                slice_as_ptr_empty_null(batches) as _,
2594                fence.map_or(VkFence::NULL, |x| x.0),
2595            )
2596            .into_result()
2597            .map(drop)
2598        }
2599    }
2600
2601    /// Submits command buffers to a queue
2602    /// # Failure
2603    /// On failure, this command returns
2604    ///
2605    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2606    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2607    /// * [`VK_ERROR_DEVICE_LOST`]
2608    #[implements("Allow1_3APIs")]
2609    fn submit2(&mut self, batches: &[SubmitInfo2], fence: Option<VkHandleRefMut<VkFence>>) -> crate::Result<()> {
2610        unsafe {
2611            crate::vkfn::queue_submit2(
2612                self.native_ptr_mut(),
2613                batches.len() as _,
2614                slice_as_ptr_empty_null(batches) as _,
2615                fence.map_or(VkFence::NULL, |x| x.0),
2616            )
2617            .into_result()
2618            .map(drop)
2619        }
2620    }
2621
2622    /// Queue images for presentation
2623    /// # Failures
2624    /// On failure, this command returns
2625    ///
2626    /// * [`VK_ERROR_OUT_OF_HOST_MEMORY`]
2627    /// * [`VK_ERROR_OUT_OF_DEVICE_MEMORY`]
2628    /// * [`VK_ERROR_DEVICE_LOST`]
2629    /// * [`VK_ERROR_OUT_OF_DATE_KHR`]
2630    /// * [`VK_ERROR_SURFACE_LOST_KHR`]
2631    #[implements("VK_KHR_swapchain")]
2632    fn present<'r>(&mut self, info: &PresentInfo<'r>) -> crate::Result<()> {
2633        unsafe {
2634            crate::vkfn::queue_present_khr(self.native_ptr_mut(), info as *const _ as _)
2635                .into_result()
2636                .map(drop)
2637        }
2638    }
2639}
2640DerefContainerBracketImpl!(for mut QueueMut {});
2641GuardsImpl!(for mut QueueMut {});
2642
2643#[cfg(feature = "VK_KHR_swapchain")]
2644#[repr(transparent)]
2645pub struct PresentInfo<'r>(
2646    VkPresentInfoKHR,
2647    core::marker::PhantomData<(&'r [VkSwapchainKHR], &'r [VkSemaphore], &'r [u32], &'r mut [VkResult])>,
2648);
2649#[cfg(feature = "VK_KHR_swapchain")]
2650impl<'r> PresentInfo<'r> {
2651    #[inline(always)]
2652    pub fn new(
2653        wait_semaphores: &'r [VkHandleRef<VkSemaphore>],
2654        swapchains: &'r [VkHandleRef<VkSwapchainKHR>],
2655        image_indices: &'r [u32],
2656        results: &'r mut [VkResult],
2657    ) -> Self {
2658        assert_eq!(swapchains.len(), image_indices.len());
2659        assert_eq!(swapchains.len(), results.len());
2660
2661        Self(
2662            VkPresentInfoKHR {
2663                sType: VkPresentInfoKHR::TYPE,
2664                pNext: core::ptr::null(),
2665                waitSemaphoreCount: wait_semaphores.len() as _,
2666                pWaitSemaphores: crate::ffi_helper::slice_as_ptr_empty_null(wait_semaphores) as _,
2667                swapchainCount: swapchains.len() as _,
2668                pSwapchains: crate::ffi_helper::slice_as_ptr_empty_null(swapchains) as _,
2669                pImageIndices: crate::ffi_helper::slice_as_ptr_empty_null(image_indices),
2670                pResults: crate::ffi_helper::slice_as_mut_ptr_empty_null(results),
2671            },
2672            core::marker::PhantomData,
2673        )
2674    }
2675
2676    pub const unsafe fn from_raw(raw: VkPresentInfoKHR) -> Self {
2677        Self(raw, core::marker::PhantomData)
2678    }
2679
2680    pub const fn into_raw(self) -> VkPresentInfoKHR {
2681        self.0
2682    }
2683
2684    #[implements]
2685    pub fn submit(&self, queue: &mut (impl QueueMut + ?Sized)) -> crate::Result<()> {
2686        queue.present(self)
2687    }
2688}
2689
2690#[cfg(feature = "VK_KHR_synchronization2")]
2691#[repr(transparent)]
2692#[derive(Debug, Clone)]
2693pub struct CommandBufferSubmitInfo<'r>(
2694    VkCommandBufferSubmitInfoKHR,
2695    core::marker::PhantomData<&'r dyn VkHandle<Handle = VkCommandBuffer>>,
2696);
2697#[cfg(feature = "VK_KHR_synchronization2")]
2698impl<'r> CommandBufferSubmitInfo<'r> {
2699    #[inline(always)]
2700    pub fn new(command_buffer: &'r (impl VkHandle<Handle = VkCommandBuffer> + ?Sized)) -> Self {
2701        Self(
2702            VkCommandBufferSubmitInfoKHR {
2703                sType: VkCommandBufferSubmitInfoKHR::TYPE,
2704                pNext: core::ptr::null(),
2705                commandBuffer: command_buffer.native_ptr(),
2706                deviceMask: 0,
2707            },
2708            core::marker::PhantomData,
2709        )
2710    }
2711
2712    pub const unsafe fn from_raw(raw: VkCommandBufferSubmitInfoKHR) -> Self {
2713        Self(raw, core::marker::PhantomData)
2714    }
2715
2716    pub const fn into_raw(self) -> VkCommandBufferSubmitInfoKHR {
2717        self.0
2718    }
2719
2720    pub const fn on_device(mut self, mask: u32) -> Self {
2721        self.0.deviceMask = mask;
2722        self
2723    }
2724}
2725
2726#[cfg(feature = "VK_KHR_synchronization2")]
2727#[repr(transparent)]
2728#[derive(Debug, Clone)]
2729pub struct SubmitInfo2<'b, 'r>(
2730    VkSubmitInfo2KHR,
2731    core::marker::PhantomData<(
2732        &'b [SemaphoreSubmitInfo<'r>],
2733        &'b [SemaphoreSubmitInfo<'r>],
2734        &'b [CommandBufferSubmitInfo<'r>],
2735    )>,
2736);
2737#[cfg(feature = "VK_KHR_synchronization2")]
2738impl<'b, 'r> SubmitInfo2<'b, 'r> {
2739    pub const fn new(
2740        wait_semaphores: &'b [SemaphoreSubmitInfo<'r>],
2741        command_buffers: &'b [CommandBufferSubmitInfo<'r>],
2742        signal_semaphores: &'b [SemaphoreSubmitInfo<'r>],
2743    ) -> Self {
2744        Self(
2745            VkSubmitInfo2KHR {
2746                sType: VkSubmitInfo2KHR::TYPE,
2747                pNext: core::ptr::null(),
2748                flags: 0,
2749                waitSemaphoreInfoCount: wait_semaphores.len() as _,
2750                pWaitSemaphoreInfos: crate::ffi_helper::slice_as_ptr_empty_null(wait_semaphores) as _,
2751                commandBufferInfoCount: command_buffers.len() as _,
2752                pCommandBufferInfos: crate::ffi_helper::slice_as_ptr_empty_null(command_buffers) as _,
2753                signalSemaphoreInfoCount: signal_semaphores.len() as _,
2754                pSignalSemaphoreInfos: crate::ffi_helper::slice_as_ptr_empty_null(signal_semaphores) as _,
2755            },
2756            core::marker::PhantomData,
2757        )
2758    }
2759
2760    pub const unsafe fn from_raw(raw: VkSubmitInfo2KHR) -> Self {
2761        Self(raw, core::marker::PhantomData)
2762    }
2763    pub const fn into_raw(self) -> VkSubmitInfo2KHR {
2764        self.0
2765    }
2766
2767    pub const fn protected(mut self) -> Self {
2768        self.0.flags |= VK_SUBMIT_PROTECTED_BIT_KHR;
2769        self
2770    }
2771}