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}