1use 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#[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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 #[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 #[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 #[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 #[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 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 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 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 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 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 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 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 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 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}