1 // Copyright (c) 2016 The vulkano developers 2 // Licensed under the Apache License, Version 2.0 3 // <LICENSE-APACHE or 4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT 5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, 6 // at your option. All files in the project carrying such 7 // notice may not be copied, modified, or distributed except 8 // according to those terms. 9 10 //! Configures how data from vertex buffers is read into vertex shader input locations. 11 //! 12 //! The vertex input stage is the stage where data is read from a buffer and fed into the vertex 13 //! shader. After each invocation of the vertex shader, the pipeline then proceeds to the input 14 //! assembly stage. 15 //! 16 //! # Input locations and components 17 //! 18 //! Input data is assigned per shader input location. Locations are set by adding the `location` 19 //! layout qualifier to an input variable in GLSL. A single location contains four data elements, 20 //! named "components", which are each 32 bits in size. These correspond to the `x`, `y`, `z` and 21 //! `w` (or equivalently `r`, `g`, `b`, `a`) components of a `vec4` inside the shader. 22 //! A component can contain at most one value, and data types that are smaller than 32 bits will 23 //! still take up a whole component, so a single `i8vec4` variable will still take up all four 24 //! components in a location, even if not all bits are actually used. 25 //! 26 //! A variable may take up fewer than four components. For example, a single `float` takes up only 27 //! one component, a `vec2` takes up two, and so on. Using the `component` layout qualifier in GLSL, 28 //! it is possible to fit multiple variables into a single four-component location slot, as long 29 //! as the components of each variable don't overlap. 30 //! 31 //! If the input variable is an array, then it takes up a series of consecutive locations. Each 32 //! element of the array always starts at a new location, regardless of whether there is still room 33 //! in the previous one. So, for example, an array of three `vec2` takes three locations, since 34 //! `vec2` alone needs one location. An array can be decorated with the `component` qualifier as 35 //! well; this is equivalent to applying the qualifier to every element of the array. If elements do 36 //! not use all components in their locations, those free components can be filled with additional 37 //! variables, just like for non-array types. 38 //! 39 //! Matrices are laid out as if they were an array of column vectors. Thus, a `mat4x3` is laid out 40 //! as an array of four `vec3`s, `mat2x4` as two `vec4`s. As with individual vectors, each column of 41 //! the matrix uses up as many components of its location as there are rows in the matrix, and the 42 //! remaining components are available for additional variables as described above. However, it is 43 //! not possible to use the `component` qualifier on a matrix. 44 //! 45 //! If a 64-bit value is to be passed to a shader, it will take up two adjacent components. Vectors 46 //! of 64-bit values are correspondingly twice as large: `dvec2` takes up all four components of a 47 //! location, `dvec4` takes two full locations, while `dvec3` takes one full location and the first 48 //! two components of the next. An array or matrix of a 64-bit type is made up of multiple adjacent 49 //! 64-bit elements, just like for smaller types: each new element starts at a fresh location. 50 //! 51 //! # Input attributes 52 //! 53 //! An input attribute is a mapping between data in a vertex buffer and the locations and components 54 //! of the vertex shader. 55 //! 56 //! Input attributes are assigned on a per-location basis; it is not possible to assign attributes 57 //! to individual components. Instead, each attribute specifies up to four values to be read from 58 //! the vertex buffer at once, which are then mapped to the four components of the given location. 59 //! Like the texels in an image, each attribute's data format in a vertex buffer is described by a 60 //! [`Format`]. The input data doesn't have to be an actual color, the format simply describes the 61 //! type, size and layout of the data for the four input components. For example, 62 //! `Format::R32G32B32A32_SFLOAT` will read four `f32` values from the vertex buffer and assigns 63 //! them to the four components of the attribute's location. 64 //! 65 //! It is possible to specify a `Format` that contains less than four components. In this case, the 66 //! missing components are given default values: the first three components default to 0, while the 67 //! fourth defaults to 1. This means that you can, for example, store only the `x`, `y` and `z` 68 //! components of a vertex position in a vertex buffer, and have the vertex input state 69 //! automatically set the `w` value to 1 for you. An exception to this are 64-bit values: these do 70 //! *not* receive default values, meaning that components that are missing from the format are 71 //! assigned no value and must not be used in the shader at all. 72 //! 73 //! When matching attribute formats to shader input types, the following rules apply: 74 //! - Signed integers in the shader must have an attribute format with a `SINT` type. 75 //! - Unsigned integers in the shader must have an attribute format with a `UINT` type. 76 //! - Floating point values in the shader must have an attribute format with a type other than 77 //! `SINT` or `UINT`. This includes `SFLOAT`, `UFLOAT` and `SRGB`, but also `SNORM`, `UNORM`, 78 //! `SSCALED` and `USCALED`. 79 //! - 64-bit values in the shader must have a 64-bit attribute format. 80 //! - 32-bit and smaller values in the shader must have a 32-bit or smaller attribute format, but 81 //! the exact number of bits doesn't matter. For example, `Format::R8G8B8A8_UNORM` can be used 82 //! with a `vec4` in the shader. 83 //! 84 //! # Input bindings 85 //! 86 //! An input binding is a definition of a Vulkan buffer that contains the actual data from which 87 //! each input attribute is to be read. The buffer itself is referred to as a "vertex buffer", and 88 //! is set during drawing with the 89 //! [`bind_vertex_buffers`](crate::command_buffer::AutoCommandBufferBuilder::bind_vertex_buffers) 90 //! command. 91 //! 92 //! The data in a vertex buffer is typically arranged into an array, where each array element 93 //! contains the data for a single vertex shader invocation. When deciding which element read from 94 //! the vertex buffer for a given vertex and instance number, each binding has an "input rate". 95 //! If the input rate is `Vertex`, then the vertex input state advances to the next element of that 96 //! buffer each time a new vertex number is processed. Likewise, if the input rate is `Instance`, 97 //! it advances to the next element for each new instance number. Different bindings can have 98 //! different input rates, and it's also possible to have multiple bindings with the same input 99 //! rate. 100 101 #[allow(deprecated)] 102 pub use self::{ 103 buffers::BuffersDefinition, 104 collection::VertexBuffersCollection, 105 definition::{IncompatibleVertexDefinitionError, VertexDefinition}, 106 impl_vertex::VertexMember, 107 vertex::{Vertex, VertexBufferDescription, VertexMemberInfo}, 108 }; 109 use crate::format::Format; 110 use ahash::HashMap; 111 112 mod buffers; 113 mod collection; 114 mod definition; 115 mod impl_vertex; 116 mod vertex; 117 118 /// The state in a graphics pipeline describing how the vertex input stage should behave. 119 #[derive(Clone, Debug, Default)] 120 pub struct VertexInputState { 121 /// A description of the vertex buffers that the vertex input stage will read from. 122 pub bindings: HashMap<u32, VertexInputBindingDescription>, 123 124 /// Describes, for each shader input location, the mapping between elements in a vertex buffer 125 /// and the components of that location in the shader. 126 pub attributes: HashMap<u32, VertexInputAttributeDescription>, 127 } 128 129 impl VertexInputState { 130 /// Constructs a new `VertexInputState` with no bindings or attributes. 131 #[inline] new() -> VertexInputState132 pub fn new() -> VertexInputState { 133 VertexInputState { 134 bindings: Default::default(), 135 attributes: Default::default(), 136 } 137 } 138 139 /// Adds a single binding. 140 #[inline] binding(mut self, binding: u32, description: VertexInputBindingDescription) -> Self141 pub fn binding(mut self, binding: u32, description: VertexInputBindingDescription) -> Self { 142 self.bindings.insert(binding, description); 143 self 144 } 145 146 /// Sets all bindings. bindings( mut self, bindings: impl IntoIterator<Item = (u32, VertexInputBindingDescription)>, ) -> Self147 pub fn bindings( 148 mut self, 149 bindings: impl IntoIterator<Item = (u32, VertexInputBindingDescription)>, 150 ) -> Self { 151 self.bindings = bindings.into_iter().collect(); 152 self 153 } 154 155 /// Adds a single attribute. 156 #[inline] attribute( mut self, location: u32, description: VertexInputAttributeDescription, ) -> Self157 pub fn attribute( 158 mut self, 159 location: u32, 160 description: VertexInputAttributeDescription, 161 ) -> Self { 162 self.attributes.insert(location, description); 163 self 164 } 165 166 /// Sets all attributes. attributes( mut self, attributes: impl IntoIterator<Item = (u32, VertexInputAttributeDescription)>, ) -> Self167 pub fn attributes( 168 mut self, 169 attributes: impl IntoIterator<Item = (u32, VertexInputAttributeDescription)>, 170 ) -> Self { 171 self.attributes = attributes.into_iter().collect(); 172 self 173 } 174 } 175 176 /// Describes a single vertex buffer binding. 177 #[derive(Clone, Debug)] 178 pub struct VertexInputBindingDescription { 179 /// The number of bytes from the start of one element in the vertex buffer to the start of the 180 /// next element. This can be simply the size of the data in each element, but larger strides 181 /// are possible. 182 pub stride: u32, 183 184 /// How often the vertex input should advance to the next element. 185 pub input_rate: VertexInputRate, 186 } 187 188 /// Describes a single vertex buffer attribute mapping. 189 #[derive(Clone, Copy, Debug)] 190 pub struct VertexInputAttributeDescription { 191 /// The vertex buffer binding number that this attribute should take its data from. 192 pub binding: u32, 193 194 /// The size and type of the vertex data. 195 pub format: Format, 196 197 /// Number of bytes between the start of a vertex buffer element and the location of attribute. 198 /// 199 /// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) 200 /// devices, if the sum of `offset + format.block_size()` is greater than the `stride` of 201 /// `binding`, the 202 /// [`vertex_attribute_access_beyond_stride`](crate::device::Features::vertex_attribute_access_beyond_stride) 203 /// feature must be enabled on the device. 204 pub offset: u32, 205 } 206 207 /// How the vertex source should be unrolled. 208 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 209 pub enum VertexInputRate { 210 /// Each element of the source corresponds to a vertex. 211 Vertex, 212 213 /// Each element of the source corresponds to an instance. 214 /// 215 /// `divisor` indicates how many consecutive instances will use the same instance buffer data. 216 /// This value must be 1, unless the [`vertex_attribute_instance_rate_divisor`] feature has 217 /// been enabled on the device. 218 /// 219 /// `divisor` can be 0 if the [`vertex_attribute_instance_rate_zero_divisor`] feature is also 220 /// enabled. This means that every vertex will use the same vertex and instance data. 221 /// 222 /// [`vertex_attribute_instance_rate_divisor`]: crate::device::Features::vertex_attribute_instance_rate_divisor 223 /// [`vertex_attribute_instance_rate_zero_divisor`]: crate::device::Features::vertex_attribute_instance_rate_zero_divisor 224 Instance { divisor: u32 }, 225 } 226 227 impl From<VertexInputRate> for ash::vk::VertexInputRate { 228 #[inline] from(val: VertexInputRate) -> Self229 fn from(val: VertexInputRate) -> Self { 230 match val { 231 VertexInputRate::Vertex => ash::vk::VertexInputRate::VERTEX, 232 VertexInputRate::Instance { .. } => ash::vk::VertexInputRate::INSTANCE, 233 } 234 } 235 } 236