Merge pull request #260 from tomaka/cubemap

Add support for cubemap images
This commit is contained in:
tomaka 2016-09-12 13:40:20 +02:00 committed by GitHub
commit 27d23725ae
10 changed files with 302 additions and 134 deletions

View File

@ -13,7 +13,7 @@ extern crate vulkano;
use vulkano::device::{Device, DeviceExtensions}; use vulkano::device::{Device, DeviceExtensions};
use vulkano::format::Format; use vulkano::format::Format;
use vulkano::image::ImmutableImage; use vulkano::image::ImmutableImage;
use vulkano::image::sys::Dimensions; use vulkano::image::Dimensions;
use vulkano::instance; use vulkano::instance;
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice}; use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::instance::debug::{DebugCallback, MessageTypes}; use vulkano::instance::debug::{DebugCallback, MessageTypes};

View File

@ -107,7 +107,7 @@ fn main() {
color: (vulkano::format::B8G8R8A8Srgb, 1) color: (vulkano::format::B8G8R8A8Srgb, 1)
}).unwrap(); }).unwrap();
let texture = vulkano::image::immutable::ImmutableImage::new(&device, vulkano::image::sys::Dimensions::Dim2d { width: 93, height: 93 }, let texture = vulkano::image::immutable::ImmutableImage::new(&device, vulkano::image::Dimensions::Dim2d { width: 93, height: 93 },
vulkano::format::R8G8B8A8Unorm, Some(queue.family())).unwrap(); vulkano::format::R8G8B8A8Unorm, Some(queue.family())).unwrap();

View File

