Merge branch 'master' into incoming

This commit is contained in:
Pierre Krieger 2017-02-08 19:46:56 +01:00
commit 1808356a81
14 changed files with 245 additions and 24 deletions

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -1,9 +1,10 @@
[package]
name = "vk-sys"
version = "0.2.1"
version = "0.2.2"
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
repository = "https://github.com/tomaka/vulkano"
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"]

View File

@ -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;
@ -887,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;
@ -2368,6 +2381,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 +2487,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, {

View File

@ -1,7 +1,12 @@
[package]
name = "vulkano-shader-derive"
version = "0.1.0"
version = "0.3.2"
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
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"

View File

@ -1,11 +1,12 @@
[package]
name = "vulkano-shaders"
version = "0.3.1"
version = "0.3.2"
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
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" }

View File

@ -65,9 +65,6 @@ pub fn reflect<R>(name: &str, mut spirv: R) -> Result<String, Error>
// 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)]

View File

@ -1,10 +1,11 @@
[package]
name = "vulkano-win"
version = "0.3.1"
version = "0.3.2"
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
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" }

View File

@ -1,11 +1,12 @@
[package]
name = "vulkano"
version = "0.3.1"
version = "0.3.2"
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
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"
@ -13,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" }

View File

@ -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, "]")
}
}
);
}
@ -134,6 +154,8 @@ 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",
ext_swapchain_colorspace => b"VK_EXT_swapchain_colorspace",
}
extensions! {

View File

@ -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;

View File

@ -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<T>(instance: &Arc<Instance>, window: *const T)
-> Result<Arc<Surface>, 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<bool, OomError> {
unsafe {
@ -776,17 +812,129 @@ 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.
///
/// ## 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 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.
///
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ColorSpace {
/// Interpret it as sRGB.
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")
}
}
}

View File

@ -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<F, S>(device: &Arc<Device>, surface: &Arc<Surface>, num_images: u32, format: F,
dimensions: [u32; 2], layers: u32, usage: &ImageUsage, sharing: S,
@ -107,9 +110,9 @@ impl Swapchain {
-> Result<(Arc<Swapchain>, Vec<Arc<SwapchainImage>>), OomError>
where F: FormatDesc, S: Into<SharingMode>
{
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<Swapchain>, Vec<Arc<SwapchainImage>>), 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<Device>, surface: &Arc<Surface>, 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<Swapchain>, Vec<Arc<SwapchainImage>>), 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(),