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.