gfx_hal/pass.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
//! Render pass handling.
//!
//! A *render pass* represents a collection of
//!
//! - [attachments][crate::pass::Attachment]
//! - [subpasses][crate::pass::SubpassDesc]
//! - [dependencies][crate::pass::SubpassDependency] between the subpasses
//!
//! and describes how the attachments are used over the course of the subpasses.
use crate::{format::Format, image, memory::Dependencies, pso::PipelineStage, Backend};
use std::ops::Range;
/// Specifies the operation to be used when reading data from a subpass attachment.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum AttachmentLoadOp {
/// Preserve existing content in the attachment.
Load,
/// Clear the attachment.
Clear,
/// Attachment content will be undefined.
DontCare,
}
/// Specifies the operation to be used when writing data to a subpass attachment.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum AttachmentStoreOp {
/// Content written to the attachment will be preserved.
Store,
/// Attachment content will be undefined.
DontCare,
}
/// Image layout of an attachment.
pub type AttachmentLayout = image::Layout;
/// Attachment operations.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct AttachmentOps {
/// Indicates how the data of the attachment will be loaded at first usage at
/// the beginning of the subpass.
pub load: AttachmentLoadOp,
/// Whether or not data from the store operation will be preserved after the subpass.
pub store: AttachmentStoreOp,
}
impl AttachmentOps {
/// Specifies `DontCare` for both load and store op.
pub const DONT_CARE: Self = AttachmentOps {
load: AttachmentLoadOp::DontCare,
store: AttachmentStoreOp::DontCare,
};
/// Specifies `Clear` for load op and `Store` for store op.
pub const INIT: Self = AttachmentOps {
load: AttachmentLoadOp::Clear,
store: AttachmentStoreOp::Store,
};
/// Specifies `Load` for load op and `Store` for store op.
pub const PRESERVE: Self = AttachmentOps {
load: AttachmentLoadOp::Load,
store: AttachmentStoreOp::Store,
};
/// Convenience function to create a new `AttachmentOps`.
pub fn new(load: AttachmentLoadOp, store: AttachmentStoreOp) -> Self {
AttachmentOps { load, store }
}
/// A method to provide `AttachmentOps::DONT_CARE` to things that expect
/// a default function rather than a value.
#[cfg(feature = "serde")]
fn whatever() -> Self {
Self::DONT_CARE
}
}
/// An attachment is a description of a resource provided to a render subpass.
///
/// It includes things such as render targets, images that were produced from
/// previous subpasses, etc.
#[derive(Clone, Debug, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Attachment {
/// Format of this attachment.
///
/// In the most cases `format` is not `None`. It should be only used for
/// creating dummy renderpasses, which are used as placeholder for compatible
/// renderpasses.
pub format: Option<Format>,
/// Number of samples to use when loading from this attachment.
///
/// If greater than 1, [multisampling](https://en.wikipedia.org/wiki/Multisample_anti-aliasing)
/// will take effect.
pub samples: image::NumSamples,
/// Load and store operations of the attachment.
pub ops: AttachmentOps,
/// Load and store operations of the stencil aspect, if any.
#[cfg_attr(feature = "serde", serde(default = "AttachmentOps::whatever"))]
pub stencil_ops: AttachmentOps,
/// Initial and final image layouts of the renderpass.
pub layouts: Range<AttachmentLayout>,
}
impl Attachment {
/// Returns true if this attachment has some clear operations.
///
/// Useful when starting a render pass, since there has to be a clear value provided.
pub fn has_clears(&self) -> bool {
self.ops.load == AttachmentLoadOp::Clear || self.stencil_ops.load == AttachmentLoadOp::Clear
}
}
/// Index of an attachment within a framebuffer/renderpass,
pub type AttachmentId = usize;
/// Reference to an attachment by index and expected image layout.
pub type AttachmentRef = (AttachmentId, AttachmentLayout);
/// An AttachmentId that can be used instead of providing an attachment.
pub const ATTACHMENT_UNUSED: AttachmentId = !0;
/// Index of a subpass.
pub type SubpassId = u8;
/// Expresses a dependency between multiple [subpasses][SubpassDesc].
///
/// This is used both to describe a source or destination subpass;
/// data either explicitly passes from this subpass to the next or from another
/// subpass into this one.
#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SubpassDependency {
/// Other subpasses this one depends on.
///
/// If one of the range sides is `None`, it refers to the external
/// scope either before or after the whole render pass.
pub passes: Range<Option<SubpassId>>,
/// Other pipeline stages this subpass depends on.
pub stages: Range<PipelineStage>,
/// Resource accesses this subpass depends on.
pub accesses: Range<image::Access>,
/// Dependency flags.
pub flags: Dependencies,
}
/// Description of a subpass for render pass creation.
#[derive(Clone, Debug)]
pub struct SubpassDesc<'a> {
/// Which attachments will be used as color buffers.
pub colors: &'a [AttachmentRef],
/// Which attachments will be used as depth/stencil buffers.
pub depth_stencil: Option<&'a AttachmentRef>,
/// Which attachments will be used as input attachments.
pub inputs: &'a [AttachmentRef],
/// Which attachments will be used as resolve destinations.
///
/// The number of resolve attachments may be zero or equal to the number of color attachments.
///
/// At the end of a subpass the color attachment will be resolved to the corresponding
/// resolve attachment.
///
/// The resolve attachment must not be multisampled.
pub resolves: &'a [AttachmentRef],
/// Attachments that are not used by the subpass but must be preserved to be
/// passed on to subsequent passes.
pub preserves: &'a [AttachmentId],
}
/// A sub-pass borrow of a pass.
#[derive(Debug)]
pub struct Subpass<'a, B: Backend> {
/// Index of the subpass
pub index: SubpassId,
/// Main pass borrow.
pub main_pass: &'a B::RenderPass,
}
impl<'a, B: Backend> Clone for Subpass<'a, B> {
fn clone(&self) -> Self {
Subpass {
index: self.index,
main_pass: self.main_pass,
}
}
}
impl<'a, B: Backend> PartialEq for Subpass<'a, B> {
fn eq(&self, other: &Self) -> bool {
self.index == other.index && std::ptr::eq(self.main_pass, other.main_pass)
}
}
impl<'a, B: Backend> Copy for Subpass<'a, B> {}
impl<'a, B: Backend> Eq for Subpass<'a, B> {}