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
//! RenderPass handling.
use format::Format;
use image;
use pso::PipelineStage;
use Backend;
use std::ops::Range;
/// Specifies the operation which will be applied at the beginning of a subpass.
#[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,
}
///
#[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 `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 {
/// Attachment format
///
/// 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.
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>,
}
/// 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);
/// Which other subpasses a particular subpass depends on.
#[derive(Copy, Clone, Debug, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum SubpassRef {
/// The subpass depends on something that was submitted to the
/// queue before or after the render pass began.
External,
/// The subpass depends on another subpass with the given index,
/// which must be less than or equal to the index of the current
/// subpass. The index here refers to the corresponding
/// `SubpassId` of a `Subpass`.
Pass(usize),
}
/// Expresses a dependency between multiple subpasses. 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.
pub passes: Range<SubpassRef>,
/// Other pipeline stages this subpass depends on.
pub stages: Range<PipelineStage>,
/// Resource accesses this subpass depends on.
pub accesses: Range<image::Access>,
}
/// Description of a subpass for renderpass creation.
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],
}
/// Index of a subpass.
pub type SubpassId = usize;
/// 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 &&
self.main_pass as *const _ == other.main_pass as *const _
}
}
impl<'a, B: Backend> Copy for Subpass<'a, B> {}
impl<'a, B: Backend> Eq for Subpass<'a, B> {}