ash/
instance.rs

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