Fixed-Function Vertex Processing
Vertex fetching is controlled via configurable state, as a logically distinct graphics pipeline stage.
Vertex Attributes
Vertex shaders can define input variables, which receive vertex attribute
data transferred from one or more VkBuffer
(s) by drawing commands.
Vertex shader input variables are bound to buffers via an indirect binding
where the vertex shader associates a vertex input attribute number with
each variable, vertex input attributes are associated to vertex input
bindings on a per-pipeline basis, and vertex input bindings are associated
with specific buffers on a per-draw basis via the
vkCmdBindVertexBuffers
command.
Vertex input attribute and vertex input binding descriptions also contain
format information controlling how data is extracted from buffer memory and
converted to the format expected by the vertex shader.
There are VkPhysicalDeviceLimits
::maxVertexInputAttributes
number of vertex input attributes and
VkPhysicalDeviceLimits
::maxVertexInputBindings
number of vertex
input bindings (each referred to by zero-based indices), where there are at
least as many vertex input attributes as there are vertex input bindings.
Applications can store multiple vertex input attributes interleaved in a
single buffer, and use a single vertex input binding to access those
attributes.
In GLSL, vertex shaders associate input variables with a vertex input
attribute number using the location
layout qualifier.
The Component
layout qualifier associates components of a vertex shader
input variable with components of a vertex input attribute.
// Assign location M to variableName
layout (location=M, component=2) in vec2 variableName;
// Assign locations [N,N+L) to the array elements of variableNameArray
layout (location=N) in vec4 variableNameArray[L];
In SPIR-V, vertex shaders associate input variables with a vertex input
attribute number using the Location
decoration.
The Component
decoration associates components of a vertex shader input
variable with components of a vertex input attribute.
The Location
and Component
decorations are specified via the
OpDecorate
instruction.
...
%1 = OpExtInstImport "GLSL.std.450"
...
OpName %9 "variableName"
OpName %15 "variableNameArray"
OpDecorate %18 BuiltIn VertexIndex
OpDecorate %19 BuiltIn InstanceIndex
OpDecorate %9 Location M
OpDecorate %9 Component 2
OpDecorate %15 Location N
...
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 2
%8 = OpTypePointer Input %7
%9 = OpVariable %8 Input
%10 = OpTypeVector %6 4
%11 = OpTypeInt 32 0
%12 = OpConstant %11 L
%13 = OpTypeArray %10 %12
%14 = OpTypePointer Input %13
%15 = OpVariable %14 Input
...
Attribute Location and Component Assignment
The Location
decoration specifies which vertex input attribute is used
to read and interpret the data that a variable will consume.
When a vertex shader input variable declared using a 16- or 32-bit scalar or
vector data type is assigned a Location
, its value(s) are taken from
the components of the input attribute specified with the corresponding
VkVertexInputAttributeDescription
::location
.
The components used depend on the type of variable and the Component
decoration specified in the variable declaration, as identified in
Input Attribute Components Accessed By 16-Bit and 32-Bit Input Variables.
Any 16-bit or 32-bit scalar or vector input will consume a single
Location
.
For 16-bit and 32-bit data types, missing components are filled in with
default values as described below.
If an implementation supports storageInputOutput16
, vertex shader input variables can have a
width of 16 bits.
In all the following component assignment specifications, if
vertexAttributeRobustness
is
enabled and there is no
VkVertexInputAttributeDescription
::location
specified for the
shader vertex attribute Location
being read, the value (0,0,0,0) or
(0,0,0,1) is used for each of the equivalent (x,y,z,w) components consumed
entries as specified below.
16-bit or 32-bit data type | Component decoration |
Components consumed |
---|---|---|
scalar |
0 or unspecified |
(x, o, o, o) |
scalar |
1 |
(o, y, o, o) |
scalar |
2 |
(o, o, z, o) |
scalar |
3 |
(o, o, o, w) |
two-component vector |
0 or unspecified |
(x, y, o, o) |
two-component vector |
1 |
(o, y, z, o) |
two-component vector |
2 |
(o, o, z, w) |
three-component vector |
0 or unspecified |
(x, y, z, o) |
three-component vector |
1 |
(o, y, z, w) |
four-component vector |
0 or unspecified |
(x, y, z, w) |
Components indicated by “o” are available for use by other input variables which are sourced from the same attribute, and if used, are either filled with the corresponding component from the input format (if present), or the default value.
When a vertex shader input variable declared using a 32-bit floating-point
matrix type is assigned a Location
i, its values are taken from
consecutive input attributes starting with the corresponding
VkVertexInputAttributeDescription
::location
.
Such matrices are treated as an array of column vectors with values taken
from the input attributes identified in Input Attributes Accessed by 32-Bit Input Matrix Variables.
The VkVertexInputAttributeDescription
::format
must be specified
with a VkFormat that corresponds to the appropriate type of column
vector.
The Component
decoration must not be used with matrix types.
Data type | Column vector type | Locations consumed | Components consumed |
---|---|---|---|
mat2 |
two-component vector |
i, i+1 |
(x, y, o, o), (x, y, o, o) |
mat2x3 |
three-component vector |
i, i+1 |
(x, y, z, o), (x, y, z, o) |
mat2x4 |
four-component vector |
i, i+1 |
(x, y, z, w), (x, y, z, w) |
mat3x2 |
two-component vector |
i, i+1, i+2 |
(x, y, o, o), (x, y, o, o), (x, y, o, o) |
mat3 |
three-component vector |
i, i+1, i+2 |
(x, y, z, o), (x, y, z, o), (x, y, z, o) |
mat3x4 |
four-component vector |
i, i+1, i+2 |
(x, y, z, w), (x, y, z, w), (x, y, z, w) |
mat4x2 |
two-component vector |
i, i+1, i+2, i+3 |
(x, y, o, o), (x, y, o, o), (x, y, o, o), (x, y, o, o) |
mat4x3 |
three-component vector |
i, i+1, i+2, i+3 |
(x, y, z, o), (x, y, z, o), (x, y, z, o), (x, y, z, o) |
mat4 |
four-component vector |
i, i+1, i+2, i+3 |
(x, y, z, w), (x, y, z, w), (x, y, z, w), (x, y, z, w) |
Components indicated by “o” are available for use by other input variables which are sourced from the same attribute, and if used, are either filled with the corresponding component from the input (if present), or the default value.
When a vertex shader input variable declared using a scalar or vector 64-bit
data type is assigned a Location
i, its values are taken from
consecutive input attributes starting with the corresponding
VkVertexInputAttributeDescription
::location
.
The Location
slots and Component
words used depend on the type of
variable and the Component
decoration specified in the variable
declaration, as identified in Input Attribute Locations and Components Accessed by 64-Bit Input Variables.
For 64-bit data types, no default attribute values are provided.
Input variables must not use more components than provided by the
attribute.
Input format | Locations consumed | 64-bit data type | Location decoration |
Component decoration |
32-bit components consumed |
---|---|---|---|---|---|
R64 |
i |
scalar |
i |
0 or unspecified |
(x, y, -, -) |
R64G64 |
i |
scalar |
i |
0 or unspecified |
(x, y, o, o) |
scalar |
i |
2 |
(o, o, z, w) |
||
two-component vector |
i |
0 or unspecified |
(x, y, z, w) |
||
R64G64B64 |
i, i+1 |
scalar |
i |
0 or unspecified |
(x, y, o, o), (o, o, -, -) |
scalar |
i |
2 |
(o, o, z, w), (o, o, -, -) |
||
scalar |
i+1 |
0 or unspecified |
(o, o, o, o), (x, y, -, -) |
||
two-component vector |
i |
0 or unspecified |
(x, y, z, w), (o, o, -, -) |
||
three-component vector |
i |
unspecified |
(x, y, z, w), (x, y, -, -) |
||
R64G64B64A64 |
i, i+1 |
scalar |
i |
0 or unspecified |
(x, y, o, o), (o, o, o, o) |
scalar |
i |
2 |
(o, o, z, w), (o, o, o, o) |
||
scalar |
i+1 |
0 or unspecified |
(o, o, o, o), (x, y, o, o) |
||
scalar |
i+1 |
2 |
(o, o, o, o), (o, o, z, w) |
||
two-component vector |
i |
0 or unspecified |
(x, y, z, w), (o, o, o, o) |
||
two-component vector |
i+1 |
0 or unspecified |
(o, o, o, o), (x, y, z, w) |
||
three-component vector |
i |
unspecified |
(x, y, z, w), (x, y, o, o) |
||
four-component vector |
i |
unspecified |
(x, y, z, w), (x, y, z, w) |
Components indicated by “o” are available for use by other input variables which are sourced from the same attribute. Components indicated by “-” are not available for input variables as there are no default values provided for 64-bit data types, and there is no data provided by the input format.
When a vertex shader input variable declared using a 64-bit floating-point
matrix type is assigned a Location
i, its values are taken from
consecutive input attribute locations.
Such matrices are treated as an array of column vectors with values taken
from the input attributes as shown in Input Attribute Locations and Components Accessed by 64-Bit Input Variables.
Each column vector starts at the Location
immediately following the
last Location
of the previous column vector.
The number of attributes and components assigned to each matrix is
determined by the matrix dimensions and ranges from two to eight locations.
When a vertex shader input variable declared using an array type is assigned
a location, its values are taken from consecutive input attributes starting
with the corresponding
VkVertexInputAttributeDescription
::location
.
The number of attributes and components assigned to each element are
determined according to the data type of the array elements and
Component
decoration (if any) specified in the declaration of the
array, as described above.
Each element of the array, in order, is assigned to consecutive locations,
but all at the same specified component within each location.
Only input variables declared with the data types and component decorations
as specified above are supported.
Two variables are allowed to share the same Location
slot only if their
Component
words do not overlap.
If multiple variables share the same Location
slot, they must all have
the same SPIR-V floating-point component type or all have the same width
scalar type components.
Vertex Input Description
Applications specify vertex input attribute and vertex input binding
descriptions as part of graphics pipeline creation by setting the
VkGraphicsPipelineCreateInfo::pVertexInputState
pointer to a
VkPipelineVertexInputStateCreateInfo structure.
Alternatively, if the graphics pipeline is created with the
VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
dynamic state enabled, then the
vertex input attribute and vertex input binding descriptions are specified
dynamically with vkCmdSetVertexInputEXT, and the
VkGraphicsPipelineCreateInfo::pVertexInputState
pointer is
ignored.
The VkPipelineVertexInputStateCreateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkPipelineVertexInputStateCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineVertexInputStateCreateFlags flags;
uint32_t vertexBindingDescriptionCount;
const VkVertexInputBindingDescription* pVertexBindingDescriptions;
uint32_t vertexAttributeDescriptionCount;
const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
} VkPipelineVertexInputStateCreateInfo;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
vertexBindingDescriptionCount
is the number of vertex binding descriptions provided inpVertexBindingDescriptions
. -
pVertexBindingDescriptions
is a pointer to an array of VkVertexInputBindingDescription structures. -
vertexAttributeDescriptionCount
is the number of vertex attribute descriptions provided inpVertexAttributeDescriptions
. -
pVertexAttributeDescriptions
is a pointer to an array of VkVertexInputAttributeDescription structures.
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineVertexInputStateCreateFlags;
VkPipelineVertexInputStateCreateFlags
is a bitmask type for setting a
mask, but is currently reserved for future use.
Each vertex input binding is specified by the
VkVertexInputBindingDescription
structure, defined as:
// Provided by VK_VERSION_1_0
typedef struct VkVertexInputBindingDescription {
uint32_t binding;
uint32_t stride;
VkVertexInputRate inputRate;
} VkVertexInputBindingDescription;
-
binding
is the binding number that this structure describes. -
stride
is the byte stride between consecutive elements within the buffer. -
inputRate
is a VkVertexInputRate value specifying whether vertex attribute addressing is a function of the vertex index or of the instance index.
Possible values of VkVertexInputBindingDescription::inputRate
,
specifying the rate at which vertex attributes are pulled from buffers, are:
// Provided by VK_VERSION_1_0
typedef enum VkVertexInputRate {
VK_VERTEX_INPUT_RATE_VERTEX = 0,
VK_VERTEX_INPUT_RATE_INSTANCE = 1,
} VkVertexInputRate;
-
VK_VERTEX_INPUT_RATE_VERTEX
specifies that vertex attribute addressing is a function of the vertex index. -
VK_VERTEX_INPUT_RATE_INSTANCE
specifies that vertex attribute addressing is a function of the instance index.
Each vertex input attribute is specified by the
VkVertexInputAttributeDescription
structure, defined as:
// Provided by VK_VERSION_1_0
typedef struct VkVertexInputAttributeDescription {
uint32_t location;
uint32_t binding;
VkFormat format;
uint32_t offset;
} VkVertexInputAttributeDescription;
-
location
is the shader input location number for this attribute. -
binding
is the binding number which this attribute takes its data from. -
format
is the size and type of the vertex attribute data. -
offset
is a byte offset of this attribute relative to the start of an element in the vertex input binding.
To dynamically set the vertex input attribute and vertex input binding descriptions, call:
// Provided by VK_EXT_shader_object, VK_EXT_vertex_input_dynamic_state
void vkCmdSetVertexInputEXT(
VkCommandBuffer commandBuffer,
uint32_t vertexBindingDescriptionCount,
const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions,
uint32_t vertexAttributeDescriptionCount,
const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions);
-
commandBuffer
is the command buffer into which the command will be recorded. -
vertexBindingDescriptionCount
is the number of vertex binding descriptions provided inpVertexBindingDescriptions
. -
pVertexBindingDescriptions
is a pointer to an array of VkVertexInputBindingDescription2EXT structures. -
vertexAttributeDescriptionCount
is the number of vertex attribute descriptions provided inpVertexAttributeDescriptions
. -
pVertexAttributeDescriptions
is a pointer to an array of VkVertexInputAttributeDescription2EXT structures.
This command sets the vertex input attribute and vertex input binding
descriptions state for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkGraphicsPipelineCreateInfo::pVertexInputState
values used to
create the currently active pipeline.
If
drawing using shader objects,
or if
the bound pipeline state object was also created with the
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE
dynamic state enabled,
then vkCmdBindVertexBuffers2 can be used instead of
vkCmdSetVertexInputEXT
to dynamically set the stride.
The vertex attribute description for any location in the range
[0,VkPhysicalDeviceLimits
::maxVertexInputAttributes
) not
specified in the pVertexAttributeDescriptions
array becomes
undefined.
The VkVertexInputBindingDescription2EXT
structure is defined as:
// Provided by VK_EXT_shader_object, VK_EXT_vertex_input_dynamic_state
typedef struct VkVertexInputBindingDescription2EXT {
VkStructureType sType;
void* pNext;
uint32_t binding;
uint32_t stride;
VkVertexInputRate inputRate;
uint32_t divisor;
} VkVertexInputBindingDescription2EXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
binding
is the binding number that this structure describes. -
stride
is the byte stride between consecutive elements within the buffer. -
inputRate
is a VkVertexInputRate value specifying whether vertex attribute addressing is a function of the vertex index or of the instance index. -
divisor
is the number of successive instances that will use the same value of the vertex attribute when instanced rendering is enabled. This member can be a value other than1
if thevertexAttributeInstanceRateDivisor
feature is enabled. For example, if the divisor is N, the same vertex attribute will be applied to N successive instances before moving on to the next vertex attribute. The maximum value ofdivisor
is implementation-dependent and can be queried usingVkPhysicalDeviceVertexAttributeDivisorPropertiesEXT
::maxVertexAttribDivisor
. A value of0
can be used for the divisor if thevertexAttributeInstanceRateZeroDivisor
feature is enabled. In this case, the same vertex attribute will be applied to all instances.
The VkVertexInputAttributeDescription2EXT
structure is defined as:
// Provided by VK_EXT_shader_object, VK_EXT_vertex_input_dynamic_state
typedef struct VkVertexInputAttributeDescription2EXT {
VkStructureType sType;
void* pNext;
uint32_t location;
uint32_t binding;
VkFormat format;
uint32_t offset;
} VkVertexInputAttributeDescription2EXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
location
is the shader input location number for this attribute. -
binding
is the binding number which this attribute takes its data from. -
format
is the size and type of the vertex attribute data. -
offset
is a byte offset of this attribute relative to the start of an element in the vertex input binding.
To bind vertex buffers to a command buffer for use in subsequent drawing commands, call:
// Provided by VK_VERSION_1_0
void vkCmdBindVertexBuffers(
VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets);
-
commandBuffer
is the command buffer into which the command is recorded. -
firstBinding
is the index of the first vertex input binding whose state is updated by the command. -
bindingCount
is the number of vertex input bindings whose state is updated by the command. -
pBuffers
is a pointer to an array of buffer handles. -
pOffsets
is a pointer to an array of buffer offsets.
The values taken from elements i of pBuffers
and pOffsets
replace the current state for the vertex input binding
firstBinding
+ i, for i in [0,
bindingCount
).
The vertex input binding is updated to start at the offset indicated by
pOffsets
[i] from the start of the buffer pBuffers
[i].
All vertex input attributes that use each of these bindings will use these
updated addresses in their address calculations for subsequent drawing
commands.
If the nullDescriptor
feature is enabled,
elements of pBuffers
can be VK_NULL_HANDLE, and can be used by
the vertex shader.
If a vertex input attribute is bound to a vertex input binding that is
VK_NULL_HANDLE, the values taken from memory are considered to be
zero, and missing G, B, or A components are
filled with (0.
Alternatively, to bind vertex buffers, along with their sizes and strides, to a command buffer for use in subsequent drawing commands, call:
// Provided by VK_VERSION_1_3
void vkCmdBindVertexBuffers2(
VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets,
const VkDeviceSize* pSizes,
const VkDeviceSize* pStrides);
or the equivalent command
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdBindVertexBuffers2EXT(
VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets,
const VkDeviceSize* pSizes,
const VkDeviceSize* pStrides);
-
commandBuffer
is the command buffer into which the command is recorded. -
firstBinding
is the index of the first vertex input binding whose state is updated by the command. -
bindingCount
is the number of vertex input bindings whose state is updated by the command. -
pBuffers
is a pointer to an array of buffer handles. -
pOffsets
is a pointer to an array of buffer offsets. -
pSizes
isNULL
or a pointer to an array of the size in bytes of vertex data bound frompBuffers
. -
pStrides
isNULL
or a pointer to an array of buffer strides.
The values taken from elements i of pBuffers
and pOffsets
replace the current state for the vertex input binding
firstBinding
+ i, for i in [0,
bindingCount
).
The vertex input binding is updated to start at the offset indicated by
pOffsets
[i] from the start of the buffer pBuffers
[i].
If pSizes
is not NULL
then pSizes
[i] specifies the bound size
of the vertex buffer starting from the corresponding elements of
pBuffers
[i] plus pOffsets
[i].
If pSizes
[i] is VK_WHOLE_SIZE
then the bound size is from
pBuffers
[i] plus pOffsets
[i] to the end of the buffer
pBuffers
[i].
All vertex input attributes that use each of these bindings will use these
updated addresses in their address calculations for subsequent drawing
commands.
If the nullDescriptor
feature is enabled,
elements of pBuffers
can be VK_NULL_HANDLE, and can be used by
the vertex shader.
If a vertex input attribute is bound to a vertex input binding that is
VK_NULL_HANDLE, the values taken from memory are considered to be
zero, and missing G, B, or A components are
filled with (0.
This command also dynamically sets the byte
strides between consecutive elements within buffer pBuffers
[i] to the
corresponding pStrides
[i] value
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, strides are specified by the
VkVertexInputBindingDescription::stride
values used to create
the currently active pipeline.
If
drawing using shader objects
or if
the bound pipeline state object was also created with the
VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
dynamic state enabled
then vkCmdSetVertexInputEXT can be used instead of
vkCmdBindVertexBuffers2
to set the stride.
Unlike the static state to set the same, |
Vertex Attribute Divisor in Instanced Rendering
If the vertexAttributeInstanceRateDivisor
feature is enabled and the
pNext
chain of VkPipelineVertexInputStateCreateInfo includes a
VkPipelineVertexInputDivisorStateCreateInfo
structure, then that
structure controls how vertex attributes are assigned to an instance when
instanced rendering is enabled.
The VkPipelineVertexInputDivisorStateCreateInfo
structure is defined
as:
// Provided by VK_VERSION_1_4
typedef struct VkPipelineVertexInputDivisorStateCreateInfo {
VkStructureType sType;
const void* pNext;
uint32_t vertexBindingDivisorCount;
const VkVertexInputBindingDivisorDescription* pVertexBindingDivisors;
} VkPipelineVertexInputDivisorStateCreateInfo;
or the equivalent
// Provided by VK_KHR_vertex_attribute_divisor
typedef VkPipelineVertexInputDivisorStateCreateInfo VkPipelineVertexInputDivisorStateCreateInfoKHR;
or the equivalent
// Provided by VK_EXT_vertex_attribute_divisor
typedef VkPipelineVertexInputDivisorStateCreateInfo VkPipelineVertexInputDivisorStateCreateInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
vertexBindingDivisorCount
is the number of elements in thepVertexBindingDivisors
array. -
pVertexBindingDivisors
is a pointer to an array of VkVertexInputBindingDivisorDescription structures specifying the divisor value for each binding.
The individual divisor values per binding are specified using the
VkVertexInputBindingDivisorDescription
structure which is defined as:
// Provided by VK_VERSION_1_4
typedef struct VkVertexInputBindingDivisorDescription {
uint32_t binding;
uint32_t divisor;
} VkVertexInputBindingDivisorDescription;
or the equivalent
// Provided by VK_KHR_vertex_attribute_divisor
typedef VkVertexInputBindingDivisorDescription VkVertexInputBindingDivisorDescriptionKHR;
or the equivalent
// Provided by VK_EXT_vertex_attribute_divisor
typedef VkVertexInputBindingDivisorDescription VkVertexInputBindingDivisorDescriptionEXT;
-
binding
is the binding number for which the divisor is specified. -
divisor
is the number of successive instances that will use the same value of the vertex attribute when instanced rendering is enabled. For example, if the divisor is N, the same vertex attribute will be applied to N successive instances before moving on to the next vertex attribute. The maximum value ofdivisor
is implementation-dependent and can be queried using VkPhysicalDeviceVertexAttributeDivisorProperties::maxVertexAttribDivisor
. A value of0
can be used for the divisor if thevertexAttributeInstanceRateZeroDivisor
feature is enabled. In this case, the same vertex attribute will be applied to all instances.
If this structure is not used to define a divisor value for an attribute, then the divisor has a logical default value of 1.
Vertex Input Address Calculation
The address of each attribute for each vertexIndex
and
instanceIndex
is calculated as follows:
-
Let
attribDesc
be the member of VkPipelineVertexInputStateCreateInfo::pVertexAttributeDescriptions
with VkVertexInputAttributeDescription::location
equal to the vertex input attribute number. -
Let
bindingDesc
be the member of VkPipelineVertexInputStateCreateInfo::pVertexBindingDescriptions
with VkVertexInputAttributeDescription::binding
equal toattribDesc.binding
. -
Let
vertexIndex
be the index of the vertex within the draw (a value betweenfirstVertex
andfirstVertex
+vertexCount
forvkCmdDraw
, or a value taken from the index buffer plusvertexOffset
forvkCmdDrawIndexed
), and letinstanceIndex
be the instance number of the draw (a value betweenfirstInstance
andfirstInstance
+instanceCount
). -
Let
offset
be an array of offsets into the bound vertex buffers specified duringvkCmdBindVertexBuffers
orvkCmdBindVertexBuffers2
withpOffsets
. -
Let
divisor
be the member of VkPipelineVertexInputDivisorStateCreateInfo::pVertexBindingDivisors
with VkVertexInputBindingDivisorDescription::binding
equal toattribDesc.binding
. If the vertex binding state is dynamically set, instead letdivisor
be the member of thepVertexBindingDescriptions
parameter to the vkCmdSetVertexInputEXT call with VkVertexInputBindingDescription2EXT::binding
equal toattribDesc.binding
. -
Let
stride
be the member of VkPipelineVertexInputStateCreateInfo::pVertexBindingDescriptions->stride
unless there is dynamic state causing the value to be ignored. In this case the value is set from the last value from one of the following-
vkCmdSetVertexInputEXT::
pVertexBindingDescriptions->stride
-
vkCmdBindVertexBuffers2::
pStride
, if notNULL
-
bufferBindingAddress = buffer[binding].baseAddress + offset[binding];
if (bindingDesc.inputRate == VK_VERTEX_INPUT_RATE_VERTEX)
effectiveVertexOffset = vertexIndex * stride;
else
if (divisor == 0)
effectiveVertexOffset = firstInstance * stride;
else
effectiveVertexOffset = (firstInstance + ((instanceIndex - firstInstance) / divisor)) * stride;
attribAddress = bufferBindingAddress + effectiveVertexOffset + attribDesc.offset;
Vertex Input Extraction
For each attribute, raw data is extracted starting at attribAddress
and is
converted from the VkVertexInputAttributeDescription’s format
to
either floating-point, unsigned integer, or signed integer based on the
numeric type of format
.
The numeric type of format
must match the numeric type of the input
variable in the shader.
The input variable in the shader must be declared as a 64-bit data type if
and only if format
is a 64-bit data type.
If
either format
is a 64-bit format or the
legacyVertexAttributes
feature is
not enabled, and
format
is a packed format, attribAddress
must be a multiple of the
size in bytes of the size of the format as described in
Packed Formats.
Otherwise,
if either format
is a 64-bit format or the
legacyVertexAttributes
feature is
not enabled,
attribAddress
must be a multiple of the size in bytes of the component
type indicated by format
(see Formats).
For attributes that are not 64-bit data types, each component is converted
to the format of the input variable based on its type and size (as defined
in the Format Definition section for each
VkFormat), using the appropriate equations in 16-Bit Floating-Point Numbers, Unsigned 11-Bit Floating-Point Numbers, Unsigned 10-Bit Floating-Point Numbers, Fixed-Point Data Conversion, and
Shared Exponent to RGB.
Signed integer components smaller than 32 bits are sign-extended.
Attributes that are not 64-bit data types are expanded to four components in
the same way as described in conversion to RGBA.
The number of components in the vertex shader input variable need not
exactly match the number of components in the format.
If the vertex shader has fewer components, the extra components are
discarded.