## C Specification

To record a non-indexed indirect draw, call:

void vkCmdDrawIndirect(
VkCommandBuffer                             commandBuffer,
VkBuffer                                    buffer,
VkDeviceSize                                offset,
uint32_t                                    drawCount,
uint32_t                                    stride);

## Parameters

• 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.

## Description

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.

Valid Usage
• If buffer is non-sparse then it must be bound completely and contiguously to a single VkDeviceMemory object

• buffer must have been created with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set

• offset must be a multiple of 4

• If drawCount is greater than 1, stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)

• If the multi-draw indirect feature is not enabled, drawCount must be 0 or 1

• If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0

• The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

• The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.

• For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in ../../html/vkspec.html#descriptorsets-compatibility

• For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in ../../html/vkspec.html#descriptorsets-compatibility

• Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline

• All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point’s interface must have valid buffers bound

• A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS

• If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer

• If drawCount is equal to 1, (offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

• If drawCount is greater than 1, (stride × (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer

• drawCount must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount

• Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set

• If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

• If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage

• If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage

• If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set

• If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set

• Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties

• Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

Valid Usage (Implicit)
• commandBuffer must be a valid VkCommandBuffer handle

• buffer must be a valid VkBuffer handle

• commandBuffer must be in the recording state

• The VkCommandPool that commandBuffer was allocated from must support graphics operations

• This command must only be called inside of a render pass instance

• Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
• Host access to commandBuffer must be externally synchronized

• Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Inside

Graphics

Graphics

VkBuffer, VkCommandBuffer, VkDeviceSize