dacite/core/
physical_device.rs

1// Copyright (c) 2017, Dennis Hamester <dennis.hamester@startmail.com>
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13// PERFORMANCE OF THIS SOFTWARE.
14
15use FromNativeObject;
16use TryDestroyError;
17use TryDestroyErrorKind;
18use VulkanObject;
19use core::allocator_helper::AllocatorHelper;
20use core::{self, Device, Instance};
21use khr_display;
22use khr_get_physical_device_properties2;
23use khr_surface;
24use mir_types;
25use nv_external_memory_capabilities;
26use std::cmp::Ordering;
27use std::ffi::CStr;
28use std::hash::{Hash, Hasher};
29use std::iter::FromIterator;
30use std::mem;
31use std::ptr;
32use utils;
33use vks;
34use wayland_types;
35use xcb_types;
36use xlib_types;
37
38/// See [`VkPhysicalDevice`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPhysicalDevice)
39#[derive(Debug, Clone)]
40pub struct PhysicalDevice {
41    pub(crate) handle: vks::core::VkPhysicalDevice,
42    pub(crate) instance: Instance,
43}
44
45unsafe impl Send for PhysicalDevice { }
46
47unsafe impl Sync for PhysicalDevice { }
48
49impl PartialEq for PhysicalDevice {
50    #[inline]
51    fn eq(&self, other: &Self) -> bool {
52        self.handle == other.handle
53    }
54}
55
56impl Eq for PhysicalDevice { }
57
58impl PartialOrd for PhysicalDevice {
59    #[inline]
60    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
61        self.handle.partial_cmp(&other.handle)
62    }
63}
64
65impl Ord for PhysicalDevice {
66    #[inline]
67    fn cmp(&self, other: &Self) -> Ordering {
68        self.handle.cmp(&other.handle)
69    }
70}
71
72impl Hash for PhysicalDevice {
73    #[inline]
74    fn hash<H: Hasher>(&self, state: &mut H) {
75        self.handle.hash(state);
76    }
77}
78
79impl VulkanObject for PhysicalDevice {
80    type NativeVulkanObject = vks::core::VkPhysicalDevice;
81
82    #[inline]
83    fn id(&self) -> u64 {
84        self.as_native_vulkan_object() as u64
85    }
86
87    #[inline]
88    fn as_native_vulkan_object(&self) -> Self::NativeVulkanObject {
89        self.handle
90    }
91
92    fn try_destroy(self) -> Result<(), TryDestroyError<Self>> {
93        Err(TryDestroyError::new(self, TryDestroyErrorKind::Unsupported))
94    }
95}
96
97impl FromNativeObject for PhysicalDevice {
98    type Parameters = Instance;
99
100    unsafe fn from_native_object(object: Self::NativeVulkanObject, params: Self::Parameters) -> Self {
101        PhysicalDevice::new(object, params)
102    }
103}
104
105impl PhysicalDevice {
106    pub(crate) fn new(handle: vks::core::VkPhysicalDevice, instance: Instance) -> Self {
107        PhysicalDevice {
108            handle: handle,
109            instance: instance,
110        }
111    }
112
113    #[inline]
114    pub(crate) fn loader(&self) -> &vks::InstanceProcAddrLoader {
115        self.instance.loader()
116    }
117
118    /// See [`vkGetPhysicalDeviceProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceProperties)
119    pub fn get_properties(&self) -> core::PhysicalDeviceProperties {
120        unsafe {
121            let mut properties = mem::uninitialized();
122            self.loader().core.vkGetPhysicalDeviceProperties(self.handle, &mut properties);
123            (&properties).into()
124        }
125    }
126
127    /// See [`vkGetPhysicalDeviceFeatures`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceFeatures)
128    pub fn get_features(&self) -> core::PhysicalDeviceFeatures {
129        unsafe {
130            let mut features = mem::uninitialized();
131            self.loader().core.vkGetPhysicalDeviceFeatures(self.handle, &mut features);
132            (&features).into()
133        }
134    }
135
136    /// See [`vkEnumerateDeviceLayerProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkEnumerateDeviceLayerProperties)
137    pub fn enumerate_device_layer_properties<B>(&self) -> Result<B, core::Error>
138        where B: FromIterator<core::LayerProperties>
139    {
140        unsafe {
141            let mut num_layer_properties = 0;
142            let res = self.loader().core.vkEnumerateDeviceLayerProperties(self.handle, &mut num_layer_properties, ptr::null_mut());
143            if res != vks::core::VK_SUCCESS {
144                return Err(res.into());
145            }
146
147            let mut layer_properties = Vec::with_capacity(num_layer_properties as usize);
148            let res = self.loader().core.vkEnumerateDeviceLayerProperties(self.handle, &mut num_layer_properties, layer_properties.as_mut_ptr());
149            layer_properties.set_len(num_layer_properties as usize);
150            if res != vks::core::VK_SUCCESS {
151                return Err(res.into());
152            }
153
154            Ok(layer_properties.iter().map(From::from).collect())
155        }
156    }
157
158    /// See [`vkEnumerateDeviceExtensionProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkEnumerateDeviceExtensionProperties)
159    pub fn get_device_extension_properties(&self, layer_name: Option<&str>) -> Result<core::DeviceExtensionsProperties, core::Error> {
160        unsafe {
161            let layer_name_cstr = utils::cstr_from_str(layer_name);
162
163            let mut num_extension_properties = 0;
164            let res = self.loader().core.vkEnumerateDeviceExtensionProperties(self.handle, layer_name_cstr.1, &mut num_extension_properties, ptr::null_mut());
165            if res != vks::core::VK_SUCCESS {
166                return Err(res.into());
167            }
168
169            let mut extension_properties = Vec::with_capacity(num_extension_properties as usize);
170            extension_properties.set_len(num_extension_properties as usize);
171            let res = self.loader().core.vkEnumerateDeviceExtensionProperties(self.handle, layer_name_cstr.1, &mut num_extension_properties, extension_properties.as_mut_ptr());
172            if res != vks::core::VK_SUCCESS {
173                return Err(res.into());
174            }
175
176            let mut res = core::DeviceExtensionsProperties::new();
177            for extension in extension_properties {
178                let name = CStr::from_ptr(extension.extensionName.as_ptr()).to_str().unwrap();
179                res.add(name, extension.specVersion);
180            }
181
182            Ok(res)
183        }
184    }
185
186    /// See [`vkGetPhysicalDeviceFormatProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceFormatProperties)
187    pub fn get_format_properties(&self, format: core::Format) -> core::FormatProperties {
188        let mut properties = unsafe { mem::uninitialized() };
189
190        unsafe {
191            self.loader().core.vkGetPhysicalDeviceFormatProperties(self.handle, format.into(), &mut properties);
192        }
193
194        (&properties).into()
195    }
196
197    /// See [`vkGetPhysicalDeviceImageFormatProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)
198    pub fn get_image_format_properties(&self, format: core::Format, image_type: core::ImageType, tiling: core::ImageTiling, usage: core::ImageUsageFlags, flags: core::ImageCreateFlags) -> Result<core::ImageFormatProperties, core::Error> {
199        let mut properties = unsafe { mem::uninitialized() };
200
201        let res = unsafe {
202            self.loader().core.vkGetPhysicalDeviceImageFormatProperties(self.handle, format.into(), image_type.into(), tiling.into(), usage.bits(), flags.bits(), &mut properties)
203        };
204
205        if res == vks::core::VK_SUCCESS {
206            Ok((&properties).into())
207        }
208        else {
209            Err(res.into())
210        }
211    }
212
213    /// See [`vkGetPhysicalDeviceSparseImageFormatProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)
214    pub fn get_sparse_image_format_properties<B>(&self, format: core::Format, image_type: core::ImageType, samples: core::SampleCountFlagBits, usage: core::ImageUsageFlags, tiling: core::ImageTiling) -> B
215        where B: FromIterator<core::SparseImageFormatProperties>
216    {
217        let mut num_properties = 0;
218        unsafe {
219            self.loader().core.vkGetPhysicalDeviceSparseImageFormatProperties(self.handle, format.into(), image_type.into(), samples.bit(), usage.bits(), tiling.into(), &mut num_properties, ptr::null_mut());
220        }
221
222        let mut properties = Vec::with_capacity(num_properties as usize);
223        unsafe {
224            self.loader().core.vkGetPhysicalDeviceSparseImageFormatProperties(self.handle, format.into(), image_type.into(), samples.bit(), usage.bits(), tiling.into(), &mut num_properties, properties.as_mut_ptr());
225            properties.set_len(num_properties as usize);
226        }
227
228        properties.iter().map(From::from).collect()
229    }
230
231    /// See [`vkGetPhysicalDeviceQueueFamilyProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties)
232    pub fn get_queue_family_properties<B>(&self) -> B
233        where B: FromIterator<core::QueueFamilyProperties>
234    {
235        let mut num_properties = 0;
236        unsafe {
237            self.loader().core.vkGetPhysicalDeviceQueueFamilyProperties(self.handle, &mut num_properties, ptr::null_mut());
238        }
239
240        let mut properties = Vec::with_capacity(num_properties as usize);
241        unsafe {
242            self.loader().core.vkGetPhysicalDeviceQueueFamilyProperties(self.handle, &mut num_properties, properties.as_mut_ptr());
243            properties.set_len(num_properties as usize);
244        }
245
246        properties.iter().map(From::from).collect()
247    }
248
249    /// See [`vkGetPhysicalDeviceMemoryProperties`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceMemoryProperties)
250    pub fn get_memory_properties(&self) -> core::PhysicalDeviceMemoryProperties {
251        let mut properties = unsafe { mem::uninitialized() };
252
253        unsafe {
254            self.loader().core.vkGetPhysicalDeviceMemoryProperties(self.handle, &mut properties);
255        }
256
257        (&properties).into()
258    }
259
260    /// See [`vkCreateDevice`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCreateDevice)
261    pub fn create_device(&self, create_info: &core::DeviceCreateInfo, allocator: Option<Box<core::Allocator>>) -> Result<Device, core::Error> {
262        let allocator_helper = allocator.map(AllocatorHelper::new);
263        let allocation_callbacks = allocator_helper.as_ref().map_or(ptr::null(), AllocatorHelper::callbacks);
264        let create_info_wrapper = core::VkDeviceCreateInfoWrapper::new(create_info, true);
265
266        let mut device = ptr::null_mut();
267        let res = unsafe {
268            self.loader().core.vkCreateDevice(self.handle, &create_info_wrapper.vks_struct, allocation_callbacks, &mut device)
269        };
270
271        if res == vks::core::VK_SUCCESS {
272            let mut loader = vks::DeviceProcAddrLoader::from_get_device_proc_addr(self.loader().core.pfn_vkGetDeviceProcAddr);
273
274            unsafe {
275                loader.load_core(device);
276                create_info.enabled_extensions.load_device(&mut loader, device);
277                self.instance.get_enabled_extensions().load_device(&mut loader, device);
278            }
279
280            Ok(Device::new(device, self.instance.clone(), allocator_helper, loader, create_info.enabled_extensions.clone()))
281        }
282        else {
283            Err(res.into())
284        }
285    }
286
287    /// See [`vkGetPhysicalDeviceSurfaceSupportKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)
288    /// and extension [`VK_KHR_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_surface)
289    pub fn get_surface_support_khr(&self, queue_family_index: u32, surface: &khr_surface::SurfaceKhr) -> Result<bool, core::Error> {
290        let mut supported = vks::core::VK_FALSE;
291        let res = unsafe {
292            self.loader().khr_surface.vkGetPhysicalDeviceSurfaceSupportKHR(self.handle, queue_family_index, surface.handle(), &mut supported)
293        };
294
295        if res == vks::core::VK_SUCCESS {
296            Ok(utils::from_vk_bool(supported))
297        }
298        else {
299            Err(res.into())
300        }
301    }
302
303    /// See [`vkGetPhysicalDeviceSurfaceCapabilitiesKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR)
304    /// and extension [`VK_KHR_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_surface)
305    pub fn get_surface_capabilities_khr(&self, surface: &khr_surface::SurfaceKhr) -> Result<khr_surface::SurfaceCapabilitiesKhr, core::Error> {
306        unsafe {
307            let mut capabilities = mem::uninitialized();
308            let res = self.loader().khr_surface.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(self.handle, surface.handle(), &mut capabilities);
309
310            if res == vks::core::VK_SUCCESS {
311                Ok((&capabilities).into())
312            }
313            else {
314                Err(res.into())
315            }
316        }
317    }
318
319    /// See [`vkGetPhysicalDeviceSurfaceFormatsKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)
320    /// and extension [`VK_KHR_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_surface)
321    pub fn get_surface_formats_khr<B>(&self, surface: &khr_surface::SurfaceKhr) -> Result<B, core::Error>
322        where B: FromIterator<khr_surface::SurfaceFormatKhr>
323    {
324        let mut num_formats = 0;
325        let res = unsafe {
326            self.loader().khr_surface.vkGetPhysicalDeviceSurfaceFormatsKHR(self.handle, surface.handle(), &mut num_formats, ptr::null_mut())
327        };
328
329        if (res != vks::core::VK_SUCCESS) && (res != vks::core::VK_INCOMPLETE) {
330            return Err(res.into());
331        }
332
333        let mut formats = Vec::with_capacity(num_formats as usize);
334        let res = unsafe {
335            self.loader().khr_surface.vkGetPhysicalDeviceSurfaceFormatsKHR(self.handle, surface.handle(), &mut num_formats, formats.as_mut_ptr())
336        };
337
338        if res == vks::core::VK_SUCCESS {
339            unsafe {
340                formats.set_len(num_formats as usize);
341            }
342
343            Ok(formats.iter().map(From::from).collect())
344        }
345        else {
346            Err(res.into())
347        }
348    }
349
350    /// See [`vkGetPhysicalDeviceSurfacePresentModesKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)
351    /// and extension [`VK_KHR_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_surface)
352    pub fn get_surface_present_modes_khr<B>(&self, surface: &khr_surface::SurfaceKhr) -> Result<B, core::Error>
353        where B: FromIterator<khr_surface::PresentModeKhr>
354    {
355        let mut num_modes = 0;
356        let res = unsafe {
357            self.loader().khr_surface.vkGetPhysicalDeviceSurfacePresentModesKHR(self.handle, surface.handle(), &mut num_modes, ptr::null_mut())
358        };
359
360        if (res != vks::core::VK_SUCCESS) && (res != vks::core::VK_INCOMPLETE) {
361            return Err(res.into());
362        }
363
364        let mut modes = Vec::with_capacity(num_modes as usize);
365        let res = unsafe {
366            self.loader().khr_surface.vkGetPhysicalDeviceSurfacePresentModesKHR(self.handle, surface.handle(), &mut num_modes, modes.as_mut_ptr())
367        };
368
369        if res == vks::core::VK_SUCCESS {
370            unsafe {
371                modes.set_len(num_modes as usize);
372            }
373
374            Ok(modes.into_iter().map(From::from).collect())
375        }
376        else {
377            Err(res.into())
378        }
379    }
380
381    /// See [`vkGetPhysicalDeviceDisplayPropertiesKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)
382    /// and extension [`VK_KHR_display`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_display)
383    pub fn get_display_properties_khr(&self) -> Result<Vec<khr_display::DisplayPropertiesKhr>, core::Error> {
384        let mut len = 0;
385        let res = unsafe {
386            self.loader().khr_display.vkGetPhysicalDeviceDisplayPropertiesKHR(self.handle, &mut len, ptr::null_mut())
387        };
388
389        if res != vks::core::VK_SUCCESS {
390            return Err(res.into());
391        }
392
393        let mut properties = Vec::with_capacity(len as usize);
394        let res = unsafe {
395            properties.set_len(len as usize);
396            self.loader().khr_display.vkGetPhysicalDeviceDisplayPropertiesKHR(self.handle, &mut len, properties.as_mut_ptr())
397        };
398
399        if res == vks::core::VK_SUCCESS {
400            unsafe {
401                Ok(properties.iter().map(|p| khr_display::DisplayPropertiesKhr::from_vks(p, self.clone())).collect())
402            }
403        }
404        else {
405            Err(res.into())
406        }
407    }
408
409    /// See [`vkGetPhysicalDeviceDisplayPlanePropertiesKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)
410    /// and extension [`VK_KHR_display`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_display)
411    pub fn get_display_plane_properties_khr(&self) -> Result<Vec<khr_display::DisplayPlanePropertiesKhr>, core::Error> {
412        let mut len = 0;
413        let res = unsafe {
414            self.loader().khr_display.vkGetPhysicalDeviceDisplayPlanePropertiesKHR(self.handle, &mut len, ptr::null_mut())
415        };
416
417        if res != vks::core::VK_SUCCESS {
418            return Err(res.into());
419        }
420
421        let mut properties = Vec::with_capacity(len as usize);
422        let res = unsafe {
423            properties.set_len(len as usize);
424            self.loader().khr_display.vkGetPhysicalDeviceDisplayPlanePropertiesKHR(self.handle, &mut len, properties.as_mut_ptr())
425        };
426
427        if res == vks::core::VK_SUCCESS {
428            unsafe {
429                Ok(properties.iter().map(|p| khr_display::DisplayPlanePropertiesKhr::from_vks(p, self)).collect())
430            }
431        }
432        else {
433            Err(res.into())
434        }
435    }
436
437    /// See [`vkGetDisplayPlaneSupportedDisplaysKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)
438    /// and extension [`VK_KHR_display`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_display)
439    pub fn get_display_plane_supported_displays_khr(&self, plane_index: u32) -> Result<Vec<khr_display::DisplayKhr>, core::Error> {
440        let mut len = 0;
441        let res = unsafe {
442            self.loader().khr_display.vkGetDisplayPlaneSupportedDisplaysKHR(self.handle, plane_index, &mut len, ptr::null_mut())
443        };
444
445        if res != vks::core::VK_SUCCESS {
446            return Err(res.into());
447        }
448
449        let mut displays = Vec::with_capacity(len as usize);
450        let res = unsafe {
451            displays.set_len(len as usize);
452            self.loader().khr_display.vkGetDisplayPlaneSupportedDisplaysKHR(self.handle, plane_index, &mut len, displays.as_mut_ptr())
453        };
454
455        if res == vks::core::VK_SUCCESS {
456            Ok(displays.iter().map(|d| khr_display::DisplayKhr::new(*d, self.clone())).collect())
457        }
458        else {
459            Err(res.into())
460        }
461    }
462
463    /// See [`vkGetPhysicalDeviceXlibPresentationSupportKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceXlibPresentationSupportKHR)
464    /// and extension [`VK_KHR_xlib_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_xlib_surface)
465    #[cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))]
466    pub fn get_xlib_presentation_support_khr(&self, queue_family_index: u32, dpy: *mut xlib_types::Display, visual_id: xlib_types::VisualID) -> bool {
467        let res = unsafe {
468            self.loader().khr_xlib_surface.vkGetPhysicalDeviceXlibPresentationSupportKHR(self.handle, queue_family_index, dpy, visual_id)
469        };
470
471        utils::from_vk_bool(res)
472    }
473
474    /// See [`vkGetPhysicalDeviceWaylandPresentationSupportKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceWaylandPresentationSupportKHR)
475    /// and extension [`VK_KHR_wayland_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_wayland_surface)
476    #[cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))]
477    pub fn get_wayland_presentation_support_khr(&self, queue_family_index: u32, display: *mut wayland_types::wl_display) -> bool {
478        let res = unsafe {
479            self.loader().khr_wayland_surface.vkGetPhysicalDeviceWaylandPresentationSupportKHR(self.handle, queue_family_index, display)
480        };
481
482        utils::from_vk_bool(res)
483    }
484
485    /// See [`vkGetPhysicalDeviceXcbPresentationSupportKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceXcbPresentationSupportKHR)
486    /// and extension [`VK_KHR_xcb_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_xcb_surface)
487    #[cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))]
488    pub fn get_xcb_presentation_support_khr(&self, queue_family_index: u32, connection: *mut xcb_types::xcb_connection_t, visual_id: xcb_types::xcb_visualid_t) -> bool {
489        let res = unsafe {
490            self.loader().khr_xcb_surface.vkGetPhysicalDeviceXcbPresentationSupportKHR(self.handle, queue_family_index, connection, visual_id)
491        };
492
493        utils::from_vk_bool(res)
494    }
495
496    /// See [`vkGetPhysicalDeviceMirPresentationSupportKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceMirPresentationSupportKHR)
497    /// and extension [`VK_KHR_mir_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_mir_surface)
498    #[cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))]
499    pub fn get_mir_presentation_support_khr(&self, queue_family_index: u32, connection: *mut mir_types::MirConnection) -> bool {
500        let res = unsafe {
501            self.loader().khr_mir_surface.vkGetPhysicalDeviceMirPresentationSupportKHR(self.handle, queue_family_index, connection)
502        };
503
504        utils::from_vk_bool(res)
505    }
506
507    /// See [`vkGetPhysicalDeviceWin32PresentationSupportKHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceWin32PresentationSupportKHR)
508    /// and extension [`VK_KHR_win32_surface`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_win32_surface)
509    pub fn get_win32_presentation_support_khr(&self, queue_family_index: u32) -> bool {
510        let res = unsafe {
511            self.loader().khr_win32_surface.vkGetPhysicalDeviceWin32PresentationSupportKHR(self.handle, queue_family_index)
512        };
513
514        utils::from_vk_bool(res)
515    }
516
517    /// See [`vkGetPhysicalDeviceFeatures2KHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceFeatures2KHR)
518    /// and extension [`VK_KHR_get_physical_device_properties2`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_get_physical_device_properties2)
519    pub fn get_features2_khr(&self, chain_query: Option<&khr_get_physical_device_properties2::PhysicalDeviceFeatures2ChainQueryKhr>) -> khr_get_physical_device_properties2::PhysicalDeviceFeatures2Khr {
520        let mut chain_query_wrapper = khr_get_physical_device_properties2::PhysicalDeviceFeatures2ChainQueryKhrWrapper::new_optional(chain_query);
521        unsafe {
522            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceFeatures2KHR(self.handle, &mut chain_query_wrapper.vks_struct);
523            khr_get_physical_device_properties2::PhysicalDeviceFeatures2Khr::from_vks(&chain_query_wrapper.vks_struct, true)
524        }
525    }
526
527    /// See [`vkGetPhysicalDeviceProperties2KHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceProperties2KHR)
528    /// and extension [`VK_KHR_get_physical_device_properties2`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_get_physical_device_properties2)
529    pub fn get_properties2_khr(&self, chain_query: Option<&khr_get_physical_device_properties2::PhysicalDeviceProperties2ChainQueryKhr>) -> khr_get_physical_device_properties2::PhysicalDeviceProperties2Khr {
530        let mut chain_query_wrapper = khr_get_physical_device_properties2::PhysicalDeviceProperties2ChainQueryKhrWrapper::new_optional(chain_query);
531        unsafe {
532            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceProperties2KHR(self.handle, &mut chain_query_wrapper.vks_struct);
533            khr_get_physical_device_properties2::PhysicalDeviceProperties2Khr::from_vks(&chain_query_wrapper.vks_struct, true)
534        }
535    }
536
537    /// See [`vkGetPhysicalDeviceFormatProperties2KHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceFormatProperties2KHR)
538    /// and extension [`VK_KHR_get_physical_device_properties2`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_get_physical_device_properties2)
539    pub fn get_format_properties2_khr(&self, format: core::Format, chain_query: Option<&khr_get_physical_device_properties2::FormatProperties2ChainQueryKhr>) -> khr_get_physical_device_properties2::FormatProperties2Khr {
540        let mut chain_query_wrapper = khr_get_physical_device_properties2::FormatProperties2ChainQueryKhrWrapper::new_optional(chain_query);
541        unsafe {
542            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceFormatProperties2KHR(self.handle, format.into(), &mut chain_query_wrapper.vks_struct);
543            khr_get_physical_device_properties2::FormatProperties2Khr::from_vks(&chain_query_wrapper.vks_struct, true)
544        }
545    }
546
547    /// See [`vkGetPhysicalDeviceImageFormatProperties2KHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceImageFormatProperties2KHR)
548    /// and extension [`VK_KHR_get_physical_device_properties2`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_get_physical_device_properties2)
549    pub fn get_image_format_properties2_khr(&self, image_format_info: &khr_get_physical_device_properties2::PhysicalDeviceImageFormatInfo2Khr, chain_query: Option<&khr_get_physical_device_properties2::ImageFormatProperties2ChainQueryKhr>) -> Result<khr_get_physical_device_properties2::ImageFormatProperties2Khr, core::Error> {
550        let image_format_info_wrapper = khr_get_physical_device_properties2::VkPhysicalDeviceImageFormatInfo2KHRWrapper::new(image_format_info, true);
551        let mut chain_query_wrapper = khr_get_physical_device_properties2::ImageFormatProperties2ChainQueryKhrWrapper::new_optional(chain_query);
552
553        unsafe {
554            let res = self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceImageFormatProperties2KHR(self.handle, &image_format_info_wrapper.vks_struct, &mut chain_query_wrapper.vks_struct);
555
556            if res == vks::core::VK_SUCCESS {
557                Ok(khr_get_physical_device_properties2::ImageFormatProperties2Khr::from_vks(&chain_query_wrapper.vks_struct, true))
558            }
559            else {
560                Err(res.into())
561            }
562        }
563    }
564
565    /// See [`vkGetPhysicalDeviceQueueFamilyProperties2KHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties2KHR)
566    /// and extension [`VK_KHR_get_physical_device_properties2`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_get_physical_device_properties2)
567    pub fn get_queue_family_properties2_khr<B>(&self, chain_query: Option<&khr_get_physical_device_properties2::QueueFamilyProperties2ChainQueryKhr>) -> B
568        where B: FromIterator<khr_get_physical_device_properties2::QueueFamilyProperties2Khr>
569    {
570        unsafe {
571            let mut num = 0;
572            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceQueueFamilyProperties2KHR(self.handle, &mut num, ptr::null_mut());
573
574            let mut chain_query_wrappers = Vec::with_capacity(num as usize);
575            for _ in 0..num {
576                chain_query_wrappers.push(khr_get_physical_device_properties2::QueueFamilyProperties2ChainQueryKhrWrapper::new_optional(chain_query));
577            }
578
579            let mut vks_structs: Vec<_> = chain_query_wrappers.iter().map(|w| w.vks_struct).collect();
580            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceQueueFamilyProperties2KHR(self.handle, &mut num, vks_structs.as_mut_ptr());
581
582            vks_structs.iter().map(|p| khr_get_physical_device_properties2::QueueFamilyProperties2Khr::from_vks(p, true)).collect()
583        }
584    }
585
586    /// See [`vkGetPhysicalDeviceMemoryProperties2KHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceMemoryProperties2KHR)
587    /// and extension [`VK_KHR_get_physical_device_properties2`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_get_physical_device_properties2)
588    pub fn get_memory_properties2_khr(&self, chain_query: Option<&khr_get_physical_device_properties2::PhysicalDeviceMemoryProperties2ChainQueryKhr>) -> khr_get_physical_device_properties2::PhysicalDeviceMemoryProperties2Khr {
589        let mut chain_query_wrapper = khr_get_physical_device_properties2::PhysicalDeviceMemoryProperties2ChainQueryKhrWrapper::new_optional(chain_query);
590        unsafe {
591            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceMemoryProperties2KHR(self.handle, &mut chain_query_wrapper.vks_struct);
592            khr_get_physical_device_properties2::PhysicalDeviceMemoryProperties2Khr::from_vks(&chain_query_wrapper.vks_struct, true)
593        }
594    }
595
596    /// See [`vkGetPhysicalDeviceSparseImageFormatProperties2KHR`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties2KHR)
597    /// and extension [`VK_KHR_get_physical_device_properties2`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_KHR_get_physical_device_properties2)
598    pub fn get_sparse_image_format_properties2_khr<B>(&self, format_info: &khr_get_physical_device_properties2::PhysicalDeviceSparseImageFormatInfo2Khr, chain_query: Option<&khr_get_physical_device_properties2::SparseImageFormatProperties2ChainQueryKhr>) -> B
599        where B: FromIterator<khr_get_physical_device_properties2::SparseImageFormatProperties2Khr>
600    {
601        let format_info_wrapper = khr_get_physical_device_properties2::VkPhysicalDeviceSparseImageFormatInfo2KHRWrapper::new(format_info, true);
602
603        unsafe {
604            let mut num = 0;
605            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceSparseImageFormatProperties2KHR(self.handle, &format_info_wrapper.vks_struct, &mut num, ptr::null_mut());
606
607            let mut chain_query_wrappers = Vec::with_capacity(num as usize);
608            for _ in 0..num {
609                chain_query_wrappers.push(khr_get_physical_device_properties2::SparseImageFormatProperties2ChainQueryKhrWrapper::new_optional(chain_query));
610            }
611
612            let mut vks_structs: Vec<_> = chain_query_wrappers.iter().map(|w| w.vks_struct).collect();
613            self.loader().khr_get_physical_device_properties2.vkGetPhysicalDeviceSparseImageFormatProperties2KHR(self.handle, &format_info_wrapper.vks_struct, &mut num, vks_structs.as_mut_ptr());
614
615            vks_structs.iter().map(|p| khr_get_physical_device_properties2::SparseImageFormatProperties2Khr::from_vks(p, true)).collect()
616        }
617    }
618
619    /// See [`vkGetPhysicalDeviceExternalImageFormatPropertiesNV`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)
620    /// and extension [`VK_NV_external_memory_capabilities`](https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VK_NV_external_memory_capabilities)
621    pub fn get_external_image_format_properties_nv(&self, format: core::Format, image_type: core::ImageType, tiling: core::ImageTiling, usage: core::ImageUsageFlags, flags: core::ImageCreateFlags, external_handle_type: nv_external_memory_capabilities::ExternalMemoryHandleTypeFlagsNv) -> Result<nv_external_memory_capabilities::ExternalImageFormatPropertiesNv, core::Error> {
622        let mut properties = unsafe { mem::uninitialized() };
623
624        let res = unsafe {
625            self.loader().nv_external_memory_capabilities.vkGetPhysicalDeviceExternalImageFormatPropertiesNV(self.handle, format.into(), image_type.into(), tiling.into(), usage.bits(), flags.bits(), external_handle_type.bits(), &mut properties)
626        };
627
628        if res == vks::core::VK_SUCCESS {
629            Ok((&properties).into())
630        }
631        else {
632            Err(res.into())
633        }
634    }
635}