ash/
instance.rs

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