Skip to main content

jay_ash/
instance.rs

1#[cfg(doc)]
2use super::Entry;
3use crate::RawPtr;
4use crate::device::Device;
5use crate::prelude::*;
6use crate::vk;
7use alloc::vec::Vec;
8use core::ffi;
9use core::mem;
10use core::ptr;
11
12/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkInstance.html>
13#[derive(Clone)]
14pub struct Instance {
15    pub(crate) handle: vk::Instance,
16
17    pub(crate) instance_fn_1_0: crate::InstanceFnV1_0,
18    pub(crate) instance_fn_1_1: crate::InstanceFnV1_1,
19    pub(crate) instance_fn_1_3: crate::InstanceFnV1_3,
20}
21
22impl Instance {
23    pub unsafe fn load(static_fn: &crate::StaticFn, instance: vk::Instance) -> Self {
24        unsafe {
25            Self::load_with(
26                |name| mem::transmute((static_fn.get_instance_proc_addr)(instance, name.as_ptr())),
27                instance,
28            )
29        }
30    }
31
32    pub unsafe fn load_with(
33        mut load_fn: impl FnMut(&ffi::CStr) -> *const ffi::c_void,
34        instance: vk::Instance,
35    ) -> Self {
36        Self::from_parts_1_3(
37            instance,
38            crate::InstanceFnV1_0::load(&mut load_fn),
39            crate::InstanceFnV1_1::load(&mut load_fn),
40            crate::InstanceFnV1_3::load(&mut load_fn),
41        )
42    }
43
44    #[inline]
45    pub fn from_parts_1_3(
46        handle: vk::Instance,
47        instance_fn_1_0: crate::InstanceFnV1_0,
48        instance_fn_1_1: crate::InstanceFnV1_1,
49        instance_fn_1_3: crate::InstanceFnV1_3,
50    ) -> Self {
51        Self {
52            handle,
53
54            instance_fn_1_0,
55            instance_fn_1_1,
56            instance_fn_1_3,
57        }
58    }
59
60    #[inline]
61    pub fn handle(&self) -> vk::Instance {
62        self.handle
63    }
64}
65
66/// Vulkan core 1.3
67impl Instance {
68    #[inline]
69    pub fn fp_v1_3(&self) -> &crate::InstanceFnV1_3 {
70        &self.instance_fn_1_3
71    }
72
73    /// Retrieve the number of elements to pass to [`get_physical_device_tool_properties()`][Self::get_physical_device_tool_properties()]
74    #[inline]
75    pub unsafe fn get_physical_device_tool_properties_len(
76        &self,
77        physical_device: vk::PhysicalDevice,
78    ) -> VkResult<usize> {
79        unsafe {
80            let mut count = mem::MaybeUninit::uninit();
81            (self.instance_fn_1_3.get_physical_device_tool_properties)(
82                physical_device,
83                count.as_mut_ptr(),
84                ptr::null_mut(),
85            )
86            .assume_init_on_success(count)
87            .map(|c| c as usize)
88        }
89    }
90
91    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceToolProperties.html>
92    ///
93    /// Call [`get_physical_device_tool_properties_len()`][Self::get_physical_device_tool_properties_len()] to query the number of elements to pass to `out`.
94    /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer.
95    #[inline]
96    pub unsafe fn get_physical_device_tool_properties(
97        &self,
98        physical_device: vk::PhysicalDevice,
99        out: &mut [vk::PhysicalDeviceToolProperties<'_>],
100    ) -> VkResult<()> {
101        unsafe {
102            let mut count = out.len() as u32;
103            (self.instance_fn_1_3.get_physical_device_tool_properties)(
104                physical_device,
105                &mut count,
106                out.as_mut_ptr(),
107            )
108            .result()?;
109            assert_eq!(count as usize, out.len());
110            Ok(())
111        }
112    }
113}
114
115/// Vulkan core 1.1
116impl Instance {
117    #[inline]
118    pub fn fp_v1_1(&self) -> &crate::InstanceFnV1_1 {
119        &self.instance_fn_1_1
120    }
121
122    /// Retrieve the number of elements to pass to [`enumerate_physical_device_groups()`][Self::enumerate_physical_device_groups()]
123    #[inline]
124    pub unsafe fn enumerate_physical_device_groups_len(&self) -> VkResult<usize> {
125        unsafe {
126            let mut group_count = mem::MaybeUninit::uninit();
127            (self.instance_fn_1_1.enumerate_physical_device_groups)(
128                self.handle(),
129                group_count.as_mut_ptr(),
130                ptr::null_mut(),
131            )
132            .assume_init_on_success(group_count)
133            .map(|c| c as usize)
134        }
135    }
136
137    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumeratePhysicalDeviceGroups.html>
138    ///
139    /// Call [`enumerate_physical_device_groups_len()`][Self::enumerate_physical_device_groups_len()] to query the number of elements to pass to `out`.
140    /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer.
141    #[inline]
142    pub unsafe fn enumerate_physical_device_groups(
143        &self,
144        out: &mut [vk::PhysicalDeviceGroupProperties<'_>],
145    ) -> VkResult<()> {
146        unsafe {
147            let mut count = out.len() as u32;
148            (self.instance_fn_1_1.enumerate_physical_device_groups)(
149                self.handle(),
150                &mut count,
151                out.as_mut_ptr(),
152            )
153            .result()?;
154            assert_eq!(count as usize, out.len());
155            Ok(())
156        }
157    }
158
159    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFeatures2.html>
160    #[inline]
161    pub unsafe fn get_physical_device_features2(
162        &self,
163        physical_device: vk::PhysicalDevice,
164        features: &mut vk::PhysicalDeviceFeatures2<'_>,
165    ) {
166        unsafe {
167            (self.instance_fn_1_1.get_physical_device_features2)(physical_device, features);
168        }
169    }
170
171    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceProperties2.html>
172    #[inline]
173    pub unsafe fn get_physical_device_properties2(
174        &self,
175        physical_device: vk::PhysicalDevice,
176        prop: &mut vk::PhysicalDeviceProperties2<'_>,
177    ) {
178        unsafe {
179            (self.instance_fn_1_1.get_physical_device_properties2)(physical_device, prop);
180        }
181    }
182
183    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFormatProperties2.html>
184    #[inline]
185    pub unsafe fn get_physical_device_format_properties2(
186        &self,
187        physical_device: vk::PhysicalDevice,
188        format: vk::Format,
189        out: &mut vk::FormatProperties2<'_>,
190    ) {
191        unsafe {
192            (self.instance_fn_1_1.get_physical_device_format_properties2)(
193                physical_device,
194                format,
195                out,
196            );
197        }
198    }
199
200    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceImageFormatProperties2.html>
201    #[inline]
202    pub unsafe fn get_physical_device_image_format_properties2(
203        &self,
204        physical_device: vk::PhysicalDevice,
205        format_info: &vk::PhysicalDeviceImageFormatInfo2<'_>,
206        image_format_prop: &mut vk::ImageFormatProperties2<'_>,
207    ) -> VkResult<()> {
208        unsafe {
209            (self
210                .instance_fn_1_1
211                .get_physical_device_image_format_properties2)(
212                physical_device,
213                format_info,
214                image_format_prop,
215            )
216            .result()
217        }
218    }
219
220    /// Retrieve the number of elements to pass to [`get_physical_device_queue_family_properties2()`][Self::get_physical_device_queue_family_properties2()]
221    #[inline]
222    pub unsafe fn get_physical_device_queue_family_properties2_len(
223        &self,
224        physical_device: vk::PhysicalDevice,
225    ) -> usize {
226        unsafe {
227            let mut queue_count = mem::MaybeUninit::uninit();
228            (self
229                .instance_fn_1_1
230                .get_physical_device_queue_family_properties2)(
231                physical_device,
232                queue_count.as_mut_ptr(),
233                ptr::null_mut(),
234            );
235            queue_count.assume_init() as usize
236        }
237    }
238
239    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceQueueFamilyProperties2.html>
240    ///
241    /// Call [`get_physical_device_queue_family_properties2_len()`][Self::get_physical_device_queue_family_properties2_len()] to query the number of elements to pass to `out`.
242    /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer.
243    #[inline]
244    pub unsafe fn get_physical_device_queue_family_properties2(
245        &self,
246        physical_device: vk::PhysicalDevice,
247        out: &mut [vk::QueueFamilyProperties2<'_>],
248    ) {
249        unsafe {
250            let mut count = out.len() as u32;
251            (self
252                .instance_fn_1_1
253                .get_physical_device_queue_family_properties2)(
254                physical_device,
255                &mut count,
256                out.as_mut_ptr(),
257            );
258            assert_eq!(count as usize, out.len());
259        }
260    }
261
262    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceMemoryProperties2.html>
263    #[inline]
264    pub unsafe fn get_physical_device_memory_properties2(
265        &self,
266        physical_device: vk::PhysicalDevice,
267        out: &mut vk::PhysicalDeviceMemoryProperties2<'_>,
268    ) {
269        unsafe {
270            (self.instance_fn_1_1.get_physical_device_memory_properties2)(physical_device, out);
271        }
272    }
273
274    /// Retrieve the number of elements to pass to [`get_physical_device_sparse_image_format_properties2()`][Self::get_physical_device_sparse_image_format_properties2()]
275    #[inline]
276    pub unsafe fn get_physical_device_sparse_image_format_properties2_len(
277        &self,
278        physical_device: vk::PhysicalDevice,
279        format_info: &vk::PhysicalDeviceSparseImageFormatInfo2<'_>,
280    ) -> usize {
281        unsafe {
282            let mut format_count = mem::MaybeUninit::uninit();
283            (self
284                .instance_fn_1_1
285                .get_physical_device_sparse_image_format_properties2)(
286                physical_device,
287                format_info,
288                format_count.as_mut_ptr(),
289                ptr::null_mut(),
290            );
291            format_count.assume_init() as usize
292        }
293    }
294
295    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceSparseImageFormatProperties2.html>
296    ///
297    /// Call [`get_physical_device_sparse_image_format_properties2_len()`][Self::get_physical_device_sparse_image_format_properties2_len()] to query the number of elements to pass to `out`.
298    /// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer.
299    #[inline]
300    pub unsafe fn get_physical_device_sparse_image_format_properties2(
301        &self,
302        physical_device: vk::PhysicalDevice,
303        format_info: &vk::PhysicalDeviceSparseImageFormatInfo2<'_>,
304        out: &mut [vk::SparseImageFormatProperties2<'_>],
305    ) {
306        unsafe {
307            let mut count = out.len() as u32;
308            (self
309                .instance_fn_1_1
310                .get_physical_device_sparse_image_format_properties2)(
311                physical_device,
312                format_info,
313                &mut count,
314                out.as_mut_ptr(),
315            );
316            assert_eq!(count as usize, out.len());
317        }
318    }
319
320    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceExternalBufferProperties.html>
321    #[inline]
322    pub unsafe fn get_physical_device_external_buffer_properties(
323        &self,
324        physical_device: vk::PhysicalDevice,
325        external_buffer_info: &vk::PhysicalDeviceExternalBufferInfo<'_>,
326        out: &mut vk::ExternalBufferProperties<'_>,
327    ) {
328        unsafe {
329            (self
330                .instance_fn_1_1
331                .get_physical_device_external_buffer_properties)(
332                physical_device,
333                external_buffer_info,
334                out,
335            );
336        }
337    }
338
339    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceExternalFenceProperties.html>
340    #[inline]
341    pub unsafe fn get_physical_device_external_fence_properties(
342        &self,
343        physical_device: vk::PhysicalDevice,
344        external_fence_info: &vk::PhysicalDeviceExternalFenceInfo<'_>,
345        out: &mut vk::ExternalFenceProperties<'_>,
346    ) {
347        unsafe {
348            (self
349                .instance_fn_1_1
350                .get_physical_device_external_fence_properties)(
351                physical_device,
352                external_fence_info,
353                out,
354            );
355        }
356    }
357
358    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceExternalSemaphoreProperties.html>
359    #[inline]
360    pub unsafe fn get_physical_device_external_semaphore_properties(
361        &self,
362        physical_device: vk::PhysicalDevice,
363        external_semaphore_info: &vk::PhysicalDeviceExternalSemaphoreInfo<'_>,
364        out: &mut vk::ExternalSemaphoreProperties<'_>,
365    ) {
366        unsafe {
367            (self
368                .instance_fn_1_1
369                .get_physical_device_external_semaphore_properties)(
370                physical_device,
371                external_semaphore_info,
372                out,
373            );
374        }
375    }
376}
377
378/// Vulkan core 1.0
379impl Instance {
380    #[inline]
381    pub fn fp_v1_0(&self) -> &crate::InstanceFnV1_0 {
382        &self.instance_fn_1_0
383    }
384
385    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCreateDevice.html>
386    ///
387    /// # Safety
388    ///
389    /// There is a [parent/child relation] between [`Instance`] and the resulting [`Device`].  The
390    /// application must not [destroy][Instance::destroy_instance()] the parent [`Instance`] object
391    /// before first [destroying][Device::destroy_device()] the returned [`Device`] child object.
392    /// [`Device`] does _not_ implement [drop][drop()] semantics and can only be destroyed via
393    /// [`destroy_device()`][Device::destroy_device()].
394    ///
395    /// See the [`Entry::create_instance()`] documentation for more destruction ordering rules on
396    /// [`Instance`].
397    ///
398    /// [parent/child relation]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#fundamentals-objectmodel-lifetime
399    #[inline]
400    pub unsafe fn create_device(
401        &self,
402        physical_device: vk::PhysicalDevice,
403        create_info: &vk::DeviceCreateInfo<'_>,
404        allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
405    ) -> VkResult<Device> {
406        unsafe {
407            let mut device = mem::MaybeUninit::uninit();
408            let device = (self.instance_fn_1_0.create_device)(
409                physical_device,
410                create_info,
411                allocation_callbacks.as_raw_ptr(),
412                device.as_mut_ptr(),
413            )
414            .assume_init_on_success(device)?;
415            Ok(Device::load(&self.instance_fn_1_0, device))
416        }
417    }
418
419    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetDeviceProcAddr.html>
420    #[inline]
421    pub unsafe fn get_device_proc_addr(
422        &self,
423        device: vk::Device,
424        p_name: *const ffi::c_char,
425    ) -> vk::PFN_vkVoidFunction {
426        unsafe { (self.instance_fn_1_0.get_device_proc_addr)(device, p_name) }
427    }
428
429    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkDestroyInstance.html>
430    #[inline]
431    pub unsafe fn destroy_instance(
432        &self,
433        allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
434    ) {
435        unsafe {
436            (self.instance_fn_1_0.destroy_instance)(
437                self.handle(),
438                allocation_callbacks.as_raw_ptr(),
439            );
440        }
441    }
442
443    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFormatProperties.html>
444    #[inline]
445    pub unsafe fn get_physical_device_format_properties(
446        &self,
447        physical_device: vk::PhysicalDevice,
448        format: vk::Format,
449    ) -> vk::FormatProperties {
450        unsafe {
451            let mut format_prop = mem::MaybeUninit::uninit();
452            (self.instance_fn_1_0.get_physical_device_format_properties)(
453                physical_device,
454                format,
455                format_prop.as_mut_ptr(),
456            );
457            format_prop.assume_init()
458        }
459    }
460
461    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceImageFormatProperties.html>
462    #[inline]
463    pub unsafe fn get_physical_device_image_format_properties(
464        &self,
465        physical_device: vk::PhysicalDevice,
466        format: vk::Format,
467        typ: vk::ImageType,
468        tiling: vk::ImageTiling,
469        usage: vk::ImageUsageFlags,
470        flags: vk::ImageCreateFlags,
471    ) -> VkResult<vk::ImageFormatProperties> {
472        unsafe {
473            let mut image_format_prop = mem::MaybeUninit::uninit();
474            (self
475                .instance_fn_1_0
476                .get_physical_device_image_format_properties)(
477                physical_device,
478                format,
479                typ,
480                tiling,
481                usage,
482                flags,
483                image_format_prop.as_mut_ptr(),
484            )
485            .assume_init_on_success(image_format_prop)
486        }
487    }
488
489    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceMemoryProperties.html>
490    #[inline]
491    pub unsafe fn get_physical_device_memory_properties(
492        &self,
493        physical_device: vk::PhysicalDevice,
494    ) -> vk::PhysicalDeviceMemoryProperties {
495        unsafe {
496            let mut memory_prop = mem::MaybeUninit::uninit();
497            (self.instance_fn_1_0.get_physical_device_memory_properties)(
498                physical_device,
499                memory_prop.as_mut_ptr(),
500            );
501            memory_prop.assume_init()
502        }
503    }
504
505    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceProperties.html>
506    #[inline]
507    pub unsafe fn get_physical_device_properties(
508        &self,
509        physical_device: vk::PhysicalDevice,
510    ) -> vk::PhysicalDeviceProperties {
511        unsafe {
512            let mut prop = mem::MaybeUninit::uninit();
513            (self.instance_fn_1_0.get_physical_device_properties)(
514                physical_device,
515                prop.as_mut_ptr(),
516            );
517            prop.assume_init()
518        }
519    }
520
521    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceQueueFamilyProperties.html>
522    #[inline]
523    pub unsafe fn get_physical_device_queue_family_properties(
524        &self,
525        physical_device: vk::PhysicalDevice,
526    ) -> Vec<vk::QueueFamilyProperties> {
527        unsafe {
528            read_into_uninitialized_vector(|count, data| {
529                (self
530                    .instance_fn_1_0
531                    .get_physical_device_queue_family_properties)(
532                    physical_device, count, data
533                );
534                vk::Result::SUCCESS
535            })
536            // The closure always returns SUCCESS
537            .unwrap()
538        }
539    }
540
541    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceFeatures.html>
542    #[inline]
543    pub unsafe fn get_physical_device_features(
544        &self,
545        physical_device: vk::PhysicalDevice,
546    ) -> vk::PhysicalDeviceFeatures {
547        unsafe {
548            let mut prop = mem::MaybeUninit::uninit();
549            (self.instance_fn_1_0.get_physical_device_features)(physical_device, prop.as_mut_ptr());
550            prop.assume_init()
551        }
552    }
553
554    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumeratePhysicalDevices.html>
555    #[inline]
556    pub unsafe fn enumerate_physical_devices(&self) -> VkResult<Vec<vk::PhysicalDevice>> {
557        unsafe {
558            read_into_uninitialized_vector(|count, data| {
559                (self.instance_fn_1_0.enumerate_physical_devices)(self.handle(), count, data)
560            })
561        }
562    }
563
564    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumerateDeviceExtensionProperties.html>
565    #[inline]
566    pub unsafe fn enumerate_device_extension_properties(
567        &self,
568        device: vk::PhysicalDevice,
569    ) -> VkResult<Vec<vk::ExtensionProperties>> {
570        unsafe {
571            read_into_uninitialized_vector(|count, data| {
572                (self.instance_fn_1_0.enumerate_device_extension_properties)(
573                    device,
574                    ptr::null(),
575                    count,
576                    data,
577                )
578            })
579        }
580    }
581
582    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumerateDeviceLayerProperties.html>
583    #[inline]
584    pub unsafe fn enumerate_device_layer_properties(
585        &self,
586        device: vk::PhysicalDevice,
587    ) -> VkResult<Vec<vk::LayerProperties>> {
588        unsafe {
589            read_into_uninitialized_vector(|count, data| {
590                (self.instance_fn_1_0.enumerate_device_layer_properties)(device, count, data)
591            })
592        }
593    }
594
595    /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceSparseImageFormatProperties.html>
596    #[inline]
597    pub unsafe fn get_physical_device_sparse_image_format_properties(
598        &self,
599        physical_device: vk::PhysicalDevice,
600        format: vk::Format,
601        typ: vk::ImageType,
602        samples: vk::SampleCountFlags,
603        usage: vk::ImageUsageFlags,
604        tiling: vk::ImageTiling,
605    ) -> Vec<vk::SparseImageFormatProperties> {
606        unsafe {
607            read_into_uninitialized_vector(|count, data| {
608                (self
609                    .instance_fn_1_0
610                    .get_physical_device_sparse_image_format_properties)(
611                    physical_device,
612                    format,
613                    typ,
614                    samples,
615                    usage,
616                    tiling,
617                    count,
618                    data,
619                );
620                vk::Result::SUCCESS
621            })
622            // The closure always returns SUCCESS
623            .unwrap()
624        }
625    }
626}