diff options
Diffstat (limited to 'src/swapchain/capabilities.rs')
-rw-r--r-- | src/swapchain/capabilities.rs | 664 |
1 files changed, 664 insertions, 0 deletions
diff --git a/src/swapchain/capabilities.rs b/src/swapchain/capabilities.rs new file mode 100644 index 0000000..2a6feca --- /dev/null +++ b/src/swapchain/capabilities.rs @@ -0,0 +1,664 @@ +// Copyright (c) 2016 The vulkano developers +// Licensed under the Apache License, Version 2.0 +// <LICENSE-APACHE or +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT +// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, +// at your option. All files in the project carrying such +// notice may not be copied, modified, or distributed except +// according to those terms. + +use crate::format::Format; +use crate::image::ImageUsage; +use std::iter::FromIterator; + +/// The capabilities of a surface when used by a physical device. +/// +/// You have to match these capabilities when you create a swapchain. +#[derive(Clone, Debug)] +pub struct Capabilities { + /// Minimum number of images that must be present in the swapchain. + pub min_image_count: u32, + + /// Maximum number of images that must be present in the swapchain, or `None` if there is no + /// maximum value. Note that "no maximum" doesn't mean that you can set a very high value, as + /// you may still get out of memory errors. + pub max_image_count: Option<u32>, + + /// The current dimensions of the surface. `None` means that the surface's dimensions will + /// depend on the dimensions of the swapchain that you are going to create. + pub current_extent: Option<[u32; 2]>, + + /// Minimum width and height of a swapchain that uses this surface. + pub min_image_extent: [u32; 2], + + /// Maximum width and height of a swapchain that uses this surface. + pub max_image_extent: [u32; 2], + + /// Maximum number of image layers if you create an image array. The minimum is 1. + pub max_image_array_layers: u32, + + /// List of transforms supported for the swapchain. + pub supported_transforms: SupportedSurfaceTransforms, + + /// Current transform used by the surface. + pub current_transform: SurfaceTransform, + + /// List of composite alpha modes supports for the swapchain. + pub supported_composite_alpha: SupportedCompositeAlpha, + + /// List of image usages that are supported for images of the swapchain. Only + /// the `color_attachment` usage is guaranteed to be supported. + pub supported_usage_flags: ImageUsage, + + /// List of formats supported for the swapchain. + pub supported_formats: Vec<(Format, ColorSpace)>, // TODO: https://github.com/KhronosGroup/Vulkan-Docs/issues/207 + + /// List of present modes that are supported. `Fifo` is always guaranteed to be supported. + pub present_modes: SupportedPresentModes, +} + +/// The way presenting a swapchain is accomplished. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(i32)] +pub enum PresentMode { + /// Immediately shows the image to the user. May result in visible tearing. + Immediate = ash::vk::PresentModeKHR::IMMEDIATE.as_raw(), + + /// The action of presenting an image puts it in wait. When the next vertical blanking period + /// happens, the waiting image is effectively shown to the user. If an image is presented while + /// another one is waiting, it is replaced. + Mailbox = ash::vk::PresentModeKHR::MAILBOX.as_raw(), + + /// The action of presenting an image adds it to a queue of images. At each vertical blanking + /// period, the queue is popped and an image is presented. + /// + /// Guaranteed to be always supported. + /// + /// This is the equivalent of OpenGL's `SwapInterval` with a value of 1. + Fifo = ash::vk::PresentModeKHR::FIFO.as_raw(), + + /// Same as `Fifo`, except that if the queue was empty during the previous vertical blanking + /// period then it is equivalent to `Immediate`. + /// + /// This is the equivalent of OpenGL's `SwapInterval` with a value of -1. + Relaxed = ash::vk::PresentModeKHR::FIFO_RELAXED.as_raw(), + // TODO: These can't be enabled yet because they have to be used with shared present surfaces + // which vulkano doesnt support yet. + //SharedDemand = ash::vk::PresentModeKHR::SHARED_DEMAND_REFRESH, + //SharedContinuous = ash::vk::PresentModeKHR::SHARED_CONTINUOUS_REFRESH, +} + +impl From<PresentMode> for ash::vk::PresentModeKHR { + #[inline] + fn from(val: PresentMode) -> Self { + Self::from_raw(val as i32) + } +} + +/// List of `PresentMode`s that are supported. +#[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, +} + +impl FromIterator<ash::vk::PresentModeKHR> for SupportedPresentModes { + fn from_iter<T>(iter: T) -> Self + where + T: IntoIterator<Item = ash::vk::PresentModeKHR>, + { + let mut result = SupportedPresentModes::none(); + for e in iter { + match e { + ash::vk::PresentModeKHR::IMMEDIATE => result.immediate = true, + ash::vk::PresentModeKHR::MAILBOX => result.mailbox = true, + ash::vk::PresentModeKHR::FIFO => result.fifo = true, + ash::vk::PresentModeKHR::FIFO_RELAXED => result.relaxed = true, + ash::vk::PresentModeKHR::SHARED_DEMAND_REFRESH => result.shared_demand = true, + ash::vk::PresentModeKHR::SHARED_CONTINUOUS_REFRESH => { + result.shared_continuous = true + } + _ => {} + } + } + result + } +} + +impl SupportedPresentModes { + /// Builds a `SupportedPresentModes` with all fields set to false. + #[inline] + pub fn none() -> SupportedPresentModes { + SupportedPresentModes { + immediate: false, + mailbox: false, + fifo: false, + relaxed: false, + shared_demand: false, + shared_continuous: false, + } + } + + /// Returns true if the given present mode is in this list of supported modes. + #[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, + } + } + + /// Returns an iterator to the list of supported present modes. + #[inline] + pub fn iter(&self) -> SupportedPresentModesIter { + SupportedPresentModesIter(self.clone()) + } +} + +/// Enumeration of the `PresentMode`s that are supported. +#[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 + } +} + +/// A transformation to apply to the image before showing it on the screen. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(u32)] +pub enum SurfaceTransform { + /// Don't transform the image. + Identity = ash::vk::SurfaceTransformFlagsKHR::IDENTITY.as_raw(), + /// Rotate 90 degrees. + Rotate90 = ash::vk::SurfaceTransformFlagsKHR::ROTATE_90.as_raw(), + /// Rotate 180 degrees. + Rotate180 = ash::vk::SurfaceTransformFlagsKHR::ROTATE_180.as_raw(), + /// Rotate 270 degrees. + Rotate270 = ash::vk::SurfaceTransformFlagsKHR::ROTATE_270.as_raw(), + /// Mirror the image horizontally. + HorizontalMirror = ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR.as_raw(), + /// Mirror the image horizontally and rotate 90 degrees. + HorizontalMirrorRotate90 = + ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR_ROTATE_90.as_raw(), + /// Mirror the image horizontally and rotate 180 degrees. + HorizontalMirrorRotate180 = + ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR_ROTATE_180.as_raw(), + /// Mirror the image horizontally and rotate 270 degrees. + HorizontalMirrorRotate270 = + ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR_ROTATE_270.as_raw(), + /// Let the operating system or driver implementation choose. + Inherit = ash::vk::SurfaceTransformFlagsKHR::INHERIT.as_raw(), +} + +impl From<SurfaceTransform> for ash::vk::SurfaceTransformFlagsKHR { + #[inline] + fn from(val: SurfaceTransform) -> Self { + Self::from_raw(val as u32) + } +} + +/// How the alpha values of the pixels of the window are treated. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(u32)] +pub enum CompositeAlpha { + /// The alpha channel of the image is ignored. All the pixels are considered as if they have a + /// value of 1.0. + Opaque = ash::vk::CompositeAlphaFlagsKHR::OPAQUE.as_raw(), + + /// The alpha channel of the image is respected. The color channels are expected to have + /// already been multiplied by the alpha value. + PreMultiplied = ash::vk::CompositeAlphaFlagsKHR::PRE_MULTIPLIED.as_raw(), + + /// The alpha channel of the image is respected. The color channels will be multiplied by the + /// alpha value by the compositor before being added to what is behind. + PostMultiplied = ash::vk::CompositeAlphaFlagsKHR::POST_MULTIPLIED.as_raw(), + + /// Let the operating system or driver implementation choose. + Inherit = ash::vk::CompositeAlphaFlagsKHR::INHERIT.as_raw(), +} + +impl From<CompositeAlpha> for ash::vk::CompositeAlphaFlagsKHR { + #[inline] + fn from(val: CompositeAlpha) -> Self { + Self::from_raw(val as u32) + } +} + +/// List of supported composite alpha modes. +/// +/// See the docs of `CompositeAlpha`. +#[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, +} + +impl From<ash::vk::CompositeAlphaFlagsKHR> for SupportedCompositeAlpha { + #[inline] + fn from(val: ash::vk::CompositeAlphaFlagsKHR) -> SupportedCompositeAlpha { + let mut result = SupportedCompositeAlpha::none(); + if !(val & ash::vk::CompositeAlphaFlagsKHR::OPAQUE).is_empty() { + result.opaque = true; + } + if !(val & ash::vk::CompositeAlphaFlagsKHR::PRE_MULTIPLIED).is_empty() { + result.pre_multiplied = true; + } + if !(val & ash::vk::CompositeAlphaFlagsKHR::POST_MULTIPLIED).is_empty() { + result.post_multiplied = true; + } + if !(val & ash::vk::CompositeAlphaFlagsKHR::INHERIT).is_empty() { + result.inherit = true; + } + result + } +} + +impl SupportedCompositeAlpha { + /// Builds a `SupportedCompositeAlpha` with all fields set to false. + #[inline] + pub fn none() -> SupportedCompositeAlpha { + SupportedCompositeAlpha { + opaque: false, + pre_multiplied: false, + post_multiplied: false, + inherit: false, + } + } + + /// Returns true if the given `CompositeAlpha` is in this list. + #[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, + } + } + + /// Returns an iterator to the list of supported composite alpha. + #[inline] + pub fn iter(&self) -> SupportedCompositeAlphaIter { + SupportedCompositeAlphaIter(self.clone()) + } +} + +/// Enumeration of the `CompositeAlpha` that are supported. +#[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 + } +} + +/// 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 From<ash::vk::SurfaceTransformFlagsKHR> for SupportedSurfaceTransforms { + fn from(val: ash::vk::SurfaceTransformFlagsKHR) -> Self { + macro_rules! v { + ($val:expr, $out:ident, $e:expr, $f:ident) => { + if !($val & $e).is_empty() { + $out.$f = true; + } + }; + } + + let mut result = SupportedSurfaceTransforms::none(); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::IDENTITY, + identity + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::ROTATE_90, + rotate90 + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::ROTATE_180, + rotate180 + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::ROTATE_270, + rotate270 + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR, + horizontal_mirror + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR_ROTATE_90, + horizontal_mirror_rotate90 + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR_ROTATE_180, + horizontal_mirror_rotate180 + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::HORIZONTAL_MIRROR_ROTATE_270, + horizontal_mirror_rotate270 + ); + v!( + val, + result, + ash::vk::SurfaceTransformFlagsKHR::INHERIT, + inherit + ); + result + } +} + +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, + } + } + + /// 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 presentation engine should interpret the data. +/// +/// # A quick lesson about color spaces +/// +/// ## What is a color space? +/// +/// Each pixel of a monitor is made of three components: one red, one green, and one blue. In the +/// past, computers would simply send to the monitor the intensity of each of the three components. +/// +/// This proved to be problematic, because depending on the brand of the monitor the colors would +/// not exactly be the same. For example on some monitors, a value of `[1.0, 0.0, 0.0]` would be a +/// bit more orange than on others. +/// +/// In order to standardize this, there exist what are called *color spaces*: sRGB, AdobeRGB, +/// DCI-P3, scRGB, etc. When you manipulate RGB values in a specific color space, these values have +/// a precise absolute meaning in terms of color, that is the same across all systems and monitors. +/// +/// > **Note**: Color spaces are orthogonal to concept of RGB. *RGB* only indicates what is the +/// > representation of the data, but not how it is interpreted. You can think of this a bit like +/// > text encoding. An *RGB* value is a like a byte, in other words it is the medium by which +/// > values are communicated, and a *color space* is like a text encoding (eg. UTF-8), in other +/// > words it is the way the value should be interpreted. +/// +/// The most commonly used color space today is sRGB. Most monitors today use this color space, +/// and most images files are encoded in this color space. +/// +/// ## Pixel formats and linear vs non-linear +/// +/// In Vulkan all images have a specific format in which the data is stored. The data of an image +/// consists of pixels in RGB but contains no information about the color space (or lack thereof) +/// of these pixels. You are free to store them in whatever color space you want. +/// +/// But one big practical problem with color spaces is that they are sometimes not linear, and in +/// particular the popular sRGB color space is not linear. In a non-linear color space, a value of +/// `[0.6, 0.6, 0.6]` for example is **not** twice as bright as a value of `[0.3, 0.3, 0.3]`. This +/// is problematic, because operations such as taking the average of two colors or calculating the +/// lighting of a texture with a dot product are mathematically incorrect and will produce +/// incorrect colors. +/// +/// > **Note**: If the texture format has an alpha component, it is not affected by the color space +/// > and always behaves linearly. +/// +/// In order to solve this Vulkan also provides image formats with the `Srgb` suffix, which are +/// expected to contain RGB data in the sRGB color space. When you sample an image with such a +/// format from a shader, the implementation will automatically turn the pixel values into a linear +/// color space that is suitable for linear operations (such as additions or multiplications). +/// When you write to a framebuffer attachment with such a format, the implementation will +/// automatically perform the opposite conversion. These conversions are most of the time performed +/// by the hardware and incur no additional cost. +/// +/// ## Color space of the swapchain +/// +/// The color space that you specify when you create a swapchain is how the implementation will +/// interpret the raw data inside of the image. +/// +/// > **Note**: The implementation can choose to send the data in the swapchain image directly to +/// > the monitor, but it can also choose to write it in an intermediary buffer that is then read +/// > by the operating system or windowing system. Therefore the color space that the +/// > implementation supports is not necessarily the same as the one supported by the monitor. +/// +/// It is *your* job to ensure that the data in the swapchain image is in the color space +/// that is specified here, otherwise colors will be incorrect. +/// The implementation will never perform any additional automatic conversion after the colors have +/// been written to the swapchain image. +/// +/// # How do I handle this correctly? +/// +/// The easiest way to handle color spaces in a cross-platform program is: +/// +/// - Always request the `SrgbNonLinear` color space when creating the swapchain. +/// - Make sure that all your image files use the sRGB color space, and load them in images whose +/// format has the `Srgb` suffix. Only use non-sRGB image formats for intermediary computations +/// or to store non-color data. +/// - Swapchain images should have a format with the `Srgb` suffix. +/// +/// > **Note**: It is unclear whether the `SrgbNonLinear` color space is always supported by the +/// > the implementation or not. See <https://github.com/KhronosGroup/Vulkan-Docs/issues/442>. +/// +/// > **Note**: Lots of developers are confused by color spaces. You can sometimes find articles +/// > talking about gamma correction and suggestion to put your colors to the power 2.2 for +/// > example. These are all hacks and you should use the sRGB pixel formats instead. +/// +/// If you follow these three rules, then everything should render the same way on all platforms. +/// +/// Additionally you can try detect whether the implementation supports any additional color space +/// and perform a manual conversion to that color space from inside your shader. +/// +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(i32)] +pub enum ColorSpace { + SrgbNonLinear = ash::vk::ColorSpaceKHR::SRGB_NONLINEAR.as_raw(), + DisplayP3NonLinear = ash::vk::ColorSpaceKHR::DISPLAY_P3_NONLINEAR_EXT.as_raw(), + ExtendedSrgbLinear = ash::vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT.as_raw(), + ExtendedSrgbNonLinear = ash::vk::ColorSpaceKHR::EXTENDED_SRGB_NONLINEAR_EXT.as_raw(), + DciP3Linear = ash::vk::ColorSpaceKHR::DCI_P3_LINEAR_EXT.as_raw(), + DciP3NonLinear = ash::vk::ColorSpaceKHR::DCI_P3_NONLINEAR_EXT.as_raw(), + Bt709Linear = ash::vk::ColorSpaceKHR::BT709_LINEAR_EXT.as_raw(), + Bt709NonLinear = ash::vk::ColorSpaceKHR::BT709_NONLINEAR_EXT.as_raw(), + Bt2020Linear = ash::vk::ColorSpaceKHR::BT2020_LINEAR_EXT.as_raw(), + Hdr10St2084 = ash::vk::ColorSpaceKHR::HDR10_ST2084_EXT.as_raw(), + DolbyVision = ash::vk::ColorSpaceKHR::DOLBYVISION_EXT.as_raw(), + Hdr10Hlg = ash::vk::ColorSpaceKHR::HDR10_HLG_EXT.as_raw(), + AdobeRgbLinear = ash::vk::ColorSpaceKHR::ADOBERGB_LINEAR_EXT.as_raw(), + AdobeRgbNonLinear = ash::vk::ColorSpaceKHR::ADOBERGB_NONLINEAR_EXT.as_raw(), + PassThrough = ash::vk::ColorSpaceKHR::PASS_THROUGH_EXT.as_raw(), + DisplayNative = ash::vk::ColorSpaceKHR::DISPLAY_NATIVE_AMD.as_raw(), +} + +impl From<ColorSpace> for ash::vk::ColorSpaceKHR { + #[inline] + fn from(val: ColorSpace) -> Self { + Self::from_raw(val as i32) + } +} + +impl From<ash::vk::ColorSpaceKHR> for ColorSpace { + #[inline] + fn from(val: ash::vk::ColorSpaceKHR) -> Self { + match val { + ash::vk::ColorSpaceKHR::SRGB_NONLINEAR => ColorSpace::SrgbNonLinear, + ash::vk::ColorSpaceKHR::DISPLAY_P3_NONLINEAR_EXT => ColorSpace::DisplayP3NonLinear, + ash::vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT => ColorSpace::ExtendedSrgbLinear, + ash::vk::ColorSpaceKHR::EXTENDED_SRGB_NONLINEAR_EXT => { + ColorSpace::ExtendedSrgbNonLinear + } + ash::vk::ColorSpaceKHR::DCI_P3_LINEAR_EXT => ColorSpace::DciP3Linear, + ash::vk::ColorSpaceKHR::DCI_P3_NONLINEAR_EXT => ColorSpace::DciP3NonLinear, + ash::vk::ColorSpaceKHR::BT709_LINEAR_EXT => ColorSpace::Bt709Linear, + ash::vk::ColorSpaceKHR::BT709_NONLINEAR_EXT => ColorSpace::Bt709NonLinear, + ash::vk::ColorSpaceKHR::BT2020_LINEAR_EXT => ColorSpace::Bt2020Linear, + ash::vk::ColorSpaceKHR::HDR10_ST2084_EXT => ColorSpace::Hdr10St2084, + ash::vk::ColorSpaceKHR::DOLBYVISION_EXT => ColorSpace::DolbyVision, + ash::vk::ColorSpaceKHR::HDR10_HLG_EXT => ColorSpace::Hdr10Hlg, + ash::vk::ColorSpaceKHR::ADOBERGB_LINEAR_EXT => ColorSpace::AdobeRgbLinear, + ash::vk::ColorSpaceKHR::ADOBERGB_NONLINEAR_EXT => ColorSpace::AdobeRgbNonLinear, + ash::vk::ColorSpaceKHR::PASS_THROUGH_EXT => ColorSpace::PassThrough, + ash::vk::ColorSpaceKHR::DISPLAY_NATIVE_AMD => ColorSpace::DisplayNative, + _ => panic!("Wrong value for color space enum {:?}", val), + } + } +} |