Once primitives are assembled, they proceed to the vertex shading stage of the pipeline. If the draw includes multiple instances, then the set of primitives is sent to the vertex shading stage multiple times, once for each instance.
It is undefined whether vertex shading occurs on vertices that are discarded as part of incomplete primitives, but if it does occur then it operates as if they were vertices in complete primitives and such invocations can have side effects.
Vertex shading receives two per-vertex inputs from the primitive assembly
stage - the vertexIndex
and the instanceIndex
.
How these values are generated is defined below, with each command.
Drawing commands fall roughly into two categories:
Non-indexed drawing commands present a sequential vertexIndex
to
the vertex shader.
The sequential index is generated automatically by the device (see
Fixed-Function Vertex Processing for details on both
specifying the vertex attributes indexed by vertexIndex
, as well as
binding vertex buffers containing those attributes to a command buffer).
These commands are:
Indexed drawing commands read index values from an index buffer and
use this to compute the vertexIndex
value for the vertex shader.
These commands are:
To bind an index buffer to a command buffer, call:
void vkCmdBindIndexBuffer( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType);
commandBuffer
is the command buffer into which the command is
recorded.
buffer
is the buffer being bound.
offset
is the starting offset in bytes within buffer
used in
index buffer address calculations.
indexType
selects whether indices are treated as 16 bits or 32
bits.
Possible values include:
typedef enum VkIndexType { VK_INDEX_TYPE_UINT16 = 0, VK_INDEX_TYPE_UINT32 = 1, } VkIndexType;
The parameters for each drawing command are specified directly in the command or read from buffer memory, depending on the command. Drawing commands that source their parameters from buffer memory are known as indirect drawing commands.
All drawing commands interact with the Robust Buffer Access feature.
Primitives assembled by draw commands are considered to have an
API order, which defines the order
their fragments affect the framebuffer.
When a draw command includes multiple instances, the lower numbered
instances are earlier in API order.
For non-indexed draws, primitives with lower numbered vertexIndex
values are earlier in API order.
For indexed draws, primitives assembled from lower index buffer addresses
are earlier in API order.
To record a non-indexed draw, call:
void vkCmdDraw( VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
commandBuffer
is the command buffer into which the command is
recorded.
vertexCount
is the number of vertices to draw.
instanceCount
is the number of instances to draw.
firstVertex
is the index of the first vertex to draw.
firstInstance
is the instance ID of the first instance to draw.
When the command is executed, primitives are assembled using the current
primitive topology and vertexCount
consecutive vertex indices with the
first vertexIndex
value equal to firstVertex
.
The primitives are drawn instanceCount
times with instanceIndex
starting with firstInstance
and increasing sequentially for each
instance.
The assembled primitives execute the currently bound graphics pipeline.
To record an indexed draw, call:
void vkCmdDrawIndexed( VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
commandBuffer
is the command buffer into which the command is
recorded.
indexCount
is the number of vertices to draw.
instanceCount
is the number of instances to draw.
firstIndex
is the base index within the index buffer.
vertexOffset
is the value added to the vertex index before
indexing into the vertex buffer.
firstInstance
is the instance ID of the first instance to draw.
When the command is executed, primitives are assembled using the current
primitive topology and indexCount
vertices whose indices are retrieved
from the index buffer.
The index buffer is treated as an array of tightly packed unsigned integers
of size defined by the vkCmdBindIndexBuffer
::indexType
parameter
with which the buffer was bound.
The first vertex index is at an offset of firstIndex
* indexSize
+ offset
within the currently bound index buffer, where offset
is the offset specified by vkCmdBindIndexBuffer
and indexSize
is
the byte size of the type specified by indexType
.
Subsequent index values are retrieved from consecutive locations in the
index buffer.
Indices are first compared to the primitive restart value, then zero
extended to 32 bits (if the indexType
is VK_INDEX_TYPE_UINT16
)
and have vertexOffset
added to them, before being supplied as the
vertexIndex
value.
The primitives are drawn instanceCount
times with instanceIndex
starting with firstInstance
and increasing sequentially for each
instance.
The assembled primitives execute the currently bound graphics pipeline.
To record a non-indexed indirect draw, call:
void vkCmdDrawIndirect( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
commandBuffer
is the command buffer into which the command is
recorded.
buffer
is the buffer containing draw parameters.
offset
is the byte offset into buffer
where parameters
begin.
drawCount
is the number of draws to execute, and can be zero.
stride
is the byte stride between successive sets of draw
parameters.
vkCmdDrawIndirect
behaves similarly to vkCmdDraw
except that the
parameters are read by the device from a buffer during execution.
drawCount
draws are executed by the command, with parameters taken
from buffer
starting at offset
and increasing by stride
bytes for each successive draw.
The parameters of each draw are encoded in an array of
VkDrawIndirectCommand
structures.
If drawCount
is less than or equal to one, stride
is ignored.
The VkDrawIndirectCommand
structure is defined as:
typedef struct VkDrawIndirectCommand { uint32_t vertexCount; uint32_t instanceCount; uint32_t firstVertex; uint32_t firstInstance; } VkDrawIndirectCommand;
vertexCount
is the number of vertices to draw.
instanceCount
is the number of instances to draw.
firstVertex
is the index of the first vertex to draw.
firstInstance
is the instance ID of the first instance to draw.
The members of VkDrawIndirectCommand
have the same meaning as the
similarly named parameters of vkCmdDraw
.
To record an indexed indirect draw, call:
void vkCmdDrawIndexedIndirect( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
commandBuffer
is the command buffer into which the command is
recorded.
buffer
is the buffer containing draw parameters.
offset
is the byte offset into buffer
where parameters
begin.
drawCount
is the number of draws to execute, and can be zero.
stride
is the byte stride between successive sets of draw
parameters.
vkCmdDrawIndexedIndirect
behaves similarly to vkCmdDrawIndexed
except that the parameters are read by the device from a buffer during
execution.
drawCount
draws are executed by the command, with parameters taken
from buffer
starting at offset
and increasing by stride
bytes for each successive draw.
The parameters of each draw are encoded in an array of
VkDrawIndexedIndirectCommand
structures.
If drawCount
is less than or equal to one, stride
is ignored.
The VkDrawIndexedIndirectCommand
structure is defined as:
typedef struct VkDrawIndexedIndirectCommand { uint32_t indexCount; uint32_t instanceCount; uint32_t firstIndex; int32_t vertexOffset; uint32_t firstInstance; } VkDrawIndexedIndirectCommand;
indexCount
is the number of vertices to draw.
instanceCount
is the number of instances to draw.
firstIndex
is the base index within the index buffer.
vertexOffset
is the value added to the vertex index before
indexing into the vertex buffer.
firstInstance
is the instance ID of the first instance to draw.
The members of VkDrawIndexedIndirectCommand
have the same meaning as
the similarly named parameters of vkCmdDrawIndexed
.