gfx_hal/pso/input_assembler.rs
1//! Input Assembler (IA) stage description.
2//! The input assembler collects raw vertex and index data.
3
4use crate::{format, IndexType};
5
6/// Shader binding location.
7pub type Location = u32;
8/// Index of a vertex buffer.
9pub type BufferIndex = u32;
10/// Offset of an attribute from the start of the buffer, in bytes
11pub type ElemOffset = u32;
12/// Offset between attribute values, in bytes
13pub type ElemStride = u32;
14/// Number of instances between each advancement of the vertex buffer.
15pub type InstanceRate = u8;
16/// Number of vertices in a patch
17pub type PatchSize = u8;
18
19/// The rate at which to advance input data to shaders for the given buffer
20#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22pub enum VertexInputRate {
23 /// Advance the buffer after every vertex
24 Vertex,
25 /// Advance the buffer after every instance
26 Instance(InstanceRate),
27}
28
29impl VertexInputRate {
30 /// Get the numeric representation of the rate
31 pub fn as_uint(&self) -> u8 {
32 match *self {
33 VertexInputRate::Vertex => 0,
34 VertexInputRate::Instance(divisor) => divisor,
35 }
36 }
37}
38
39/// A struct element descriptor.
40#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
41#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42pub struct Element<F> {
43 /// Element format
44 pub format: F,
45 /// Offset from the beginning of the container, in bytes
46 pub offset: ElemOffset,
47}
48
49/// Vertex buffer description. Notably, completely separate from resource `Descriptor`s
50/// used in `DescriptorSet`s.
51#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
52#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
53pub struct VertexBufferDesc {
54 /// Binding number of this vertex buffer. This binding number is
55 /// used only for vertex buffers, and is completely separate from
56 /// `Descriptor` and `DescriptorSet` bind points.
57 pub binding: BufferIndex,
58 /// Total container size, in bytes.
59 /// Specifies the byte distance between two consecutive elements.
60 pub stride: ElemStride,
61 /// The rate at which to advance data for the given buffer
62 ///
63 /// i.e. the rate at which data passed to shaders will get advanced by
64 /// `stride` bytes
65 pub rate: VertexInputRate,
66}
67
68/// Vertex attribute description. Notably, completely separate from resource `Descriptor`s
69/// used in `DescriptorSet`s.
70#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
71#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
72pub struct AttributeDesc {
73 /// Attribute binding location in the shader. Attribute locations are
74 /// shared between all vertex buffers in a pipeline, meaning that even if the
75 /// data for this attribute comes from a different vertex buffer, it still cannot
76 /// share the same location with another attribute.
77 pub location: Location,
78 /// Binding number of the associated vertex buffer.
79 pub binding: BufferIndex,
80 /// Attribute element description.
81 pub element: Element<format::Format>,
82}
83
84/// Describes the type of geometric primitives,
85/// created from vertex data.
86#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
87#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
88#[repr(u8)]
89pub enum Primitive {
90 /// Each vertex represents a single point.
91 PointList,
92 /// Each pair of vertices represent a single line segment. For example, with `[a, b, c, d,
93 /// e]`, `a` and `b` form a line, `c` and `d` form a line, and `e` is discarded.
94 LineList,
95 /// Every two consecutive vertices represent a single line segment. Visually forms a "path" of
96 /// lines, as they are all connected. For example, with `[a, b, c]`, `a` and `b` form a line
97 /// line, and `b` and `c` form a line.
98 LineStrip,
99 /// Each triplet of vertices represent a single triangle. For example, with `[a, b, c, d, e]`,
100 /// `a`, `b`, and `c` form a triangle, `d` and `e` are discarded.
101 TriangleList,
102 /// Every three consecutive vertices represent a single triangle. For example, with `[a, b, c,
103 /// d]`, `a`, `b`, and `c` form a triangle, and `b`, `c`, and `d` form a triangle.
104 TriangleStrip,
105 /// Patch list,
106 /// used with shaders capable of producing primitives on their own (tessellation)
107 PatchList(PatchSize),
108}
109
110/// All the information needed to create an input assembler.
111#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
113pub struct InputAssemblerDesc {
114 /// Type of the primitive
115 pub primitive: Primitive,
116 /// When adjacency information is enabled, every even-numbered vertex
117 /// (every other starting from the first) represents an additional
118 /// vertex for the primitive, while odd-numbered vertices (every other starting from the
119 /// second) represent adjacent vertices.
120 ///
121 /// For example, with `[a, b, c, d, e, f, g, h]`, `[a, c,
122 /// e, g]` form a triangle strip, and `[b, d, f, h]` are the adjacent vertices, where `b`, `d`,
123 /// and `f` are adjacent to the first triangle in the strip, and `d`, `f`, and `h` are adjacent
124 /// to the second.
125 pub with_adjacency: bool,
126 /// Describes whether or not primitive restart is supported for
127 /// an input assembler. Primitive restart is a feature that
128 /// allows a mark to be placed in an index buffer where it is
129 /// is "broken" into multiple pieces of geometry.
130 ///
131 /// See <https://www.khronos.org/opengl/wiki/Vertex_Rendering#Primitive_Restart>
132 /// for more detail.
133 pub restart_index: Option<IndexType>,
134}
135
136impl InputAssemblerDesc {
137 /// Create a new IA descriptor without primitive restart or adjucency.
138 pub fn new(primitive: Primitive) -> Self {
139 InputAssemblerDesc {
140 primitive,
141 with_adjacency: false,
142 restart_index: None,
143 }
144 }
145}