gfx_hal/pso/
graphics.rs

1//! Graphics pipeline descriptor.
2
3use crate::{
4    image, pass,
5    pso::{
6        input_assembler::{AttributeDesc, InputAssemblerDesc, VertexBufferDesc},
7        output_merger::{ColorBlendDesc, DepthStencilDesc, Face},
8        BasePipeline, EntryPoint, PipelineCreationFlags, State,
9    },
10    Backend,
11};
12
13use std::ops::Range;
14
15/// A simple struct describing a rect with integer coordinates.
16#[derive(Clone, Copy, Debug, Hash, PartialEq, PartialOrd)]
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18pub struct Rect {
19    /// X position.
20    pub x: i16,
21    /// Y position.
22    pub y: i16,
23    /// Width.
24    pub w: i16,
25    /// Height.
26    pub h: i16,
27}
28
29/// A simple struct describing a rect with integer coordinates.
30#[derive(Clone, Debug, PartialEq)]
31#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32pub struct ClearRect {
33    /// 2D region.
34    pub rect: Rect,
35    /// Layer range.
36    pub layers: Range<image::Layer>,
37}
38
39/// A viewport, generally equating to a window on a display.
40#[derive(Clone, Debug, PartialEq)]
41#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42pub struct Viewport {
43    /// The viewport boundaries.
44    pub rect: Rect,
45    /// The viewport depth limits.
46    pub depth: Range<f32>,
47}
48
49/// A single RGBA float color.
50pub type ColorValue = [f32; 4];
51/// A single depth value from a depth buffer.
52pub type DepthValue = f32;
53/// A single value from a stencil buffer.
54pub type StencilValue = u32;
55/// Baked-in pipeline states.
56#[derive(Clone, Debug, Default, PartialEq)]
57#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
58pub struct BakedStates {
59    /// Static viewport. TODO: multiple viewports
60    pub viewport: Option<Viewport>,
61    /// Static scissor. TODO: multiple scissors
62    pub scissor: Option<Rect>,
63    /// Static blend constant color.
64    pub blend_constants: Option<ColorValue>,
65    /// Static depth bounds.
66    pub depth_bounds: Option<Range<f32>>,
67}
68#[derive(Debug)]
69/// Primitive Assembler describes how input data are fetched in the pipeline and formed into primitives before being sent into the fragment shader.
70pub enum PrimitiveAssemblerDesc<'a, B: Backend> {
71    /// Vertex based pipeline
72    Vertex {
73        /// Vertex buffers (IA)
74        buffers: &'a [VertexBufferDesc],
75        /// Vertex attributes (IA)
76        attributes: &'a [AttributeDesc],
77        /// Input assembler attributes, describes how
78        /// vertices are assembled into primitives (such as triangles).
79        input_assembler: InputAssemblerDesc,
80        /// A shader that outputs a vertex in a model.
81        vertex: EntryPoint<'a, B>,
82        /// Tesselation shaders consisting of:
83        ///
84        /// 1. Hull shader: takes in an input patch (values representing
85        /// a small portion of a shape, which may be actual geometry or may
86        /// be parameters for creating geometry) and produces one or more
87        /// output patches.
88        ///
89        /// 2. Domain shader: takes in domains produced from a hull shader's output
90        /// patches and computes actual vertex positions.
91        tessellation: Option<(EntryPoint<'a, B>, EntryPoint<'a, B>)>,
92        /// A shader that takes given input vertexes and outputs zero
93        /// or more output vertexes.
94        geometry: Option<EntryPoint<'a, B>>,
95    },
96    /// Mesh shading pipeline
97    Mesh {
98        /// A shader that creates a variable amount of mesh shader
99        /// invocations.
100        task: Option<EntryPoint<'a, B>>,
101        /// A shader of which each workgroup emits zero or
102        /// more output primitives and the group of vertices and their
103        /// associated data required for each output primitive.
104        mesh: EntryPoint<'a, B>,
105    },
106}
107/// A description of all the settings that can be altered
108/// when creating a graphics pipeline.
109#[derive(Debug)]
110pub struct GraphicsPipelineDesc<'a, B: Backend> {
111    /// Pipeline label
112    pub label: Option<&'a str>,
113    /// Primitive assembler
114    pub primitive_assembler: PrimitiveAssemblerDesc<'a, B>,
115    /// Rasterizer setup
116    pub rasterizer: Rasterizer,
117    /// A shader that outputs a value for a fragment.
118    /// Usually this value is a color that is then displayed as a
119    /// pixel on a screen.
120    ///
121    /// If a fragment shader is omitted, the results of fragment
122    /// processing are undefined. Specifically, any fragment color
123    /// outputs are considered to have undefined values, and the
124    /// fragment depth is considered to be unmodified. This can
125    /// be useful for depth-only rendering.
126    pub fragment: Option<EntryPoint<'a, B>>,
127    /// Description of how blend operations should be performed.
128    pub blender: BlendDesc,
129    /// Depth stencil (DSV)
130    pub depth_stencil: DepthStencilDesc,
131    /// Multisampling.
132    pub multisampling: Option<Multisampling>,
133    /// Static pipeline states.
134    pub baked_states: BakedStates,
135    /// Pipeline layout.
136    pub layout: &'a B::PipelineLayout,
137    /// Subpass in which the pipeline can be executed.
138    pub subpass: pass::Subpass<'a, B>,
139    /// Options that may be set to alter pipeline properties.
140    pub flags: PipelineCreationFlags,
141    /// The parent pipeline, which may be
142    /// `BasePipeline::None`.
143    pub parent: BasePipeline<'a, B::GraphicsPipeline>,
144}
145
146impl<'a, B: Backend> GraphicsPipelineDesc<'a, B> {
147    /// Create a new empty PSO descriptor.
148    pub fn new(
149        primitive_assembler: PrimitiveAssemblerDesc<'a, B>,
150        rasterizer: Rasterizer,
151        fragment: Option<EntryPoint<'a, B>>,
152        layout: &'a B::PipelineLayout,
153        subpass: pass::Subpass<'a, B>,
154    ) -> Self {
155        GraphicsPipelineDesc {
156            label: None,
157            primitive_assembler,
158            rasterizer,
159            fragment,
160            blender: BlendDesc::default(),
161            depth_stencil: DepthStencilDesc::default(),
162            multisampling: None,
163            baked_states: BakedStates::default(),
164            layout,
165            subpass,
166            flags: PipelineCreationFlags::empty(),
167            parent: BasePipeline::None,
168        }
169    }
170}
171
172/// Methods for rasterizing polygons, ie, turning the mesh
173/// into a raster image.
174#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
175#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
176pub enum PolygonMode {
177    /// Rasterize as a point.
178    Point,
179    /// Rasterize as a line with the given width.
180    Line,
181    /// Rasterize as a face.
182    Fill,
183}
184
185/// The front face winding order of a set of vertices. This is
186/// the order of vertexes that define which side of a face is
187/// the "front".
188#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
189#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
190pub enum FrontFace {
191    /// Clockwise winding order.
192    Clockwise,
193    /// Counter-clockwise winding order.
194    CounterClockwise,
195}
196
197/// A depth bias allows changing the produced depth values
198/// for fragments slightly but consistently. This permits
199/// drawing of multiple polygons in the same plane without
200/// Z-fighting, such as when trying to draw shadows on a wall.
201///
202/// For details of the algorithm and equations, see
203/// [the Vulkan spec](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#primsrast-depthbias).
204#[derive(Copy, Clone, Debug, Default, PartialEq)]
205#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
206pub struct DepthBias {
207    /// A constant depth value added to each fragment.
208    pub const_factor: f32,
209    /// The minimum or maximum depth bias of a fragment.
210    pub clamp: f32,
211    /// A constant bias applied to the fragment's slope.
212    pub slope_factor: f32,
213}
214
215/// Rasterization state.
216#[derive(Copy, Clone, Debug, PartialEq)]
217#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
218pub struct Rasterizer {
219    /// How to rasterize this primitive.
220    pub polygon_mode: PolygonMode,
221    /// Which face should be culled.
222    pub cull_face: Face,
223    /// Which vertex winding is considered to be the front face for culling.
224    pub front_face: FrontFace,
225    /// Whether or not to enable depth clamping; when enabled, instead of
226    /// fragments being omitted when they are outside the bounds of the z-plane,
227    /// they will be clamped to the min or max z value.
228    pub depth_clamping: bool,
229    /// What depth bias, if any, to use for the drawn primitives.
230    pub depth_bias: Option<State<DepthBias>>,
231    /// Controls how triangles will be rasterized depending on their overlap with pixels.
232    pub conservative: bool,
233    /// Controls width of rasterized line segments.
234    pub line_width: State<f32>,
235}
236
237impl Rasterizer {
238    /// Simple polygon-filling rasterizer state
239    pub const FILL: Self = Rasterizer {
240        polygon_mode: PolygonMode::Fill,
241        cull_face: Face::NONE,
242        front_face: FrontFace::CounterClockwise,
243        depth_clamping: false,
244        depth_bias: None,
245        conservative: false,
246        line_width: State::Static(1.0),
247    };
248}
249
250/// A description of an equation for how to blend transparent, overlapping fragments.
251#[derive(Clone, Debug, Default, PartialEq)]
252#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
253pub struct BlendDesc {
254    /// The logic operation to apply to the blending equation, if any.
255    pub logic_op: Option<LogicOp>,
256    /// Which color targets to apply the blending operation to.
257    pub targets: Vec<ColorBlendDesc>,
258}
259
260/// Logic operations used for specifying blend equations.
261#[derive(Clone, Debug, Eq, PartialEq)]
262#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
263#[allow(missing_docs)]
264pub enum LogicOp {
265    Clear = 0,
266    And = 1,
267    AndReverse = 2,
268    Copy = 3,
269    AndInverted = 4,
270    NoOp = 5,
271    Xor = 6,
272    Or = 7,
273    Nor = 8,
274    Equivalent = 9,
275    Invert = 10,
276    OrReverse = 11,
277    CopyInverted = 12,
278    OrInverted = 13,
279    Nand = 14,
280    Set = 15,
281}
282
283///
284pub type SampleMask = u64;
285
286///
287#[derive(Clone, Debug, PartialEq)]
288pub struct Multisampling {
289    ///
290    pub rasterization_samples: image::NumSamples,
291    ///
292    pub sample_shading: Option<f32>,
293    ///
294    pub sample_mask: SampleMask,
295    /// Toggles alpha-to-coverage multisampling, which can produce nicer edges
296    /// when many partially-transparent polygons are overlapping.
297    /// See [here]( https://msdn.microsoft.com/en-us/library/windows/desktop/bb205072(v=vs.85).aspx#Alpha_To_Coverage) for a full description.
298    pub alpha_coverage: bool,
299    ///
300    pub alpha_to_one: bool,
301}