# vkCmdDrawIndirectCount(3) Manual Page

## Name

vkCmdDrawIndirectCount - Perform an indirect draw with the draw count sourced from a buffer

## C Specification

To record a non-indexed draw call with a draw call count sourced from a buffer, call:

    void vkCmdDrawIndirectCount(
        VkCommandBuffer                             commandBuffer,
        VkBuffer                                    buffer,
        VkDeviceSize                                offset,
        VkBuffer                                    countBuffer,
        VkDeviceSize                                countBufferOffset,
        uint32_t                                    maxDrawCount,
        uint32_t                                    stride);

or the equivalent command

    void vkCmdDrawIndirectCountKHR(
        VkCommandBuffer                             commandBuffer,
        VkBuffer                                    buffer,
        VkDeviceSize                                offset,
        VkBuffer                                    countBuffer,
        VkDeviceSize                                countBufferOffset,
        uint32_t                                    maxDrawCount,
        uint32_t                                    stride);

or the equivalent command

    void vkCmdDrawIndirectCountAMD(
        VkCommandBuffer                             commandBuffer,
        VkBuffer                                    buffer,
        VkDeviceSize                                offset,
        VkBuffer                                    countBuffer,
        VkDeviceSize                                countBufferOffset,
        uint32_t                                    maxDrawCount,
        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.

- `countBuffer` is the buffer containing the draw count.

- `countBufferOffset` is the byte offset into `countBuffer` where the draw count begins.

- `maxDrawCount` specifies the maximum number of draws that will be executed. The actual number of executed draw calls is the minimum of the count specified in `countBuffer` and `maxDrawCount`.

- `stride` is the byte stride between successive sets of draw parameters.

## Description

`vkCmdDrawIndirectCount` behaves similarly to vkCmdDrawIndirect except that the draw count is read by the device from a buffer during execution. The command will read an unsigned 32-bit integer from `countBuffer` located at `countBufferOffset` and use this as the draw count.

Valid Usage

- If a `VkImageView` is sampled with `VK_FILTER_LINEAR` as a result of this command, then the image view’s format features must contain `VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT`

- If a `VkImageView` is accessed using atomic operations as a result of this command, then the image view’s format features must contain `VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT`

- If a `VkImageView` is sampled with `VK_FILTER_CUBIC_EXT` as a result of this command, then the image view’s format features must contain `VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT`

- Any VkImageView being sampled with `VK_FILTER_CUBIC_EXT` as a result of this command must have a VkImageViewType and format that supports cubic filtering, as specified by `VkFilterCubicImageViewImageFormatPropertiesEXT`::`filterCubic` returned by `vkGetPhysicalDeviceImageFormatProperties2`

- Any VkImageView being sampled with `VK_FILTER_CUBIC_EXT` with a reduction mode of either `VK_SAMPLER_REDUCTION_MODE_MIN` or `VK_SAMPLER_REDUCTION_MODE_MAX` as a result of this command must have a VkImageViewType and format that supports cubic filtering together with minmax filtering, as specified by `VkFilterCubicImageViewImageFormatPropertiesEXT`::`filterCubicMinmax` returned by `vkGetPhysicalDeviceImageFormatProperties2`

- Any VkImage created with a VkImageCreateInfo::`flags` containing `VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV` sampled as a result of this command must only be sampled using a VkSamplerAddressMode of `VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE`.

- For each set n that is statically used by the `VkPipeline` bound to the pipeline bind point used by this command, a descriptor set must have been bound to n at the same pipeline bind point, with a `VkPipelineLayout` that is compatible for set n, with the `VkPipelineLayout` used to create the current `VkPipeline`, as described in [descriptorsets-compatibility]

- For each push constant that is statically used by the `VkPipeline` bound to the pipeline bind point used by this command, a push constant value must have been set for the same pipeline bind point, with a `VkPipelineLayout` that is compatible for push constants, with the `VkPipelineLayout` used to create the current `VkPipeline`, as described in [descriptorsets-compatibility]

- Descriptors in each bound descriptor set, specified via `vkCmdBindDescriptorSets`, must be valid if they are statically used by the `VkPipeline` bound to the pipeline bind point used by this command

- A valid pipeline must be bound to the pipeline bind point used by this command

- If the `VkPipeline` object bound to the pipeline bind point used by this command requires any dynamic state, that state must have been set for `commandBuffer`, and done so after any previously bound pipeline with the corresponding state not specified as dynamic

- There must not have been any calls to dynamic state setting commands for any state not specified as dynamic in the `VkPipeline` object bound to the pipeline bind point used by this command, since that pipeline was bound

- If the `VkPipeline` object bound to the pipeline bind point used by this command accesses a `VkSampler` object that uses unnormalized coordinates, that sampler 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 the `VkPipeline` object bound to the pipeline bind point used by this command accesses a `VkSampler` object that uses unnormalized coordinates, that sampler 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 the `VkPipeline` object bound to the pipeline bind point used by this command accesses a `VkSampler` object that uses unnormalized coordinates, that sampler 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 if the `VkPipeline` object bound to the pipeline bind point used by this command accesses a uniform buffer, it must not access values outside of the range of the buffer as specified in the descriptor set bound to the same pipeline bind point

- If the robust buffer access feature is not enabled, and if the `VkPipeline` object bound to the pipeline bind point used by this command accesses a storage buffer, it must not access values outside of the range of the buffer as specified in the descriptor set bound to the same pipeline bind point

- If `commandBuffer` is an unprotected command buffer, any resource accessed by the `VkPipeline` object bound to the pipeline bind point used by this command must not be a protected resource

- The current render pass must be compatible with the `renderPass` member of the `VkGraphicsPipelineCreateInfo` structure specified when creating the `VkPipeline` 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` bound to `VK_PIPELINE_BIND_POINT_GRAPHICS`.

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

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

- If the draw is recorded in a render pass instance with multiview enabled, the maximum instance index must be less than or equal to VkPhysicalDeviceMultiviewProperties::`maxMultiviewInstanceIndex`.

- If the bound graphics pipeline was created with VkPipelineSampleLocationsStateCreateInfoEXT::`sampleLocationsEnable` set to `VK_TRUE` and the current subpass has a depth/stencil attachment, then that attachment must have been created with the `VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT` bit set

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

- For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in [fxvertex-input]

- 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`

- `commandBuffer` must not be a protected command buffer

- If `countBuffer` is non-sparse then it must be bound completely and contiguously to a single `VkDeviceMemory` object

- `countBuffer` must have been created with the `VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT` bit set

- `countBufferOffset` must be a multiple of `4`

- The count stored in `countBuffer` must be less than or equal to `VkPhysicalDeviceLimits`::`maxDrawIndirectCount`

- `stride` must be a multiple of `4` and must be greater than or equal to sizeof(`VkDrawIndirectCommand`)

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

- If the count stored in `countBuffer` is equal to `1`, (`offset` + sizeof(`VkDrawIndirectCommand`)) must be less than or equal to the size of `buffer`

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

- If drawIndirectCount is not enabled this function must not be used

Valid Usage (Implicit)

- `commandBuffer` must be a valid VkCommandBuffer handle

- `buffer` must be a valid VkBuffer handle

- `countBuffer` 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

- Each of `buffer`, `commandBuffer`, and `countBuffer` 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

## See Also

VkBuffer, VkCommandBuffer, `VkDeviceSize`

## Document Notes

For more information, see the Vulkan Specification

This page is extracted from the Vulkan Specification. Fixes and changes should be made to the Specification, not directly.

## Copyright

Copyright (c) 2014-2020 Khronos Group. This work is licensed under a Creative Commons Attribution 4.0 International License.