use format::Format;
use image::ImageUsage;
use vk;
#[derive(Clone, Debug)]
pub struct Capabilities {
pub min_image_count: u32,
pub max_image_count: Option<u32>,
pub current_extent: Option<[u32; 2]>,
pub min_image_extent: [u32; 2],
pub max_image_extent: [u32; 2],
pub max_image_array_layers: u32,
pub supported_transforms: SupportedSurfaceTransforms,
pub current_transform: SurfaceTransform,
pub supported_composite_alpha: SupportedCompositeAlpha,
pub supported_usage_flags: ImageUsage,
pub supported_formats: Vec<(Format, ColorSpace)>,
pub present_modes: SupportedPresentModes,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum PresentMode {
Immediate = vk::PRESENT_MODE_IMMEDIATE_KHR,
Mailbox = vk::PRESENT_MODE_MAILBOX_KHR,
Fifo = vk::PRESENT_MODE_FIFO_KHR,
Relaxed = vk::PRESENT_MODE_FIFO_RELAXED_KHR,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct SupportedPresentModes {
pub immediate: bool,
pub mailbox: bool,
pub fifo: bool,
pub relaxed: bool,
pub shared_demand: bool,
pub shared_continuous: bool,
}
pub fn supported_present_modes_from_list<I>(elem: I) -> SupportedPresentModes
where I: Iterator<Item = vk::PresentModeKHR>
{
let mut result = SupportedPresentModes::none();
for e in elem {
match e {
vk::PRESENT_MODE_IMMEDIATE_KHR => result.immediate = true,
vk::PRESENT_MODE_MAILBOX_KHR => result.mailbox = true,
vk::PRESENT_MODE_FIFO_KHR => result.fifo = true,
vk::PRESENT_MODE_FIFO_RELAXED_KHR => result.relaxed = true,
vk::PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR => result.shared_demand = true,
vk::PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR => result.shared_continuous = true,
_ => { }
}
}
result
}
impl SupportedPresentModes {
#[inline]
pub fn none() -> SupportedPresentModes {
SupportedPresentModes {
immediate: false,
mailbox: false,
fifo: false,
relaxed: false,
shared_demand: false,
shared_continuous: false,
}
}
#[inline]
pub fn supports(&self, mode: PresentMode) -> bool {
match mode {
PresentMode::Immediate => self.immediate,
PresentMode::Mailbox => self.mailbox,
PresentMode::Fifo => self.fifo,
PresentMode::Relaxed => self.relaxed,
}
}
#[inline]
pub fn iter(&self) -> SupportedPresentModesIter {
SupportedPresentModesIter(self.clone())
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct SupportedPresentModesIter(SupportedPresentModes);
impl Iterator for SupportedPresentModesIter {
type Item = PresentMode;
#[inline]
fn next(&mut self) -> Option<PresentMode> {
if self.0.immediate {
self.0.immediate = false;
return Some(PresentMode::Immediate);
}
if self.0.mailbox {
self.0.mailbox = false;
return Some(PresentMode::Mailbox);
}
if self.0.fifo {
self.0.fifo = false;
return Some(PresentMode::Fifo);
}
if self.0.relaxed {
self.0.relaxed = false;
return Some(PresentMode::Relaxed);
}
None
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum SurfaceTransform {
Identity = vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
Rotate90 = vk::SURFACE_TRANSFORM_ROTATE_90_BIT_KHR,
Rotate180 = vk::SURFACE_TRANSFORM_ROTATE_180_BIT_KHR,
Rotate270 = vk::SURFACE_TRANSFORM_ROTATE_270_BIT_KHR,
HorizontalMirror = vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR,
HorizontalMirrorRotate90 = vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR,
HorizontalMirrorRotate180 = vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR,
HorizontalMirrorRotate270 = vk::SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR,
Inherit = vk::SURFACE_TRANSFORM_INHERIT_BIT_KHR,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum CompositeAlpha {
Opaque = vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
PreMultiplied = vk::COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
PostMultiplied = vk::COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
Inherit = vk::COMPOSITE_ALPHA_INHERIT_BIT_KHR,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[allow(missing_docs)]
pub struct SupportedCompositeAlpha {
pub opaque: bool,
pub pre_multiplied: bool,
pub post_multiplied: bool,
pub inherit: bool,
}
pub fn supported_composite_alpha_from_bits(val: u32) -> SupportedCompositeAlpha {
let mut result = SupportedCompositeAlpha::none();
if (val & vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR) != 0 {
result.opaque = true;
}
if (val & vk::COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) != 0 {
result.pre_multiplied = true;
}
if (val & vk::COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) != 0 {
result.post_multiplied = true;
}
if (val & vk::COMPOSITE_ALPHA_INHERIT_BIT_KHR) != 0 {
result.inherit = true;
}
result
}
impl SupportedCompositeAlpha {
#[inline]
pub fn none() -> SupportedCompositeAlpha {
SupportedCompositeAlpha {
opaque: false,
pre_multiplied: false,
post_multiplied: false,
inherit: false,
}
}
#[inline]
pub fn supports(&self, value: CompositeAlpha) -> bool {
match value {
CompositeAlpha::Opaque => self.opaque,
CompositeAlpha::PreMultiplied => self.pre_multiplied,
CompositeAlpha::PostMultiplied => self.post_multiplied,
CompositeAlpha::Inherit => self.inherit,
}
}
#[inline]
pub fn iter(&self) -> SupportedCompositeAlphaIter {
SupportedCompositeAlphaIter(self.clone())
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct SupportedCompositeAlphaIter(SupportedCompositeAlpha);
impl Iterator for SupportedCompositeAlphaIter {
type Item = CompositeAlpha;
#[inline]
fn next(&mut self) -> Option<CompositeAlpha> {
if self.0.opaque {
self.0.opaque = false;
return Some(CompositeAlpha::Opaque);
}
if self.0.pre_multiplied {
self.0.pre_multiplied = false;
return Some(CompositeAlpha::PreMultiplied);
}
if self.0.post_multiplied {
self.0.post_multiplied = false;
return Some(CompositeAlpha::PostMultiplied);
}
if self.0.inherit {
self.0.inherit = false;
return Some(CompositeAlpha::Inherit);
}
None
}
}
#[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,
}
pub fn surface_transforms_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
}
impl SupportedSurfaceTransforms {
#[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]
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,
}
}
#[inline]
pub fn iter(&self) -> SupportedSurfaceTransformsIter {
SupportedSurfaceTransformsIter(self.clone())
}
}
#[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
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ColorSpace {
SrgbNonLinear = vk::COLOR_SPACE_SRGB_NONLINEAR_KHR,
DisplayP3NonLinear = vk::COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT,
ExtendedSrgbLinear = vk::COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT,
DciP3Linear = vk::COLOR_SPACE_DCI_P3_LINEAR_EXT,
DciP3NonLinear = vk::COLOR_SPACE_DCI_P3_NONLINEAR_EXT,
Bt709Linear = vk::COLOR_SPACE_BT709_LINEAR_EXT,
Bt709NonLinear = vk::COLOR_SPACE_BT709_NONLINEAR_EXT,
Bt2020Linear = vk::COLOR_SPACE_BT2020_LINEAR_EXT,
Hdr10St2084 = vk::COLOR_SPACE_HDR10_ST2084_EXT,
DolbyVision = vk::COLOR_SPACE_DOLBYVISION_EXT,
Hdr10Hlg = vk::COLOR_SPACE_HDR10_HLG_EXT,
AdobeRgbLinear = vk::COLOR_SPACE_ADOBERGB_LINEAR_EXT,
AdobeRgbNonLinear = vk::COLOR_SPACE_ADOBERGB_NONLINEAR_EXT,
PassThrough = vk::COLOR_SPACE_PASS_THROUGH_EXT,
}
#[inline]
pub fn color_space_from_num(val: u32) -> ColorSpace {
match val {
vk::COLOR_SPACE_SRGB_NONLINEAR_KHR => ColorSpace::SrgbNonLinear,
vk::COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT => ColorSpace::DisplayP3NonLinear,
vk::COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT => ColorSpace::ExtendedSrgbLinear,
vk::COLOR_SPACE_DCI_P3_LINEAR_EXT => ColorSpace::DciP3Linear,
vk::COLOR_SPACE_DCI_P3_NONLINEAR_EXT => ColorSpace::DciP3NonLinear,
vk::COLOR_SPACE_BT709_LINEAR_EXT => ColorSpace::Bt709Linear,
vk::COLOR_SPACE_BT709_NONLINEAR_EXT => ColorSpace::Bt709NonLinear,
vk::COLOR_SPACE_BT2020_LINEAR_EXT => ColorSpace::Bt2020Linear,
vk::COLOR_SPACE_HDR10_ST2084_EXT => ColorSpace::Hdr10St2084,
vk::COLOR_SPACE_DOLBYVISION_EXT => ColorSpace::DolbyVision,
vk::COLOR_SPACE_HDR10_HLG_EXT => ColorSpace::Hdr10Hlg,
vk::COLOR_SPACE_ADOBERGB_LINEAR_EXT => ColorSpace::AdobeRgbLinear,
vk::COLOR_SPACE_ADOBERGB_NONLINEAR_EXT => ColorSpace::AdobeRgbNonLinear,
vk::COLOR_SPACE_PASS_THROUGH_EXT => ColorSpace::PassThrough,
_ => panic!("Wrong value for color space enum"),
}
}