Switch to new design for images

This commit is contained in:
Pierre Krieger 2016-03-23 19:41:02 +01:00
parent da109b79b8
commit 8ee4d6c301
13 changed files with 242 additions and 1367 deletions

View File

@ -57,7 +57,7 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
{
Some((
"::vulkano::descriptor_set::DescriptorType::SampledImage",
"::std::sync::Arc<::vulkano::image::AbstractImageView>",
"::std::sync::Arc<::vulkano::image::ImageView>",
"::vulkano::descriptor_set::DescriptorBind::SampledImage(data, ::vulkano::image::Layout::ShaderReadOnlyOptimal)" // FIXME:
))
},
@ -67,7 +67,7 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
{
Some((
"::vulkano::descriptor_set::DescriptorType::InputAttachment", // FIXME: can be `StorageImage`
"::std::sync::Arc<::vulkano::image::AbstractImageView>",
"::std::sync::Arc<::vulkano::image::ImageView>",
"::vulkano::descriptor_set::DescriptorBind::InputAttachment(data, ::vulkano::image::Layout::ShaderReadOnlyOptimal)" // FIXME:
))
},
@ -76,7 +76,7 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
{
Some((
"::vulkano::descriptor_set::DescriptorType::CombinedImageSampler",
"(::std::sync::Arc<::vulkano::sampler::Sampler>, ::std::sync::Arc<::vulkano::image::AbstractImageView>)",
"(::std::sync::Arc<::vulkano::sampler::Sampler>, ::std::sync::Arc<::vulkano::image::ImageView>)",
"::vulkano::descriptor_set::DescriptorBind::CombinedImageSampler(data.0, data.1, ::vulkano::image::Layout::ShaderReadOnlyOptimal)" // FIXME:
))
},

View File

