diff options
Diffstat (limited to 'stockton-skeleton/src/draw_passes/mod.rs')
-rw-r--r-- | stockton-skeleton/src/draw_passes/mod.rs | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/stockton-skeleton/src/draw_passes/mod.rs b/stockton-skeleton/src/draw_passes/mod.rs index a0dbba5..5a92a45 100644 --- a/stockton-skeleton/src/draw_passes/mod.rs +++ b/stockton-skeleton/src/draw_passes/mod.rs @@ -1,6 +1,12 @@ //! Traits and common draw passes. +use std::ops::Range; + use super::{queue_negotiator::QueueNegotiator, RenderingContext}; use crate::types::*; +use hal::{ + image::Layout, + pass::{AttachmentLoadOp, AttachmentOps, AttachmentStoreOp}, +}; use stockton_types::Session; use anyhow::Result; @@ -11,7 +17,7 @@ pub mod util; pub use cons::ConsDrawPass; /// One of several 'passes' that draw on each frame. -pub trait DrawPass { +pub trait DrawPass<P: PassPosition> { /// Queue any necessary draw commands to cmd_buffer /// This should assume the command buffer isn't in the middle of a renderpass, and should leave it as such. fn queue_draw( @@ -34,7 +40,7 @@ pub trait DrawPass { /// A type that can be made into a specific draw pass type. /// This allows extra data to be used in initialisation without the Renderer needing to worry about it. -pub trait IntoDrawPass<T: DrawPass> { +pub trait IntoDrawPass<T: DrawPass<P>, P: PassPosition> { fn init(self, session: &mut Session, context: &mut RenderingContext) -> Result<T>; /// This function should ask the queue negotatior to find families for any auxilary operations this draw pass needs to perform @@ -45,3 +51,102 @@ pub trait IntoDrawPass<T: DrawPass> { queue_negotiator: &mut QueueNegotiator, ) -> Result<Vec<(&'a QueueFamilyT, Vec<f32>)>>; } + +/// Used so that draw passes can determine what state shared resources are in and how they should be left. +pub trait PassPosition: private::Sealed { + /// The layout the image is in going in. + fn layout_in() -> Layout; + + /// The layout the image should be once this drawpass is completed + fn layout_out() -> Layout; + + /// Has the layout already been cleared this frame + fn is_cleared() -> bool; + + /// Convenience function to get a range from layout_in() to layout_out() + fn layout_as_range() -> Range<Layout> { + Self::layout_in()..Self::layout_out() + } + + /// Convenience function to get the attachment ops that should be used when loading the image attachment. + fn attachment_ops() -> AttachmentOps { + match Self::is_cleared() { + true => AttachmentOps::new(AttachmentLoadOp::Load, AttachmentStoreOp::Store), + false => AttachmentOps::new(AttachmentLoadOp::Clear, AttachmentStoreOp::Store), + } + } +} + +/// Pass is at the beginning of the list +pub struct Beginning; +impl PassPosition for Beginning { + fn layout_in() -> Layout { + Layout::Undefined + } + + fn layout_out() -> Layout { + Layout::ColorAttachmentOptimal + } + + fn is_cleared() -> bool { + false + } +} + +/// Pass is in the middle of the list +pub struct Middle; +impl PassPosition for Middle { + fn layout_in() -> Layout { + Layout::ColorAttachmentOptimal + } + + fn layout_out() -> Layout { + Layout::ColorAttachmentOptimal + } + + fn is_cleared() -> bool { + true + } +} + +/// Pass is at the end of the list +pub struct End; +impl PassPosition for End { + fn layout_in() -> Layout { + Layout::ColorAttachmentOptimal + } + + fn layout_out() -> Layout { + Layout::Present + } + + fn is_cleared() -> bool { + true + } +} + +/// Pass is the only draw pass being used +pub struct Singular; +impl PassPosition for Singular { + fn layout_in() -> Layout { + Layout::Undefined + } + + fn layout_out() -> Layout { + Layout::Present + } + + fn is_cleared() -> bool { + false + } +} + +mod private { + use super::{Beginning, End, Middle, Singular}; + + pub trait Sealed {} + impl Sealed for Beginning {} + impl Sealed for Middle {} + impl Sealed for End {} + impl Sealed for Singular {} +} |