Skip to main content

bedrock/
device.rs

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