#![allow(dead_code)] #![allow(unused_variables)]
use std::ffi::CStr;
use std::ptr;
use std::sync::Arc;
use std::vec::IntoIter;
use instance::Instance;
use instance::PhysicalDevice;
use swapchain::SupportedSurfaceTransforms;
use swapchain::capabilities;
use OomError;
use VulkanObject;
use check_errors;
use vk;
pub struct DisplayPlane {
instance: Arc<Instance>,
physical_device: usize,
index: u32,
properties: vk::DisplayPlanePropertiesKHR,
supported_displays: Vec<vk::DisplayKHR>,
}
impl DisplayPlane {
pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<DisplayPlane>, OomError> {
let vk = device.instance().pointers();
assert!(device.instance().loaded_extensions().khr_display);
let num = unsafe {
let mut num: u32 = 0;
check_errors(vk.GetPhysicalDeviceDisplayPlanePropertiesKHR(device.internal_object(),
&mut num,
ptr::null_mut()))?;
num
};
let planes: Vec<vk::DisplayPlanePropertiesKHR> = unsafe {
let mut planes = Vec::with_capacity(num as usize);
let mut num = num;
check_errors(vk.GetPhysicalDeviceDisplayPlanePropertiesKHR(device.internal_object(),
&mut num,
planes.as_mut_ptr()))?;
planes.set_len(num as usize);
planes
};
Ok(planes.into_iter().enumerate().map(|(index, prop)| {
let num = unsafe {
let mut num: u32 = 0;
check_errors(vk.GetDisplayPlaneSupportedDisplaysKHR(device.internal_object(), index as u32,
&mut num, ptr::null_mut())).unwrap(); num
};
let supported_displays: Vec<vk::DisplayKHR> = unsafe {
let mut displays = Vec::with_capacity(num as usize);
let mut num = num;
check_errors(vk.GetDisplayPlaneSupportedDisplaysKHR(device.internal_object(),
index as u32, &mut num,
displays.as_mut_ptr())).unwrap(); displays.set_len(num as usize);
displays
};
DisplayPlane {
instance: device.instance().clone(),
physical_device: device.index(),
index: index as u32,
properties: prop,
supported_displays: supported_displays,
}
}).collect::<Vec<_>>().into_iter())
}
#[inline]
pub fn enumerate(device: PhysicalDevice) -> IntoIter<DisplayPlane> {
DisplayPlane::enumerate_raw(device).unwrap()
}
#[inline]
pub fn physical_device(&self) -> PhysicalDevice {
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
}
#[inline]
pub fn index(&self) -> u32 {
self.index
}
#[inline]
pub fn supports(&self, display: &Display) -> bool {
if self.physical_device().internal_object() != display.physical_device().internal_object() {
return false;
}
self.supported_displays
.iter()
.find(|&&d| d == display.internal_object())
.is_some()
}
}
#[derive(Clone)]
pub struct Display {
instance: Arc<Instance>,
physical_device: usize,
properties: Arc<vk::DisplayPropertiesKHR>, }
impl Display {
pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<Display>, OomError> {
let vk = device.instance().pointers();
assert!(device.instance().loaded_extensions().khr_display);
let num = unsafe {
let mut num = 0;
check_errors(vk.GetPhysicalDeviceDisplayPropertiesKHR(device.internal_object(),
&mut num,
ptr::null_mut()))?;
num
};
let displays: Vec<vk::DisplayPropertiesKHR> = unsafe {
let mut displays = Vec::with_capacity(num as usize);
let mut num = num;
check_errors(vk.GetPhysicalDeviceDisplayPropertiesKHR(device.internal_object(),
&mut num,
displays.as_mut_ptr()))?;
displays.set_len(num as usize);
displays
};
Ok(displays
.into_iter()
.map(|prop| {
Display {
instance: device.instance().clone(),
physical_device: device.index(),
properties: Arc::new(prop),
}
})
.collect::<Vec<_>>()
.into_iter())
}
#[inline]
pub fn enumerate(device: PhysicalDevice) -> IntoIter<Display> {
Display::enumerate_raw(device).unwrap()
}
#[inline]
pub fn name(&self) -> &str {
unsafe {
CStr::from_ptr(self.properties.displayName)
.to_str()
.expect("non UTF-8 characters in display name")
}
}
#[inline]
pub fn physical_device(&self) -> PhysicalDevice {
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
}
#[inline]
pub fn physical_dimensions(&self) -> [u32; 2] {
let ref r = self.properties.physicalDimensions;
[r.width, r.height]
}
#[inline]
pub fn physical_resolution(&self) -> [u32; 2] {
let ref r = self.properties.physicalResolution;
[r.width, r.height]
}
#[inline]
pub fn supported_transforms(&self) -> SupportedSurfaceTransforms {
capabilities::surface_transforms_from_bits(self.properties.supportedTransforms)
}
#[inline]
pub fn plane_reorder_possible(&self) -> bool {
self.properties.planeReorderPossible != 0
}
#[inline]
pub fn persistent_content(&self) -> bool {
self.properties.persistentContent != 0
}
pub fn display_modes_raw(&self) -> Result<IntoIter<DisplayMode>, OomError> {
let vk = self.instance.pointers();
let num = unsafe {
let mut num = 0;
check_errors(vk.GetDisplayModePropertiesKHR(self.physical_device().internal_object(),
self.properties.display,
&mut num,
ptr::null_mut()))?;
num
};
let modes: Vec<vk::DisplayModePropertiesKHR> = unsafe {
let mut modes = Vec::with_capacity(num as usize);
let mut num = num;
check_errors(vk.GetDisplayModePropertiesKHR(self.physical_device().internal_object(),
self.properties.display,
&mut num,
modes.as_mut_ptr()))?;
modes.set_len(num as usize);
modes
};
Ok(modes
.into_iter()
.map(|mode| {
DisplayMode {
display: self.clone(),
display_mode: mode.displayMode,
parameters: mode.parameters,
}
})
.collect::<Vec<_>>()
.into_iter())
}
#[inline]
pub fn display_modes(&self) -> IntoIter<DisplayMode> {
self.display_modes_raw().unwrap()
}
}
unsafe impl VulkanObject for Display {
type Object = vk::DisplayKHR;
const TYPE: vk::DebugReportObjectTypeEXT = vk::DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT;
#[inline]
fn internal_object(&self) -> vk::DisplayKHR {
self.properties.display
}
}
pub struct DisplayMode {
display: Display,
display_mode: vk::DisplayModeKHR,
parameters: vk::DisplayModeParametersKHR,
}
impl DisplayMode {
#[inline]
pub fn display(&self) -> &Display {
&self.display
}
#[inline]
pub fn visible_region(&self) -> [u32; 2] {
let ref d = self.parameters.visibleRegion;
[d.width, d.height]
}
#[inline]
pub fn refresh_rate(&self) -> u32 {
self.parameters.refreshRate
}
}
unsafe impl VulkanObject for DisplayMode {
type Object = vk::DisplayModeKHR;
const TYPE: vk::DebugReportObjectTypeEXT = vk::DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT;
#[inline]
fn internal_object(&self) -> vk::DisplayModeKHR {
self.display_mode
}
}