ash/
instance.rs

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