From 19beb1eb06cd3ba3bde2043a04bada6e6e6b47af Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 4 Jan 2017 16:55:19 +0100 Subject: [PATCH] Rework attachments list --- examples/src/bin/triangle.rs | 2 +- vulkano/src/framebuffer/attachments_list.rs | 121 +++++++++++++ vulkano/src/framebuffer/framebuffer.rs | 186 +------------------- vulkano/src/framebuffer/macros.rs | 15 +- vulkano/src/framebuffer/mod.rs | 4 +- vulkano/src/framebuffer/traits.rs | 9 +- 6 files changed, 147 insertions(+), 190 deletions(-) create mode 100644 vulkano/src/framebuffer/attachments_list.rs diff --git a/examples/src/bin/triangle.rs b/examples/src/bin/triangle.rs index 06cb64b62..9a42901f1 100644 --- a/examples/src/bin/triangle.rs +++ b/examples/src/bin/triangle.rs @@ -322,7 +322,7 @@ fn main() { // each image. let framebuffers = images.iter().map(|image| { let dimensions = [image.dimensions()[0], image.dimensions()[1], 1]; - Framebuffer::new(render_pass.clone(), dimensions, (image.clone(),)).unwrap() + Framebuffer::new(render_pass.clone(), dimensions, render_pass.desc().start_attachments().color(image.clone())).unwrap() }).collect::>(); // Initialization is finally finished! diff --git a/vulkano/src/framebuffer/attachments_list.rs b/vulkano/src/framebuffer/attachments_list.rs new file mode 100644 index 000000000..00a28189a --- /dev/null +++ b/vulkano/src/framebuffer/attachments_list.rs @@ -0,0 +1,121 @@ +// Copyright (c) 2016 The vulkano developers +// Licensed under the Apache License, Version 2.0 +// or the MIT +// license , +// at your option. All files in the project carrying such +// notice may not be copied, modified, or distributed except +// according to those terms. + +use command_buffer::cmd::CommandsListSink; +use image::traits::ImageView; +//use sync::AccessFlagBits; +//use sync::PipelineStages; +use VulkanObject; +use vk; + +/// A list of attachments. +// TODO: rework this trait +pub unsafe trait AttachmentsList { + /// Returns the raw handles of the image views of this list. + // TODO: better return type + fn raw_image_view_handles(&self) -> Vec; + + /// Returns the minimal dimensions of the views. Returns `None` if the list is empty. + /// + /// Must be done for each component individually. + /// + /// For example if one view is 256x256x1 and another one is 128x512x2, then this function + /// should return 128x256x1. + fn min_dimensions(&self) -> Option<[u32; 3]>; + + fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>); +} + +unsafe impl AttachmentsList for () { + #[inline] + fn raw_image_view_handles(&self) -> Vec { + vec![] + } + + #[inline] + fn min_dimensions(&self) -> Option<[u32; 3]> { + None + } + + #[inline] + fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) { + } +} + +macro_rules! impl_into_atch_list { + ($first:ident $(, $rest:ident)*) => ( + unsafe impl<$first $(, $rest)*> AttachmentsList for ($first, $($rest),*) + where $first: ImageView, + $($rest: ImageView,)* + { + #[inline] + #[allow(non_snake_case)] + fn raw_image_view_handles(&self) -> Vec { + let &(ref $first, $(ref $rest,)*) = self; + + vec![ + $first.inner().internal_object(), + $( + $rest.inner().internal_object(), + )* + ] + } + + #[inline] + fn min_dimensions(&self) -> Option<[u32; 3]> { + unimplemented!() + /*let my_view_dims = self.first.parent().dimensions(); + debug_assert_eq!(my_view_dims.depth(), 1); + let my_view_dims = [my_view_dims.width(), my_view_dims.height(), + my_view_dims.array_layers()]; // FIXME: should be the view's layers, not the image's + + match self.rest.min_dimensions() { + Some(r_dims) => { + Some([ + cmp::min(r_dims[0], my_view_dims[0]), + cmp::min(r_dims[1], my_view_dims[1]), + cmp::min(r_dims[2], my_view_dims[2]) + ]) + }, + None => Some(my_view_dims), + }*/ + } + + #[inline] + fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) { + unimplemented!() + /*// TODO: "wrong" values + let stages = PipelineStages { + color_attachment_output: true, + late_fragment_tests: true, + .. PipelineStages::none() + }; + + let access = AccessFlagBits { + color_attachment_read: true, + color_attachment_write: true, + depth_stencil_attachment_read: true, + depth_stencil_attachment_write: true, + .. AccessFlagBits::none() + }; + + // FIXME: adjust layers & mipmaps with the view's parameters + sink.add_image_transition(self.first.parent(), 0, 1, 0, 1, true, Layout::General /* FIXME: wrong */, + stages, access); + self.rest.add_transition(sink);*/ + } + } + + impl_into_atch_list!($($rest),*); + ); + + () => (); +} + +impl_into_atch_list!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); diff --git a/vulkano/src/framebuffer/framebuffer.rs b/vulkano/src/framebuffer/framebuffer.rs index b51a750c6..c1db8363c 100644 --- a/vulkano/src/framebuffer/framebuffer.rs +++ b/vulkano/src/framebuffer/framebuffer.rs @@ -7,7 +7,6 @@ // notice may not be copied, modified, or distributed except // according to those terms. -use std::cmp; use std::error; use std::fmt; use std::mem; @@ -16,15 +15,12 @@ use std::sync::Arc; use command_buffer::cmd::CommandsListSink; use device::Device; +use framebuffer::AttachmentsList; use framebuffer::FramebufferRef; use framebuffer::RenderPass; use framebuffer::RenderPassRef; use framebuffer::RenderPassDescAttachmentsList; use framebuffer::RenderPassCompatible; -use image::sys::Layout; -use image::traits::ImageView; -use sync::AccessFlagBits; -use sync::PipelineStages; use Error; use OomError; @@ -53,20 +49,17 @@ impl Framebuffer { /// Builds a new framebuffer. /// /// The `attachments` parameter depends on which `RenderPassRef` implementation is used. - pub fn new(render_pass: Rp, dimensions: [u32; 3], - attachments: Ia) -> Result>, FramebufferCreationError> + pub fn new(render_pass: Rp, dimensions: [u32; 3], attachments: Ia) + -> Result>, FramebufferCreationError> where Rp: RenderPassRef, - Rp::Desc: RenderPassDescAttachmentsList, - Ia: IntoAttachmentsList, - A: AttachmentsList + Rp::Desc: RenderPassDescAttachmentsList, + A: AttachmentsList, { let device = render_pass.inner().device().clone(); // This function call is supposed to check whether the attachments are valid. // For more safety, we do some additional `debug_assert`s below. - try!(render_pass.inner().desc().check_attachments_list(&attachments)); - - let attachments = attachments.into_attachments_list(); + let attachments = try!(render_pass.inner().desc().check_attachments_list(attachments)); // Checking the dimensions against the limits. { @@ -216,173 +209,6 @@ impl Drop for Framebuffer { } } -pub unsafe trait AttachmentsList { - /// Returns the raw handles of the image views of this list. - // TODO: better return type - fn raw_image_view_handles(&self) -> Vec; - - /// Returns the minimal dimensions of the views. Returns `None` if the list is empty. - /// - /// Must be done for each component individually. - /// - /// For example if one view is 256x256x1 and another one is 128x512x2, then this function - /// should return 128x256x1. - fn min_dimensions(&self) -> Option<[u32; 3]>; - - fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>); -} - -#[derive(Debug, Copy, Clone)] -pub struct EmptyAttachmentsList; -unsafe impl AttachmentsList for EmptyAttachmentsList { - #[inline] - fn raw_image_view_handles(&self) -> Vec { - vec![] - } - - #[inline] - fn min_dimensions(&self) -> Option<[u32; 3]> { - None - } - - #[inline] - fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) { - } -} - -unsafe impl AttachmentsList for () { - #[inline] - fn raw_image_view_handles(&self) -> Vec { - vec![] - } - - #[inline] - fn min_dimensions(&self) -> Option<[u32; 3]> { - None - } - - #[inline] - fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) { - } -} - -pub struct List { pub first: A, pub rest: R } - -unsafe impl AttachmentsList for List - where A: ImageView, - R: AttachmentsList -{ - #[inline] - fn raw_image_view_handles(&self) -> Vec { - let mut list = self.rest.raw_image_view_handles(); - list.insert(0, self.first.inner().internal_object()); - list - } - - #[inline] - fn min_dimensions(&self) -> Option<[u32; 3]> { - let my_view_dims = self.first.parent().dimensions(); - debug_assert_eq!(my_view_dims.depth(), 1); - let my_view_dims = [my_view_dims.width(), my_view_dims.height(), - my_view_dims.array_layers()]; // FIXME: should be the view's layers, not the image's - - match self.rest.min_dimensions() { - Some(r_dims) => { - Some([ - cmp::min(r_dims[0], my_view_dims[0]), - cmp::min(r_dims[1], my_view_dims[1]), - cmp::min(r_dims[2], my_view_dims[2]) - ]) - }, - None => Some(my_view_dims), - } - } - - #[inline] - fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) { - // TODO: "wrong" values - let stages = PipelineStages { - color_attachment_output: true, - late_fragment_tests: true, - .. PipelineStages::none() - }; - - let access = AccessFlagBits { - color_attachment_read: true, - color_attachment_write: true, - depth_stencil_attachment_read: true, - depth_stencil_attachment_write: true, - .. AccessFlagBits::none() - }; - - // FIXME: adjust layers & mipmaps with the view's parameters - sink.add_image_transition(self.first.parent(), 0, 1, 0, 1, true, Layout::General /* FIXME: wrong */, - stages, access); - self.rest.add_transition(sink); - } -} - -/// Trait for types that can be turned into a list of attachments. -pub trait IntoAttachmentsList { - /// The list of attachments. - type List; - - /// Performs the conversion. - fn into_attachments_list(self) -> Self::List; -} - -/*impl IntoAttachmentsList for T where T: AttachmentsList { - type List = T; - - #[inline] - fn into_attachments_list(self) -> T { - self - } -}*/ - -impl IntoAttachmentsList for () { - type List = EmptyAttachmentsList; - - #[inline] - fn into_attachments_list(self) -> EmptyAttachmentsList { - EmptyAttachmentsList - } -} - -macro_rules! impl_into_atch_list { - ($first:ident, $($rest:ident),+) => ( - impl<$first, $($rest),+> IntoAttachmentsList for ($first, $($rest),+) { - type List = List<$first, <($($rest,)+) as IntoAttachmentsList>::List>; - - #[inline] - #[allow(non_snake_case)] - fn into_attachments_list(self) -> Self::List { - let ($first, $($rest),+) = self; - - List { - first: $first, - rest: IntoAttachmentsList::into_attachments_list(($($rest,)+)) - } - } - } - - impl_into_atch_list!($($rest),+); - ); - - ($alone:ident) => ( - impl IntoAttachmentsList for (A,) { - type List = List; - - #[inline] - fn into_attachments_list(self) -> Self::List { - List { first: self.0, rest: EmptyAttachmentsList } - } - } - ); -} - -impl_into_atch_list!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); - /// Error that can happen when creating a framebuffer object. #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[repr(u32)] diff --git a/vulkano/src/framebuffer/macros.rs b/vulkano/src/framebuffer/macros.rs index 905c102f8..147d0785a 100644 --- a/vulkano/src/framebuffer/macros.rs +++ b/vulkano/src/framebuffer/macros.rs @@ -73,7 +73,6 @@ macro_rules! ordered_passes_renderpass { use $crate::framebuffer::LayoutPassDependencyDescription; use $crate::framebuffer::FramebufferCreationError; use $crate::framebuffer::RenderPassCreationError; - use $crate::framebuffer::IntoAttachmentsList; use $crate::image::Layout; use $crate::image::traits::ImageView; use $crate::sync::AccessFlagBits; @@ -347,7 +346,9 @@ macro_rules! ordered_passes_renderpass { ([] __impl_attachments__ [] [] [] [$($params:ident),*]) => { unsafe impl RenderPassDescAttachmentsList for CustomRenderPassDesc { - fn check_attachments_list(&self, attachments: &AttachmentsStart) -> Result<(), FramebufferCreationError> { + type List = (); + + fn check_attachments_list(&self, attachments: AttachmentsStart) -> Result<(), FramebufferCreationError> { Ok(()) // FIXME: } } @@ -370,9 +371,13 @@ macro_rules! ordered_passes_renderpass { }; ([] __impl_attachments__ [$prev:ident] [$($prev_params:ident),*] [] [$($params:ident),*]) => { - unsafe impl<$($prev_params,)*> RenderPassDescAttachmentsList<$prev<$($prev_params,)*>> for CustomRenderPassDesc { - fn check_attachments_list(&self, attachments: &$prev<$($prev_params,)*>) -> Result<(), FramebufferCreationError> { - Ok(()) // FIXME: + unsafe impl<$($prev_params,)*> RenderPassDescAttachmentsList<$prev<$($prev_params,)*>> for CustomRenderPassDesc + where $($prev_params: ImageView,)* + { + type List = ($($prev_params,)*); // TODO: wrong + + fn check_attachments_list(&self, attachments: $prev<$($prev_params,)*>) -> Result { + unimplemented!() // FIXME: } } }; diff --git a/vulkano/src/framebuffer/mod.rs b/vulkano/src/framebuffer/mod.rs index 29941398b..19a92851b 100644 --- a/vulkano/src/framebuffer/mod.rs +++ b/vulkano/src/framebuffer/mod.rs @@ -77,9 +77,8 @@ //! //! TODO +pub use self::attachments_list::AttachmentsList; pub use self::empty::EmptySinglePassRenderPassDesc; -pub use self::framebuffer::AttachmentsList; // TODO: rework and remove -pub use self::framebuffer::IntoAttachmentsList; // TODO: rework and remove pub use self::framebuffer::Framebuffer; pub use self::framebuffer::FramebufferCreationError; pub use self::sys::RenderPass; @@ -100,6 +99,7 @@ pub use self::traits::Subpass; #[macro_use] mod macros; +mod attachments_list; mod empty; mod framebuffer; mod sys; diff --git a/vulkano/src/framebuffer/traits.rs b/vulkano/src/framebuffer/traits.rs index 9ed267e86..dbdee53ad 100644 --- a/vulkano/src/framebuffer/traits.rs +++ b/vulkano/src/framebuffer/traits.rs @@ -13,6 +13,7 @@ use device::Device; use format::ClearValue; use format::Format; use format::FormatTy; +use framebuffer::AttachmentsList; use framebuffer::Framebuffer; use framebuffer::FramebufferCreationError; use framebuffer::RenderPass; @@ -436,10 +437,14 @@ impl<'a, R: ?Sized + 'a> Iterator for RenderPassDescDependencies<'a, R> where R: /// TODO: more stuff with aliasing /// pub unsafe trait RenderPassDescAttachmentsList: RenderPassDesc { + /// The "compiled" list of attachments. + type List: AttachmentsList; + /// Decodes a `A` into a list of attachments. /// - /// Returns an error if one of the attachments is wrong. - fn check_attachments_list(&self, &A) -> Result<(), FramebufferCreationError>; + /// Checks that the attachments match the render pass, and returns a list. Returns an error if + /// one of the attachments is wrong. + fn check_attachments_list(&self, A) -> Result; } /*unsafe impl RenderPassDescAttachmentsList for R where R: RenderPassDesc {