// Copyright (c) 2015-2017 The Khronos Group Inc.
// Copyright notice at https://www.khronos.org/registry/speccopyright.html

[[dispatch]]
= Dispatching Commands

_Dispatching commands_ (commands with ftext:Dispatch in the name) provoke
work in a compute pipeline.
Dispatching commands are recorded into a command buffer and when executed by
a queue, will produce work which executes according to the currently bound
compute pipeline.
A compute pipeline must: be bound to a command buffer before any dispatch
commands are recorded in that command buffer.

// refBegin vkCmdDispatch Dispatch compute work items

To record a dispatch, call:

include::../api/protos/vkCmdDispatch.txt[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:groupCountX is the number of local workgroups to dispatch in the X
    dimension.
  * pname:groupCountY is the number of local workgroups to dispatch in the Y
    dimension.
  * pname:groupCountZ is the number of local workgroups to dispatch in the Z
    dimension.

When the command is executed, a global workgroup consisting of
[eq]#groupCountX {times} groupCountY {times} groupCountZ# local workgroups
is assembled.

.Valid Usage
****
  * [[VUID-vkCmdDispatch-groupCountX-00386]]
    pname:groupCountX must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0]
  * [[VUID-vkCmdDispatch-groupCountY-00387]]
    pname:groupCountY must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1]
  * [[VUID-vkCmdDispatch-groupCountZ-00388]]
    pname:groupCountZ must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2]
  * [[VUID-vkCmdDispatch-None-00389]]
    For each set _n_ that is statically used by the sname:VkPipeline
    currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor
    set must: have been bound to _n_ at
    ename:VK_PIPELINE_BIND_POINT_COMPUTE, with a sname:VkPipelineLayout that
    is compatible for set _n_, with the sname:VkPipelineLayout used to
    create the current sname:VkPipeline, as described in
    <<descriptorsets-compatibility>>
  * [[VUID-vkCmdDispatch-None-00390]]
    Descriptors in each bound descriptor set, specified via
    fname:vkCmdBindDescriptorSets, must: be valid if they are statically
    used by the currently bound sname:VkPipeline object, specified via
    fname:vkCmdBindPipeline
  * [[VUID-vkCmdDispatch-None-00391]]
    A valid compute pipeline must: be bound to the current command buffer
    with ename:VK_PIPELINE_BIND_POINT_COMPUTE
  * [[VUID-vkCmdDispatch-None-00392]]
    For each push constant that is statically used by the sname:VkPipeline
    currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a push constant
    value must: have been set for ename:VK_PIPELINE_BIND_POINT_COMPUTE, with
    a sname:VkPipelineLayout that is compatible for push constants with the
    one used to create the current sname:VkPipeline, as described in
    <<descriptorsets-compatibility>>
  * [[VUID-vkCmdDispatch-None-00393]]
    If any sname:VkSampler object that is accessed from a shader by the
    sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE
    uses unnormalized coordinates, it must: not be used to sample from any
    sname:VkImage with a sname:VkImageView of the type
    ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE,
    ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or
    ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage
  * [[VUID-vkCmdDispatch-None-00394]]
    If any sname:VkSampler object that is accessed from a shader by the
    sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE
    uses unnormalized coordinates, it must: not be used with any of the
    SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with
    code:ImplicitLod, code:Dref or code:Proj in their name, in any shader
    stage
  * [[VUID-vkCmdDispatch-None-00395]]
    If any sname:VkSampler object that is accessed from a shader by the
    sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE
    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
  * [[VUID-vkCmdDispatch-None-00396]]
    If the <<features-features-robustBufferAccess,robust buffer access>>
    feature is not enabled, and any shader stage in the sname:VkPipeline
    object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses
    a uniform buffer, it must: not access values outside of the range of
    that buffer specified in the currently bound descriptor set
  * [[VUID-vkCmdDispatch-None-00397]]
    If the <<features-features-robustBufferAccess,robust buffer access>>
    feature is not enabled, and any shader stage in the sname:VkPipeline
    object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses
    a storage buffer, it must: not access values outside of the range of
    that buffer specified in the currently bound descriptor set
  * [[VUID-vkCmdDispatch-linearTilingFeatures-00398]]
    Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a
    result of this command must: be of a format which supports linear
    filtering, as specified by the
    ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in
    sname:VkFormatProperties::pname:linearTilingFeatures (for a linear
    image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an
    optimally tiled image) returned by
    fname:vkGetPhysicalDeviceFormatProperties
