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}