diff options
Diffstat (limited to 'src/swapchain/display.rs')
-rw-r--r-- | src/swapchain/display.rs | 332 |
1 files changed, 176 insertions, 156 deletions
diff --git a/src/swapchain/display.rs b/src/swapchain/display.rs index 67f135e..09517bd 100644 --- a/src/swapchain/display.rs +++ b/src/swapchain/display.rs @@ -22,23 +22,23 @@ //! rate. You can enumerate the modes available on a display with `Display::display_modes`, or //! attempt to create your own mode with `TODO`. //! - Choose a `DisplayPlane`. A display can show multiple planes in a stacking fashion. -//! - Create a `Surface` object with `Surface::from_display_mode` and pass the chosen `DisplayMode` +//! - Create a `Surface` object with `Surface::from_display_plane` and pass the chosen `DisplayMode` //! and `DisplayPlane`. #![allow(dead_code)] // TODO: this module isn't finished #![allow(unused_variables)] // TODO: this module isn't finished -use crate::check_errors; -use crate::device::physical::PhysicalDevice; -use crate::instance::Instance; -use crate::swapchain::SupportedSurfaceTransforms; -use crate::OomError; -use crate::VulkanObject; -use std::ffi::CStr; -use std::fmt::Formatter; -use std::sync::Arc; -use std::vec::IntoIter; -use std::{fmt, ptr}; +use crate::{ + device::physical::PhysicalDevice, swapchain::SurfaceTransforms, OomError, VulkanError, + VulkanObject, +}; +use std::{ + ffi::CStr, + fmt::{Display as FmtDisplay, Error as FmtError, Formatter}, + ptr, + sync::Arc, + vec::IntoIter, +}; // TODO: extract this to a `display` module and solve the visibility problems @@ -46,8 +46,7 @@ use std::{fmt, ptr}; // TODO: plane capabilities // TODO: store properties in the instance? pub struct DisplayPlane { - instance: Arc<Instance>, - physical_device: usize, + physical_device: Arc<PhysicalDevice>, index: u32, properties: ash::vk::DisplayPlanePropertiesKHR, supported_displays: Vec<ash::vk::DisplayKHR>, @@ -55,75 +54,86 @@ pub struct DisplayPlane { impl DisplayPlane { /// See the docs of enumerate(). - pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<DisplayPlane>, OomError> { - let fns = device.instance().fns(); - - 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 planes: Vec<ash::vk::DisplayPlanePropertiesKHR> = 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 + pub fn enumerate_raw( + physical_device: Arc<PhysicalDevice>, + ) -> Result<IntoIter<DisplayPlane>, OomError> { + let fns = physical_device.instance().fns(); + + assert!(physical_device.instance().enabled_extensions().khr_display); // TODO: return error instead + + let display_plane_properties = unsafe { + loop { + let mut count = 0; + (fns.khr_display + .get_physical_device_display_plane_properties_khr)( + physical_device.handle(), + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from)?; + + let mut properties = Vec::with_capacity(count as usize); + let result = (fns + .khr_display + .get_physical_device_display_plane_properties_khr)( + physical_device.handle(), + &mut count, + properties.as_mut_ptr(), + ); + + match result { + ash::vk::Result::SUCCESS => { + properties.set_len(count as usize); + break properties; + } + ash::vk::Result::INCOMPLETE => (), + err => return Err(VulkanError::from(err).into()), + } + } }; - 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<ash::vk::DisplayKHR> = 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; + (fns.khr_display.get_display_plane_supported_displays_khr)( + physical_device.handle(), + index as u32, + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from) + .unwrap(); // TODO: shouldn't unwrap + + let mut displays = Vec::with_capacity(count as usize); + let result = (fns.khr_display.get_display_plane_supported_displays_khr)( + physical_device.handle(), + index as u32, + &mut count, + displays.as_mut_ptr(), + ); + + match result { + ash::vk::Result::SUCCESS => { + displays.set_len(count as usize); + break displays; + } + ash::vk::Result::INCOMPLETE => (), + err => todo!(), // TODO: shouldn't panic + } + } }; DisplayPlane { - instance: device.instance().clone(), - physical_device: device.index(), + physical_device: physical_device.clone(), index: index as u32, properties: prop, - supported_displays: supported_displays, + supported_displays, } }) .collect::<Vec<_>>() @@ -132,20 +142,19 @@ impl DisplayPlane { /// Enumerates all the display planes that are available on a given physical device. /// - /// # Panic + /// # Panics /// /// - Panics if the device or host ran out of memory. - /// // TODO: move iterator creation here from raw constructor? #[inline] - pub fn enumerate(device: PhysicalDevice) -> IntoIter<DisplayPlane> { - DisplayPlane::enumerate_raw(device).unwrap() + pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<DisplayPlane> { + DisplayPlane::enumerate_raw(physical_device).unwrap() } /// Returns the physical device that was used to create this display. #[inline] - pub fn physical_device(&self) -> PhysicalDevice { - PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap() + pub fn physical_device(&self) -> &Arc<PhysicalDevice> { + &self.physical_device } /// Returns the index of the plane. @@ -158,14 +167,13 @@ impl DisplayPlane { #[inline] pub fn supports(&self, display: &Display) -> bool { // making sure that the physical device is the same - if self.physical_device().internal_object() != display.physical_device().internal_object() { + if self.physical_device().handle() != display.physical_device().handle() { return false; } self.supported_displays .iter() - .find(|&&d| d == display.internal_object()) - .is_some() + .any(|&d| d == display.handle()) } } @@ -173,44 +181,51 @@ impl DisplayPlane { // TODO: store properties in the instance? #[derive(Clone)] pub struct Display { - instance: Arc<Instance>, - physical_device: usize, + physical_device: Arc<PhysicalDevice>, properties: Arc<ash::vk::DisplayPropertiesKHR>, // TODO: Arc because struct isn't clone } impl Display { /// See the docs of enumerate(). - pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<Display>, OomError> { - 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 displays: Vec<ash::vk::DisplayPropertiesKHR> = 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( - device.internal_object(), - &mut num, - displays.as_mut_ptr(), - ))?; - displays.set_len(num as usize); - displays + pub fn enumerate_raw( + physical_device: Arc<PhysicalDevice>, + ) -> Result<IntoIter<Display>, OomError> { + let fns = physical_device.instance().fns(); + assert!(physical_device.instance().enabled_extensions().khr_display); // TODO: return error instead + + let display_properties = unsafe { + loop { + let mut count = 0; + (fns.khr_display.get_physical_device_display_properties_khr)( + physical_device.handle(), + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from)?; + + let mut properties = Vec::with_capacity(count as usize); + let result = (fns.khr_display.get_physical_device_display_properties_khr)( + physical_device.handle(), + &mut count, + properties.as_mut_ptr(), + ); + + match result { + ash::vk::Result::SUCCESS => { + properties.set_len(count as usize); + break properties; + } + ash::vk::Result::INCOMPLETE => (), + err => return Err(VulkanError::from(err).into()), + } + } }; - Ok(displays + Ok(display_properties .into_iter() .map(|prop| Display { - instance: device.instance().clone(), - physical_device: device.index(), + physical_device: physical_device.clone(), properties: Arc::new(prop), }) .collect::<Vec<_>>() @@ -219,14 +234,13 @@ impl Display { /// Enumerates all the displays that are available on a given physical device. /// - /// # Panic + /// # Panics /// /// - Panics if the device or host ran out of memory. - /// // TODO: move iterator creation here from raw constructor? #[inline] - pub fn enumerate(device: PhysicalDevice) -> IntoIter<Display> { - Display::enumerate_raw(device).unwrap() + pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<Display> { + Display::enumerate_raw(physical_device).unwrap() } /// Returns the name of the display. @@ -241,14 +255,14 @@ impl Display { /// Returns the physical device that was used to create this display. #[inline] - pub fn physical_device(&self) -> PhysicalDevice { - PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap() + pub fn physical_device(&self) -> &Arc<PhysicalDevice> { + &self.physical_device } /// Returns the physical dimensions of the display in millimeters. #[inline] pub fn physical_dimensions(&self) -> [u32; 2] { - let ref r = self.properties.physical_dimensions; + let r = &self.properties.physical_dimensions; [r.width, r.height] } @@ -258,13 +272,13 @@ impl Display { /// > only the "best" resolution. #[inline] pub fn physical_resolution(&self) -> [u32; 2] { - let ref r = self.properties.physical_resolution; + let r = &self.properties.physical_resolution; [r.width, r.height] } /// Returns the transforms supported by this display. #[inline] - pub fn supported_transforms(&self) -> SupportedSurfaceTransforms { + pub fn supported_transforms(&self) -> SurfaceTransforms { self.properties.supported_transforms.into() } @@ -282,33 +296,40 @@ impl Display { /// See the docs of display_modes(). pub fn display_modes_raw(&self) -> Result<IntoIter<DisplayMode>, 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<ash::vk::DisplayModePropertiesKHR> = 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 fns = self.physical_device.instance().fns(); + + let mode_properties = unsafe { + loop { + let mut count = 0; + (fns.khr_display.get_display_mode_properties_khr)( + self.physical_device().handle(), + self.properties.display, + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from)?; + + let mut properties = Vec::with_capacity(count as usize); + let result = (fns.khr_display.get_display_mode_properties_khr)( + self.physical_device().handle(), + self.properties.display, + &mut count, + properties.as_mut_ptr(), + ); + + match result { + ash::vk::Result::SUCCESS => { + properties.set_len(count as usize); + break properties; + } + ash::vk::Result::INCOMPLETE => (), + err => return Err(VulkanError::from(err).into()), + } + } }; - Ok(modes + Ok(mode_properties .into_iter() .map(|mode| DisplayMode { display: self.clone(), @@ -321,10 +342,9 @@ impl Display { /// Returns a list of all modes available on this display. /// - /// # Panic + /// # Panics /// /// - Panics if the device or host ran out of memory. - /// // TODO: move iterator creation here from display_modes_raw? #[inline] pub fn display_modes(&self) -> IntoIter<DisplayMode> { @@ -333,10 +353,10 @@ impl Display { } unsafe impl VulkanObject for Display { - type Object = ash::vk::DisplayKHR; + type Handle = ash::vk::DisplayKHR; #[inline] - fn internal_object(&self) -> ash::vk::DisplayKHR { + fn handle(&self) -> Self::Handle { self.properties.display } } @@ -368,9 +388,9 @@ impl DisplayMode { }; let mut output = mem::uninitialized(); - check_errors(fns.v1_0.CreateDisplayModeKHR(display.device.internal_object(), + (fns.v1_0.CreateDisplayModeKHR)(display.device.handle(), display.display, &infos, ptr::null(), - &mut output))?; + &mut output).result().map_err(VulkanError::from)?; output }; @@ -390,7 +410,7 @@ impl DisplayMode { /// Returns the dimensions of the region that is visible on the monitor. #[inline] pub fn visible_region(&self) -> [u32; 2] { - let ref d = self.parameters.visible_region; + let d = &self.parameters.visible_region; [d.width, d.height] } @@ -404,9 +424,9 @@ impl DisplayMode { } } -impl fmt::Display for DisplayMode { +impl FmtDisplay for DisplayMode { #[inline] - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { let visible_region = self.visible_region(); write!( @@ -421,10 +441,10 @@ impl fmt::Display for DisplayMode { } unsafe impl VulkanObject for DisplayMode { - type Object = ash::vk::DisplayModeKHR; + type Handle = ash::vk::DisplayModeKHR; #[inline] - fn internal_object(&self) -> ash::vk::DisplayModeKHR { + fn handle(&self) -> Self::Handle { self.display_mode } } |