From 9a32bd1baac6af60bd2b20a2f0f64b1ba943aa3b Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 18 Nov 2016 08:47:26 +0100 Subject: [PATCH 1/3] Add more getters for Display --- vulkano/src/swapchain/display.rs | 37 ++++++++++- vulkano/src/swapchain/mod.rs | 108 +++++++++++++++++++++++++++++++ vulkano/src/swapchain/surface.rs | 108 +------------------------------ 3 files changed, 143 insertions(+), 110 deletions(-) diff --git a/vulkano/src/swapchain/display.rs b/vulkano/src/swapchain/display.rs index 5773c592..61892e7a 100644 --- a/vulkano/src/swapchain/display.rs +++ b/vulkano/src/swapchain/display.rs @@ -22,6 +22,7 @@ use std::vec::IntoIter; use instance::Instance; use instance::PhysicalDevice; +use swapchain::SupportedSurfaceTransforms; use check_errors; use OomError; @@ -124,6 +125,7 @@ impl DisplayPlane { } /// Represents a monitor connected to a physical device. +// TODO: store properties in the instance? #[derive(Clone)] pub struct Display { instance: Arc, @@ -179,8 +181,9 @@ impl Display { #[inline] pub fn name(&self) -> &str { unsafe { - CStr::from_ptr(self.properties.displayName).to_str() - .expect("non UTF-8 characters in display name") + CStr::from_ptr(self.properties.displayName) + .to_str() + .expect("non UTF-8 characters in display name") } } @@ -190,13 +193,41 @@ impl Display { PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap() } - /// Returns the physical resolution of the display. + /// Returns the physical dimensions of the display in millimeters. + #[inline] + pub fn physical_dimensions(&self) -> [u32; 2] { + let ref r = self.properties.physicalDimensions; + [r.width, r.height] + } + + /// Returns the physical, native, or preferred resolution of the display. + /// + /// > **Note**: The display is usually still capable of displaying other resolutions. This is + /// > only the "best" resolution. #[inline] pub fn physical_resolution(&self) -> [u32; 2] { let ref r = self.properties.physicalResolution; [r.width, r.height] } + /// Returns the transforms supported by this display. + #[inline] + pub fn supported_transforms(&self) -> SupportedSurfaceTransforms { + SupportedSurfaceTransforms::from_bits(self.properties.supportedTransforms) + } + + /// Returns true if TODO. + #[inline] + pub fn plane_reorder_possible(&self) -> bool { + self.properties.planeReorderPossible != 0 + } + + /// Returns true if TODO. + #[inline] + pub fn persistent_content(&self) -> bool { + self.properties.persistentContent != 0 + } + /// See the docs of display_modes(). pub fn display_modes_raw(&self) -> Result, OomError> { let vk = self.instance.pointers(); diff --git a/vulkano/src/swapchain/mod.rs b/vulkano/src/swapchain/mod.rs index 66ec6e9c..42e1b2ae 100644 --- a/vulkano/src/swapchain/mod.rs +++ b/vulkano/src/swapchain/mod.rs @@ -188,6 +188,7 @@ //! use std::sync::atomic::AtomicBool; +use vk; pub use self::surface::Capabilities; pub use self::surface::Surface; @@ -204,6 +205,113 @@ pub mod display; mod surface; mod swapchain; +/// List of supported composite alpha modes. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct SupportedSurfaceTransforms { + pub identity: bool, + pub rotate90: bool, + pub rotate180: bool, + pub rotate270: bool, + pub horizontal_mirror: bool, + pub horizontal_mirror_rotate90: bool, + pub horizontal_mirror_rotate180: bool, + pub horizontal_mirror_rotate270: bool, + pub inherit: bool, +} + +impl SupportedSurfaceTransforms { + /// Builds a `SupportedSurfaceTransforms` with all fields set to false. + #[inline] + pub fn none() -> SupportedSurfaceTransforms { + SupportedSurfaceTransforms { + identity: false, + rotate90: false, + rotate180: false, + rotate270: false, + horizontal_mirror: false, + horizontal_mirror_rotate90: false, + horizontal_mirror_rotate180: false, + horizontal_mirror_rotate270: false, + inherit: false, + } + } + + #[inline] + fn from_bits(val: vk::SurfaceTransformFlagsKHR) -> SupportedSurfaceTransforms { + macro_rules! v { + ($val:expr, $out:ident, $e:expr, $f:ident) => ( + if ($val & $e) != 0 { $out.$f = true; } + ); + } + + let mut result = SupportedSurfaceTransforms::none(); + v!(val, result, vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR, identity); + v!(val, result, vk::SURFACE_TRANSFORM_ROTATE_90_BIT_KHR, rotate90); + v!(val, result, vk::SURFACE_TRANSFORM_ROTATE_180_BIT_KHR, rotate180); + v!(val, result, vk::SURFACE_TRANSFORM_ROTATE_270_BIT_KHR, rotate270); + v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR, horizontal_mirror); + v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR, + horizontal_mirror_rotate90); + v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR, + horizontal_mirror_rotate180); + v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR, + horizontal_mirror_rotate270); + v!(val, result, vk::SURFACE_TRANSFORM_INHERIT_BIT_KHR, inherit); + result + } + + /// Returns true if the given `SurfaceTransform` is in this list. + #[inline] + pub fn supports(&self, value: SurfaceTransform) -> bool { + match value { + SurfaceTransform::Identity => self.identity, + SurfaceTransform::Rotate90 => self.rotate90, + SurfaceTransform::Rotate180 => self.rotate180, + SurfaceTransform::Rotate270 => self.rotate270, + SurfaceTransform::HorizontalMirror => self.horizontal_mirror, + SurfaceTransform::HorizontalMirrorRotate90 => self.horizontal_mirror_rotate90, + SurfaceTransform::HorizontalMirrorRotate180 => self.horizontal_mirror_rotate180, + SurfaceTransform::HorizontalMirrorRotate270 => self.horizontal_mirror_rotate270, + SurfaceTransform::Inherit => self.inherit, + } + } + + /// Returns an iterator to the list of supported composite alpha. + #[inline] + pub fn iter(&self) -> SupportedSurfaceTransformsIter { + SupportedSurfaceTransformsIter(self.clone()) + } +} + +/// Enumeration of the `SurfaceTransform` that are supported. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct SupportedSurfaceTransformsIter(SupportedSurfaceTransforms); + +impl Iterator for SupportedSurfaceTransformsIter { + type Item = SurfaceTransform; + + #[inline] + fn next(&mut self) -> Option { + if self.0.identity { self.0.identity = false; return Some(SurfaceTransform::Identity); } + if self.0.rotate90 { self.0.rotate90 = false; return Some(SurfaceTransform::Rotate90); } + if self.0.rotate180 { self.0.rotate180 = false; return Some(SurfaceTransform::Rotate180); } + if self.0.rotate270 { self.0.rotate270 = false; return Some(SurfaceTransform::Rotate270); } + if self.0.horizontal_mirror { self.0.horizontal_mirror = false; return Some(SurfaceTransform::HorizontalMirror); } + if self.0.horizontal_mirror_rotate90 { self.0.horizontal_mirror_rotate90 = false; return Some(SurfaceTransform::HorizontalMirrorRotate90); } + if self.0.horizontal_mirror_rotate180 { self.0.horizontal_mirror_rotate180 = false; return Some(SurfaceTransform::HorizontalMirrorRotate180); } + if self.0.horizontal_mirror_rotate270 { self.0.horizontal_mirror_rotate270 = false; return Some(SurfaceTransform::HorizontalMirrorRotate270); } + if self.0.inherit { self.0.inherit = false; return Some(SurfaceTransform::Inherit); } + None + } +} + +impl Default for SurfaceTransform { + #[inline] + fn default() -> SurfaceTransform { + SurfaceTransform::Identity + } +} + /// Internal trait so that creating/destroying a swapchain can access the surface's "has_swapchain" /// flag. unsafe trait SurfaceSwapchainLock { diff --git a/vulkano/src/swapchain/surface.rs b/vulkano/src/swapchain/surface.rs index a09ce5e5..37a69fe3 100644 --- a/vulkano/src/swapchain/surface.rs +++ b/vulkano/src/swapchain/surface.rs @@ -21,6 +21,7 @@ use instance::Instance; use instance::PhysicalDevice; use instance::QueueFamily; use swapchain::SurfaceSwapchainLock; +use swapchain::SupportedSurfaceTransforms; use swapchain::display::DisplayMode; use swapchain::display::DisplayPlane; @@ -685,113 +686,6 @@ pub enum SurfaceTransform { Inherit = vk::SURFACE_TRANSFORM_INHERIT_BIT_KHR, } -/// List of supported composite alpha modes. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub struct SupportedSurfaceTransforms { - pub identity: bool, - pub rotate90: bool, - pub rotate180: bool, - pub rotate270: bool, - pub horizontal_mirror: bool, - pub horizontal_mirror_rotate90: bool, - pub horizontal_mirror_rotate180: bool, - pub horizontal_mirror_rotate270: bool, - pub inherit: bool, -} - -impl SupportedSurfaceTransforms { - /// Builds a `SupportedSurfaceTransforms` with all fields set to false. - #[inline] - pub fn none() -> SupportedSurfaceTransforms { - SupportedSurfaceTransforms { - identity: false, - rotate90: false, - rotate180: false, - rotate270: false, - horizontal_mirror: false, - horizontal_mirror_rotate90: false, - horizontal_mirror_rotate180: false, - horizontal_mirror_rotate270: false, - inherit: false, - } - } - - #[inline] - fn from_bits(val: u32) -> SupportedSurfaceTransforms { - macro_rules! v { - ($val:expr, $out:ident, $e:expr, $f:ident) => ( - if ($val & $e) != 0 { $out.$f = true; } - ); - } - - let mut result = SupportedSurfaceTransforms::none(); - v!(val, result, vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR, identity); - v!(val, result, vk::SURFACE_TRANSFORM_ROTATE_90_BIT_KHR, rotate90); - v!(val, result, vk::SURFACE_TRANSFORM_ROTATE_180_BIT_KHR, rotate180); - v!(val, result, vk::SURFACE_TRANSFORM_ROTATE_270_BIT_KHR, rotate270); - v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR, horizontal_mirror); - v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR, - horizontal_mirror_rotate90); - v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR, - horizontal_mirror_rotate180); - v!(val, result, vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR, - horizontal_mirror_rotate270); - v!(val, result, vk::SURFACE_TRANSFORM_INHERIT_BIT_KHR, inherit); - result - } - - /// Returns true if the given `SurfaceTransform` is in this list. - #[inline] - pub fn supports(&self, value: SurfaceTransform) -> bool { - match value { - SurfaceTransform::Identity => self.identity, - SurfaceTransform::Rotate90 => self.rotate90, - SurfaceTransform::Rotate180 => self.rotate180, - SurfaceTransform::Rotate270 => self.rotate270, - SurfaceTransform::HorizontalMirror => self.horizontal_mirror, - SurfaceTransform::HorizontalMirrorRotate90 => self.horizontal_mirror_rotate90, - SurfaceTransform::HorizontalMirrorRotate180 => self.horizontal_mirror_rotate180, - SurfaceTransform::HorizontalMirrorRotate270 => self.horizontal_mirror_rotate270, - SurfaceTransform::Inherit => self.inherit, - } - } - - /// Returns an iterator to the list of supported composite alpha. - #[inline] - pub fn iter(&self) -> SupportedSurfaceTransformsIter { - SupportedSurfaceTransformsIter(self.clone()) - } -} - -/// Enumeration of the `SurfaceTransform` that are supported. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub struct SupportedSurfaceTransformsIter(SupportedSurfaceTransforms); - -impl Iterator for SupportedSurfaceTransformsIter { - type Item = SurfaceTransform; - - #[inline] - fn next(&mut self) -> Option { - if self.0.identity { self.0.identity = false; return Some(SurfaceTransform::Identity); } - if self.0.rotate90 { self.0.rotate90 = false; return Some(SurfaceTransform::Rotate90); } - if self.0.rotate180 { self.0.rotate180 = false; return Some(SurfaceTransform::Rotate180); } - if self.0.rotate270 { self.0.rotate270 = false; return Some(SurfaceTransform::Rotate270); } - if self.0.horizontal_mirror { self.0.horizontal_mirror = false; return Some(SurfaceTransform::HorizontalMirror); } - if self.0.horizontal_mirror_rotate90 { self.0.horizontal_mirror_rotate90 = false; return Some(SurfaceTransform::HorizontalMirrorRotate90); } - if self.0.horizontal_mirror_rotate180 { self.0.horizontal_mirror_rotate180 = false; return Some(SurfaceTransform::HorizontalMirrorRotate180); } - if self.0.horizontal_mirror_rotate270 { self.0.horizontal_mirror_rotate270 = false; return Some(SurfaceTransform::HorizontalMirrorRotate270); } - if self.0.inherit { self.0.inherit = false; return Some(SurfaceTransform::Inherit); } - None - } -} - -impl Default for SurfaceTransform { - #[inline] - fn default() -> SurfaceTransform { - SurfaceTransform::Identity - } -} - /// How the alpha values of the pixels of the window are treated. #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[repr(u32)] From 0161dc3c93e5c3bb9fff6c97dd53e390802ad584 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 18 Nov 2016 09:02:56 +0100 Subject: [PATCH 2/3] Restore Surface::from_display_mode --- vulkano/src/swapchain/display.rs | 7 +++++++ vulkano/src/swapchain/surface.rs | 14 +++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/vulkano/src/swapchain/display.rs b/vulkano/src/swapchain/display.rs index 61892e7a..b4575284 100644 --- a/vulkano/src/swapchain/display.rs +++ b/vulkano/src/swapchain/display.rs @@ -34,6 +34,7 @@ use vk; /// ? // TODO: plane capabilities +// TODO: store properties in the instance? pub struct DisplayPlane { instance: Arc, physical_device: usize, @@ -112,6 +113,12 @@ impl DisplayPlane { PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap() } + /// Returns the index of the plane. + #[inline] + pub fn index(&self) -> u32 { + self.index + } + /// Returns true if this plane supports the given display. #[inline] pub fn supports(&self, display: &Display) -> bool { diff --git a/vulkano/src/swapchain/surface.rs b/vulkano/src/swapchain/surface.rs index 37a69fe3..25b2136d 100644 --- a/vulkano/src/swapchain/surface.rs +++ b/vulkano/src/swapchain/surface.rs @@ -56,8 +56,7 @@ impl Surface { pub fn from_display_mode(display_mode: &DisplayMode, plane: &DisplayPlane) -> Result, SurfaceCreationError> { - unimplemented!() // TODO: - /*if !display_mode.display().physical_device().instance().loaded_extensions().khr_display { + if !display_mode.display().physical_device().instance().loaded_extensions().khr_display { return Err(SurfaceCreationError::MissingExtension { name: "VK_KHR_display" }); } @@ -74,14 +73,14 @@ impl Surface { pNext: ptr::null(), flags: 0, // reserved displayMode: display_mode.internal_object(), - planeIndex: plane.index, - planeStackIndex: plane.properties.currentStackIndex, + planeIndex: plane.index(), + planeStackIndex: 0, // FIXME: plane.properties.currentStackIndex, transform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR, // TODO: let user choose globalAlpha: 0.0, // TODO: let user choose alphaMode: vk::DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR, // TODO: let user choose imageExtent: vk::Extent2D { // TODO: let user choose - width: display_mode.parameters.visibleRegion.width, - height: display_mode.parameters.visibleRegion.height, + width: display_mode.visible_region()[0], + height: display_mode.visible_region()[1], }, }; @@ -94,7 +93,8 @@ impl Surface { Ok(Arc::new(Surface { instance: instance.clone(), surface: surface, - }))*/ + has_swapchain: AtomicBool::new(false), + })) } /// Creates a `Surface` from a Win32 window. From f20980ea4e7e4a8afc3d668fcc7051246f826cd1 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 18 Nov 2016 09:23:49 +0100 Subject: [PATCH 3/3] Add some documentation to the display module --- vulkano/src/swapchain/display.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/vulkano/src/swapchain/display.rs b/vulkano/src/swapchain/display.rs index b4575284..6cc4ea95 100644 --- a/vulkano/src/swapchain/display.rs +++ b/vulkano/src/swapchain/display.rs @@ -9,8 +9,21 @@ //! Allows you to create surfaces that fill a whole display, outside of the windowing system. //! -//! As far as the author knows, no existing device supports these features. Therefore the code here -//! is mostly a draft and needs rework in both the API and the implementation. +//! **As far as the author knows, no existing device supports these features. Therefore the code +//! here is mostly a draft and needs rework in both the API and the implementation.** +//! +//! The purpose of the objects in this module is to let you create a `Surface` object that +//! represents a location on the screen. This is done in four steps: +//! +//! - Choose a `Display` where the surface will be located. A `Display` represents a display +//! display, usually a monitor. The available displays can be enumerated with +//! `Display::enumerate`. +//! - Choose a `DisplayMode`, which is the combination of a display, a resolution and a refresh +//! 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` +//! and `DisplayPlane`. #![allow(dead_code)] // TODO: this module isn't finished #![allow(unused_variables)] // TODO: this module isn't finished