gfx_hal/pso/
mod.rs

1//! Raw Pipeline State Objects
2//!
3//! This module contains items used to create and manage Pipelines.
4
5use crate::{device, pass, Backend};
6
7mod compute;
8mod descriptor;
9mod graphics;
10mod input_assembler;
11mod output_merger;
12mod specialization;
13
14pub use self::{
15    compute::*, descriptor::*, graphics::*, input_assembler::*, output_merger::*, specialization::*,
16};
17
18/// Error types happening upon PSO creation on the device side.
19#[derive(Clone, Debug, PartialEq, thiserror::Error)]
20pub enum CreationError {
21    /// Unknown other error.
22    #[error("Implementation specific error occurred")]
23    Other,
24    /// Shader module creation error.
25    #[error("{0:?} shader creation failed: {1:}")]
26    ShaderCreationError(ShaderStageFlags, String),
27    /// Unsupported pipeline on hardware or implementation. Example: mesh shaders on DirectX 11.
28    #[error("Pipeline kind is not supported")]
29    UnsupportedPipeline,
30    /// Invalid subpass (not part of renderpass).
31    #[error("Invalid subpass: {0:?}")]
32    InvalidSubpass(pass::SubpassId),
33    /// The shader is missing an entry point.
34    #[error("Invalid entry point: {0:}")]
35    MissingEntryPoint(String),
36    /// The specialization values are incorrect.
37    #[error("Specialization failed: {0:}")]
38    InvalidSpecialization(String),
39    /// Out of either host or device memory.
40    #[error(transparent)]
41    OutOfMemory(#[from] device::OutOfMemory),
42}
43
44bitflags!(
45    /// Stages of the logical pipeline.
46    ///
47    /// The pipeline is structured by the ordering of the flags.
48    /// Some stages are queue type dependent.
49    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50    pub struct PipelineStage: u32 {
51        /// Beginning of the command queue.
52        const TOP_OF_PIPE = 0x1;
53        /// Indirect data consumption.
54        const DRAW_INDIRECT = 0x2;
55        /// Vertex data consumption.
56        const VERTEX_INPUT = 0x4;
57        /// Vertex shader execution.
58        const VERTEX_SHADER = 0x8;
59        /// Hull shader execution.
60        const HULL_SHADER = 0x10;
61        /// Domain shader execution.
62        const DOMAIN_SHADER = 0x20;
63        /// Geometry shader execution.
64        const GEOMETRY_SHADER = 0x40;
65        /// Fragment shader execution.
66        const FRAGMENT_SHADER = 0x80;
67        /// Stage of early depth and stencil test.
68        const EARLY_FRAGMENT_TESTS = 0x100;
69        /// Stage of late depth and stencil test.
70        const LATE_FRAGMENT_TESTS = 0x200;
71        /// Stage of final color value calculation.
72        const COLOR_ATTACHMENT_OUTPUT = 0x400;
73        /// Compute shader execution,
74        const COMPUTE_SHADER = 0x800;
75        /// Copy/Transfer command execution.
76        const TRANSFER = 0x1000;
77        /// End of the command queue.
78        const BOTTOM_OF_PIPE = 0x2000;
79        /// Read/Write access from host.
80        /// (Not a real pipeline stage)
81        const HOST = 0x4000;
82        /// Task shader stage.
83        const TASK_SHADER = 0x80000;
84        /// Mesh shader stage.
85        const MESH_SHADER = 0x100000;
86    }
87);
88
89bitflags!(
90    /// Combination of different shader pipeline stages.
91    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
92    #[derive(Default)]
93    pub struct ShaderStageFlags: u32 {
94        /// Vertex shader stage.
95        const VERTEX   = 0x1;
96        /// Hull (tessellation) shader stage.
97        const HULL     = 0x2;
98        /// Domain (tessellation) shader stage.
99        const DOMAIN   = 0x4;
100        /// Geometry shader stage.
101        const GEOMETRY = 0x8;
102        /// Fragment shader stage.
103        const FRAGMENT = 0x10;
104        /// Compute shader stage.
105        const COMPUTE  = 0x20;
106        /// Task shader stage.
107        const TASK     = 0x40;
108        /// Mesh shader stage.
109        const MESH     = 0x80;
110        /// All graphics pipeline shader stages.
111        const GRAPHICS = Self::VERTEX.bits | Self::HULL.bits |
112            Self::DOMAIN.bits | Self::GEOMETRY.bits | Self::FRAGMENT.bits;
113        /// All shader stages (matches Vulkan).
114        const ALL      = 0x7FFFFFFF;
115    }
116);
117
118impl From<naga::ShaderStage> for ShaderStageFlags {
119    fn from(stage: naga::ShaderStage) -> Self {
120        use naga::ShaderStage as Ss;
121        match stage {
122            Ss::Vertex => Self::VERTEX,
123            Ss::Fragment => Self::FRAGMENT,
124            Ss::Compute => Self::COMPUTE,
125        }
126    }
127}
128
129/// Shader entry point.
130#[derive(Debug)]
131pub struct EntryPoint<'a, B: Backend> {
132    /// Entry point name.
133    pub entry: &'a str,
134    /// Reference to the shader module containing this entry point.
135    pub module: &'a B::ShaderModule,
136    /// Specialization constants to be used when creating the pipeline.
137    pub specialization: Specialization<'a>,
138}
139
140impl<'a, B: Backend> Clone for EntryPoint<'a, B> {
141    fn clone(&self) -> Self {
142        EntryPoint {
143            entry: self.entry,
144            module: self.module,
145            specialization: self.specialization.clone(),
146        }
147    }
148}
149
150bitflags!(
151    /// Pipeline creation flags.
152    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
153    pub struct PipelineCreationFlags: u32 {
154        /// Disable pipeline optimizations.
155        ///
156        /// May speedup pipeline creation.
157        const DISABLE_OPTIMIZATION = 0x1;
158        /// Allow derivatives (children) of the pipeline.
159        ///
160        /// Must be set when pipelines set the pipeline as base.
161        const ALLOW_DERIVATIVES = 0x2;
162    }
163);
164
165/// A reference to a parent pipeline.  The assumption is that
166/// a parent and derivative/child pipeline have most settings
167/// in common, and one may be switched for another more quickly
168/// than entirely unrelated pipelines would be.
169#[derive(Debug)]
170pub enum BasePipeline<'a, P: 'a> {
171    /// Referencing an existing pipeline as parent.
172    Pipeline(&'a P),
173    /// A pipeline in the same create pipelines call.
174    ///
175    /// The index of the parent must be lower than the index of the child.
176    Index(usize),
177    /// No parent pipeline exists.
178    None,
179}
180
181/// Pipeline state which may be static or dynamic.
182#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
183#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
184pub enum State<T> {
185    /// Static state that cannot be altered.
186    Static(T),
187    /// Dynamic state set through a command buffer.
188    Dynamic,
189}
190
191impl<T> State<T> {
192    /// Returns the static value or a default.
193    pub fn static_or(self, default: T) -> T {
194        match self {
195            State::Static(v) => v,
196            State::Dynamic => default,
197        }
198    }
199
200    /// Whether the state is static.
201    pub fn is_static(self) -> bool {
202        match self {
203            State::Static(_) => true,
204            State::Dynamic => false,
205        }
206    }
207
208    /// Whether the state is dynamic.
209    pub fn is_dynamic(self) -> bool {
210        !self.is_static()
211    }
212}