aboutsummaryrefslogtreecommitdiff
path: root/stockton-skeleton/src/draw_passes/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'stockton-skeleton/src/draw_passes/mod.rs')
-rw-r--r--stockton-skeleton/src/draw_passes/mod.rs109
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 {}
+}