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