diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/gfx-hal/src/pso/output_merger.rs | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/gfx-hal/src/pso/output_merger.rs')
-rw-r--r-- | third_party/rust/gfx-hal/src/pso/output_merger.rs | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/third_party/rust/gfx-hal/src/pso/output_merger.rs b/third_party/rust/gfx-hal/src/pso/output_merger.rs new file mode 100644 index 0000000000..88fbc8a8b6 --- /dev/null +++ b/third_party/rust/gfx-hal/src/pso/output_merger.rs @@ -0,0 +1,359 @@ +//! Output Merger (OM) stage description. +//! The final stage in a pipeline that creates pixel colors from +//! the input shader results, depth/stencil information, etc. + +use crate::pso::{graphics::StencilValue, State}; + +/// A pixel-wise comparison function. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum Comparison { + /// `false` + Never = 0, + /// `x < y` + Less = 1, + /// `x == y` + Equal = 2, + /// `x <= y` + LessEqual = 3, + /// `x > y` + Greater = 4, + /// `x != y` + NotEqual = 5, + /// `x >= y` + GreaterEqual = 6, + /// `true` + Always = 7, +} + +bitflags!( + /// Target output color mask. + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct ColorMask: u8 { + /// Red mask + const RED = 0x1; + /// Green mask + const GREEN = 0x2; + /// Blue mask + const BLUE = 0x4; + /// Alpha channel mask + const ALPHA = 0x8; + /// Mask for RGB channels + const COLOR = 0x7; + /// Mask all channels + const ALL = 0xF; + /// Mask no channels. + const NONE = 0x0; + } +); + +impl Default for ColorMask { + fn default() -> Self { + Self::ALL + } +} + +/// Defines the possible blending factors. +/// During blending, the source or destination fragment may be +/// multiplied by a factor to produce the final result. +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum Factor { + Zero = 0, + One = 1, + SrcColor = 2, + OneMinusSrcColor = 3, + DstColor = 4, + OneMinusDstColor = 5, + SrcAlpha = 6, + OneMinusSrcAlpha = 7, + DstAlpha = 8, + OneMinusDstAlpha = 9, + ConstColor = 10, + OneMinusConstColor = 11, + ConstAlpha = 12, + OneMinusConstAlpha = 13, + SrcAlphaSaturate = 14, + Src1Color = 15, + OneMinusSrc1Color = 16, + Src1Alpha = 17, + OneMinusSrc1Alpha = 18, +} + +/// Blending operations. +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum BlendOp { + /// Adds source and destination. + /// Source and destination are multiplied by factors before addition. + Add { src: Factor, dst: Factor }, + /// Subtracts destination from source. + /// Source and destination are multiplied by factors before subtraction. + Sub { src: Factor, dst: Factor }, + /// Subtracts source from destination. + /// Source and destination are multiplied by factors before subtraction. + RevSub { src: Factor, dst: Factor }, + /// Component-wise minimum value of source and destination. + Min, + /// Component-wise maximum value of source and destination. + Max, +} + +impl BlendOp { + /// Replace the destination value with the source. + pub const REPLACE: Self = BlendOp::Add { + src: Factor::One, + dst: Factor::Zero, + }; + /// Add the source and destination together. + pub const ADD: Self = BlendOp::Add { + src: Factor::One, + dst: Factor::One, + }; + /// Alpha blend the source and destination together. + pub const ALPHA: Self = BlendOp::Add { + src: Factor::SrcAlpha, + dst: Factor::OneMinusSrcAlpha, + }; + /// Alpha blend a premultiplied-alpha source with the destination. + pub const PREMULTIPLIED_ALPHA: Self = BlendOp::Add { + src: Factor::One, + dst: Factor::OneMinusSrcAlpha, + }; +} + +/// Specifies whether to use blending, and if so, +/// which operations to use for color and alpha channels. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct BlendState { + /// The blend operation to use for the color channels. + pub color: BlendOp, + /// The blend operation to use for the alpha channel. + pub alpha: BlendOp, +} + +impl BlendState { + /// Replace the color. + pub const REPLACE: Self = BlendState { + color: BlendOp::REPLACE, + alpha: BlendOp::REPLACE, + }; + /// Additive blending. + pub const ADD: Self = BlendState { + color: BlendOp::ADD, + alpha: BlendOp::ADD, + }; + /// Multiplicative blending. + pub const MULTIPLY: Self = BlendState { + color: BlendOp::Add { + src: Factor::Zero, + dst: Factor::SrcColor, + }, + alpha: BlendOp::Add { + src: Factor::Zero, + dst: Factor::SrcAlpha, + }, + }; + /// Alpha blending. + pub const ALPHA: Self = BlendState { + color: BlendOp::ALPHA, + alpha: BlendOp::PREMULTIPLIED_ALPHA, + }; + /// Pre-multiplied alpha blending. + pub const PREMULTIPLIED_ALPHA: Self = BlendState { + color: BlendOp::PREMULTIPLIED_ALPHA, + alpha: BlendOp::PREMULTIPLIED_ALPHA, + }; +} + +/// PSO color target descriptor. +#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ColorBlendDesc { + /// Color write mask. + pub mask: ColorMask, + /// Blend state, if enabled. + pub blend: Option<BlendState>, +} + +impl ColorBlendDesc { + /// Empty blend descriptor just writes out the color without blending. + // this can be used because `Default::default()` isn't a const function... + pub const EMPTY: Self = ColorBlendDesc { + mask: ColorMask::ALL, + blend: None, + }; +} + +/// Depth test state. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct DepthTest { + /// Comparison function to use. + pub fun: Comparison, + /// Specify whether to write to the depth buffer or not. + pub write: bool, +} + +impl DepthTest { + /// A depth test that always fails. + pub const FAIL: Self = DepthTest { + fun: Comparison::Never, + write: false, + }; + /// A depth test that always succeeds but doesn't + /// write to the depth buffer + // DOC TODO: Not a terribly helpful description there... + pub const PASS_TEST: Self = DepthTest { + fun: Comparison::Always, + write: false, + }; + /// A depth test that always succeeds and writes its result + /// to the depth buffer. + pub const PASS_WRITE: Self = DepthTest { + fun: Comparison::Always, + write: true, + }; +} + +/// The operation to use for stencil masking. +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum StencilOp { + /// Keep the current value in the stencil buffer (no change). + Keep = 0, + /// Set the value in the stencil buffer to zero. + Zero = 1, + /// Set the stencil buffer value to `reference` from `StencilFace`. + Replace = 2, + /// Increment the stencil buffer value, clamping to its maximum value. + IncrementClamp = 3, + /// Decrement the stencil buffer value, clamping to its minimum value. + DecrementClamp = 4, + /// Bitwise invert the current value in the stencil buffer. + Invert = 5, + /// Increment the stencil buffer value, wrapping around to 0 on overflow. + IncrementWrap = 6, + /// Decrement the stencil buffer value, wrapping around to the maximum value on overflow. + DecrementWrap = 7, +} + +/// Complete stencil state for a given side of a face. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct StencilFace { + /// Comparison function to use to determine if the stencil test passes. + pub fun: Comparison, + /// What operation to do if the stencil test fails. + pub op_fail: StencilOp, + /// What operation to do if the stencil test passes but the depth test fails. + pub op_depth_fail: StencilOp, + /// What operation to do if both the depth and stencil test pass. + pub op_pass: StencilOp, +} + +impl Default for StencilFace { + fn default() -> StencilFace { + StencilFace { + fun: Comparison::Never, + op_fail: StencilOp::Keep, + op_depth_fail: StencilOp::Keep, + op_pass: StencilOp::Keep, + } + } +} + +/// A generic struct holding the properties of two sides of a polygon. +#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct Sided<T> { + /// Information about the front face. + pub front: T, + /// Information about the back face. + pub back: T, +} + +impl<T: Copy> Sided<T> { + /// Create a new `Sided` structure with both `front` and `back` holding + /// the same value. + pub fn new(value: T) -> Self { + Sided { + front: value, + back: value, + } + } +} + +/// Pair of stencil values that could be either baked into a graphics pipeline +/// or provided dynamically. +pub type StencilValues = State<Sided<StencilValue>>; + +/// Defines a stencil test. Stencil testing is an operation +/// performed to cull fragments; +/// the new fragment is tested against the value held in the +/// stencil buffer, and if the test fails the fragment is +/// discarded. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct StencilTest { + /// Operations for stencil faces. + pub faces: Sided<StencilFace>, + /// Masks that are ANDd with both the stencil buffer value and the reference value when they + /// are read before doing the stencil test. + pub read_masks: StencilValues, + /// Mask that are ANDd with the stencil value before writing to the stencil buffer. + pub write_masks: StencilValues, + /// The reference values used for stencil tests. + pub reference_values: StencilValues, +} + +impl Default for StencilTest { + fn default() -> Self { + StencilTest { + faces: Sided::default(), + read_masks: State::Static(Sided::new(!0)), + write_masks: State::Static(Sided::new(!0)), + reference_values: State::Static(Sided::new(0)), + } + } +} + +/// PSO depth-stencil target descriptor. +#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct DepthStencilDesc { + /// Optional depth testing/writing. + pub depth: Option<DepthTest>, + /// Enable depth bounds testing. + pub depth_bounds: bool, + /// Stencil test/write. + pub stencil: Option<StencilTest>, +} + +impl DepthStencilDesc { + /// Returns true if the descriptor assumes the depth attachment. + pub fn uses_depth(&self) -> bool { + self.depth.is_some() || self.depth_bounds + } + /// Returns true if the descriptor assumes the stencil attachment. + pub fn uses_stencil(&self) -> bool { + self.stencil.is_some() + } +} + +bitflags!( + /// Face. + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + pub struct Face: u32 { + /// Empty face. TODO: remove when constexpr are stabilized to use empty() + const NONE = 0x0; + /// Front face. + const FRONT = 0x1; + /// Back face. + const BACK = 0x2; + } +); |