@ -19,7 +19,9 @@ use device::Device;
use format::ClearValue; use format::ClearValue;
use format::FormatDesc; use format::FormatDesc;
use format::FormatTy; use format::FormatTy;
use image::sys::Dimensions; use image::Dimensions;
use image::ImageDimensions;
use image::ViewType;
use image::sys::ImageCreationError; use image::sys::ImageCreationError;
use image::sys::Layout; use image::sys::Layout;
use image::sys::UnsafeImage; use image::sys::UnsafeImage;
@ -154,7 +156,7 @@ impl<F> AttachmentImage<F> {
let (image, mem_reqs) = unsafe { let (image, mem_reqs) = unsafe {
try!(UnsafeImage::new(device, &usage, format.format(), try!(UnsafeImage::new(device, &usage, format.format(),
Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] }, ImageDimensions::Dim2d { width: dimensions[0], height: dimensions[1], array_layers: 1, cubemap_compatible: false },
1, 1, Sharing::Exclusive::<Empty<u32>>, false, false)) 1, 1, Sharing::Exclusive::<Empty<u32>>, false, false))
}; };
@ -173,7 +175,7 @@ impl<F> AttachmentImage<F> {
unsafe { try!(image.bind_memory(mem.memory(), mem.offset())); } unsafe { try!(image.bind_memory(mem.memory(), mem.offset())); }
let view = unsafe { let view = unsafe {
try!(UnsafeImageView::raw(&image, 0 .. 1, 0 .. 1)) try!(UnsafeImageView::raw(&image, ViewType::Dim2d, 0 .. 1, 0 .. 1))
}; };
Ok(Arc::new(AttachmentImage { Ok(Arc::new(AttachmentImage {
@ -301,6 +303,12 @@ unsafe impl<F, A> ImageView for AttachmentImage<F, A>
me.clone() as Arc<_> me.clone() as Arc<_>
} }
#[inline]
fn dimensions(&self) -> Dimensions {
let dims = self.image.dimensions();
Dimensions::Dim2d { width: dims.width(), height: dims.height() }
}
#[inline] #[inline]
fn blocks(&self) -> Vec<(u32, u32)> { fn blocks(&self) -> Vec<(u32, u32)> {
vec![(0, 0)] vec![(0, 0)]

View File

@ -20,7 +20,7 @@ use smallvec::SmallVec;
use command_buffer::Submission; use command_buffer::Submission;
use device::Device; use device::Device;
use format::FormatDesc; use format::FormatDesc;
use image::sys::Dimensions; use image::Dimensions;
use image::sys::ImageCreationError; use image::sys::ImageCreationError;
use image::sys::Layout; use image::sys::Layout;
use image::sys::UnsafeImage; use image::sys::UnsafeImage;
@ -45,6 +45,7 @@ use sync::Sharing;
pub struct ImmutableImage<F, A = Arc<StdMemoryPool>> where A: MemoryPool { pub struct ImmutableImage<F, A = Arc<StdMemoryPool>> where A: MemoryPool {
image: UnsafeImage, image: UnsafeImage,
view: UnsafeImageView, view: UnsafeImageView,
dimensions: Dimensions,
memory: A::Alloc, memory: A::Alloc,
format: F, format: F,
per_layer: SmallVec<[PerLayer; 1]>, per_layer: SmallVec<[PerLayer; 1]>,
@ -79,7 +80,7 @@ impl<F> ImmutableImage<F> {
Sharing::Exclusive Sharing::Exclusive
}; };
try!(UnsafeImage::new(device, &usage, format.format(), dimensions, try!(UnsafeImage::new(device, &usage, format.format(), dimensions.to_image_dimensions(),
1, 1, Sharing::Exclusive::<Empty<u32>>, false, false)) 1, 1, Sharing::Exclusive::<Empty<u32>>, false, false))
}; };
@ -98,7 +99,7 @@ impl<F> ImmutableImage<F> {
unsafe { try!(image.bind_memory(mem.memory(), mem.offset())); } unsafe { try!(image.bind_memory(mem.memory(), mem.offset())); }
let view = unsafe { let view = unsafe {
try!(UnsafeImageView::raw(&image, 0 .. image.mipmap_levels(), try!(UnsafeImageView::raw(&image, dimensions.to_view_type(), 0 .. image.mipmap_levels(),
0 .. image.dimensions().array_layers())) 0 .. image.dimensions().array_layers()))
}; };
@ -106,6 +107,7 @@ impl<F> ImmutableImage<F> {
image: image, image: image,
view: view, view: view,
memory: mem, memory: mem,
dimensions: dimensions,
format: format, format: format,
per_layer: { per_layer: {
let mut v = SmallVec::new(); let mut v = SmallVec::new();
@ -125,7 +127,7 @@ impl<F, A> ImmutableImage<F, A> where A: MemoryPool {
/// Returns the dimensions of the image. /// Returns the dimensions of the image.
#[inline] #[inline]
pub fn dimensions(&self) -> Dimensions { pub fn dimensions(&self) -> Dimensions {
self.image.dimensions() self.dimensions
} }
} }
@ -229,6 +231,11 @@ unsafe impl<F: 'static, A> ImageView for ImmutableImage<F, A>
me.clone() as Arc<_> me.clone() as Arc<_>
} }
#[inline]
fn dimensions(&self) -> Dimensions {
self.dimensions
}
#[inline] #[inline]
fn blocks(&self) -> Vec<(u32, u32)> { fn blocks(&self) -> Vec<(u32, u32)> {
vec![(0, 0)] vec![(0, 0)]

View File

@ -136,3 +136,180 @@ impl Default for ComponentSwizzle {
ComponentSwizzle::Identity ComponentSwizzle::Identity
} }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Dimensions {
Dim1d { width: u32 },
Dim1dArray { width: u32, array_layers: u32 },
Dim2d { width: u32, height: u32 },
Dim2dArray { width: u32, height: u32, array_layers: u32 },
Dim3d { width: u32, height: u32, depth: u32 },
Cubemap { size: u32 },
CubemapArray { size: u32, array_layers: u32 },
}
impl Dimensions {
#[inline]
pub fn width(&self) -> u32 {
match *self {
Dimensions::Dim1d { width } => width,
Dimensions::Dim1dArray { width, .. } => width,
Dimensions::Dim2d { width, .. } => width,
Dimensions::Dim2dArray { width, .. } => width,
Dimensions::Dim3d { width, .. } => width,
Dimensions::Cubemap { size } => size,
Dimensions::CubemapArray { size, .. } => size,
}
}
#[inline]
pub fn height(&self) -> u32 {
match *self {
Dimensions::Dim1d { .. } => 1,
Dimensions::Dim1dArray { .. } => 1,
Dimensions::Dim2d { height, .. } => height,
Dimensions::Dim2dArray { height, .. } => height,
Dimensions::Dim3d { height, .. } => height,
Dimensions::Cubemap { size } => size,
Dimensions::CubemapArray { size, .. } => size,
}
}
#[inline]
pub fn width_height(&self) -> [u32; 2] {
[self.width(), self.height()]
}
#[inline]
pub fn depth(&self) -> u32 {
match *self {
Dimensions::Dim1d { .. } => 1,
Dimensions::Dim1dArray { .. } => 1,
Dimensions::Dim2d { .. } => 1,
Dimensions::Dim2dArray { .. } => 1,
Dimensions::Dim3d { depth, .. } => depth,
Dimensions::Cubemap { .. } => 1,
Dimensions::CubemapArray { .. } => 1,
}
}
#[inline]
pub fn array_layers(&self) -> u32 {
match *self {
Dimensions::Dim1d { .. } => 1,
Dimensions::Dim1dArray { array_layers, .. } => array_layers,
Dimensions::Dim2d { .. } => 1,
Dimensions::Dim2dArray { array_layers, .. } => array_layers,
Dimensions::Dim3d { .. } => 1,
Dimensions::Cubemap { .. } => 1,
Dimensions::CubemapArray { array_layers, .. } => array_layers,
}
}
/// Builds the corresponding `ImageDimensions`.
#[inline]
pub fn to_image_dimensions(&self) -> ImageDimensions {
match *self {
Dimensions::Dim1d { width } => {
ImageDimensions::Dim1d { width: width, array_layers: 1 }
},
Dimensions::Dim1dArray { width, array_layers } => {
ImageDimensions::Dim1d { width: width, array_layers: array_layers }
},
Dimensions::Dim2d { width, height } => {
ImageDimensions::Dim2d { width: width, height: height, array_layers: 1,
cubemap_compatible: false }
},
Dimensions::Dim2dArray { width, height, array_layers } => {
ImageDimensions::Dim2d { width: width, height: height,
array_layers: array_layers, cubemap_compatible: false }
},
Dimensions::Dim3d { width, height, depth } => {
ImageDimensions::Dim3d { width: width, height: height, depth: depth }
},
Dimensions::Cubemap { size } => {
ImageDimensions::Dim2d { width: size, height: size, array_layers: 6,
cubemap_compatible: true }
},
Dimensions::CubemapArray { size, array_layers } => {
ImageDimensions::Dim2d { width: size, height: size, array_layers: array_layers * 6,
cubemap_compatible: true }
},
}
}
/// Builds the corresponding `ViewType`.
#[inline]
pub fn to_view_type(&self) -> ViewType {
match *self {
Dimensions::Dim1d { .. } => ViewType::Dim1d,
Dimensions::Dim1dArray { .. } => ViewType::Dim1dArray,
Dimensions::Dim2d { .. } => ViewType::Dim2d,
Dimensions::Dim2dArray { .. } => ViewType::Dim2dArray,
Dimensions::Dim3d { .. } => ViewType::Dim3d,
Dimensions::Cubemap { .. } => ViewType::Cubemap,
Dimensions::CubemapArray { .. } => ViewType::CubemapArray,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ViewType {
Dim1d,
Dim1dArray,
Dim2d,
Dim2dArray,
Dim3d,
Cubemap,
CubemapArray,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ImageDimensions {
Dim1d { width: u32, array_layers: u32 },
Dim2d { width: u32, height: u32, array_layers: u32, cubemap_compatible: bool },
Dim3d { width: u32, height: u32, depth: u32 }
}
impl ImageDimensions {
#[inline]
pub fn width(&self) -> u32 {
match *self {
ImageDimensions::Dim1d { width, .. } => width,
ImageDimensions::Dim2d { width, .. } => width,
ImageDimensions::Dim3d { width, .. } => width,
}
}
#[inline]
pub fn height(&self) -> u32 {
match *self {
ImageDimensions::Dim1d { .. } => 1,
ImageDimensions::Dim2d { height, .. } => height,
ImageDimensions::Dim3d { height, .. } => height,
}
}
#[inline]
pub fn width_height(&self) -> [u32; 2] {
[self.width(), self.height()]
}
#[inline]
pub fn depth(&self) -> u32 {
match *self {
ImageDimensions::Dim1d { .. } => 1,
ImageDimensions::Dim2d { .. } => 1,
ImageDimensions::Dim3d { depth, .. } => depth,
}
}
#[inline]
pub fn array_layers(&self) -> u32 {
match *self {
ImageDimensions::Dim1d { array_layers, .. } => array_layers,
ImageDimensions::Dim2d { array_layers, .. } => array_layers,
ImageDimensions::Dim3d { .. } => 1,
}
}
}

View File

@ -20,7 +20,7 @@ use device::Device;
use format::ClearValue; use format::ClearValue;
use format::FormatDesc; use format::FormatDesc;
use format::FormatTy; use format::FormatTy;
use image::sys::Dimensions; use image::Dimensions;
use image::sys::ImageCreationError; use image::sys::ImageCreationError;
use image::sys::Layout; use image::sys::Layout;
use image::sys::UnsafeImage; use image::sys::UnsafeImage;
@ -53,6 +53,9 @@ pub struct StorageImage<F, A = Arc<StdMemoryPool>> where A: MemoryPool {
// Memory used to back the image. // Memory used to back the image.
memory: A::Alloc, memory: A::Alloc,
// Dimensions of the image view.
dimensions: Dimensions,
// Format. // Format.
format: F, format: F,
@ -111,7 +114,7 @@ impl<F> StorageImage<F> {
Sharing::Exclusive Sharing::Exclusive
}; };
try!(UnsafeImage::new(device, &usage, format.format(), dimensions, try!(UnsafeImage::new(device, &usage, format.format(), dimensions.to_image_dimensions(),
1, 1, Sharing::Exclusive::<Empty<u32>>, false, false)) 1, 1, Sharing::Exclusive::<Empty<u32>>, false, false))
}; };
@ -130,7 +133,7 @@ impl<F> StorageImage<F> {
unsafe { try!(image.bind_memory(mem.memory(), mem.offset())); } unsafe { try!(image.bind_memory(mem.memory(), mem.offset())); }
let view = unsafe { let view = unsafe {
try!(UnsafeImageView::raw(&image, 0 .. image.mipmap_levels(), try!(UnsafeImageView::raw(&image, dimensions.to_view_type(), 0 .. image.mipmap_levels(),
0 .. image.dimensions().array_layers())) 0 .. image.dimensions().array_layers()))
}; };
@ -138,6 +141,7 @@ impl<F> StorageImage<F> {
image: image, image: image,
view: view, view: view,
memory: mem, memory: mem,
dimensions: dimensions,
format: format, format: format,
queue_families: queue_families, queue_families: queue_families,
guarded: Mutex::new(Guarded { guarded: Mutex::new(Guarded {
@ -153,7 +157,7 @@ impl<F, A> StorageImage<F, A> where A: MemoryPool {
/// Returns the dimensions of the image. /// Returns the dimensions of the image.
#[inline] #[inline]
pub fn dimensions(&self) -> Dimensions { pub fn dimensions(&self) -> Dimensions {
self.image.dimensions() self.dimensions
} }
} }
@ -281,6 +285,11 @@ unsafe impl<F, A> ImageView for StorageImage<F, A>
me.clone() as Arc<_> me.clone() as Arc<_>
} }
#[inline]
fn dimensions(&self) -> Dimensions {
self.dimensions
}
#[inline] #[inline]
fn blocks(&self) -> Vec<(u32, u32)> { fn blocks(&self) -> Vec<(u32, u32)> {
vec![(0, 0)] vec![(0, 0)]
@ -321,7 +330,7 @@ unsafe impl<F, A> ImageView for StorageImage<F, A>
mod tests { mod tests {
use super::StorageImage; use super::StorageImage;
use format::Format; use format::Format;
use image::sys::Dimensions; use image::Dimensions;
#[test] #[test]
fn create() { fn create() {

View File

@ -18,6 +18,8 @@ use device::Queue;
use format::ClearValue; use format::ClearValue;
use format::Format; use format::Format;
use format::FormatDesc; use format::FormatDesc;
use image::Dimensions;
use image::ViewType;
use image::traits::AccessRange; use image::traits::AccessRange;
use image::traits::CommandBufferState; use image::traits::CommandBufferState;
use image::traits::CommandListState; use image::traits::CommandListState;
@ -78,7 +80,7 @@ impl SwapchainImage {
pub unsafe fn from_raw(image: UnsafeImage, format: Format, swapchain: &Arc<Swapchain>, id: u32) pub unsafe fn from_raw(image: UnsafeImage, format: Format, swapchain: &Arc<Swapchain>, id: u32)
-> Result<Arc<SwapchainImage>, OomError> -> Result<Arc<SwapchainImage>, OomError>
{ {
let view = try!(UnsafeImageView::raw(&image, 0 .. 1, 0 .. 1)); let view = try!(UnsafeImageView::raw(&image, ViewType::Dim2d, 0 .. 1, 0 .. 1));
Ok(Arc::new(SwapchainImage { Ok(Arc::new(SwapchainImage {
image: image, image: image,
@ -223,6 +225,12 @@ unsafe impl ImageView for SwapchainImage {
me.clone() as Arc<_> me.clone() as Arc<_>
} }
#[inline]
fn dimensions(&self) -> Dimensions {
let dims = self.image.dimensions();
Dimensions::Dim2d { width: dims.width(), height: dims.height() }
}
#[inline] #[inline]
fn blocks(&self) -> Vec<(u32, u32)> { fn blocks(&self) -> Vec<(u32, u32)> {
vec![(0, 0)] vec![(0, 0)]

View File

@ -24,7 +24,9 @@ use smallvec::SmallVec;
use device::Device; use device::Device;
use format::Format; use format::Format;
use format::FormatTy; use format::FormatTy;
use image::ImageDimensions;
use image::MipmapsCount; use image::MipmapsCount;
use image::ViewType;
use memory::DeviceMemory; use memory::DeviceMemory;
use memory::MemoryRequirements; use memory::MemoryRequirements;
use sync::Sharing; use sync::Sharing;
@ -56,7 +58,7 @@ pub struct UnsafeImage {
usage: vk::ImageUsageFlagBits, usage: vk::ImageUsageFlagBits,
format: Format, format: Format,
dimensions: Dimensions, dimensions: ImageDimensions,
samples: u32, samples: u32,
mipmaps: u32, mipmaps: u32,
@ -78,7 +80,7 @@ impl UnsafeImage {
/// ///
#[inline] #[inline]
pub unsafe fn new<'a, Mi, I>(device: &Arc<Device>, usage: &Usage, format: Format, pub unsafe fn new<'a, Mi, I>(device: &Arc<Device>, usage: &Usage, format: Format,
dimensions: Dimensions, num_samples: u32, mipmaps: Mi, dimensions: ImageDimensions, num_samples: u32, mipmaps: Mi,
sharing: Sharing<I>, linear_tiling: bool, sharing: Sharing<I>, linear_tiling: bool,
preinitialized_layout: bool) preinitialized_layout: bool)
-> Result<(UnsafeImage, MemoryRequirements), ImageCreationError> -> Result<(UnsafeImage, MemoryRequirements), ImageCreationError>
@ -95,7 +97,7 @@ impl UnsafeImage {
// Non-templated version to avoid inlining and improve compile times. // Non-templated version to avoid inlining and improve compile times.
unsafe fn new_impl(device: &Arc<Device>, usage: &Usage, format: Format, unsafe fn new_impl(device: &Arc<Device>, usage: &Usage, format: Format,
dimensions: Dimensions, num_samples: u32, mipmaps: MipmapsCount, dimensions: ImageDimensions, num_samples: u32, mipmaps: MipmapsCount,
(sh_mode, sh_indices): (vk::SharingMode, SmallVec<[u32; 8]>), (sh_mode, sh_indices): (vk::SharingMode, SmallVec<[u32; 8]>),
linear_tiling: bool, preinitialized_layout: bool) linear_tiling: bool, preinitialized_layout: bool)
-> Result<(UnsafeImage, MemoryRequirements), ImageCreationError> -> Result<(UnsafeImage, MemoryRequirements), ImageCreationError>
@ -168,11 +170,11 @@ impl UnsafeImage {
// TODO: only compte if necessary? // TODO: only compte if necessary?
let max_mipmaps = { let max_mipmaps = {
let smallest_dim: u32 = match dimensions { let smallest_dim: u32 = match dimensions {
Dimensions::Dim1d { width } | Dimensions::Dim1dArray { width, .. } => width, ImageDimensions::Dim1d { width, .. } => width,
Dimensions::Dim2d { width, height } | Dimensions::Dim2dArray { width, height, .. } => { ImageDimensions::Dim2d { width, height, .. } => {
if width < height { width } else { height } if width < height { width } else { height }
}, },
Dimensions::Dim3d { width, height, depth } => { ImageDimensions::Dim3d { width, height, depth } => {
if width < height { if width < height {
if depth < width { depth } else { width } if depth < width { depth } else { width }
} else { } else {
@ -285,41 +287,29 @@ impl UnsafeImage {
} }
// Decoding the dimensions. // Decoding the dimensions.
let (ty, extent, array_layers) = match dimensions { let (ty, extent, array_layers, flags) = match dimensions {
Dimensions::Dim1d { width } => { ImageDimensions::Dim1d { width, array_layers } => {
if width == 0 {
return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions });
}
let extent = vk::Extent3D { width: width, height: 1, depth: 1 };
(vk::IMAGE_TYPE_1D, extent, 1)
},
Dimensions::Dim1dArray { width, array_layers } => {
if width == 0 || array_layers == 0 { if width == 0 || array_layers == 0 {
return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions }); return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions });
} }
let extent = vk::Extent3D { width: width, height: 1, depth: 1 }; let extent = vk::Extent3D { width: width, height: 1, depth: 1 };
(vk::IMAGE_TYPE_1D, extent, array_layers) (vk::IMAGE_TYPE_1D, extent, array_layers, 0)
}, },
Dimensions::Dim2d { width, height } => { ImageDimensions::Dim2d { width, height, array_layers, cubemap_compatible } => {
if width == 0 || height == 0 {
return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions });
}
let extent = vk::Extent3D { width: width, height: height, depth: 1 };
(vk::IMAGE_TYPE_2D, extent, 1)
},
Dimensions::Dim2dArray { width, height, array_layers } => {
if width == 0 || height == 0 || array_layers == 0 { if width == 0 || height == 0 || array_layers == 0 {
return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions }); return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions });
} }
let extent = vk::Extent3D { width: width, height: height, depth: 1 }; let extent = vk::Extent3D { width: width, height: height, depth: 1 };
(vk::IMAGE_TYPE_2D, extent, array_layers) let flags = if cubemap_compatible { vk::IMAGE_CREATE_CUBE_COMPATIBLE_BIT }
else { 0 };
(vk::IMAGE_TYPE_2D, extent, array_layers, flags)
}, },
Dimensions::Dim3d { width, height, depth } => { ImageDimensions::Dim3d { width, height, depth } => {
if width == 0 || height == 0 || depth == 0 { if width == 0 || height == 0 || depth == 0 {
return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions }); return Err(ImageCreationError::UnsupportedDimensions { dimensions: dimensions });
} }
let extent = vk::Extent3D { width: width, height: height, depth: depth }; let extent = vk::Extent3D { width: width, height: height, depth: depth };
(vk::IMAGE_TYPE_3D, extent, 1) (vk::IMAGE_TYPE_3D, extent, 1, 0)
}, },
}; };
@ -388,7 +378,7 @@ impl UnsafeImage {
let infos = vk::ImageCreateInfo { let infos = vk::ImageCreateInfo {
sType: vk::STRUCTURE_TYPE_IMAGE_CREATE_INFO, sType: vk::STRUCTURE_TYPE_IMAGE_CREATE_INFO,
pNext: ptr::null(), pNext: ptr::null(),
flags: 0, // TODO: flags: flags,
imageType: ty, imageType: ty,
format: format as u32, format: format as u32,
extent: extent, extent: extent,
@ -443,7 +433,7 @@ impl UnsafeImage {
/// ///
/// This function is for example used at the swapchain's initialization. /// This function is for example used at the swapchain's initialization.
pub unsafe fn from_raw(device: &Arc<Device>, handle: u64, usage: u32, format: Format, pub unsafe fn from_raw(device: &Arc<Device>, handle: u64, usage: u32, format: Format,
dimensions: Dimensions, samples: u32, mipmaps: u32) dimensions: ImageDimensions, samples: u32, mipmaps: u32)
-> UnsafeImage -> UnsafeImage
{ {
let vk_i = device.instance().pointers(); let vk_i = device.instance().pointers();
@ -503,7 +493,7 @@ impl UnsafeImage {
} }
#[inline] #[inline]
pub fn dimensions(&self) -> Dimensions { pub fn dimensions(&self) -> ImageDimensions {
self.dimensions self.dimensions
} }
@ -642,7 +632,7 @@ pub enum ImageCreationError {
/// The requeted number of samples is not supported, or is 0. /// The requeted number of samples is not supported, or is 0.
UnsupportedSamplesCount { obtained: u32 }, UnsupportedSamplesCount { obtained: u32 },
/// The dimensions are too large, or one of the dimensions is 0. /// The dimensions are too large, or one of the dimensions is 0.
UnsupportedDimensions { dimensions: Dimensions }, UnsupportedDimensions { dimensions: ImageDimensions },
/// The requested format is not supported by the Vulkan implementation. /// The requested format is not supported by the Vulkan implementation.
FormatNotSupported, FormatNotSupported,
/// The format is supported, but at least one of the requested usages is not supported. /// The format is supported, but at least one of the requested usages is not supported.
@ -742,8 +732,8 @@ pub struct UnsafeImageView {
impl UnsafeImageView { impl UnsafeImageView {
/// See the docs of new(). /// See the docs of new().
pub unsafe fn raw(image: &UnsafeImage, mipmap_levels: Range<u32>, array_layers: Range<u32>) pub unsafe fn raw(image: &UnsafeImage, ty: ViewType, mipmap_levels: Range<u32>,
-> Result<UnsafeImageView, OomError> array_layers: Range<u32>) -> Result<UnsafeImageView, OomError>
{ {
let vk = image.device.pointers(); let vk = image.device.pointers();
@ -761,21 +751,30 @@ impl UnsafeImageView {
FormatTy::DepthStencil => vk::IMAGE_ASPECT_DEPTH_BIT | vk::IMAGE_ASPECT_STENCIL_BIT, FormatTy::DepthStencil => vk::IMAGE_ASPECT_DEPTH_BIT | vk::IMAGE_ASPECT_STENCIL_BIT,
}; };
let view_type = match (image.dimensions(), ty, array_layers.end - array_layers.start) {
(ImageDimensions::Dim1d { .. }, ViewType::Dim1d, 1) => vk::IMAGE_VIEW_TYPE_1D,
(ImageDimensions::Dim1d { .. }, ViewType::Dim1dArray, _) => vk::IMAGE_VIEW_TYPE_1D_ARRAY,
(ImageDimensions::Dim2d { .. }, ViewType::Dim2d, 1) => vk::IMAGE_VIEW_TYPE_2D,
(ImageDimensions::Dim2d { .. }, ViewType::Dim2dArray, _) => vk::IMAGE_VIEW_TYPE_2D,
(ImageDimensions::Dim2d { cubemap_compatible, .. }, ViewType::Cubemap, n) if cubemap_compatible => {
assert_eq!(n, 6);
vk::IMAGE_VIEW_TYPE_CUBE
},
(ImageDimensions::Dim2d { cubemap_compatible, .. }, ViewType::CubemapArray, n) if cubemap_compatible => {
assert_eq!(n % 6, 0);
vk::IMAGE_VIEW_TYPE_CUBE_ARRAY
},
(ImageDimensions::Dim3d { .. }, ViewType::Dim3d, _) => vk::IMAGE_VIEW_TYPE_3D,
_ => panic!()
};
let view = { let view = {
let infos = vk::ImageViewCreateInfo { let infos = vk::ImageViewCreateInfo {
sType: vk::STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, sType: vk::STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
pNext: ptr::null(), pNext: ptr::null(),
flags: 0, // reserved flags: 0, // reserved
image: image.internal_object(), image: image.internal_object(),
viewType: match (image.dimensions(), array_layers.end - array_layers.start) { viewType: view_type, // TODO: cube
(Dimensions::Dim1d { .. }, _) => vk::IMAGE_VIEW_TYPE_1D,
(Dimensions::Dim1dArray { .. }, 1) => vk::IMAGE_VIEW_TYPE_1D,
(Dimensions::Dim1dArray { .. }, _) => vk::IMAGE_VIEW_TYPE_1D_ARRAY,
(Dimensions::Dim2d { .. }, _) => vk::IMAGE_VIEW_TYPE_2D,
(Dimensions::Dim2dArray { .. }, 1) => vk::IMAGE_VIEW_TYPE_2D,
(Dimensions::Dim2dArray { .. }, _) => vk::IMAGE_VIEW_TYPE_2D_ARRAY,
(Dimensions::Dim3d { .. }, _) => vk::IMAGE_VIEW_TYPE_3D,
}, // TODO: cube
format: image.format as u32, format: image.format as u32,
components: vk::ComponentMapping { r: 0, g: 0, b: 0, a: 0 }, // FIXME: components: vk::ComponentMapping { r: 0, g: 0, b: 0, a: 0 }, // FIXME:
subresourceRange: vk::ImageSubresourceRange { subresourceRange: vk::ImageSubresourceRange {
@ -809,12 +808,19 @@ impl UnsafeImageView {
/// ///
/// # Panic /// # Panic
/// ///
/// - Panics if `mipmap_levels` or `array_layers` is out of range of the image.
/// - Panics if the view types doesn't match the dimensions of the image (for example a 2D
/// view from a 3D image).
/// - Panics if trying to create a cubemap with a number of array layers different from 6.
/// - Panics if trying to create a cubemap array with a number of array layers not a multiple
/// of 6.
/// - Panics if the device or host ran out of memory. /// - Panics if the device or host ran out of memory.
///
#[inline] #[inline]
pub unsafe fn new(image: &UnsafeImage, mipmap_levels: Range<u32>, array_layers: Range<u32>) pub unsafe fn new(image: &UnsafeImage, ty: ViewType, mipmap_levels: Range<u32>,
-> UnsafeImageView array_layers: Range<u32>) -> UnsafeImageView
{ {
UnsafeImageView::raw(image, mipmap_levels, array_layers).unwrap() UnsafeImageView::raw(image, ty, mipmap_levels, array_layers).unwrap()
} }
#[inline] #[inline]
@ -882,66 +888,6 @@ impl Drop for UnsafeImageView {
} }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Dimensions {
Dim1d { width: u32 },
Dim1dArray { width: u32, array_layers: u32 },
Dim2d { width: u32, height: u32 },
Dim2dArray { width: u32, height: u32, array_layers: u32 },
Dim3d { width: u32, height: u32, depth: u32 }
}
impl Dimensions {
#[inline]
pub fn width(&self) -> u32 {
match *self {
Dimensions::Dim1d { width } => width,
Dimensions::Dim1dArray { width, .. } => width,
Dimensions::Dim2d { width, .. } => width,
Dimensions::Dim2dArray { width, .. } => width,
Dimensions::Dim3d { width, .. } => width,
}
}
#[inline]
pub fn height(&self) -> u32 {
match *self {
Dimensions::Dim1d { .. } => 1,
Dimensions::Dim1dArray { .. } => 1,
Dimensions::Dim2d { height, .. } => height,
Dimensions::Dim2dArray { height, .. } => height,
Dimensions::Dim3d { height, .. } => height,
}
}
#[inline]
pub fn width_height(&self) -> [u32; 2] {
[self.width(), self.height()]
}
#[inline]
pub fn depth(&self) -> u32 {
match *self {
Dimensions::Dim1d { .. } => 1,
Dimensions::Dim1dArray { .. } => 1,
Dimensions::Dim2d { .. } => 1,
Dimensions::Dim2dArray { .. } => 1,
Dimensions::Dim3d { depth, .. } => depth,
}
}
#[inline]
pub fn array_layers(&self) -> u32 {
match *self {
Dimensions::Dim1d { .. } => 1,
Dimensions::Dim1dArray { array_layers, .. } => array_layers,
Dimensions::Dim2d { .. } => 1,
Dimensions::Dim2dArray { array_layers, .. } => array_layers,
Dimensions::Dim3d { .. } => 1,
}
}
}
/// Describes how an image is going to be used. This is **not** an optimization. /// Describes how an image is going to be used. This is **not** an optimization.
/// ///
/// If you try to use an image in a way that you didn't declare, a panic will happen. /// If you try to use an image in a way that you didn't declare, a panic will happen.
@ -1076,11 +1022,11 @@ mod tests {
use std::iter::Empty; use std::iter::Empty;
use std::u32; use std::u32;
use super::Dimensions;
use super::ImageCreationError; use super::ImageCreationError;
use super::UnsafeImage; use super::UnsafeImage;
use super::Usage; use super::Usage;
use image::ImageDimensions;
use format::Format; use format::Format;
use sync::Sharing; use sync::Sharing;
@ -1095,7 +1041,8 @@ mod tests {
let (_img, _) = unsafe { let (_img, _) = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 1, 1, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 1, 1,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}.unwrap(); }.unwrap();
} }
@ -1112,7 +1059,8 @@ mod tests {
let (_img, _) = unsafe { let (_img, _) = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 1, 1, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 1, 1,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}.unwrap(); }.unwrap();
} }
@ -1128,7 +1076,8 @@ mod tests {
let res = unsafe { let res = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 0, 1, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 0, 1,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}; };
@ -1149,7 +1098,8 @@ mod tests {
let res = unsafe { let res = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 5, 1, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 5, 1,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}; };
@ -1170,7 +1120,8 @@ mod tests {
let res = unsafe { let res = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 1, 0, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 1, 0,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}; };
@ -1192,7 +1143,8 @@ mod tests {
let res = unsafe { let res = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 1, u32::MAX, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 1, u32::MAX,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}; };
@ -1216,7 +1168,8 @@ mod tests {
let res = unsafe { let res = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 2, 1, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 2, 1,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}; };
@ -1238,7 +1191,8 @@ mod tests {
let res = unsafe { let res = unsafe {
UnsafeImage::new(&device, &usage, Format::ASTC_5x4UnormBlock, UnsafeImage::new(&device, &usage, Format::ASTC_5x4UnormBlock,
Dimensions::Dim2d { width: 32, height: 32 }, 1, u32::MAX, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 1, u32::MAX,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}; };
@ -1261,7 +1215,8 @@ mod tests {
let res = unsafe { let res = unsafe {
UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm, UnsafeImage::new(&device, &usage, Format::R8G8B8A8Unorm,
Dimensions::Dim2d { width: 32, height: 32 }, 1, 1, ImageDimensions::Dim2d { width: 32, height: 32, array_layers: 1,
cubemap_compatible: false }, 1, 1,
Sharing::Exclusive::<Empty<_>>, false, false) Sharing::Exclusive::<Empty<_>>, false, false)
}; };

View File

@ -18,7 +18,8 @@ use command_buffer::Submission;
use device::Queue; use device::Queue;
use format::ClearValue; use format::ClearValue;
use format::Format; use format::Format;
use image::sys::Dimensions; use image::Dimensions;
use image::ImageDimensions;
use image::sys::Layout; use image::sys::Layout;
use image::sys::UnsafeImage; use image::sys::UnsafeImage;
use image::sys::UnsafeImageView; use image::sys::UnsafeImageView;
@ -51,7 +52,7 @@ pub unsafe trait Image: 'static + Send + Sync {
/// Returns the dimensions of the image. /// Returns the dimensions of the image.
#[inline] #[inline]
fn dimensions(&self) -> Dimensions { fn dimensions(&self) -> ImageDimensions {
self.inner().dimensions() self.inner().dimensions()
} }
@ -259,6 +260,9 @@ pub unsafe trait ImageView: 'static + Send + Sync {
fn parent_arc(&Arc<Self>) -> Arc<Image> where Self: Sized; fn parent_arc(&Arc<Self>) -> Arc<Image> where Self: Sized;
/// Returns the dimensions of the image view.
fn dimensions(&self) -> Dimensions;
/// Returns the inner unsafe image view object used by this image view. /// Returns the inner unsafe image view object used by this image view.
fn inner(&self) -> &UnsafeImageView; fn inner(&self) -> &UnsafeImageView;

View File

@ -20,7 +20,7 @@ use device::Device;
use device::Queue; use device::Queue;
use format::Format; use format::Format;
use format::FormatDesc; use format::FormatDesc;
use image::sys::Dimensions; use image::ImageDimensions;
use image::sys::UnsafeImage; use image::sys::UnsafeImage;
use image::sys::Usage as ImageUsage; use image::sys::Usage as ImageUsage;
use image::swapchain::SwapchainImage; use image::swapchain::SwapchainImage;
@ -214,7 +214,7 @@ impl Swapchain {
let images = images.into_iter().enumerate().map(|(id, image)| unsafe { let images = images.into_iter().enumerate().map(|(id, image)| unsafe {
let unsafe_image = UnsafeImage::from_raw(device, image, usage, format, let unsafe_image = UnsafeImage::from_raw(device, image, usage, format,
Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] }, 1, 1); ImageDimensions::Dim2d { width: dimensions[0], height: dimensions[1], array_layers: 1, cubemap_compatible: false }, 1, 1);
SwapchainImage::from_raw(unsafe_image, format, &swapchain, id as u32).unwrap() // TODO: propagate error SwapchainImage::from_raw(unsafe_image, format, &swapchain, id as u32).unwrap() // TODO: propagate error
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();