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