Merge pull request #318 from tomaka/khr-display

Some improvements to VK_KHR_display support
This commit is contained in:
tomaka 2016-11-18 14:22:56 +01:00 committed by GitHub
commit cb61fd4824
3 changed files with 172 additions and 119 deletions

View File

@ -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
@ -22,6 +35,7 @@ use std::vec::IntoIter;
use instance::Instance;
use instance::PhysicalDevice;
use swapchain::SupportedSurfaceTransforms;
use check_errors;
use OomError;
@ -33,6 +47,7 @@ use vk;
/// ?
// TODO: plane capabilities
// TODO: store properties in the instance?
pub struct DisplayPlane {
instance: Arc<Instance>,
physical_device: usize,
@ -111,6 +126,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 {
@ -124,6 +145,7 @@ impl DisplayPlane {
}
/// Represents a monitor connected to a physical device.
// TODO: store properties in the instance?
#[derive(Clone)]
pub struct Display {
instance: Arc<Instance>,
@ -179,8 +201,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 +213,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<IntoIter<DisplayMode>, OomError> {
let vk = self.instance.pointers();

View File

@ -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<SurfaceTransform> {
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 {

View File

@ -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;
@ -55,8 +56,7 @@ impl Surface {
pub fn from_display_mode(display_mode: &DisplayMode, plane: &DisplayPlane)
-> Result<Arc<Surface>, 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" });
}
@ -73,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],
},
};
@ -93,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.
@ -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<SurfaceTransform> {
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)]