From 91638a0d79b9a0e6060584a5f14633e09fd01d86 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 24 Jan 2017 09:10:39 +0100 Subject: [PATCH 01/11] Add support for the Nintendo Switch! --- vk-sys/src/lib.rs | 13 +++++++++++ vulkano/src/instance/extensions.rs | 1 + vulkano/src/swapchain/surface.rs | 36 ++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/vk-sys/src/lib.rs b/vk-sys/src/lib.rs index 9ecddde4..f0c48df5 100644 --- a/vk-sys/src/lib.rs +++ b/vk-sys/src/lib.rs @@ -162,6 +162,7 @@ pub const STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR: u32 = 1000007000; pub const STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR: u32 = 1000008000; pub const STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR: u32 = 1000009000; pub const STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT: u32 = 1000011000; +pub const STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN: u32 = 1000062000; pub type SystemAllocationScope = u32; pub const SYSTEM_ALLOCATION_SCOPE_COMMAND: u32 = 0; @@ -2368,6 +2369,17 @@ pub struct DebugReportCallbackCreateInfoEXT { pub pUserData: *mut c_void, } +pub type ViSurfaceCreateFlagsNN = Flags; + +#[repr(C)] +pub struct ViSurfaceCreateInfoNN { + pub sType: StructureType, + pub pNext: *const c_void, + pub flags: ViSurfaceCreateFlagsNN, + pub window: *const c_void, +} + + macro_rules! ptrs { ($struct_name:ident, { $($name:ident => ($($param_n:ident: $param_ty:ty),*) -> $ret:ty,)+ }) => ( pub struct $struct_name { @@ -2463,6 +2475,7 @@ ptrs!(InstancePointers, { CreateDebugReportCallbackEXT => (instance: Instance, pCreateInfo: *const DebugReportCallbackCreateInfoEXT, pAllocator: *const AllocationCallbacks, pCallback: *mut DebugReportCallbackEXT) -> Result, DestroyDebugReportCallbackEXT => (instance: Instance, callback: DebugReportCallbackEXT, pAllocator: *const AllocationCallbacks) -> (), DebugReportMessageEXT => (instance: Instance, flags: DebugReportFlagsEXT, objectType: DebugReportObjectTypeEXT, object: u64, location: usize, messageCode: i32, pLayerPrefix: *const c_char, pMessage: *const c_char) -> (), + CreateViSurfaceNN => (instance: Instance, pCreateInfo: *const ViSurfaceCreateInfoNN, pAllocator: *const AllocationCallbacks, pSurface: *mut SurfaceKHR) -> Result, }); ptrs!(DevicePointers, { diff --git a/vulkano/src/instance/extensions.rs b/vulkano/src/instance/extensions.rs index fe88c0e8..f231c59d 100644 --- a/vulkano/src/instance/extensions.rs +++ b/vulkano/src/instance/extensions.rs @@ -134,6 +134,7 @@ instance_extensions! { khr_android_surface => b"VK_KHR_android_surface", khr_win32_surface => b"VK_KHR_win32_surface", ext_debug_report => b"VK_EXT_debug_report", + nn_vi_surface => b"VK_NN_vi_surface", } extensions! { diff --git a/vulkano/src/swapchain/surface.rs b/vulkano/src/swapchain/surface.rs index 25b2136d..babd2b54 100644 --- a/vulkano/src/swapchain/surface.rs +++ b/vulkano/src/swapchain/surface.rs @@ -329,6 +329,42 @@ impl Surface { })) } + /// Creates a `Surface` from a `code:nn::code:vi::code:Layer`. + /// + /// # Safety + /// + /// The caller must ensure that the `window` is correct and stays alive for the entire + /// lifetime of the surface. + pub unsafe fn from_vi_surface(instance: &Arc, window: *const T) + -> Result, SurfaceCreationError> + { + let vk = instance.pointers(); + + if !instance.loaded_extensions().nn_vi_surface { + return Err(SurfaceCreationError::MissingExtension { name: "VK_NN_vi_surface" }); + } + + let surface = { + let infos = vk::ViSurfaceCreateInfoNN { + sType: vk::STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN, + pNext: ptr::null(), + flags: 0, // reserved + window: window as *mut _, + }; + + let mut output = mem::uninitialized(); + try!(check_errors(vk.CreateViSurfaceNN(instance.internal_object(), &infos, + ptr::null(), &mut output))); + output + }; + + Ok(Arc::new(Surface { + instance: instance.clone(), + surface: surface, + has_swapchain: AtomicBool::new(false), + })) + } + /// Returns true if the given queue family can draw on this surface. pub fn is_supported(&self, queue: &QueueFamily) -> Result { unsafe { From f536b9db60b95771ccf89bc38162059bf54349e4 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 24 Jan 2017 17:05:04 +0100 Subject: [PATCH 02/11] Cleaner implementation of Debug for extensions structs --- vulkano/src/instance/extensions.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/vulkano/src/instance/extensions.rs b/vulkano/src/instance/extensions.rs index f231c59d..074c6780 100644 --- a/vulkano/src/instance/extensions.rs +++ b/vulkano/src/instance/extensions.rs @@ -11,6 +11,7 @@ use std::error; use std::ffi::CString; use std::fmt; use std::ptr; +use std::str; use Error; use OomError; @@ -22,7 +23,7 @@ use check_errors; macro_rules! extensions { ($sname:ident, $($ext:ident => $s:expr,)*) => ( /// List of extensions that are enabled or available. - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Copy, Clone, PartialEq, Eq)] #[allow(missing_docs)] pub struct $sname { $( @@ -64,6 +65,25 @@ macro_rules! extensions { } } } + + impl fmt::Debug for $sname { + #[allow(unused_assignments)] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "[")); + + let mut first = true; + + $( + if self.$ext { + if !first { try!(write!(f, ", ")); } + else { first = false; } + try!(f.write_str(str::from_utf8($s).unwrap())); + } + )* + + write!(f, "]") + } + } ); } From f039fb9123e5aa1a9fb9da2ac74dbc8e74fc3412 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 31 Jan 2017 09:50:19 +0100 Subject: [PATCH 03/11] Remove the debugging println in vulkano-shader --- vulkano-shaders/src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/vulkano-shaders/src/lib.rs b/vulkano-shaders/src/lib.rs index 93ac85c4..2186a052 100644 --- a/vulkano-shaders/src/lib.rs +++ b/vulkano-shaders/src/lib.rs @@ -65,9 +65,6 @@ pub fn reflect(name: &str, mut spirv: R) -> Result // now parsing the document let doc = try!(parse::parse_spirv(&data)); - // TODO: remove - println!("{:#?}", doc); - let mut output = String::new(); output.push_str(r#" #[allow(unused_imports)] From e67f615ad2539fb210d45c2dfdc1c2962399baac Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 31 Jan 2017 09:59:07 +0100 Subject: [PATCH 04/11] Add categories to all the crates --- glsl-to-spirv/Cargo.toml | 1 + vk-sys/Cargo.toml | 1 + vulkano-shaders/Cargo.toml | 1 + vulkano-win/Cargo.toml | 1 + vulkano/Cargo.toml | 1 + 5 files changed, 5 insertions(+) diff --git a/glsl-to-spirv/Cargo.toml b/glsl-to-spirv/Cargo.toml index f13f54b6..7f8956db 100644 --- a/glsl-to-spirv/Cargo.toml +++ b/glsl-to-spirv/Cargo.toml @@ -6,6 +6,7 @@ repository = "https://github.com/tomaka/vulkano" description = "Wrapper around the official GLSL to SPIR-V compiler" license = "MIT/Apache-2.0" build = "build/build.rs" +categories = ["rendering::graphics-api"] [dependencies] tempdir = "0.3.5" diff --git a/vk-sys/Cargo.toml b/vk-sys/Cargo.toml index b0fc3019..fbbd9f00 100644 --- a/vk-sys/Cargo.toml +++ b/vk-sys/Cargo.toml @@ -7,3 +7,4 @@ description = "Bindings for the Vulkan graphics API" license = "MIT/Apache-2.0" documentation = "https://docs.rs/vk-sys" keywords = ["vulkan", "bindings", "graphics", "gpu"] +categories = ["rendering::graphics-api"] diff --git a/vulkano-shaders/Cargo.toml b/vulkano-shaders/Cargo.toml index 6a86dcb6..a1bc0290 100644 --- a/vulkano-shaders/Cargo.toml +++ b/vulkano-shaders/Cargo.toml @@ -6,6 +6,7 @@ repository = "https://github.com/tomaka/vulkano" description = "Shaders " license = "MIT/Apache-2.0" documentation = "http://tomaka.github.io/vulkano/vulkano/index.html" +categories = ["rendering::graphics-api"] [dependencies] glsl-to-spirv = { version = "0.1.2", path = "../glsl-to-spirv" } diff --git a/vulkano-win/Cargo.toml b/vulkano-win/Cargo.toml index 9f5e371e..c8b1d86b 100644 --- a/vulkano-win/Cargo.toml +++ b/vulkano-win/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Pierre Krieger "] repository = "https://github.com/tomaka/vulkano" description = "Link between vulkano and winit" license = "MIT/Apache-2.0" +categories = ["rendering::graphics-api"] [dependencies] vulkano = { version = "0.3.0", path = "../vulkano" } diff --git a/vulkano/Cargo.toml b/vulkano/Cargo.toml index 45297bb7..1567a4cc 100644 --- a/vulkano/Cargo.toml +++ b/vulkano/Cargo.toml @@ -6,6 +6,7 @@ repository = "https://github.com/tomaka/vulkano" description = "Safe wrapper for the Vulkan graphics API" license = "MIT/Apache-2.0" documentation = "https://docs.rs/vulkano" +categories = ["rendering::graphics-api"] [dependencies] crossbeam = "0.2.10" From 543f6c567b214824e0c725e29e848b85efaf05a0 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 31 Jan 2017 17:09:03 +0100 Subject: [PATCH 05/11] Documentation for ColorSpace --- vulkano/src/swapchain/surface.rs | 82 +++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/vulkano/src/swapchain/surface.rs b/vulkano/src/swapchain/surface.rs index babd2b54..0e6821e2 100644 --- a/vulkano/src/swapchain/surface.rs +++ b/vulkano/src/swapchain/surface.rs @@ -812,9 +812,89 @@ impl Iterator for SupportedCompositeAlphaIter { } /// 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. What this means is that the RGB values +/// sent from the computer to the monitor are expected to be in sRGB, and the RGB values loaded +/// from an image file are supposed to be in sRGB as well. +/// +/// ## 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 usually not linear, and in +/// particular the popular sRGB color space is not linear. I 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 an image 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 implementaiton 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 is supported by +/// > the implementation 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 (for example by doing the conversion in a fragment shader if necessary), +/// otherwise colors will be incorrect. The implementation will never perform any additional +/// conversion after the colors have been written to the swapchain image. +/// +/// # How do I handle this correctly? +/// +/// When you write a cross-platform program, you should: +/// +/// - Always request the `SrgbNonLinear` color space when creating the swapchain. +/// - Images loaded from files (such as PNG, JPEG, etc.) should be put in an image whose format +/// has the `Srgb` suffix. +/// - Swapchain images should have a format with the `Srgb` suffix. +/// +/// If you follow these three rules, then everything should go well and 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)] pub enum ColorSpace { - /// Interpret it as sRGB. SrgbNonLinear, } From 62ef894514500eba56c7c30180ab0f79965f5468 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 2 Feb 2017 10:23:58 +0100 Subject: [PATCH 06/11] Add support for VK_EXT_swapchain_colorspace --- vk-sys/src/lib.rs | 12 +++++++++++ vulkano/src/instance/extensions.rs | 1 + vulkano/src/swapchain/surface.rs | 33 +++++++++++++++++++++++++++--- vulkano/src/swapchain/swapchain.rs | 25 +++++++++++++--------- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/vk-sys/src/lib.rs b/vk-sys/src/lib.rs index f0c48df5..70b9601a 100644 --- a/vk-sys/src/lib.rs +++ b/vk-sys/src/lib.rs @@ -888,6 +888,18 @@ pub type ColorSpaceKHR = u32; #[deprecated = "Renamed to COLOR_SPACE_SRGB_NONLINEAR_KHR"] pub const COLORSPACE_SRGB_NONLINEAR_KHR: u32 = 0; pub const COLOR_SPACE_SRGB_NONLINEAR_KHR: u32 = 0; +pub const COLOR_SPACE_DISPLAY_P3_LINEAR_EXT: u32 = 1000104001; +pub const COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: u32 = 1000104002; +pub const COLOR_SPACE_SCRGB_LINEAR_EXT: u32 = 1000104003; +pub const COLOR_SPACE_SCRGB_NONLINEAR_EXT: u32 = 1000104004; +pub const COLOR_SPACE_DCI_P3_LINEAR_EXT: u32 = 1000104005; +pub const COLOR_SPACE_DCI_P3_NONLINEAR_EXT: u32 = 1000104006; +pub const COLOR_SPACE_BT709_LINEAR_EXT: u32 = 1000104007; +pub const COLOR_SPACE_BT709_NONLINEAR_EXT: u32 = 1000104008; +pub const COLOR_SPACE_BT2020_LINEAR_EXT: u32 = 1000104009; +pub const COLOR_SPACE_BT2020_NONLINEAR_EXT: u32 = 1000104010; +pub const COLOR_SPACE_ADOBERGB_LINEAR_EXT: u32 = 1000104011; +pub const COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: u32 = 1000104012; pub type PresentModeKHR = u32; pub const PRESENT_MODE_IMMEDIATE_KHR: u32 = 0; diff --git a/vulkano/src/instance/extensions.rs b/vulkano/src/instance/extensions.rs index 074c6780..8b77eca1 100644 --- a/vulkano/src/instance/extensions.rs +++ b/vulkano/src/instance/extensions.rs @@ -155,6 +155,7 @@ instance_extensions! { khr_win32_surface => b"VK_KHR_win32_surface", ext_debug_report => b"VK_EXT_debug_report", nn_vi_surface => b"VK_NN_vi_surface", + ext_swapchain_colorspace => b"VK_EXT_swapchain_colorspace", } extensions! { diff --git a/vulkano/src/swapchain/surface.rs b/vulkano/src/swapchain/surface.rs index 0e6821e2..c15adc36 100644 --- a/vulkano/src/swapchain/surface.rs +++ b/vulkano/src/swapchain/surface.rs @@ -894,15 +894,42 @@ impl Iterator for SupportedCompositeAlphaIter { /// and perform a manual conversion to that color space from inside your shader. /// #[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[repr(u32)] pub enum ColorSpace { - SrgbNonLinear, + SrgbNonLinear = vk::COLOR_SPACE_SRGB_NONLINEAR_KHR, + DisplayP3Linear = vk::COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, + DisplayP3NonLinear = vk::COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, + ScrgbLinear = vk::COLOR_SPACE_SCRGB_LINEAR_EXT, + ScrgbNonLinear = vk::COLOR_SPACE_SCRGB_NONLINEAR_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, + Bt2020NonLinear = vk::COLOR_SPACE_BT2020_NONLINEAR_EXT, + AdobeRgbLinear = vk::COLOR_SPACE_ADOBERGB_LINEAR_EXT, + AdobeRgbNonLinear = vk::COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, } impl ColorSpace { #[inline] fn from_num(val: u32) -> ColorSpace { - assert_eq!(val, vk::COLOR_SPACE_SRGB_NONLINEAR_KHR); - ColorSpace::SrgbNonLinear + match val { + vk::COLOR_SPACE_SRGB_NONLINEAR_KHR => ColorSpace::SrgbNonLinear, + vk::COLOR_SPACE_DISPLAY_P3_LINEAR_EXT => ColorSpace::DisplayP3Linear, + vk::COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT => ColorSpace::DisplayP3NonLinear, + vk::COLOR_SPACE_SCRGB_LINEAR_EXT => ColorSpace::ScrgbLinear, + vk::COLOR_SPACE_SCRGB_NONLINEAR_EXT => ColorSpace::ScrgbNonLinear, + 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_BT2020_NONLINEAR_EXT => ColorSpace::Bt2020NonLinear, + vk::COLOR_SPACE_ADOBERGB_LINEAR_EXT => ColorSpace::AdobeRgbLinear, + vk::COLOR_SPACE_ADOBERGB_NONLINEAR_EXT => ColorSpace::AdobeRgbNonLinear, + _ => panic!("Wrong value for color space enum") + } } } diff --git a/vulkano/src/swapchain/swapchain.rs b/vulkano/src/swapchain/swapchain.rs index 6874cd52..a1ae8b4c 100644 --- a/vulkano/src/swapchain/swapchain.rs +++ b/vulkano/src/swapchain/swapchain.rs @@ -24,6 +24,7 @@ use image::ImageDimensions; use image::sys::UnsafeImage; use image::sys::Usage as ImageUsage; use image::swapchain::SwapchainImage; +use swapchain::ColorSpace; use swapchain::CompositeAlpha; use swapchain::PresentMode; use swapchain::Surface; @@ -67,6 +68,7 @@ pub struct Swapchain { // Parameters passed to the constructor. num_images: u32, format: Format, + color_space: ColorSpace, dimensions: [u32; 2], layers: u32, usage: ImageUsage, @@ -99,6 +101,7 @@ impl Swapchain { /// - Panics if `color_attachment` is false in `usage`. /// // TODO: remove `old_swapchain` parameter and add another function `with_old_swapchain`. + // TODO: add `ColorSpace` parameter #[inline] pub fn new(device: &Arc, surface: &Arc, num_images: u32, format: F, dimensions: [u32; 2], layers: u32, usage: &ImageUsage, sharing: S, @@ -107,9 +110,9 @@ impl Swapchain { -> Result<(Arc, Vec>), OomError> where F: FormatDesc, S: Into { - Swapchain::new_inner(device, surface, num_images, format.format(), dimensions, layers, - usage, sharing.into(), transform, alpha, mode, clipped, - old_swapchain.map(|s| &**s)) + Swapchain::new_inner(device, surface, num_images, format.format(), + ColorSpace::SrgbNonLinear, dimensions, layers, usage, sharing.into(), + transform, alpha, mode, clipped, old_swapchain.map(|s| &**s)) } /// Recreates the swapchain with new dimensions. @@ -117,16 +120,17 @@ impl Swapchain { -> Result<(Arc, Vec>), OomError> { Swapchain::new_inner(&self.device, &self.surface, self.num_images, self.format, - dimensions, self.layers, &self.usage, self.sharing.clone(), - self.transform, self.alpha, self.mode, self.clipped, Some(self)) + self.color_space, dimensions, self.layers, &self.usage, + self.sharing.clone(), self.transform, self.alpha, self.mode, + self.clipped, Some(self)) } // TODO: images layouts should always be set to "PRESENT", since we have no way to switch the // layout at present time fn new_inner(device: &Arc, surface: &Arc, num_images: u32, format: Format, - dimensions: [u32; 2], layers: u32, usage: &ImageUsage, sharing: SharingMode, - transform: SurfaceTransform, alpha: CompositeAlpha, mode: PresentMode, - clipped: bool, old_swapchain: Option<&Swapchain>) + color_space: ColorSpace, dimensions: [u32; 2], layers: u32, usage: &ImageUsage, + sharing: SharingMode, transform: SurfaceTransform, alpha: CompositeAlpha, + mode: PresentMode, clipped: bool, old_swapchain: Option<&Swapchain>) -> Result<(Arc, Vec>), OomError> { // Checking that the requested parameters match the capabilities. @@ -134,7 +138,7 @@ impl Swapchain { // TODO: return errors instead assert!(num_images >= capabilities.min_image_count); if let Some(c) = capabilities.max_image_count { assert!(num_images <= c) }; - assert!(capabilities.supported_formats.iter().find(|&&(f, _)| f == format).is_some()); + assert!(capabilities.supported_formats.iter().any(|&(f, c)| f == format && c == color_space)); assert!(dimensions[0] >= capabilities.min_image_extent[0]); assert!(dimensions[1] >= capabilities.min_image_extent[1]); assert!(dimensions[0] <= capabilities.max_image_extent[0]); @@ -182,7 +186,7 @@ impl Swapchain { surface: surface.internal_object(), minImageCount: num_images, imageFormat: format as u32, - imageColorSpace: vk::COLOR_SPACE_SRGB_NONLINEAR_KHR, // only available value + imageColorSpace: color_space as u32, imageExtent: vk::Extent2D { width: dimensions[0], height: dimensions[1] }, imageArrayLayers: layers, imageUsage: usage.to_usage_bits(), @@ -215,6 +219,7 @@ impl Swapchain { stale: Mutex::new(false), num_images: num_images, format: format, + color_space: color_space, dimensions: dimensions, layers: layers, usage: usage.clone(), From 45e1d587af370a274442c583b35839dcbc0e2a23 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 2 Feb 2017 11:23:52 +0100 Subject: [PATCH 07/11] More color space doc improvement --- vulkano/src/swapchain/surface.rs | 43 ++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/vulkano/src/swapchain/surface.rs b/vulkano/src/swapchain/surface.rs index 0e6821e2..8d6ba171 100644 --- a/vulkano/src/swapchain/surface.rs +++ b/vulkano/src/swapchain/surface.rs @@ -835,9 +835,7 @@ impl Iterator for SupportedCompositeAlphaIter { /// > 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. What this means is that the RGB values -/// sent from the computer to the monitor are expected to be in sRGB, and the RGB values loaded -/// from an image file are supposed to be in sRGB as well. +/// and most images files are encoded in this color space. /// /// ## Pixel formats and linear vs non-linear /// @@ -845,8 +843,8 @@ impl Iterator for SupportedCompositeAlphaIter { /// 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 usually not linear, and in -/// particular the popular sRGB color space is not linear. I a non-linear color space, a value of +/// 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 @@ -859,36 +857,43 @@ impl Iterator for SupportedCompositeAlphaIter { /// 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 an image 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. +/// 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 implementaiton can choose to send the data in the swapchain image directly to +/// > **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 is supported by -/// > the implementation is not necessarily the same as the one supported by the monitor. +/// > 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 (for example by doing the conversion in a fragment shader if necessary), -/// otherwise colors will be incorrect. The implementation will never perform any additional -/// conversion after the colors have been written to the swapchain image. +/// 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? /// -/// When you write a cross-platform program, you should: +/// The easiest way to handle color spaces in a cross-platform program is: /// /// - Always request the `SrgbNonLinear` color space when creating the swapchain. -/// - Images loaded from files (such as PNG, JPEG, etc.) should be put in an image whose format -/// has the `Srgb` suffix. +/// - 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. /// -/// If you follow these three rules, then everything should go well and render the same way on all -/// platforms. +/// > **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 intead. +/// +/// 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. From 9f9965c7104370fde1db811312e91021dd12ba6d Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 2 Feb 2017 20:50:38 +0100 Subject: [PATCH 08/11] Publish 0.3.2 --- .travis.yml | 5 +++++ vulkano-shader-derive/Cargo.toml | 7 ++++++- vulkano-shaders/Cargo.toml | 2 +- vulkano-win/Cargo.toml | 2 +- vulkano/Cargo.toml | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e2b766d8..a522d18f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ addons: script: - cargo test -v --manifest-path glsl-to-spirv/Cargo.toml - cargo test -v --manifest-path vulkano-shaders/Cargo.toml + - cargo test -v --manifest-path vulkano-shader-derive/Cargo.toml # We run the projects that depend on vulkano with `-j 1` or we have a # chance to reach travis' memory limit - cargo test -j 1 --manifest-path vulkano-win/Cargo.toml @@ -49,3 +50,7 @@ after_success: [ $TRAVIS_BRANCH = master ] && [ $TRAVIS_PULL_REQUEST = false ] && cargo publish --token ${CRATESIO_TOKEN} --manifest-path vulkano-shaders/Cargo.toml + - | + [ $TRAVIS_BRANCH = master ] && + [ $TRAVIS_PULL_REQUEST = false ] && + cargo publish --token ${CRATESIO_TOKEN} --manifest-path vulkano-shader-derive/Cargo.toml diff --git a/vulkano-shader-derive/Cargo.toml b/vulkano-shader-derive/Cargo.toml index 18aadb18..dd9c610a 100644 --- a/vulkano-shader-derive/Cargo.toml +++ b/vulkano-shader-derive/Cargo.toml @@ -1,7 +1,12 @@ [package] name = "vulkano-shader-derive" -version = "0.1.0" +version = "0.3.2" authors = ["Pierre Krieger "] +repository = "https://github.com/tomaka/vulkano" +description = "Safe wrapper for the Vulkan graphics API" +license = "MIT/Apache-2.0" +documentation = "https://docs.rs/vulkano" +categories = ["rendering::graphics-api"] [lib] name = "vulkano_shader_derive" diff --git a/vulkano-shaders/Cargo.toml b/vulkano-shaders/Cargo.toml index a1bc0290..7a8cbcc1 100644 --- a/vulkano-shaders/Cargo.toml +++ b/vulkano-shaders/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vulkano-shaders" -version = "0.3.1" +version = "0.3.2" authors = ["Pierre Krieger "] repository = "https://github.com/tomaka/vulkano" description = "Shaders " diff --git a/vulkano-win/Cargo.toml b/vulkano-win/Cargo.toml index c8b1d86b..43f7d988 100644 --- a/vulkano-win/Cargo.toml +++ b/vulkano-win/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vulkano-win" -version = "0.3.1" +version = "0.3.2" authors = ["Pierre Krieger "] repository = "https://github.com/tomaka/vulkano" description = "Link between vulkano and winit" diff --git a/vulkano/Cargo.toml b/vulkano/Cargo.toml index 1567a4cc..510e8dcf 100644 --- a/vulkano/Cargo.toml +++ b/vulkano/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vulkano" -version = "0.3.1" +version = "0.3.2" authors = ["Pierre Krieger "] repository = "https://github.com/tomaka/vulkano" description = "Safe wrapper for the Vulkan graphics API" From 36bfa12bcab156ab6f4ba8474b44b592333320d5 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 2 Feb 2017 22:30:23 +0100 Subject: [PATCH 09/11] Fix missing vk-sys update --- vk-sys/Cargo.toml | 2 +- vulkano/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vk-sys/Cargo.toml b/vk-sys/Cargo.toml index fbbd9f00..a005cd13 100644 --- a/vk-sys/Cargo.toml +++ b/vk-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vk-sys" -version = "0.2.1" +version = "0.2.2" authors = ["Pierre Krieger "] repository = "https://github.com/tomaka/vulkano" description = "Bindings for the Vulkan graphics API" diff --git a/vulkano/Cargo.toml b/vulkano/Cargo.toml index 510e8dcf..575b67a4 100644 --- a/vulkano/Cargo.toml +++ b/vulkano/Cargo.toml @@ -14,4 +14,4 @@ fnv = "1.0.5" shared_library = "0.1.5" smallvec = "0.3.1" lazy_static = "0.2.2" -vk-sys = { version = "0.2.1", path = "../vk-sys" } +vk-sys = { version = "0.2.2", path = "../vk-sys" } From ebe1005ec8104b790cd12b5601fee2873f3fb59a Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 8 Feb 2017 13:11:00 +0100 Subject: [PATCH 10/11] Add a note about the SDK --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 4839e733..c7a5929c 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,11 @@ What does vulkano do? **Warning: this library breaks every five minutes for the moment.** +Note that vulkano does **not** require you to install the official Vulkan SDK. This is not +something specific to vulkano (you don't need to SDK to write program that use Vulkan, even +without vulkano), but many people are unaware of that and install the SDK thinking that it is +required. + ## [Documentation](https://docs.rs/vulkano) [![](https://docs.rs/vulkano/badge.svg)](https://docs.rs/vulkano) From 0ddfd8ff4dfb97cbd57a61193ada27b3296803fe Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 3 Feb 2017 09:44:02 +0100 Subject: [PATCH 11/11] Fix some types not being reexported --- vulkano/src/swapchain/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vulkano/src/swapchain/mod.rs b/vulkano/src/swapchain/mod.rs index 42e1b2ae..494c0a6a 100644 --- a/vulkano/src/swapchain/mod.rs +++ b/vulkano/src/swapchain/mod.rs @@ -193,8 +193,12 @@ use vk; pub use self::surface::Capabilities; pub use self::surface::Surface; pub use self::surface::PresentMode; +pub use self::surface::SupportedPresentModes; +pub use self::surface::SupportedPresentModesIter; pub use self::surface::SurfaceTransform; pub use self::surface::CompositeAlpha; +pub use self::surface::SupportedCompositeAlpha; +pub use self::surface::SupportedCompositeAlphaIter; pub use self::surface::ColorSpace; pub use self::surface::SurfaceCreationError; pub use self::swapchain::Swapchain;