mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-26 00:34:19 +00:00
Merge pull request #318 from tomaka/khr-display
Some improvements to VK_KHR_display support
This commit is contained in:
commit
cb61fd4824
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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)]
|
||||
|
Loading…
Reference in New Issue
Block a user