ifdef::VK_IMG_filter_cubic[]
  * [[VUID-vkCmdDispatch-linearTilingFeatures-00399]]
    Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a
    result of this command must: be of a format which supports cubic
    filtering, as specified by the
    ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in
    sname:VkFormatProperties::pname:linearTilingFeatures (for a linear
    image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an
    optimally tiled image) returned by
    fname:vkGetPhysicalDeviceFormatProperties
  * [[VUID-vkCmdDispatch-None-00400]]
    Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a
    result of this command must: not have a elink:VkImageViewType of
    ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or
    ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
endif::VK_IMG_filter_cubic[]
****

include::../validity/protos/vkCmdDispatch.txt[]

// refBegin vkCmdDispatchIndirect Dispatch compute work items using indirect parameters

To record an indirect command dispatch, call:

include::../api/protos/vkCmdDispatchIndirect.txt[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:buffer is the buffer containing dispatch parameters.
  * pname:offset is the byte offset into pname:buffer where parameters
    begin.

fname:vkCmdDispatchIndirect behaves similarly to flink:vkCmdDispatch except
that the parameters are read by the device from a buffer during execution.
The parameters of the dispatch are encoded in a
slink:VkDispatchIndirectCommand structure taken from pname:buffer starting
at pname:offset.

.Valid Usage
****
  * [[VUID-vkCmdDispatchIndirect-buffer-00401]]
    If pname:buffer is non-sparse then it must: be bound completely and
    contiguously to a single sname:VkDeviceMemory object
  * [[VUID-vkCmdDispatchIndirect-None-00402]]
    For each set _n_ that is statically used by the sname:VkPipeline
    currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor
    set must: have been bound to _n_ at
    ename:VK_PIPELINE_BIND_POINT_COMPUTE, with a sname:VkPipelineLayout that
    is compatible for set _n_, with the sname:VkPipelineLayout used to
    create the current sname:VkPipeline, as described in
    <<descriptorsets-compatibility>>
  * [[VUID-vkCmdDispatchIndirect-None-00403]]
    Descriptors in each bound descriptor set, specified via
    fname:vkCmdBindDescriptorSets, must: be valid if they are statically
    used by the currently bound sname:VkPipeline object, specified via
    fname:vkCmdBindPipeline
  * [[VUID-vkCmdDispatchIndirect-None-00404]]
    A valid compute pipeline must: be bound to the current command buffer
    with ename:VK_PIPELINE_BIND_POINT_COMPUTE
  * [[VUID-vkCmdDispatchIndirect-buffer-00405]]
    pname:buffer must: have been created with the
    ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set
  * [[VUID-vkCmdDispatchIndirect-offset-00406]]
    pname:offset must: be a multiple of `4`
  * [[VUID-vkCmdDispatchIndirect-offset-00407]]
    The sum of pname:offset and the size of sname:VkDispatchIndirectCommand
    must: be less than or equal to the size of pname:buffer
  * [[VUID-vkCmdDispatchIndirect-None-00408]]
    For each push constant that is statically used by the sname:VkPipeline
    currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a push constant
    value must: have been set for ename:VK_PIPELINE_BIND_POINT_COMPUTE, with
    a sname:VkPipelineLayout that is compatible for push constants with the
    one used to create the current sname:VkPipeline, as described in
    <<descriptorsets-compatibility>>
  * [[VUID-vkCmdDispatchIndirect-None-00409]]
    If any sname:VkSampler object that is accessed from a shader by the
    sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE
    uses unnormalized coordinates, it must: not be used to sample from any
    sname:VkImage with a sname:VkImageView of the type
    ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE,
    ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or
    ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage
  * [[VUID-vkCmdDispatchIndirect-None-00410]]
    If any sname:VkSampler object that is accessed from a shader by the
    sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE
    uses unnormalized coordinates, it must: not be used with any of the
    SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with
    code:ImplicitLod, code:Dref or code:Proj in their name, in any shader
    stage
  * [[VUID-vkCmdDispatchIndirect-None-00411]]
    If any sname:VkSampler object that is accessed from a shader by the
    sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE
    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
  * [[VUID-vkCmdDispatchIndirect-None-00412]]
    If the <<features-features-robustBufferAccess,robust buffer access>>
    feature is not enabled, and any shader stage in the sname:VkPipeline
    object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses
    a uniform buffer, it must: not access values outside of the range of
    that buffer specified in the currently bound descriptor set
  * [[VUID-vkCmdDispatchIndirect-None-00413]]
    If the <<features-features-robustBufferAccess,robust buffer access>>
    feature is not enabled, and any shader stage in the sname:VkPipeline
    object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses
    a storage buffer, it must: not access values outside of the range of
    that buffer specified in the currently bound descriptor set
  * [[VUID-vkCmdDispatchIndirect-linearTilingFeatures-00414]]
    Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a
    result of this command must: be of a format which supports linear
    filtering, as specified by the
    ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in
    sname:VkFormatProperties::pname:linearTilingFeatures (for a linear
    image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an
    optimally tiled image) returned by
    fname:vkGetPhysicalDeviceFormatProperties
ifdef::VK_IMG_filter_cubic[]
  * [[VUID-vkCmdDispatchIndirect-linearTilingFeatures-00415]]
    Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a
    result of this command must: be of a format which supports cubic
    filtering, as specified by the
    ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in
    sname:VkFormatProperties::pname:linearTilingFeatures (for a linear
    image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an
    optimally tiled image) returned by
    fname:vkGetPhysicalDeviceFormatProperties
  * [[VUID-vkCmdDispatchIndirect-None-00416]]
    Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a
    result of this command must: not have a elink:VkImageViewType of
    ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or
    ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
endif::VK_IMG_filter_cubic[]
****

include::../validity/protos/vkCmdDispatchIndirect.txt[]

// refBegin VkDispatchIndirectCommand Structure specifying a dispatch indirect command

The sname:VkDispatchIndirectCommand structure is defined as:

include::../api/structs/VkDispatchIndirectCommand.txt[]

  * pname:x is the number of local workgroups to dispatch in the X
    dimension.
  * pname:y is the number of local workgroups to dispatch in the Y
    dimension.
  * pname:z is the number of local workgroups to dispatch in the Z
    dimension.

The members of sname:VkDispatchIndirectCommand have the same meaning as the
corresponding parameters of flink:vkCmdDispatch.

.Valid Usage
****
  * [[VUID-VkDispatchIndirectCommand-x-00417]]
    pname:x must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0]
  * [[VUID-VkDispatchIndirectCommand-y-00418]]
    pname:y must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1]
  * [[VUID-VkDispatchIndirectCommand-z-00419]]
    pname:z must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2]