@ -71,11 +71,7 @@ fn main() {
.expect("failed to create command buffer pool");
let depth_buffer = vulkano::image::Image::<vulkano::image::Type2d, _, _>::new(&device, &vulkano::image::Usage::all(),
vulkano::memory::DeviceLocal, &queue,
vulkano::format::D16Unorm, images[0].dimensions(), (), 1).unwrap();
let depth_buffer = depth_buffer.transition(vulkano::image::Layout::DepthStencilAttachmentOptimal, &cb_pool, &queue).unwrap();
let depth_buffer = vulkano::image::ImageView::new(&depth_buffer).expect("failed to create image view");
let depth_buffer = vulkano::image::attachment::AttachmentImage::new(&device, images[0].dimensions().width_height(), vulkano::format::D16Unorm).unwrap();
let vertex_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer
::array(&device, teapot::VERTICES.len(),
@ -115,7 +111,7 @@ fn main() {
// note: this teapot was meant for OpenGL where the origin is at the lower left
// instead the origin is at the upper left in vulkan, so we reverse the Y axis
let proj = cgmath::perspective(cgmath::rad(3.141592 / 2.0), { let d = images[0].dimensions(); d[0] as f32 / d[1] as f32 }, 0.01, 100.0);
let proj = cgmath::perspective(cgmath::rad(3.141592 / 2.0), { let d = images[0].dimensions(); d.width() as f32 / d.height() as f32 }, 0.01, 100.0);
let view = cgmath::Matrix4::look_at(cgmath::Point3::new(0.3, 0.3, 1.0), cgmath::Point3::new(0.0, 0.0, 0.0), cgmath::Vector3::new(0.0, -1.0, 0.0));
let scale = cgmath::Matrix4::from_scale(0.01);
@ -131,12 +127,6 @@ fn main() {
let vs = vs::Shader::load(&device).expect("failed to create shader module");
let fs = fs::Shader::load(&device).expect("failed to create shader module");
let images = images.into_iter().map(|image| {
let image = image.transition(vulkano::image::Layout::PresentSrc, &cb_pool,
&queue).unwrap();
vulkano::image::ImageView::new(&image).expect("failed to create image view")
}).collect::<Vec<_>>();
mod renderpass {
single_pass_renderpass!{
attachments: {
@ -199,7 +189,7 @@ fn main() {
};
let framebuffers = images.iter().map(|image| {
vulkano::framebuffer::Framebuffer::new(&renderpass, (1244, 699, 1), (image.clone() as std::sync::Arc<_>, depth_buffer.clone() as std::sync::Arc<_>)).unwrap()
vulkano::framebuffer::Framebuffer::new(&renderpass, (1244, 699, 1), vec![image.clone() as std::sync::Arc<_>, depth_buffer.clone() as std::sync::Arc<_>]).unwrap()
}).collect::<Vec<_>>();

View File

@ -7,7 +7,7 @@ use smallvec::SmallVec;
use buffer::Buffer;
use buffer::BufferSlice;
use buffer::TypedBuffer;
use buffer::traits::AccessRange;
use buffer::traits::AccessRange as BufferAccessRange;
use command_buffer::AbstractCommandBuffer;
use command_buffer::CommandBufferPool;
use command_buffer::DynamicState;
@ -19,16 +19,15 @@ use format::ClearValue;
use format::FormatDesc;
use format::PossibleFloatOrCompressedFormatDesc;
use format::PossibleFloatFormatDesc;
use format::StrongStorage;
use framebuffer::AbstractFramebuffer;
use framebuffer::RenderPass;
use framebuffer::Framebuffer;
use framebuffer::Subpass;
use image::AbstractImage;
use image::AbstractImageView;
use image::Image;
use image::ImageTypeMarker;
use memory::MemorySource;
use image::ImageView;
use image::traits::ImageClearValue;
use image::traits::ImageContent;
use image::traits::AccessRange as ImageAccessRange;
use pipeline::GenericPipeline;
use pipeline::ComputePipeline;
use pipeline::GraphicsPipeline;
@ -36,7 +35,6 @@ use pipeline::input_assembly::Index;
use pipeline::vertex::Definition as VertexDefinition;
use pipeline::vertex::Source as VertexSource;
use sync::Fence;
use sync::Resource;
use sync::Semaphore;
use device::Device;
@ -70,11 +68,11 @@ pub struct InnerCommandBufferBuilder {
// List of all resources that are used by this command buffer.
buffer_resources: Vec<Arc<Buffer>>,
image_resources: Vec<Arc<AbstractImage>>,
image_resources: Vec<Arc<Image>>,
// Same as `resources`. Should be merged with `resources` once Rust allows turning a
// `Arc<AbstractImageView>` into an `Arc<Buffer>`.
image_views_resources: Vec<Arc<AbstractImageView>>,
// `Arc<ImageView>` into an `Arc<Buffer>`.
image_views_resources: Vec<Arc<ImageView>>,
// List of pipelines that are used by this command buffer.
//
@ -348,13 +346,13 @@ impl InnerCommandBufferBuilder {
///
/// - Care must be taken to respect the rules about secondary command buffers.
///
pub unsafe fn clear_color_image<'a, Ty, F, M>(self, image: &Arc<Image<Ty, F, M>>,
color: F::ClearValue) -> InnerCommandBufferBuilder
where Ty: ImageTypeMarker, F: PossibleFloatFormatDesc, M: MemorySource // FIXME: should accept uint and int images too
pub unsafe fn clear_color_image<'a, I, V>(self, image: &Arc<I>, color: V)
-> InnerCommandBufferBuilder
where I: ImageClearValue<V> + 'static // FIXME: should accept uint and int images too
{
assert!(image.format().is_float()); // FIXME: should accept uint and int images too
let color = match image.format().decode_clear_value(color) {
let color = match image.decode(color).unwrap() /* FIXME: error */ {
ClearValue::Float(data) => vk::ClearColorValue::float32(data),
ClearValue::Int(data) => vk::ClearColorValue::int32(data),
ClearValue::Uint(data) => vk::ClearColorValue::uint32(data),
@ -372,7 +370,8 @@ impl InnerCommandBufferBuilder {
{
let vk = self.device.pointers();
let _ = self.pool.internal_object_guard(); // the pool needs to be synchronized
vk.CmdClearColorImage(self.cmd.unwrap(), image.internal_object(), vk::IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL /* FIXME: */,
vk.CmdClearColorImage(self.cmd.unwrap(), image.inner_image().internal_object(),
vk::IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL /* FIXME: */,
&color, 1, &range);
}
@ -387,10 +386,10 @@ impl InnerCommandBufferBuilder {
///
/// - Care must be taken to respect the rules about secondary command buffers.
///
pub unsafe fn copy_buffer_to_color_image<'a, S, Sb, Ty, F, Im>(mut self, source: S, image: &Arc<Image<Ty, F, Im>>)
-> InnerCommandBufferBuilder
where S: Into<BufferSlice<'a, [F::Pixel], Sb>>, F: StrongStorage + 'static + PossibleFloatOrCompressedFormatDesc, // FIXME: wrong trait
Ty: ImageTypeMarker + 'static, Im: MemorySource + 'static, Sb: Buffer + 'static
pub unsafe fn copy_buffer_to_color_image<'a, P, S, Sb, Img>(mut self, source: S, image: &Arc<Img>)
-> InnerCommandBufferBuilder
where S: Into<BufferSlice<'a, [P], Sb>>, Img: ImageContent<P> + Image + 'static,
Sb: Buffer + 'static
{
assert!(image.format().is_float_or_compressed());
@ -423,7 +422,8 @@ impl InnerCommandBufferBuilder {
{
let vk = self.device.pointers();
let _ = self.pool.internal_object_guard(); // the pool needs to be synchronized
vk.CmdCopyBufferToImage(self.cmd.unwrap(), source.buffer().inner_buffer().internal_object(), image.internal_object(),
vk.CmdCopyBufferToImage(self.cmd.unwrap(), source.buffer().inner_buffer().internal_object(),
image.inner_image().internal_object(),
vk::IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL /* FIXME */,
1, &region);
}
@ -757,7 +757,7 @@ impl InnerCommandBufferBuilder {
// TODO: image views as well
let image_resources = self.image_resources.iter().enumerate().filter_map(|(num, elem)| {
if self.image_resources.iter().take(num)
.find(|e| &***e as *const AbstractImage == &**elem as *const AbstractImage).is_some()
.find(|e| &***e as *const Image == &**elem as *const Image).is_some()
{
None
} else {
@ -791,7 +791,7 @@ impl InnerCommandBufferBuilder {
}
/// Adds an image resource to the list of resources used by this command buffer.
fn add_image_resource(&mut self, image: Arc<AbstractImage>, _write: bool) { // TODO:
fn add_image_resource(&mut self, image: Arc<Image>, _write: bool) { // TODO:
self.image_resources.push(image);
}
}
@ -821,8 +821,8 @@ pub struct InnerCommandBuffer {
framebuffers: Vec<Arc<AbstractFramebuffer>>,
renderpasses: Vec<Arc<RenderPass>>,
buffer_resources: Vec<Arc<Buffer>>,
image_resources: Vec<Arc<AbstractImage>>,
image_views_resources: Vec<Arc<AbstractImageView>>,
image_resources: Vec<Arc<Image>>,
image_views_resources: Vec<Arc<ImageView>>,
pipelines: Vec<Arc<GenericPipeline>>,
}
@ -898,7 +898,7 @@ pub fn submit(me: &InnerCommandBuffer, me_arc: Arc<AbstractCommandBuffer>,
for resource in me.buffer_resources.iter() {
let deps = unsafe {
// FIXME: wrong ranges
let range = AccessRange {
let range = BufferAccessRange {
range: 0 .. 18,
write: true,
};
@ -911,26 +911,18 @@ pub fn submit(me: &InnerCommandBuffer, me_arc: Arc<AbstractCommandBuffer>,
// Then images.
for resource in me.image_resources.iter() {
let post_semaphore = if resource.requires_semaphore() {
let semaphore = try!(Semaphore::new(queue.device()));
post_semaphores.push(semaphore.clone());
post_semaphores_ids.push(semaphore.internal_object());
Some(semaphore)
let deps = unsafe {
// FIXME: wrong ranges
let range = ImageAccessRange {
mipmap_levels_range: 0 .. 1,
array_layers_range: 0 .. 1,
write: true,
};
} else {
None
resource.gpu_access(&mut Some(range).into_iter(), &submission)
};
// FIXME: for the moment `write` is always true ; that shouldn't be the case
let sem = unsafe {
resource.gpu_access(true, queue, Some(fence.clone()), post_semaphore)
};
if let Some(s) = sem {
pre_semaphores_ids.push(s.internal_object());
pre_semaphores_stages.push(vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT); // TODO:
pre_semaphores.push(s);
}
dependencies.extend(deps.into_iter());
}
// For each dependency, we either wait on one of its semaphores, or create a new one.

View File

@ -13,18 +13,14 @@ use command_buffer::inner::submit as inner_submit;
use descriptor_set::Layout as PipelineLayoutDesc;
use descriptor_set::DescriptorSetsCollection;
use device::Queue;
use format::PossibleFloatOrCompressedFormatDesc;
use format::PossibleFloatFormatDesc;
use format::StrongStorage;
use framebuffer::Framebuffer;
use framebuffer::UnsafeRenderPass;
use framebuffer::RenderPassCompatible;
use framebuffer::RenderPass;
use framebuffer::RenderPassClearValues;
use framebuffer::Subpass;
use image::Image;
use image::ImageTypeMarker;
use memory::MemorySource;
use image::traits::ImageClearValue;
use image::traits::ImageContent;
use pipeline::ComputePipeline;
use pipeline::GraphicsPipeline;
use pipeline::input_assembly::Index;
@ -123,11 +119,10 @@ impl PrimaryCommandBufferBuilder {
}
}
pub fn copy_buffer_to_color_image<'a, S, Ty, F, Im, Sb>(self, source: S, destination: &Arc<Image<Ty, F, Im>>)
pub fn copy_buffer_to_color_image<'a, P, S, Img, Sb>(self, source: S, destination: &Arc<Img>)
-> PrimaryCommandBufferBuilder
where S: Into<BufferSlice<'a, [F::Pixel], Sb>>, Sb: Buffer + 'static,
F: StrongStorage + PossibleFloatOrCompressedFormatDesc + 'static,
Ty: ImageTypeMarker + 'static, Im: MemorySource + 'static
where S: Into<BufferSlice<'a, [P], Sb>>, Sb: Buffer + 'static,
Img: ImageContent<P> + 'static
{
unsafe {
PrimaryCommandBufferBuilder {
@ -138,9 +133,9 @@ impl PrimaryCommandBufferBuilder {
///
/// Note that compressed formats are not supported.
pub fn clear_color_image<'a, Ty, F, M>(self, image: &Arc<Image<Ty, F, M>>,
color: F::ClearValue) -> PrimaryCommandBufferBuilder
where Ty: ImageTypeMarker, F: PossibleFloatFormatDesc, M: MemorySource
pub fn clear_color_image<'a, I, V>(self, image: &Arc<I>, color: V)
-> PrimaryCommandBufferBuilder
where I: ImageClearValue<V> + 'static
{
unsafe {
PrimaryCommandBufferBuilder {

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use buffer::Buffer;
use descriptor_set::AbstractDescriptorSet;
use descriptor_set::AbstractDescriptorSetLayout;
use image::AbstractImageView;
use image::ImageView;
use image::Layout as ImageLayout;
use sampler::Sampler;
@ -78,17 +78,17 @@ pub struct DescriptorWrite {
// FIXME: incomplete
#[derive(Clone)] // TODO: Debug
pub enum DescriptorBind {
StorageImage(Arc<AbstractImageView>, ImageLayout),
StorageImage(Arc<ImageView>, ImageLayout),
Sampler(Arc<Sampler>),
SampledImage(Arc<AbstractImageView>, ImageLayout),
CombinedImageSampler(Arc<Sampler>, Arc<AbstractImageView>, ImageLayout),
SampledImage(Arc<ImageView>, ImageLayout),
CombinedImageSampler(Arc<Sampler>, Arc<ImageView>, ImageLayout),
//UniformTexelBuffer(Arc<Buffer>), // FIXME: requires buffer views
//StorageTexelBuffer(Arc<Buffer>), // FIXME: requires buffer views
UniformBuffer { buffer: Arc<Buffer>, offset: usize, size: usize },
StorageBuffer { buffer: Arc<Buffer>, offset: usize, size: usize },
DynamicUniformBuffer { buffer: Arc<Buffer>, offset: usize, size: usize },
DynamicStorageBuffer { buffer: Arc<Buffer>, offset: usize, size: usize },
InputAttachment(Arc<AbstractImageView>, ImageLayout),
InputAttachment(Arc<ImageView>, ImageLayout),
}
impl DescriptorBind {

View File

@ -12,7 +12,7 @@ use descriptor_set::layout_def::DescriptorWrite;
use descriptor_set::layout_def::DescriptorBind;
use descriptor_set::pool::DescriptorPool;
use device::Device;
use image::AbstractImageView;
use image::ImageView;
use sampler::Sampler;
use OomError;
@ -31,7 +31,7 @@ pub struct DescriptorSet<S> {
// Here we store the resources used by the descriptor set.
// TODO: for the moment even when a resource is overwritten it stays in these lists
resources_samplers: Vec<Arc<Sampler>>,
resources_image_views: Vec<Arc<AbstractImageView>>,
resources_image_views: Vec<Arc<ImageView>>,
resources_buffers: Vec<Arc<Buffer>>,
}
@ -156,39 +156,39 @@ impl<S> DescriptorSet<S> where S: SetLayout {
})
},
DescriptorBind::CombinedImageSampler(ref sampler, ref image, layout) => {
assert!(image.usage_sampled());
assert!(image.inner_view().usage_sampled());
self_resources_samplers.push(sampler.clone());
self_resources_image_views.push(image.clone());
Some(vk::DescriptorImageInfo {
sampler: sampler.internal_object(),
imageView: image.internal_object(),
imageView: image.inner_view().internal_object(),
imageLayout: layout as u32,
})
},
DescriptorBind::StorageImage(ref image, layout) => {
assert!(image.usage_storage());
assert!(image.inner_view().usage_storage());
self_resources_image_views.push(image.clone());
Some(vk::DescriptorImageInfo {
sampler: 0,
imageView: image.internal_object(),
imageView: image.inner_view().internal_object(),
imageLayout: layout as u32,
})
},
DescriptorBind::SampledImage(ref image, layout) => {
assert!(image.usage_sampled());
assert!(image.inner_view().usage_sampled());
self_resources_image_views.push(image.clone());
Some(vk::DescriptorImageInfo {
sampler: 0,
imageView: image.internal_object(),
imageView: image.inner_view().internal_object(),
imageLayout: layout as u32,
})
},
DescriptorBind::InputAttachment(ref image, layout) => {
assert!(image.usage_input_attachment());
assert!(image.inner_view().usage_input_attachment());
self_resources_image_views.push(image.clone());
Some(vk::DescriptorImageInfo {
sampler: 0,
imageView: image.internal_object(),
imageView: image.inner_view().internal_object(),
imageLayout: layout as u32,
})
},

View File

@ -74,8 +74,8 @@ use device::Device;
use format::ClearValue;
use format::Format;
use format::FormatDesc;
use image::AbstractImageView;
use image::Layout as ImageLayout;
use image::traits::ImageView;
use Error;
use OomError;
@ -104,7 +104,7 @@ pub unsafe trait RenderPass {
/// Extension trait for `RenderPass`. Defines which types are allowed as an attachments list.
pub unsafe trait RenderPassAttachmentsList<A>: RenderPass {
/// A decoded `A`.
type AttachmentsIter: ExactSizeIterator<Item = Arc<AbstractImageView>>;
type AttachmentsIter: ExactSizeIterator<Item = Arc<ImageView>>;
/// Decodes a `A` into a list of attachments.
fn convert_attachments_list(&self, A) -> Self::AttachmentsIter;
@ -294,7 +294,7 @@ unsafe impl RenderPass for EmptySinglePassRenderPass {
}
unsafe impl RenderPassAttachmentsList<()> for EmptySinglePassRenderPass {
type AttachmentsIter = EmptyIter<Arc<AbstractImageView>>;
type AttachmentsIter = EmptyIter<Arc<ImageView>>;
#[inline]
fn convert_attachments_list(&self, _: ()) -> Self::AttachmentsIter {
@ -464,17 +464,15 @@ macro_rules! ordered_passes_renderpass {
}
}
pub type AList = ($( // FIXME: should not use a trait
Arc<$crate::image::AbstractTypedImageView<$crate::image::Type2d, $crate::format::$format>>,
)*);
pub type AList = Vec<Arc<$crate::image::ImageView>>; // FIXME: better type
unsafe impl $crate::framebuffer::RenderPassAttachmentsList<AList> for CustomRenderPass {
// TODO: shouldn't build a Vec
type AttachmentsIter = std::vec::IntoIter<std::sync::Arc<$crate::image::AbstractImageView>>;
type AttachmentsIter = std::vec::IntoIter<std::sync::Arc<$crate::image::ImageView>>;
#[inline]
fn convert_attachments_list(&self, l: AList) -> Self::AttachmentsIter {
$crate::image::AbstractTypedImageViewsTuple::iter(l)
l.into_iter()
}
}
@ -880,7 +878,7 @@ pub struct Framebuffer<L> {
render_pass: Arc<L>,
framebuffer: vk::Framebuffer,
dimensions: (u32, u32, u32),
resources: Vec<Arc<AbstractImageView>>,
resources: Vec<Arc<ImageView>>,
}
impl<L> Framebuffer<L> {
@ -916,8 +914,8 @@ impl<L> Framebuffer<L> {
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let ids = attachments.iter().map(|a| {
//assert!(a.is_identity_swizzled());
a.internal_object()
assert!(a.identity_swizzle());
a.inner_view().internal_object()
}).collect::<Vec<_>>();
let framebuffer = unsafe {
@ -992,7 +990,7 @@ impl<L> Framebuffer<L> {
/// Returns all the resources attached to that framebuffer.
#[inline]
pub fn attachments(&self) -> &[Arc<AbstractImageView>] {
pub fn attachments(&self) -> &[Arc<ImageView>] {
&self.resources
}
}

View File

@ -4,14 +4,15 @@ use std::sync::Arc;
use command_buffer::Submission;
use device::Device;
use format::FormatDesc;
use image::traits::AccessRange;
use image::traits::Image;
use image::traits::ImageView;
use image::sys::Dimensions;
use image::sys::Layout;
use image::sys::UnsafeImage;
use image::sys::UnsafeImageView;
use image::sys::Usage;
use image::traits::AccessRange;
use image::traits::Image;
use image::traits::ImageContent;
use image::traits::ImageView;
use memory::DeviceMemory;
use sync::Sharing;
@ -69,6 +70,11 @@ impl<F> AttachmentImage<F> {
format: format,
}))
}
#[inline]
pub fn dimensions(&self) -> Dimensions {
self.image.dimensions()
}
}
unsafe impl<F> Image for AttachmentImage<F> {
@ -88,6 +94,13 @@ unsafe impl<F> Image for AttachmentImage<F> {
}
}
unsafe impl<P, F> ImageContent<P> for AttachmentImage<F> {
#[inline]
fn matches_format(&self) -> bool {
true // FIXME:
}
}
unsafe impl<F> ImageView for AttachmentImage<F> {
#[inline]
fn parent(&self) -> &Image {

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,9 @@ use command_buffer::Submission;
use format::Format;
use image::traits::AccessRange;
use image::traits::Image;
use image::traits::ImageContent;
use image::traits::ImageView;
use image::sys::Dimensions;
use image::sys::Layout;
use image::sys::UnsafeImage;
use image::sys::UnsafeImageView;
@ -34,6 +36,11 @@ impl SwapchainImage {
id: id,
}))
}
#[inline]
pub fn dimensions(&self) -> Dimensions {
self.image.dimensions()
}
}
unsafe impl Image for SwapchainImage {
@ -53,6 +60,13 @@ unsafe impl Image for SwapchainImage {
}
}
unsafe impl<P> ImageContent<P> for SwapchainImage {
#[inline]
fn matches_format(&self) -> bool {
true // FIXME:
}
}
unsafe impl ImageView for SwapchainImage {
#[inline]
fn parent(&self) -> &Image {

View File

@ -24,8 +24,7 @@ pub struct UnsafeImage {
usage: vk::ImageUsageFlagBits,
format: Format,
dimensions: [f32; 3],
array_layers: u32,
dimensions: Dimensions,
samples: u32,
mipmaps: u32,
@ -89,31 +88,26 @@ impl UnsafeImage {
let vk = device.pointers();
// TODO: check for limits
let (ty, extent, array_layers, dims) = match dimensions {
let (ty, extent, array_layers) = match dimensions {
Dimensions::Dim1d { width } => {
let extent = vk::Extent3D { width: width, height: 1, depth: 1 };
let dims = [width as f32, 1.0, 1.0];
(vk::IMAGE_TYPE_1D, extent, 1, dims)
(vk::IMAGE_TYPE_1D, extent, 1)
},
Dimensions::Dim1dArray { width, array_layers } => {
let extent = vk::Extent3D { width: width, height: 1, depth: 1 };
let dims = [width as f32, 1.0, 1.0];
(vk::IMAGE_TYPE_1D, extent, array_layers, dims)
(vk::IMAGE_TYPE_1D, extent, array_layers)
},
Dimensions::Dim2d { width, height } => {
let extent = vk::Extent3D { width: width, height: height, depth: 1 };
let dims = [width as f32, height as f32, 1.0];
(vk::IMAGE_TYPE_2D, extent, 1, dims)
(vk::IMAGE_TYPE_2D, extent, 1)
},
Dimensions::Dim2dArray { width, height, array_layers } => {
let extent = vk::Extent3D { width: width, height: height, depth: 1 };
let dims = [width as f32, height as f32, 1.0];
(vk::IMAGE_TYPE_2D, extent, array_layers, dims)
(vk::IMAGE_TYPE_2D, extent, array_layers)
},
Dimensions::Dim3d { width, height, depth } => {
let extent = vk::Extent3D { width: width, height: height, depth: depth };
let dims = [width as f32, height as f32, depth as f32];
(vk::IMAGE_TYPE_3D, extent, 1, dims)
(vk::IMAGE_TYPE_3D, extent, 1)
},
};
@ -168,8 +162,7 @@ impl UnsafeImage {
image: image,
usage: usage,
format: format,
dimensions: dims,
array_layers: array_layers,
dimensions: dimensions,
samples: num_samples,
mipmaps: mipmaps,
needs_destruction: true,
@ -182,35 +175,15 @@ impl UnsafeImage {
///
/// 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,
dimensions: Dimensions, array_layers: u32, samples: u32, mipmaps: u32)
dimensions: Dimensions, samples: u32, mipmaps: u32)
-> UnsafeImage
{
// TODO: DRY
let dims = match dimensions {
Dimensions::Dim1d { width } => {
[width as f32, 1.0, 1.0]
},
Dimensions::Dim1dArray { width, array_layers } => {
[width as f32, 1.0, 1.0]
},
Dimensions::Dim2d { width, height } => {
[width as f32, height as f32, 1.0]
},
Dimensions::Dim2dArray { width, height, array_layers } => {
[width as f32, height as f32, 1.0]
},
Dimensions::Dim3d { width, height, depth } => {
[width as f32, height as f32, depth as f32]
},
};
UnsafeImage {
device: device.clone(),
image: handle,
usage: usage,
format: format,
dimensions: dims,
array_layers: array_layers,
dimensions: dimensions,
samples: samples,
mipmaps: mipmaps,
needs_destruction: false, // TODO: pass as parameter
@ -226,6 +199,16 @@ impl UnsafeImage {
range.start as vk::DeviceSize)));
Ok(())
}
#[inline]
pub fn format(&self) -> Format {
self.format
}
#[inline]
pub fn dimensions(&self) -> Dimensions {
self.dimensions
}
}
unsafe impl VulkanObject for UnsafeImage {
@ -254,7 +237,9 @@ impl Drop for UnsafeImage {
pub struct UnsafeImageView {
view: vk::ImageView,
device: Arc<Device>,
usage: vk::ImageUsageFlagBits,
identity_swizzle: bool,
format: Format,
}
impl UnsafeImageView {
@ -301,9 +286,65 @@ impl UnsafeImageView {
Ok(UnsafeImageView {
view: view,
device: image.device.clone(),
usage: image.usage,
identity_swizzle: true, // FIXME:
format: image.format,
})
}
#[inline]
pub fn format(&self) -> Format {
self.format
}
#[inline]
pub fn usage_transfer_src(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_TRANSFER_SRC_BIT) != 0
}
#[inline]
pub fn usage_transfer_dest(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_TRANSFER_DST_BIT) != 0
}
#[inline]
pub fn usage_sampled(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_SAMPLED_BIT) != 0
}
#[inline]
pub fn usage_storage(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_STORAGE_BIT) != 0
}
#[inline]
pub fn usage_color_attachment(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0
}
#[inline]
pub fn usage_depth_stencil_attachment(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0
}
#[inline]
pub fn usage_transient_attachment(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0
}
#[inline]
pub fn usage_input_attachment(&self) -> bool {
(self.usage & vk::IMAGE_USAGE_INPUT_ATTACHMENT_BIT) != 0
}
}
unsafe impl VulkanObject for UnsafeImageView {
type Object = vk::ImageView;
#[inline]
fn internal_object(&self) -> vk::ImageView {
self.view
}
}
impl Drop for UnsafeImageView {
@ -316,6 +357,7 @@ impl Drop for UnsafeImageView {
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Dimensions {
Dim1d { width: u32 },
Dim1dArray { width: u32, array_layers: u32 },
@ -324,6 +366,35 @@ pub enum Dimensions {
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()]
}
}
/// 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.

View File

@ -3,6 +3,8 @@ use std::sync::Arc;
use command_buffer::Submission;
use format::ClearValue;
use format::Format;
use image::sys::Dimensions;
use image::sys::Layout;
use image::sys::UnsafeImage;
use image::sys::UnsafeImageView;
@ -15,6 +17,18 @@ pub unsafe trait Image {
//fn align(&self, subresource_range: ) -> ;
/// Returns the format of this image.
#[inline]
fn format(&self) -> Format {
self.inner_image().format()
}
/// Returns the dimensions of the image.
#[inline]
fn dimensions(&self) -> Dimensions {
self.inner_image().dimensions()
}
/// Returns whether accessing a subresource of that image should signal a fence.
fn needs_fence(&self, access: &mut Iterator<Item = AccessRange>) -> Option<bool>;
@ -23,7 +37,12 @@ pub unsafe trait Image {
}
pub unsafe trait ImageClearValue<T>: Image {
fn decode(&self, T) -> ClearValue;
fn decode(&self, T) -> Option<ClearValue>;
}
pub unsafe trait ImageContent<P>: Image {
/// Checks whether pixels of type `P` match the format of the image.
fn matches_format(&self) -> bool;
}
pub unsafe trait ImageView {
@ -33,6 +52,12 @@ pub unsafe trait ImageView {
// TODO: should be named "inner()" after https://github.com/rust-lang/rust/issues/12808 is fixed
fn inner_view(&self) -> &UnsafeImageView;
/// Returns the format of this view. This can be different from the parent's format.
#[inline]
fn format(&self) -> Format {
self.inner_view().format()
}
/// Returns the image layout to use in a descriptor with the given subresource.
fn descriptor_set_storage_image_layout(&self, AccessRange) -> Layout;
/// Returns the image layout to use in a descriptor with the given subresource.

View File

@ -147,7 +147,7 @@ impl Swapchain {
let images = images.into_iter().enumerate().map(|(id, image)| unsafe {
let unsafe_image = UnsafeImage::from_raw(device, image, usage, format.format(),
Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] }, 1, 1, 1);
Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] }, 1, 1);
SwapchainImage::from_raw(unsafe_image, format.format(), &swapchain, id as u32).unwrap() // TODO: propagate error
}).collect::<Vec<_>>();