gfx_hal/
pass.rs

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