****

include::../validity/structs/VkDispatchIndirectCommand.txt[]

// refEnd VkDispatchIndirectCommand vkCmdDispatchIndirect

ifdef::VK_KHX_device_group[]

// refBegin vkCmdDispatchBaseKHX Dispatch compute work items

To record a dispatch using non-zero base values for the components of
code:WorkgroupId, call:

include::../api/protos/vkCmdDispatchBaseKHX.txt[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:baseGroupX is the start value for the X component of
    code:WorkgroupId.
  * pname:baseGroupY is the start value for the Y component of
    code:WorkgroupId.
  * pname:baseGroupZ is the start value for the Z component of
    code:WorkgroupId.
  * pname:groupCountX is the number of local workgroups to dispatch in the X
    dimension.
  * pname:groupCountY is the number of local workgroups to dispatch in the Y
    dimension.
  * pname:groupCountZ is the number of local workgroups to dispatch in the Z
    dimension.

When the command is executed, a global workgroup consisting of
[eq]#groupCountX {times} groupCountY {times} groupCountZ# local workgroups
is assembled, with code:WorkgroupId values ranging from [eq]#[baseGroup,
baseGroup {plus} groupCount)# in each component.
flink:vkCmdDispatch is equivalent to
vkCmdDispatchBaseKHX(0,0,0,groupCountX,groupCountY,groupCountZ).

.Valid Usage
****
  * [[VUID-vkCmdDispatchBaseKHX-None-00420]]
    All valid usage rules from flink:vkCmdDispatch apply
  * [[VUID-vkCmdDispatchBaseKHX-baseGroupX-00421]]
    pname:baseGroupX must: be less than
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0]
  * [[VUID-vkCmdDispatchBaseKHX-baseGroupX-00422]]
    pname:baseGroupX must: be less than
    sname:VkPhysicaYDeviceLimits::pname:maxComputeWorkGroupCount[1]
  * [[VUID-vkCmdDispatchBaseKHX-baseGroupZ-00423]]
    pname:baseGroupZ must: be less than
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2]
  * [[VUID-vkCmdDispatchBaseKHX-groupCountX-00424]]
    pname:groupCountX must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0] minus
    pname:baseGroupX
  * [[VUID-vkCmdDispatchBaseKHX-groupCountY-00425]]
    pname:groupCountY must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1] minus
    pname:baseGroupY
  * [[VUID-vkCmdDispatchBaseKHX-groupCountZ-00426]]
    pname:groupCountZ must: be less than or equal to
    sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2] minus
    pname:baseGroupZ
  * [[VUID-vkCmdDispatchBaseKHX-baseGroupX-00427]]
    If any of pname:baseGroupX, pname:baseGroupY, or pname:baseGroupZ are
    not zero, then the currently bound compute pipeline must: have been
    created with the ename:VK_PIPELINE_CREATE_DISPATCH_BASE_KHX flag.
****

include::../validity/protos/vkCmdDispatchBaseKHX.txt[]

endif::VK_KHX_device_group[]
