mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
Rework attachments list
This commit is contained in:
parent
0b5d494288
commit
19beb1eb06
@ -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::<Vec<_>>();
|
||||
|
||||
// Initialization is finally finished!
|
||||
|
121
vulkano/src/framebuffer/attachments_list.rs
Normal file
121
vulkano/src/framebuffer/attachments_list.rs
Normal file
@ -0,0 +1,121 @@
|
||||
// Copyright (c) 2016 The vulkano developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
||||
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// 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<vk::ImageView>;
|
||||
|
||||
/// 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<vk::ImageView> {
|
||||
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<vk::ImageView> {
|
||||
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);
|
@ -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<Rp, A> Framebuffer<Rp, A> {
|
||||
/// Builds a new framebuffer.
|
||||
///
|
||||
/// The `attachments` parameter depends on which `RenderPassRef` implementation is used.
|
||||
pub fn new<Ia>(render_pass: Rp, dimensions: [u32; 3],
|
||||
attachments: Ia) -> Result<Arc<Framebuffer<Rp, A>>, FramebufferCreationError>
|
||||
pub fn new<Ia>(render_pass: Rp, dimensions: [u32; 3], attachments: Ia)
|
||||
-> Result<Arc<Framebuffer<Rp, A>>, FramebufferCreationError>
|
||||
where Rp: RenderPassRef,
|
||||
Rp::Desc: RenderPassDescAttachmentsList<Ia>,
|
||||
Ia: IntoAttachmentsList<List = A>,
|
||||
A: AttachmentsList
|
||||
Rp::Desc: RenderPassDescAttachmentsList<Ia, List = A>,
|
||||
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<Rp, A> Drop for Framebuffer<Rp, A> {
|
||||
}
|
||||
}
|
||||
|
||||
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<vk::ImageView>;
|
||||
|
||||
/// 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<vk::ImageView> {
|
||||
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<vk::ImageView> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn min_dimensions(&self) -> Option<[u32; 3]> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct List<A, R> { pub first: A, pub rest: R }
|
||||
|
||||
unsafe impl<A, R> AttachmentsList for List<A, R>
|
||||
where A: ImageView,
|
||||
R: AttachmentsList
|
||||
{
|
||||
#[inline]
|
||||
fn raw_image_view_handles(&self) -> Vec<vk::ImageView> {
|
||||
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<S, T> IntoAttachmentsList for T where T: AttachmentsList<S> {
|
||||
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<A> IntoAttachmentsList for (A,) {
|
||||
type List = List<A, EmptyAttachmentsList>;
|
||||
|
||||
#[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)]
|
||||
|
@ -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<AttachmentsStart> 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<Self::List, FramebufferCreationError> {
|
||||
unimplemented!() // FIXME:
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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<A>: 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<Self::List, FramebufferCreationError>;
|
||||
}
|
||||
|
||||
/*unsafe impl<A, R> RenderPassDescAttachmentsList<A> for R where R: RenderPassDesc {
|
||||
|
Loading…
Reference in New Issue
Block a user