aboutsummaryrefslogtreecommitdiff
path: root/src/swapchain/display.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/swapchain/display.rs')
-rw-r--r--src/swapchain/display.rs332
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
}
}