From 315b1b9c2a2698dd67992d9d78859738563a9612 Mon Sep 17 00:00:00 2001 From: Rua Date: Tue, 31 May 2022 14:52:18 +0200 Subject: [PATCH] Fix #1881 --- vulkano/src/device/physical.rs | 226 ++++++++++++++++------------- vulkano/src/instance/extensions.rs | 63 ++++---- vulkano/src/instance/layers.rs | 43 +++--- vulkano/src/pipeline/cache.rs | 49 ++++--- vulkano/src/swapchain/display.rs | 197 +++++++++++++------------ vulkano/src/swapchain/swapchain.rs | 23 +-- 6 files changed, 331 insertions(+), 270 deletions(-) diff --git a/vulkano/src/device/physical.rs b/vulkano/src/device/physical.rs index e4f29f2772..5b143923ca 100644 --- a/vulkano/src/device/physical.rs +++ b/vulkano/src/device/physical.rs @@ -19,7 +19,7 @@ use crate::{ SurfaceApi, SurfaceCapabilities, SurfaceInfo, }, sync::{ExternalSemaphoreInfo, ExternalSemaphoreProperties, PipelineStage}, - DeviceSize, Error, OomError, Version, VulkanObject, + DeviceSize, Error, OomError, Success, Version, VulkanObject, }; use std::{error, ffi::CStr, fmt, hash::Hash, mem::MaybeUninit, ptr, sync::Arc}; @@ -41,22 +41,27 @@ pub(crate) fn init_physical_devices( let fns = instance.fns(); let instance_extensions = instance.enabled_extensions(); - let handles: Vec = unsafe { - let mut num = 0; - check_errors((fns.v1_0.enumerate_physical_devices)( - instance.internal_object(), - &mut num, - ptr::null_mut(), - ))?; + let handles = unsafe { + loop { + let mut count = 0; + check_errors((fns.v1_0.enumerate_physical_devices)( + instance.internal_object(), + &mut count, + ptr::null_mut(), + ))?; - let mut handles = Vec::with_capacity(num as usize); - check_errors((fns.v1_0.enumerate_physical_devices)( - instance.internal_object(), - &mut num, - handles.as_mut_ptr(), - ))?; - handles.set_len(num as usize); - handles + let mut handles = Vec::with_capacity(count as usize); + let result = check_errors((fns.v1_0.enumerate_physical_devices)( + instance.internal_object(), + &mut count, + handles.as_mut_ptr(), + ))?; + + if !matches!(result, Success::Incomplete) { + handles.set_len(count as usize); + break handles; + } + } }; Ok(handles @@ -70,24 +75,29 @@ pub(crate) fn init_physical_devices( std::cmp::min(instance.max_api_version(), api_version) }; - let extension_properties: Vec = unsafe { - let mut num = 0; - check_errors((fns.v1_0.enumerate_device_extension_properties)( - handle, - ptr::null(), - &mut num, - ptr::null_mut(), - ))?; - - let mut properties = Vec::with_capacity(num as usize); - check_errors((fns.v1_0.enumerate_device_extension_properties)( - handle, - ptr::null(), - &mut num, - properties.as_mut_ptr(), - ))?; - properties.set_len(num as usize); - properties + let extension_properties = unsafe { + loop { + let mut count = 0; + check_errors((fns.v1_0.enumerate_device_extension_properties)( + handle, + ptr::null(), + &mut count, + ptr::null_mut(), + ))?; + + let mut properties = Vec::with_capacity(count as usize); + let result = check_errors((fns.v1_0.enumerate_device_extension_properties)( + handle, + ptr::null(), + &mut count, + properties.as_mut_ptr(), + ))?; + + if !matches!(result, Success::Incomplete) { + properties.set_len(count as usize); + break properties; + } + } }; let supported_extensions = DeviceExtensions::from( @@ -1163,31 +1173,37 @@ impl<'a> PhysicalDevice<'a> { surface_full_screen_exclusive_win32_info as *const _ as *const _; } - let mut surface_format2s; - - unsafe { - let fns = self.instance.fns(); - - let mut num = 0; - check_errors((fns - .khr_get_surface_capabilities2 - .get_physical_device_surface_formats2_khr)( - self.internal_object(), - &surface_info2, - &mut num, - ptr::null_mut(), - ))?; + let fns = self.instance.fns(); - surface_format2s = vec![ash::vk::SurfaceFormat2KHR::default(); num as usize]; - check_errors((fns - .khr_get_surface_capabilities2 - .get_physical_device_surface_formats2_khr)( - self.internal_object(), - &surface_info2, - &mut num, - surface_format2s.as_mut_ptr(), - ))?; - } + let surface_format2s = unsafe { + loop { + let mut count = 0; + check_errors((fns + .khr_get_surface_capabilities2 + .get_physical_device_surface_formats2_khr)( + self.internal_object(), + &surface_info2, + &mut count, + ptr::null_mut(), + ))?; + + let mut surface_format2s = + vec![ash::vk::SurfaceFormat2KHR::default(); count as usize]; + let result = check_errors((fns + .khr_get_surface_capabilities2 + .get_physical_device_surface_formats2_khr)( + self.internal_object(), + &surface_info2, + &mut count, + surface_format2s.as_mut_ptr(), + ))?; + + if !matches!(result, Success::Incomplete) { + surface_format2s.set_len(count as usize); + break surface_format2s; + } + } + }; Ok(surface_format2s .into_iter() @@ -1201,28 +1217,33 @@ impl<'a> PhysicalDevice<'a> { return Ok(Vec::new()); } - let mut surface_formats; - - unsafe { - let fns = self.instance.fns(); - - let mut num = 0; - check_errors((fns.khr_surface.get_physical_device_surface_formats_khr)( - self.internal_object(), - surface.internal_object(), - &mut num, - ptr::null_mut(), - ))?; + let fns = self.instance.fns(); - surface_formats = Vec::with_capacity(num as usize); - check_errors((fns.khr_surface.get_physical_device_surface_formats_khr)( - self.internal_object(), - surface.internal_object(), - &mut num, - surface_formats.as_mut_ptr(), - ))?; - surface_formats.set_len(num as usize); - } + let surface_formats = unsafe { + loop { + let mut count = 0; + check_errors((fns.khr_surface.get_physical_device_surface_formats_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + ptr::null_mut(), + ))?; + + let mut surface_formats = Vec::with_capacity(count as usize); + let result = + check_errors((fns.khr_surface.get_physical_device_surface_formats_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + surface_formats.as_mut_ptr(), + ))?; + + if !matches!(result, Success::Incomplete) { + surface_formats.set_len(count as usize); + break surface_formats; + } + } + }; Ok(surface_formats .into_iter() @@ -1248,30 +1269,35 @@ impl<'a> PhysicalDevice<'a> { surface.instance().internal_object(), ); + let fns = self.instance.fns(); + let modes = unsafe { - let fns = self.instance.fns(); + loop { + let mut count = 0; + check_errors((fns + .khr_surface + .get_physical_device_surface_present_modes_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + ptr::null_mut(), + ))?; - let mut num = 0; - check_errors((fns - .khr_surface - .get_physical_device_surface_present_modes_khr)( - self.internal_object(), - surface.internal_object(), - &mut num, - ptr::null_mut(), - ))?; + let mut modes = Vec::with_capacity(count as usize); + let result = check_errors((fns + .khr_surface + .get_physical_device_surface_present_modes_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + modes.as_mut_ptr(), + ))?; - let mut modes = Vec::with_capacity(num as usize); - check_errors((fns - .khr_surface - .get_physical_device_surface_present_modes_khr)( - self.internal_object(), - surface.internal_object(), - &mut num, - modes.as_mut_ptr(), - ))?; - modes.set_len(num as usize); - modes + if !matches!(result, Success::Incomplete) { + modes.set_len(count as usize); + break modes; + } + } }; debug_assert!(modes.len() > 0); diff --git a/vulkano/src/instance/extensions.rs b/vulkano/src/instance/extensions.rs index ee99cd133f..42b6804748 100644 --- a/vulkano/src/instance/extensions.rs +++ b/vulkano/src/instance/extensions.rs @@ -7,16 +7,20 @@ // notice may not be copied, modified, or distributed except // according to those terms. -use crate::check_errors; -pub use crate::extensions::{ - ExtensionRestriction, ExtensionRestrictionError, OneOfRequirements, SupportedExtensionsError, +use super::{loader, LoadingError}; +use crate::{check_errors, Success}; +pub use crate::{ + extensions::{ + ExtensionRestriction, ExtensionRestrictionError, OneOfRequirements, + SupportedExtensionsError, + }, + Version, +}; +use std::{ + ffi::{CStr, CString}, + fmt::Formatter, + ptr, }; -use crate::instance::loader; -use crate::instance::loader::LoadingError; -use crate::Version; -use std::ffi::{CStr, CString}; -use std::fmt::Formatter; -use std::ptr; // Generated by build.rs include!(concat!(env!("OUT_DIR"), "/instance_extensions.rs")); @@ -59,27 +63,32 @@ impl InstanceExtensions { { let fns = ptrs.fns(); - let properties: Vec = unsafe { - let mut num = 0; - check_errors((fns.v1_0.enumerate_instance_extension_properties)( - ptr::null(), - &mut num, - ptr::null_mut(), - ))?; + let extension_properties = unsafe { + loop { + let mut count = 0; + check_errors((fns.v1_0.enumerate_instance_extension_properties)( + ptr::null(), + &mut count, + ptr::null_mut(), + ))?; + + let mut properties = Vec::with_capacity(count as usize); + let result = check_errors((fns.v1_0.enumerate_instance_extension_properties)( + ptr::null(), + &mut count, + properties.as_mut_ptr(), + ))?; - let mut properties = Vec::with_capacity(num as usize); - check_errors((fns.v1_0.enumerate_instance_extension_properties)( - ptr::null(), - &mut num, - properties.as_mut_ptr(), - ))?; - properties.set_len(num as usize); - properties + if !matches!(result, Success::Incomplete) { + properties.set_len(count as usize); + break properties; + } + } }; - Ok(Self::from(properties.iter().map(|property| unsafe { - CStr::from_ptr(property.extension_name.as_ptr()) - }))) + Ok(Self::from(extension_properties.iter().map( + |property| unsafe { CStr::from_ptr(property.extension_name.as_ptr()) }, + ))) } } diff --git a/vulkano/src/instance/layers.rs b/vulkano/src/instance/layers.rs index bac9b51fe4..905b8ec173 100644 --- a/vulkano/src/instance/layers.rs +++ b/vulkano/src/instance/layers.rs @@ -12,6 +12,7 @@ use crate::instance::loader; use crate::instance::loader::LoadingError; use crate::Error; use crate::OomError; +use crate::Success; use crate::Version; use std::error; use std::ffi::CStr; @@ -52,23 +53,31 @@ pub fn layers_list_from_loader( where L: loader::Loader, { - unsafe { - let fns = ptrs.fns(); - - let mut num = 0; - check_errors((fns.v1_0.enumerate_instance_layer_properties)( - &mut num, - ptr::null_mut(), - ))?; - - let mut layers: Vec = Vec::with_capacity(num as usize); - check_errors({ - (fns.v1_0.enumerate_instance_layer_properties)(&mut num, layers.as_mut_ptr()) - })?; - layers.set_len(num as usize); - - Ok(layers.into_iter().map(|p| LayerProperties { props: p })) - } + let fns = ptrs.fns(); + + let layer_properties = unsafe { + loop { + let mut count = 0; + check_errors((fns.v1_0.enumerate_instance_layer_properties)( + &mut count, + ptr::null_mut(), + ))?; + + let mut properties = Vec::with_capacity(count as usize); + let result = check_errors({ + (fns.v1_0.enumerate_instance_layer_properties)(&mut count, properties.as_mut_ptr()) + })?; + + if !matches!(result, Success::Incomplete) { + properties.set_len(count as usize); + break properties; + } + } + }; + + Ok(layer_properties + .into_iter() + .map(|p| LayerProperties { props: p })) } /// Properties of a layer. diff --git a/vulkano/src/pipeline/cache.rs b/vulkano/src/pipeline/cache.rs index 07582a7541..b732c6b368 100644 --- a/vulkano/src/pipeline/cache.rs +++ b/vulkano/src/pipeline/cache.rs @@ -24,6 +24,7 @@ use crate::check_errors; use crate::device::Device; use crate::OomError; +use crate::Success; use crate::VulkanObject; use std::mem::MaybeUninit; use std::ptr; @@ -199,28 +200,34 @@ impl PipelineCache { /// } /// ``` pub fn get_data(&self) -> Result, OomError> { - unsafe { - let fns = self.device.fns(); - - let mut num = 0; - check_errors((fns.v1_0.get_pipeline_cache_data)( - self.device.internal_object(), - self.cache, - &mut num, - ptr::null_mut(), - ))?; - - let mut data: Vec = Vec::with_capacity(num as usize); - check_errors((fns.v1_0.get_pipeline_cache_data)( - self.device.internal_object(), - self.cache, - &mut num, - data.as_mut_ptr() as *mut _, - ))?; - data.set_len(num as usize); + let fns = self.device.fns(); + + let data = unsafe { + loop { + let mut count = 0; + check_errors((fns.v1_0.get_pipeline_cache_data)( + self.device.internal_object(), + self.cache, + &mut count, + ptr::null_mut(), + ))?; + + let mut data: Vec = Vec::with_capacity(count as usize); + let result = check_errors((fns.v1_0.get_pipeline_cache_data)( + self.device.internal_object(), + self.cache, + &mut count, + data.as_mut_ptr() as *mut _, + ))?; + + if !matches!(result, Success::Incomplete) { + data.set_len(count as usize); + break data; + } + } + }; - Ok(data) - } + Ok(data) } } diff --git a/vulkano/src/swapchain/display.rs b/vulkano/src/swapchain/display.rs index 9af4c659bd..ce1a8fb96a 100644 --- a/vulkano/src/swapchain/display.rs +++ b/vulkano/src/swapchain/display.rs @@ -33,6 +33,7 @@ use crate::device::physical::PhysicalDevice; use crate::instance::Instance; use crate::swapchain::SupportedSurfaceTransforms; use crate::OomError; +use crate::Success; use crate::VulkanObject; use std::ffi::CStr; use std::fmt::Formatter; @@ -60,60 +61,64 @@ impl DisplayPlane { assert!(device.instance().enabled_extensions().khr_display); // TODO: return error instead - let num = unsafe { - let mut num: u32 = 0; - check_errors((fns - .khr_display - .get_physical_device_display_plane_properties_khr)( - device.internal_object(), - &mut num, - ptr::null_mut(), - ))?; - num - }; + let display_plane_properties = unsafe { + loop { + let mut count = 0; + check_errors((fns + .khr_display + .get_physical_device_display_plane_properties_khr)( + device.internal_object(), + &mut count, + ptr::null_mut(), + ))?; - let planes: Vec = unsafe { - let mut planes = Vec::with_capacity(num as usize); - let mut num = num; - check_errors((fns - .khr_display - .get_physical_device_display_plane_properties_khr)( - device.internal_object(), - &mut num, - planes.as_mut_ptr(), - ))?; - planes.set_len(num as usize); - planes + let mut properties = Vec::with_capacity(count as usize); + let result = check_errors((fns + .khr_display + .get_physical_device_display_plane_properties_khr)( + device.internal_object(), + &mut count, + properties.as_mut_ptr(), + ))?; + + if !matches!(result, Success::Incomplete) { + properties.set_len(count as usize); + break properties; + } + } }; - Ok(planes + Ok(display_plane_properties .into_iter() .enumerate() .map(|(index, prop)| { - let num = unsafe { - let mut num: u32 = 0; - check_errors((fns.khr_display.get_display_plane_supported_displays_khr)( - device.internal_object(), - index as u32, - &mut num, - ptr::null_mut(), - )) - .unwrap(); // TODO: shouldn't unwrap - num - }; - - let supported_displays: Vec = unsafe { - let mut displays = Vec::with_capacity(num as usize); - let mut num = num; - check_errors((fns.khr_display.get_display_plane_supported_displays_khr)( - device.internal_object(), - index as u32, - &mut num, - displays.as_mut_ptr(), - )) - .unwrap(); // TODO: shouldn't unwrap - displays.set_len(num as usize); - displays + let supported_displays = unsafe { + loop { + let mut count = 0; + check_errors((fns.khr_display.get_display_plane_supported_displays_khr)( + device.internal_object(), + index as u32, + &mut count, + ptr::null_mut(), + )) + .unwrap(); // TODO: shouldn't unwrap + + let mut displays = Vec::with_capacity(count as usize); + let result = check_errors((fns + .khr_display + .get_display_plane_supported_displays_khr)( + device.internal_object(), + index as u32, + &mut count, + displays.as_mut_ptr(), + )) + .unwrap(); // TODO: shouldn't unwrap + + if !matches!(result, Success::Incomplete) { + displays.set_len(count as usize); + break displays; + } + } }; DisplayPlane { @@ -121,7 +126,7 @@ impl DisplayPlane { physical_device: device.index(), index: index as u32, properties: prop, - supported_displays: supported_displays, + supported_displays, } }) .collect::>() @@ -182,33 +187,34 @@ impl Display { let fns = device.instance().fns(); assert!(device.instance().enabled_extensions().khr_display); // TODO: return error instead - let num = unsafe { - let mut num = 0; - check_errors( - (fns.khr_display.get_physical_device_display_properties_khr)( - device.internal_object(), - &mut num, - ptr::null_mut(), - ), - )?; - num - }; + let display_properties = unsafe { + loop { + let mut count = 0; + check_errors( + (fns.khr_display.get_physical_device_display_properties_khr)( + device.internal_object(), + &mut count, + ptr::null_mut(), + ), + )?; - let displays: Vec = unsafe { - let mut displays = Vec::with_capacity(num as usize); - let mut num = num; - check_errors( - (fns.khr_display.get_physical_device_display_properties_khr)( + let mut properties = Vec::with_capacity(count as usize); + let result = check_errors((fns + .khr_display + .get_physical_device_display_properties_khr)( device.internal_object(), - &mut num, - displays.as_mut_ptr(), - ), - )?; - displays.set_len(num as usize); - displays + &mut count, + properties.as_mut_ptr(), + ))?; + + if !matches!(result, Success::Incomplete) { + properties.set_len(count as usize); + break properties; + } + } }; - Ok(displays + Ok(display_properties .into_iter() .map(|prop| Display { instance: device.instance().clone(), @@ -286,31 +292,32 @@ impl Display { pub fn display_modes_raw(&self) -> Result, OomError> { let fns = self.instance.fns(); - let num = unsafe { - let mut num = 0; - check_errors((fns.khr_display.get_display_mode_properties_khr)( - self.physical_device().internal_object(), - self.properties.display, - &mut num, - ptr::null_mut(), - ))?; - num - }; - - let modes: Vec = unsafe { - let mut modes = Vec::with_capacity(num as usize); - let mut num = num; - check_errors((fns.khr_display.get_display_mode_properties_khr)( - self.physical_device().internal_object(), - self.properties.display, - &mut num, - modes.as_mut_ptr(), - ))?; - modes.set_len(num as usize); - modes + let mode_properties = unsafe { + loop { + let mut count = 0; + check_errors((fns.khr_display.get_display_mode_properties_khr)( + self.physical_device().internal_object(), + self.properties.display, + &mut count, + ptr::null_mut(), + ))?; + + let mut properties = Vec::with_capacity(count as usize); + let result = check_errors((fns.khr_display.get_display_mode_properties_khr)( + self.physical_device().internal_object(), + self.properties.display, + &mut count, + properties.as_mut_ptr(), + ))?; + + if !matches!(result, Success::Incomplete) { + properties.set_len(count as usize); + break properties; + } + } }; - Ok(modes + Ok(mode_properties .into_iter() .map(|mode| DisplayMode { display: self.clone(), diff --git a/vulkano/src/swapchain/swapchain.rs b/vulkano/src/swapchain/swapchain.rs index a21fa59f15..5ac7712155 100644 --- a/vulkano/src/swapchain/swapchain.rs +++ b/vulkano/src/swapchain/swapchain.rs @@ -577,8 +577,9 @@ impl Swapchain { create_info.p_next = surface_full_screen_exclusive_win32_info as *const _ as *const _; } + let fns = device.fns(); + let handle = { - let fns = device.fns(); let mut output = MaybeUninit::uninit(); check_errors((fns.khr_swapchain.create_swapchain_khr)( device.internal_object(), @@ -589,25 +590,27 @@ impl Swapchain { output.assume_init() }; - let image_handles = { - let fns = device.fns(); - let mut num = 0; + let image_handles = loop { + let mut count = 0; check_errors((fns.khr_swapchain.get_swapchain_images_khr)( device.internal_object(), handle, - &mut num, + &mut count, ptr::null_mut(), ))?; - let mut images = Vec::with_capacity(num as usize); - check_errors((fns.khr_swapchain.get_swapchain_images_khr)( + let mut images = Vec::with_capacity(count as usize); + let result = check_errors((fns.khr_swapchain.get_swapchain_images_khr)( device.internal_object(), handle, - &mut num, + &mut count, images.as_mut_ptr(), ))?; - images.set_len(num as usize); - images + + if !matches!(result, Success::Incomplete) { + images.set_len(count as usize); + break images; + } }; Ok((handle, image_handles))