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 11 use crate::{format::Format, image, memory::Dependencies, pso::PipelineStage, Backend}; 12 use 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))] 17 pub 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))] 29 pub 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. 37 pub type AttachmentLayout = image::Layout; 38 39 /// Attachment operations. 40 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] 41 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 42 pub 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 50 impl 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`. new(load: AttachmentLoadOp, store: AttachmentStoreOp) -> Self70 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")] whatever() -> Self77 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))] 88 pub 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 109 impl 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. has_clears(&self) -> bool113 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, 119 pub type AttachmentId = usize; 120 /// Reference to an attachment by index and expected image layout. 121 pub type AttachmentRef = (AttachmentId, AttachmentLayout); 122 /// An AttachmentId that can be used instead of providing an attachment. 123 pub const ATTACHMENT_UNUSED: AttachmentId = !0; 124 125 /// Index of a subpass. 126 pub 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))] 135 pub 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)] 151 pub 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)] 174 pub 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 181 impl<'a, B: Backend> Clone for Subpass<'a, B> { clone(&self) -> Self182 fn clone(&self) -> Self { 183 Subpass { 184 index: self.index, 185 main_pass: self.main_pass, 186 } 187 } 188 } 189 190 impl<'a, B: Backend> PartialEq for Subpass<'a, B> { eq(&self, other: &Self) -> bool191 fn eq(&self, other: &Self) -> bool { 192 self.index == other.index && std::ptr::eq(self.main_pass, other.main_pass) 193 } 194 } 195 196 impl<'a, B: Backend> Copy for Subpass<'a, B> {} 197 impl<'a, B: Backend> Eq for Subpass<'a, B> {} 198