// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[commandbuffers]]
= Command Buffers

[open,refpage='VkCommandBuffer',desc='Opaque handle to a command buffer object',type='handles']
--
Command buffers are objects used to record commands which can: be
subsequently submitted to a device queue for execution.
There are two levels of command buffers - _primary command buffers_, which
can: execute secondary command buffers, and which are submitted to queues,
and _secondary command buffers_, which can: be executed by primary command
buffers, and which are not directly submitted to queues.

Command buffers are represented by sname:VkCommandBuffer handles:

include::{generated}/api/handles/VkCommandBuffer.adoc[]
--

Recorded commands include commands to bind pipelines and descriptor sets to
the command buffer, commands to modify dynamic state, commands to draw (for
graphics rendering), commands to dispatch (for compute), commands to execute
secondary command buffers (for primary command buffers only), commands to
copy buffers and images, and other commands.

[[commandbuffers-statereset]]
Each command buffer manages state independently of other command buffers.
There is no inheritance of state across primary and secondary command
buffers, or between secondary command buffers.
When a command buffer begins recording, all state in that command buffer is
undefined:.
When secondary command buffer(s) are recorded to execute on a primary
command buffer, the secondary command buffer inherits no state from the
primary command buffer, and all state of the primary command buffer is
undefined: after an execute secondary command buffer command is recorded.
There is one exception to this rule - if the primary command buffer is
inside a render pass instance, then the render pass and subpass state is not
disturbed by executing secondary command buffers.
For state dependent commands (such as draws and dispatches), any state
consumed by those commands must: not be undefined:.

ifdef::VK_NV_inherited_viewport_scissor[]
slink:VkCommandBufferInheritanceViewportScissorInfoNV defines an exception
allowing limited inheritance of dynamic viewport and scissor state.
endif::VK_NV_inherited_viewport_scissor[]

Unless otherwise specified, and without explicit synchronization, the
various commands submitted to a queue via command buffers may: execute in
arbitrary order relative to each other, and/or concurrently.
Also, the memory side effects of those commands may: not be directly visible
to other commands without explicit memory dependencies.
This is true within a command buffer, and across command buffers submitted
to a given queue.
See <<synchronization, the synchronization chapter>> for information on
<<synchronization-implicit, implicit>> and explicit synchronization between
commands.


[[commandbuffers-lifecycle]]
== Command Buffer Lifecycle

Each command buffer is always in one of the following states:

Initial::
    When a command buffer is <<vkAllocateCommandBuffers, allocated>>, it is
    in the _initial state_.
    Some commands are able to _reset_ a command buffer (or a set of command
    buffers) back to this state from any of the executable, recording or
    invalid state.
    Command buffers in the initial state can: only be moved to the recording
    state, or freed.
Recording::
    flink:vkBeginCommandBuffer changes the state of a command buffer from
    the initial state to the _recording state_.
    Once a command buffer is in the recording state, ftext:vkCmd* commands
    can: be used to record to the command buffer.
Executable::
    flink:vkEndCommandBuffer ends the recording of a command buffer, and
    moves it from the recording state to the _executable state_.
    Executable command buffers can: be <<commandbuffers-submission,
    submitted>>, reset, or <<commandbuffers-secondary, recorded to another
    command buffer>>.
Pending::
    <<commandbuffers-submission, Queue submission>> of a command buffer
    changes the state of a command buffer from the executable state to the
    _pending state_.
    Whilst in the pending state, applications must: not attempt to modify
    the command buffer in any way - as the device may: be processing the
    commands recorded to it.
    Once execution of a command buffer completes, the command buffer either
    reverts back to the _executable state_, or if it was recorded with
    ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, it moves to the
    _invalid state_.
    A <<synchronization, synchronization>> command should: be used to detect
    when this occurs.
Invalid::
    Some operations, such as <<fundamentals-objectmodel-lifetime-cmdbuffers,
    modifying or deleting a resource>> that was used in a command recorded
    to a command buffer, will transition the state of that command buffer
    into the _invalid state_.
    Command buffers in the invalid state can: only be reset or freed.

[[commandbuffer-lifecycle-diagram]]
image::{images}/commandbuffer_lifecycle.svg[title="Lifecycle of a command buffer",align="center",opts="{imageopts}"]

Any given command that operates on a command buffer has its own requirements
on what state a command buffer must: be in, which are detailed in the valid
usage constraints for that command.

Resetting a command buffer is an operation that discards any previously
recorded commands and puts a command buffer in the _initial state_.
Resetting occurs as a result of flink:vkResetCommandBuffer or
flink:vkResetCommandPool, or as part of flink:vkBeginCommandBuffer (which
additionally puts the command buffer in the _recording state_).

<<commandbuffers-secondary, Secondary command buffers>> can: be recorded to
a primary command buffer via flink:vkCmdExecuteCommands.
This partially ties the lifecycle of the two command buffers together - if
the primary is submitted to a queue, both the primary and any secondaries
recorded to it move to the _pending state_.
Once execution of the primary completes, so it does for any secondary
recorded within it.
After all executions of each command buffer complete, they each move to
their appropriate completion state (either to the _executable state_ or the
_invalid state_, as specified above).

If a secondary moves to the _invalid state_ or the _initial state_, then all
primary buffers it is recorded in move to the _invalid state_.
A primary moving to any other state does not affect the state of a secondary
recorded in it.

[NOTE]
.Note
====
Resetting or freeing a primary command buffer removes the lifecycle linkage
to all secondary command buffers that were recorded into it.
====


[[commandbuffers-pools]]
== Command Pools

[open,refpage='VkCommandPool',desc='Opaque handle to a command pool object',type='handles']
--
Command pools are opaque objects that command buffer memory is allocated
from, and which allow the implementation to amortize the cost of resource
creation across multiple command buffers.
Command pools are externally synchronized, meaning that a command pool must:
not be used concurrently in multiple threads.
That includes use via recording commands on any command buffers allocated
from the pool, as well as operations that allocate, free, and reset command
buffers or the pool itself.

Command pools are represented by sname:VkCommandPool handles:

include::{generated}/api/handles/VkCommandPool.adoc[]
--

[open,refpage='vkCreateCommandPool',desc='Create a new command pool object',type='protos']
--
:refpage: vkCreateCommandPool
:objectnameplural: command pools
:objectnamecamelcase: commandPool
:objectcount: 1

To create a command pool, call:

include::{generated}/api/protos/vkCreateCommandPool.adoc[]

  * pname:device is the logical device that creates the command pool.
  * pname:pCreateInfo is a pointer to a slink:VkCommandPoolCreateInfo
    structure specifying the state of the command pool object.
  * pname:pAllocator controls host memory allocation as described in the
    <<memory-allocation, Memory Allocation>> chapter.
  * pname:pCommandPool is a pointer to a slink:VkCommandPool handle in which
    the created pool is returned.

include::{chapters}/commonvalidity/no_dynamic_allocations_common.adoc[]

.Valid Usage
****
  * [[VUID-vkCreateCommandPool-queueFamilyIndex-01937]]
    pname:pCreateInfo->queueFamilyIndex must: be the index of a queue family
    available in the logical device pname:device
include::{chapters}/commonvalidity/memory_reservation_request_count_common.adoc[]
****

include::{generated}/validity/protos/vkCreateCommandPool.adoc[]
--

[open,refpage='VkCommandPoolCreateInfo',desc='Structure specifying parameters of a newly created command pool',type='structs']
--
The sname:VkCommandPoolCreateInfo structure is defined as:

include::{generated}/api/structs/VkCommandPoolCreateInfo.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:flags is a bitmask of elink:VkCommandPoolCreateFlagBits indicating
    usage behavior for the pool and command buffers allocated from it.
  * pname:queueFamilyIndex designates a queue family as described in section
    <<devsandqueues-queueprops,Queue Family Properties>>.
    All command buffers allocated from this command pool must: be submitted
    on queues from the same queue family.

.Valid Usage
****
ifdef::VK_VERSION_1_1[]
  * [[VUID-VkCommandPoolCreateInfo-flags-02860]]
    If the <<features-protectedMemory, pname:protectedMemory>> feature is
    not enabled, the ename:VK_COMMAND_POOL_CREATE_PROTECTED_BIT bit of
    pname:flags must: not be set
endif::VK_VERSION_1_1[]
ifdef::VKSC_VERSION_1_0[]
  * [[VUID-VkCommandPoolCreateInfo-pNext-05002]]
    The pname:pNext chain must: include a
    slink:VkCommandPoolMemoryReservationCreateInfo structure
endif::VKSC_VERSION_1_0[]
****
ifdef::VKSC_VERSION_1_0[]
ifdef::hidden[]
// tag::scdeviation[]
  * The slink:VkCommandPoolCreateInfo::pname:pNext chain must: include a
    valid slink:VkCommandPoolMemoryReservationCreateInfo structure
    <<SCID-4>>.
// end::scdeviation[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]

include::{generated}/validity/structs/VkCommandPoolCreateInfo.adoc[]
--

[open,refpage='VkCommandPoolCreateFlagBits',desc='Bitmask specifying usage behavior for a command pool',type='enums']
--
Bits which can: be set in slink:VkCommandPoolCreateInfo::pname:flags,
specifying usage behavior for a command pool, are:

include::{generated}/api/enums/VkCommandPoolCreateFlagBits.adoc[]

  * ename:VK_COMMAND_POOL_CREATE_TRANSIENT_BIT specifies that command
    buffers allocated from the pool will be short-lived, meaning that they
    will be reset or freed in a relatively short timeframe.
    This flag may: be used by the implementation to control memory
    allocation behavior within the pool.
  * ename:VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT allows any command
    buffer allocated from a pool to be individually reset to the
    <<commandbuffers-lifecycle, initial state>>; either by calling
    flink:vkResetCommandBuffer, or via the implicit reset when calling
    flink:vkBeginCommandBuffer.
    If this flag is not set on a pool, then fname:vkResetCommandBuffer must:
    not be called for any command buffer allocated from that pool.
ifdef::VK_VERSION_1_1[]
  * ename:VK_COMMAND_POOL_CREATE_PROTECTED_BIT specifies that command
    buffers allocated from the pool are protected command buffers.
endif::VK_VERSION_1_1[]
--

[open,refpage='VkCommandPoolCreateFlags',desc='Bitmask of VkCommandPoolCreateFlagBits',type='flags']
--
include::{generated}/api/flags/VkCommandPoolCreateFlags.adoc[]

tname:VkCommandPoolCreateFlags is a bitmask type for setting a mask of zero
or more elink:VkCommandPoolCreateFlagBits.
--

ifdef::VKSC_VERSION_1_0[]

[open,refpage='VkCommandPoolMemoryReservationCreateInfo',desc='Structure specifying command pool memory reservation info',type='structs']
--

The pname:pNext chain of slink:VkCommandPoolCreateInfo must: include a
sname:VkCommandPoolMemoryReservationCreateInfo structure.
This structure controls how much memory is allocated at command pool
creation time to be used for all command buffers recorded from this pool.

The sname:VkCommandPoolMemoryReservationCreateInfo structure is defined as:

include::{generated}/api/structs/VkCommandPoolMemoryReservationCreateInfo.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:commandPoolReservedSize is the number of bytes to be allocated for
    all command buffer data recorded into this pool.
  * pname:commandPoolMaxCommandBuffers is the maximum number of command
    buffers that can be allocated from this command pool.

The number of command buffers reserved using
pname:commandPoolMaxCommandBuffers is permanently counted against the total
number of command buffers requested via
slink:VkDeviceObjectReservationCreateInfo::pname:commandBufferRequestCount
even if the command buffers are freed at a later time.

Each command recorded into a command buffer has an implementation-dependent
size that counts against pname:commandPoolReservedSize.
There is no minimum command pool size, but some sizes may be too small for
any commands to be recorded in them on a given implementation.
Applications are expected to estimate their worst-case command buffer memory
usage at development time using flink:vkGetCommandPoolMemoryConsumption and
reserve large enough command buffers.
This command can: also be used at runtime to verify expected memory usage.

While the memory consumption of a particular command is
implementation-dependent, it is a deterministic function of the parameters
to the command and of the objects used by the command (including the command
buffer itself).
Two command buffers will consume the same amount of pool memory if:

  * all numerical parameters to each command match exactly,
  * all objects used by each command are
    <<glossary-identically-defined,identically defined>>, and
  * the order of the commands is the same.

[NOTE]
.Note
====
The rules for identically defined objects apply recursively, implying for
example that if the command buffers are created in different devices that
those devices must have been created with the same features enabled.
====

Each command buffer may: require some base alignment in the pool, so the
total pool memory will match if each command buffer's consumption matches
and the command buffers are recorded one at a time and in the same order.

If all these criteria are satisfied, then a command pool memory consumption
returned by flink:vkGetCommandPoolMemoryConsumption will be sufficient to
record the same command buffers again.

ifdef::hidden[]
// tag::scaddition[]
  * slink:VkCommandPoolMemoryReservationCreateInfo <<SCID-4>>
// end::scaddition[]
endif::hidden[]

.Valid Usage
****
  * [[VUID-VkCommandPoolMemoryReservationCreateInfo-commandPoolReservedSize-05003]]
    pname:commandPoolReservedSize must: be greater than `0`
  * [[VUID-VkCommandPoolMemoryReservationCreateInfo-commandPoolMaxCommandBuffers-05004]]
    pname:commandPoolMaxCommandBuffers must: be greater than `0`
  * [[VUID-VkCommandPoolMemoryReservationCreateInfo-commandPoolMaxCommandBuffers-05090]]
    pname:commandPoolMaxCommandBuffers must: be less than or equal to
    slink:VkPhysicalDeviceVulkanSC10Properties::pname:maxCommandPoolCommandBuffers
  * [[VUID-VkCommandPoolMemoryReservationCreateInfo-commandPoolMaxCommandBuffers-05074]]
    The number of command buffers reserved by all command pools plus
    pname:commandPoolMaxCommandBuffers must: be less than or equal to the
    total number of command buffers requested via
    slink:VkDeviceObjectReservationCreateInfo::pname:commandBufferRequestCount
****

include::{generated}/validity/structs/VkCommandPoolMemoryReservationCreateInfo.adoc[]
--

[open,refpage='vkGetCommandPoolMemoryConsumption',desc='Get memory usage information for a command pool object',type='protos']
--

ifdef::hidden[]
// tag::scaddition[]
  * flink:vkGetCommandPoolMemoryConsumption <<SCID-1>>
// end::scaddition[]
endif::hidden[]

To get memory usage information for a command pool object, call:

include::{generated}/api/protos/vkGetCommandPoolMemoryConsumption.adoc[]

  * pname:device is the logical device that owns the command pool.
  * pname:commandPool is the command pool from which to query the memory
    usage.
  * pname:commandBuffer is an optional command buffer from which to query
    the memory usage.
  * pname:pConsumption is a pointer to a
    sname:VkCommandPoolMemoryConsumption structure where the memory usage is
    written.

include::{generated}/validity/protos/vkGetCommandPoolMemoryConsumption.adoc[]
--

[open,refpage='VkCommandPoolMemoryConsumption',desc='Structure where memory usage information is written',type='structs']
--

The sname:VkCommandPoolMemoryConsumption structure is defined as:

include::{generated}/api/structs/VkCommandPoolMemoryConsumption.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:commandPoolAllocated is the number of bytes currently allocated
    from this pool for command buffer data.
  * pname:commandPoolReservedSize is the total number of bytes available for
    all command buffer data recorded into this pool.
    This is equal to the value requested in
    slink:VkCommandPoolMemoryReservationCreateInfo::pname:commandPoolReservedSize.
  * pname:commandBufferAllocated is the number of bytes currently allocated
    from this pool for the specified command buffer's data.
    This number will be less than or equal to
    slink:VkPhysicalDeviceVulkanSC10Properties::pname:maxCommandBufferSize.
    If no command buffer is specified, then this is set to zero.

ifdef::hidden[]
// tag::scaddition[]
  * slink:VkCommandPoolMemoryConsumption <<SCID-1>>
// end::scaddition[]
endif::hidden[]

include::{generated}/validity/structs/VkCommandPoolMemoryConsumption.adoc[]
--

endif::VKSC_VERSION_1_0[]

ifdef::VKSC_VERSION_1_0[]
ifdef::hidden[]
// tag::scremoved[]
  * fname:vkTrimCommandPool, fname:vkTrimCommandPoolKHR <<SCID-8>>
  * tname:VkCommandPoolTrimFlags, tname:VkCommandPoolTrimFlagsKHR <<SCID-8>>
// end::scremoved[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]
ifndef::VKSC_VERSION_1_0[]
ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[]
[open,refpage='vkTrimCommandPool',desc='Trim a command pool',type='protos']
--
To trim a command pool, call:

ifdef::VK_VERSION_1_1[]
include::{generated}/api/protos/vkTrimCommandPool.adoc[]
endif::VK_VERSION_1_1[]

ifdef::VK_VERSION_1_1+VK_KHR_maintenance1[or the equivalent command]

ifdef::VK_KHR_maintenance1[]
include::{generated}/api/protos/vkTrimCommandPoolKHR.adoc[]
endif::VK_KHR_maintenance1[]

  * pname:device is the logical device that owns the command pool.
  * pname:commandPool is the command pool to trim.
  * pname:flags is reserved for future use.

Trimming a command pool recycles unused memory from the command pool back to
the system.
Command buffers allocated from the pool are not affected by the command.

[NOTE]
.Note
====
This command provides applications with some control over the internal
memory allocations used by command pools.

Unused memory normally arises from command buffers that have been recorded
and later reset, such that they are no longer using the memory.
On reset, a command buffer can return memory to its command pool, but the
only way to release memory from a command pool to the system requires
calling flink:vkResetCommandPool, which cannot be executed while any command
buffers from that pool are still in use.
Subsequent recording operations into command buffers will reuse this memory
but since total memory requirements fluctuate over time, unused memory can
accumulate.

In this situation, trimming a command pool may: be useful to return unused
memory back to the system, returning the total outstanding memory allocated
by the pool back to a more "`average`" value.

Implementations utilize many internal allocation strategies that make it
impossible to guarantee that all unused memory is released back to the
system.
For instance, an implementation of a command pool may: involve allocating
memory in bulk from the system and sub-allocating from that memory.
In such an implementation any live command buffer that holds a reference to
a bulk allocation would prevent that allocation from being freed, even if
only a small proportion of the bulk allocation is in use.

In most cases trimming will result in a reduction in allocated but unused
memory, but it does not guarantee the "`ideal`" behavior.

Trimming may: be an expensive operation, and should: not be called
frequently.
Trimming should: be treated as a way to relieve memory pressure after
application-known points when there exists enough unused memory that the
cost of trimming is "`worth`" it.
====

include::{generated}/validity/protos/vkTrimCommandPool.adoc[]
--

[open,refpage='VkCommandPoolTrimFlags',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkCommandPoolTrimFlags.adoc[]

ifdef::VK_KHR_maintenance1[]
or the equivalent

include::{generated}/api/flags/VkCommandPoolTrimFlagsKHR.adoc[]
endif::VK_KHR_maintenance1[]

tname:VkCommandPoolTrimFlags is a bitmask type for setting a mask, but is
currently reserved for future use.
--
endif::VK_VERSION_1_1,VK_KHR_maintenance1[]
endif::VKSC_VERSION_1_0[]

[open,refpage='vkResetCommandPool',desc='Reset a command pool',type='protos']
--
To reset a command pool, call:

include::{generated}/api/protos/vkResetCommandPool.adoc[]

  * pname:device is the logical device that owns the command pool.
  * pname:commandPool is the command pool to reset.
  * pname:flags is a bitmask of elink:VkCommandPoolResetFlagBits controlling
    the reset operation.

Resetting a command pool recycles all of the resources from all of the
command buffers allocated from the command pool back to the command pool.
All command buffers that have been allocated from the command pool are put
in the <<commandbuffers-lifecycle, initial state>>.

Any primary command buffer allocated from another slink:VkCommandPool that
is in the <<commandbuffers-lifecycle, recording or executable state>> and
has a secondary command buffer allocated from pname:commandPool recorded
into it, becomes <<commandbuffers-lifecycle, invalid>>.

.Valid Usage
****
  * [[VUID-vkResetCommandPool-commandPool-00040]]
    All sname:VkCommandBuffer objects allocated from pname:commandPool must:
    not be in the <<commandbuffers-lifecycle, pending state>>
****

include::{generated}/validity/protos/vkResetCommandPool.adoc[]
--

[open,refpage='VkCommandPoolResetFlagBits',desc='Bitmask controlling behavior of a command pool reset',type='enums']
--
Bits which can: be set in flink:vkResetCommandPool::pname:flags, controlling
the reset operation, are:

include::{generated}/api/enums/VkCommandPoolResetFlagBits.adoc[]

  * ename:VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT
ifndef::VKSC_VERSION_1_0[]
    specifies that resetting a command pool recycles all of the resources
    from the command pool back to the system.
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[]
    is not supported in Vulkan SC <<SCID-4>>.
ifdef::hidden[]
// tag::scremoved[]
  * elink:VkCommandPoolResetFlagBits
  ** ename:VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT <<SCID-4>>
// end::scremoved[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]
--

[open,refpage='VkCommandPoolResetFlags',desc='Bitmask of VkCommandPoolResetFlagBits',type='flags']
--
include::{generated}/api/flags/VkCommandPoolResetFlags.adoc[]

tname:VkCommandPoolResetFlags is a bitmask type for setting a mask of zero
or more elink:VkCommandPoolResetFlagBits.
--

ifdef::VKSC_VERSION_1_0[]
ifdef::hidden[]
// tag::scremoved[]
  * fname:vkDestroyCommandPool <<SCID-4>>
// end::scremoved[]
endif::hidden[]

Command pools cannot: be destroyed or trimmed <<SCID-4>>.
If
slink:VkPhysicalDeviceVulkanSC10Properties::<<limits-deviceDestroyFreesMemory,pname:deviceDestroyFreesMemory>>
is ename:VK_TRUE, then the memory used by command pools is returned to the
system when the device is destroyed.

endif::VKSC_VERSION_1_0[]
ifndef::VKSC_VERSION_1_0[]

[open,refpage='vkDestroyCommandPool',desc='Destroy a command pool object',type='protos']
--
To destroy a command pool, call:

include::{generated}/api/protos/vkDestroyCommandPool.adoc[]

  * pname:device is the logical device that destroys the command pool.
  * pname:commandPool is the handle of the command pool to destroy.
  * pname:pAllocator controls host memory allocation as described in the
    <<memory-allocation, Memory Allocation>> chapter.

When a pool is destroyed, all command buffers allocated from the pool are
<<vkFreeCommandBuffers, freed>>.

Any primary command buffer allocated from another slink:VkCommandPool that
is in the <<commandbuffers-lifecycle, recording or executable state>> and
has a secondary command buffer allocated from pname:commandPool recorded
into it, becomes <<commandbuffers-lifecycle, invalid>>.

.Valid Usage
****
  * [[VUID-vkDestroyCommandPool-commandPool-00041]]
    All sname:VkCommandBuffer objects allocated from pname:commandPool must:
    not be in the <<commandbuffers-lifecycle, pending state>>
  * [[VUID-vkDestroyCommandPool-commandPool-00042]]
    If sname:VkAllocationCallbacks were provided when pname:commandPool was
    created, a compatible set of callbacks must: be provided here
  * [[VUID-vkDestroyCommandPool-commandPool-00043]]
    If no sname:VkAllocationCallbacks were provided when pname:commandPool
    was created, pname:pAllocator must: be `NULL`
****

include::{generated}/validity/protos/vkDestroyCommandPool.adoc[]
--

endif::VKSC_VERSION_1_0[]

[[commandbuffer-allocation]]
== Command Buffer Allocation and Management

[open,refpage='vkAllocateCommandBuffers',desc='Allocate command buffers from an existing command pool',type='protos']
--
:refpage: vkAllocateCommandBuffers

To allocate command buffers, call:

include::{generated}/api/protos/vkAllocateCommandBuffers.adoc[]

  * pname:device is the logical device that owns the command pool.
  * pname:pAllocateInfo is a pointer to a slink:VkCommandBufferAllocateInfo
    structure describing parameters of the allocation.
  * pname:pCommandBuffers is a pointer to an array of slink:VkCommandBuffer
    handles in which the resulting command buffer objects are returned.
    The array must: be at least the length specified by the
    pname:commandBufferCount member of pname:pAllocateInfo.
    Each allocated command buffer begins in the initial state.

ifdef::VK_VERSION_1_1,VK_KHR_maintenance1[]
fname:vkAllocateCommandBuffers can: be used to allocate multiple command
buffers.
If the allocation of any of those command buffers fails, the implementation
must: free all successfully allocated command buffer objects from this
command, set all entries of the pname:pCommandBuffers array to `NULL` and
return the error.

[NOTE]
.Note
====
Filling pname:pCommandBuffers with `NULL` values on failure is an exception
to the default error behavior that output parameters will have undefined:
contents.
====

endif::VK_VERSION_1_1,VK_KHR_maintenance1[]

When command buffers are first allocated, they are in the
<<commandbuffers-lifecycle, initial state>>.

include::{chapters}/commonvalidity/no_dynamic_allocations_common.adoc[]

include::{generated}/validity/protos/vkAllocateCommandBuffers.adoc[]
--

[open,refpage='VkCommandBufferAllocateInfo',desc='Structure specifying the allocation parameters for command buffer object',type='structs']
--
The sname:VkCommandBufferAllocateInfo structure is defined as:

include::{generated}/api/structs/VkCommandBufferAllocateInfo.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:commandPool is the command pool from which the command buffers are
    allocated.
  * pname:level is a elink:VkCommandBufferLevel value specifying the command
    buffer level.
  * pname:commandBufferCount is the number of command buffers to allocate
    from the pool.

ifdef::VKSC_VERSION_1_0[]
The number of command buffers allocated using pname:commandBufferCount
counts against the maximum number of command buffers reserved via
slink:VkCommandPoolMemoryReservationCreateInfo::pname:commandPoolMaxCommandBuffers
specified when pname:commandPool was created.
Once command buffers are freed with flink:vkFreeCommandBuffers, they can be
allocated from pname:commandPool again.

.Valid Usage
****
  * [[VUID-VkCommandBufferAllocateInfo-commandPool-05006]]
    The number of command buffers currently allocated from pname:commandPool
    plus pname:commandBufferCount must: be less than or equal to the value
    of
    slink:VkCommandPoolMemoryReservationCreateInfo::pname:commandPoolMaxCommandBuffers
    specified when pname:commandPool was created
****
endif::VKSC_VERSION_1_0[]

include::{generated}/validity/structs/VkCommandBufferAllocateInfo.adoc[]
--

[open,refpage='VkCommandBufferLevel',desc='Enumerant specifying a command buffer level',type='enums']
--
Possible values of slink:VkCommandBufferAllocateInfo::pname:level,
specifying the command buffer level, are:

include::{generated}/api/enums/VkCommandBufferLevel.adoc[]

  * ename:VK_COMMAND_BUFFER_LEVEL_PRIMARY specifies a primary command
    buffer.
  * ename:VK_COMMAND_BUFFER_LEVEL_SECONDARY specifies a secondary command
    buffer.
--

[open,refpage='vkResetCommandBuffer',desc='Reset a command buffer to the initial state',type='protos']
--
To reset a command buffer, call:

include::{generated}/api/protos/vkResetCommandBuffer.adoc[]

  * pname:commandBuffer is the command buffer to reset.
    The command buffer can: be in any state other than
    <<commandbuffers-lifecycle, pending>>, and is moved into the
    <<commandbuffers-lifecycle, initial state>>.
  * pname:flags is a bitmask of elink:VkCommandBufferResetFlagBits
    controlling the reset operation.

Any primary command buffer that is in the <<commandbuffers-lifecycle,
recording or executable state>> and has pname:commandBuffer recorded into
it, becomes <<commandbuffers-lifecycle, invalid>>.

.Valid Usage
****
  * [[VUID-vkResetCommandBuffer-commandBuffer-00045]]
    pname:commandBuffer must: not be in the <<commandbuffers-lifecycle,
    pending state>>
  * [[VUID-vkResetCommandBuffer-commandBuffer-00046]]
    pname:commandBuffer must: have been allocated from a pool that was
    created with the ename:VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
ifdef::VKSC_VERSION_1_0[]
  * [[VUID-vkResetCommandBuffer-commandPoolResetCommandBuffer-05135]]
    <<limits-commandPoolResetCommandBuffer,pname:commandPoolResetCommandBuffer>>
    must: be supported
endif::VKSC_VERSION_1_0[]
****
ifdef::VKSC_VERSION_1_0[]
ifdef::hidden[]
// tag::scdeviation[]
  * If
    <<limits-commandPoolResetCommandBuffer,pname:commandPoolResetCommandBuffer>>
    is not supported <<SCID-8>>, flink:vkResetCommandBuffer must: not be
    called.
// end::scdeviation[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]

include::{generated}/validity/protos/vkResetCommandBuffer.adoc[]
--

[open,refpage='VkCommandBufferResetFlagBits',desc='Bitmask controlling behavior of a command buffer reset',type='enums']
--
Bits which can: be set in flink:vkResetCommandBuffer::pname:flags,
controlling the reset operation, are:

include::{generated}/api/enums/VkCommandBufferResetFlagBits.adoc[]

  * ename:VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT specifies that most
    or all memory resources currently owned by the command buffer should: be
    returned to the parent command pool.
    If this flag is not set, then the command buffer may: hold onto memory
    resources and reuse them when recording commands.
    pname:commandBuffer is moved to the <<commandbuffers-lifecycle, initial
    state>>.
--

[open,refpage='VkCommandBufferResetFlags',desc='Bitmask of VkCommandBufferResetFlagBits',type='flags']
--
include::{generated}/api/flags/VkCommandBufferResetFlags.adoc[]

tname:VkCommandBufferResetFlags is a bitmask type for setting a mask of zero
or more elink:VkCommandBufferResetFlagBits.
--

[open,refpage='vkFreeCommandBuffers',desc='Free command buffers',type='protos']
--
To free command buffers, call:

include::{generated}/api/protos/vkFreeCommandBuffers.adoc[]

  * pname:device is the logical device that owns the command pool.
  * pname:commandPool is the command pool from which the command buffers
    were allocated.
  * pname:commandBufferCount is the length of the pname:pCommandBuffers
    array.
  * pname:pCommandBuffers is a pointer to an array of handles of command
    buffers to free.

Any primary command buffer that is in the <<commandbuffers-lifecycle,
recording or executable state>> and has any element of pname:pCommandBuffers
recorded into it, becomes <<commandbuffers-lifecycle, invalid>>.

ifdef::VKSC_VERSION_1_0[]
Freeing a command buffer does not return the memory used by command
recording back to its parent command pool.
This memory will be reclaimed the next time flink:vkResetCommandPool is
called.
ifdef::hidden[]
// tag::scdeviation[]
  * flink:vkFreeCommandBuffers does not return the memory used by command
    recording back to its parent command pool <<SCID-4>>.
    This memory is reclaimed when flink:vkResetCommandPool is next called.
// end::scdeviation[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]

.Valid Usage
****
  * [[VUID-vkFreeCommandBuffers-pCommandBuffers-00047]]
    All elements of pname:pCommandBuffers must: not be in the
    <<commandbuffers-lifecycle, pending state>>
  * [[VUID-vkFreeCommandBuffers-pCommandBuffers-00048]]
    pname:pCommandBuffers must: be a valid pointer to an array of
    pname:commandBufferCount sname:VkCommandBuffer handles, each element of
    which must: either be a valid handle or `NULL`
****

include::{generated}/validity/protos/vkFreeCommandBuffers.adoc[]
--


[[commandbuffers-recording]]
== Command Buffer Recording

[open,refpage='vkBeginCommandBuffer',desc='Start recording a command buffer',type='protos']
--

:refpage: vkBeginCommandBuffer

To begin recording a command buffer, call:

include::{generated}/api/protos/vkBeginCommandBuffer.adoc[]

  * pname:commandBuffer is the handle of the command buffer which is to be
    put in the recording state.
  * pname:pBeginInfo is a pointer to a slink:VkCommandBufferBeginInfo
    structure defining additional information about how the command buffer
    begins recording.

include::{chapters}/commonvalidity/no_dynamic_allocations_common.adoc[]

.Valid Usage
****
  * [[VUID-vkBeginCommandBuffer-commandBuffer-00049]]
    pname:commandBuffer must: not be in the <<commandbuffers-lifecycle,
    recording or pending state>>
  * [[VUID-vkBeginCommandBuffer-commandBuffer-00050]]
    If pname:commandBuffer was allocated from a slink:VkCommandPool which
    did not have the ename:VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
    flag set, pname:commandBuffer must: be in the
    <<commandbuffers-lifecycle, initial state>>
ifdef::VKSC_VERSION_1_0[]
  * [[VUID-vkBeginCommandBuffer-commandPoolResetCommandBuffer-05136]]
    If
    <<limits-commandPoolResetCommandBuffer,pname:commandPoolResetCommandBuffer>>
    is not supported, pname:commandBuffer must: be in the
    <<commandbuffers-lifecycle, initial state>>
endif::VKSC_VERSION_1_0[]
  * [[VUID-vkBeginCommandBuffer-commandBuffer-00051]]
    If pname:commandBuffer is a secondary command buffer, the
    pname:pInheritanceInfo member of pname:pBeginInfo must: be a valid
    sname:VkCommandBufferInheritanceInfo structure
  * [[VUID-vkBeginCommandBuffer-commandBuffer-00052]]
    If pname:commandBuffer is a secondary command buffer and either the
    pname:occlusionQueryEnable member of the pname:pInheritanceInfo member
    of pname:pBeginInfo is ename:VK_FALSE, or the
    <<features-occlusionQueryPrecise, pname:occlusionQueryPrecise>> feature
    is not enabled, then pname:pBeginInfo->pInheritanceInfo->queryFlags
    must: not contain ename:VK_QUERY_CONTROL_PRECISE_BIT
  * [[VUID-vkBeginCommandBuffer-commandBuffer-02840]]
    If pname:commandBuffer is a primary command buffer, then
    pname:pBeginInfo->flags must: not set both the
    ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT and the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flags
ifdef::VKSC_VERSION_1_0[]
  * [[VUID-vkBeginCommandBuffer-commandPoolMultipleCommandBuffersRecording-05007]]
    If
    <<limits-commandPoolMultipleCommandBuffersRecording,pname:commandPoolMultipleCommandBuffersRecording>>
    is ename:VK_FALSE, then the command pool that pname:commandBuffer was
    created from must: have no other command buffers in the
    <<commandbuffers-lifecycle, recording state>>
  * [[VUID-vkBeginCommandBuffer-commandBufferSimultaneousUse-05008]]
    If
    <<limits-commandBufferSimultaneousUse,pname:commandBufferSimultaneousUse>>
    is ename:VK_FALSE, then pname:pBeginInfo->flags must: not include
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
endif::VKSC_VERSION_1_0[]
****
ifdef::VKSC_VERSION_1_0[]
ifdef::hidden[]
// tag::scdeviation[]
  * If
    slink:VkPhysicalDeviceVulkanSC10Properties::pname:commandPoolMultipleCommandBuffersRecording
    is ename:VK_FALSE, then only one command buffer from a command pool can
    be in the <<commandbuffers-lifecycle, recording state>> at a time
    <<SCID-8>>.
  * If
    slink:VkPhysicalDeviceVulkanSC10Properties::pname:commandBufferSimultaneousUse
    is ename:VK_FALSE, then slink:VkCommandBufferBeginInfo::pname:flags
    must: not include ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
    <<SCID-8>>.
  * If
    <<limits-commandPoolResetCommandBuffer,pname:commandPoolResetCommandBuffer>>
    is not supported, pname:commandBuffer must: be in the
    <<commandbuffers-lifecycle, initial state>> when
    flink:vkBeginCommandBuffer is called <<SCID-8>>.
// end::scdeviation[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]

include::{generated}/validity/protos/vkBeginCommandBuffer.adoc[]
--

[open,refpage='VkCommandBufferBeginInfo',desc='Structure specifying a command buffer begin operation',type='structs']
--
The sname:VkCommandBufferBeginInfo structure is defined as:

include::{generated}/api/structs/VkCommandBufferBeginInfo.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:flags is a bitmask of elink:VkCommandBufferUsageFlagBits
    specifying usage behavior for the command buffer.
  * pname:pInheritanceInfo is a pointer to a
    slink:VkCommandBufferInheritanceInfo structure, used if
    pname:commandBuffer is a secondary command buffer.
    If this is a primary command buffer, then this value is ignored.

.Valid Usage
****
  * [[VUID-VkCommandBufferBeginInfo-flags-09123]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the
    slink:VkCommandPool that pname:commandBuffer was allocated from must:
    support graphics operations
ifndef::VKSC_VERSION_1_0[]
  * [[VUID-VkCommandBufferBeginInfo-flags-00055]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the
    pname:framebuffer member of pname:pInheritanceInfo must: be either
    dlink:VK_NULL_HANDLE, or a valid sname:VkFramebuffer that is compatible
    with the pname:renderPass member of pname:pInheritanceInfo
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[]
  * [[VUID-VkCommandBufferBeginInfo-flags-05009]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT and
    pname:secondaryCommandBufferNullOrImagelessFramebuffer is ename:VK_TRUE,
    the pname:framebuffer member of pname:pInheritanceInfo must: be either
    dlink:VK_NULL_HANDLE, or a valid sname:VkFramebuffer that is compatible
    with the pname:renderPass member of pname:pInheritanceInfo
  * [[VUID-VkCommandBufferBeginInfo-flags-05010]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT and
    pname:secondaryCommandBufferNullOrImagelessFramebuffer is
    ename:VK_FALSE, the pname:framebuffer member of pname:pInheritanceInfo
    must: be a valid sname:VkFramebuffer that is compatible with the
    pname:renderPass member of pname:pInheritanceInfo and must: not have
    been created with a slink:VkFramebufferCreateInfo::pname:flags value
    that includes ename:VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT
endif::VKSC_VERSION_1_0[]
ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
  * [[VUID-VkCommandBufferBeginInfo-flags-09240]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT and the
    <<features-dynamicRendering,pname:dynamicRendering>> feature is not
    enabled, the pname:renderPass member of pname:pInheritanceInfo must: not
    be dlink:VK_NULL_HANDLE
  * [[VUID-VkCommandBufferBeginInfo-flags-06002]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT and the
    pname:renderPass member of pname:pInheritanceInfo is
    dlink:VK_NULL_HANDLE, the pname:pNext chain of pname:pInheritanceInfo
    must: include a slink:VkCommandBufferInheritanceRenderingInfo structure
ifdef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples[]
  * [[VUID-VkCommandBufferBeginInfo-flags-06003]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the
    pname:renderPass member of pname:pInheritanceInfo is
    dlink:VK_NULL_HANDLE, and the pname:pNext chain of
    pname:pInheritanceInfo includes a slink:VkAttachmentSampleCountInfoAMD
    or slink:VkAttachmentSampleCountInfoNV structure, the
    pname:colorAttachmentCount member of that structure must: be equal to
    the value of
    slink:VkCommandBufferInheritanceRenderingInfo::pname:colorAttachmentCount
endif::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples[]
endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
  * [[VUID-VkCommandBufferBeginInfo-flags-06000]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
    and the pname:renderPass member of pname:pInheritanceInfo is not
    dlink:VK_NULL_HANDLE,
endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
    the pname:renderPass member of pname:pInheritanceInfo must: be a valid
    sname:VkRenderPass
  * [[VUID-VkCommandBufferBeginInfo-flags-06001]]
    If pname:flags contains
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
    and the pname:renderPass member of pname:pInheritanceInfo is not
    dlink:VK_NULL_HANDLE,
endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
    the pname:subpass member of pname:pInheritanceInfo must: be a valid
    subpass index within the pname:renderPass member of
    pname:pInheritanceInfo
****
ifdef::VKSC_VERSION_1_0[]
ifdef::hidden[]
// tag::scdeviation[]
  * If
    slink:VkPhysicalDeviceVulkanSC10Properties::pname:secondaryCommandBufferNullOrImagelessFramebuffer
    is ename:VK_FALSE, then
    slink:VkCommandBufferInheritanceInfo:pname:framebuffer must: not be
    dlink:VK_NULL_HANDLE and must: not have been created with a
    slink:VkFramebufferCreateInfo::pname:flags value that includes
    ename:VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT if the command buffer will be
    executed within a render pass instance <<SCID-8>>.
// end::scdeviation[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]

include::{generated}/validity/structs/VkCommandBufferBeginInfo.adoc[]
--

[open,refpage='VkCommandBufferUsageFlagBits',desc='Bitmask specifying usage behavior for command buffer',type='enums']
--
Bits which can: be set in slink:VkCommandBufferBeginInfo::pname:flags,
specifying usage behavior for a command buffer, are:

include::{generated}/api/enums/VkCommandBufferUsageFlagBits.adoc[]

  * ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT specifies that each
    recording of the command buffer will only be submitted once, and the
    command buffer will be reset and recorded again between each submission.
  * ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT specifies that a
    secondary command buffer is considered to be entirely inside a render
    pass.
    If this is a primary command buffer, then this bit is ignored.
  * ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT specifies that a
    command buffer can: be resubmitted to any queue of the same queue family
    while it is in the _pending state_, and recorded into multiple primary
    command buffers.
--

[open,refpage='VkCommandBufferUsageFlags',desc='Bitmask of VkCommandBufferUsageFlagBits',type='flags']
--
include::{generated}/api/flags/VkCommandBufferUsageFlags.adoc[]

tname:VkCommandBufferUsageFlags is a bitmask type for setting a mask of zero
or more elink:VkCommandBufferUsageFlagBits.
--

[open,refpage='VkCommandBufferInheritanceInfo',desc='Structure specifying command buffer inheritance information',type='structs']
--
If the command buffer is a secondary command buffer, then the
sname:VkCommandBufferInheritanceInfo structure defines any state that will
be inherited from the primary command buffer:

include::{generated}/api/structs/VkCommandBufferInheritanceInfo.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:renderPass is a slink:VkRenderPass object defining which render
    passes the sname:VkCommandBuffer will be <<renderpass-compatibility,
    compatible>> with and can: be executed within.
  * pname:subpass is the index of the subpass within the render pass
    instance that the sname:VkCommandBuffer will be executed within.
  * pname:framebuffer can: refer to the slink:VkFramebuffer object that the
    sname:VkCommandBuffer will be rendering to if it is executed within a
    render pass instance.
    It can: be dlink:VK_NULL_HANDLE if the framebuffer is not known.
+
[NOTE]
.Note
====
Specifying the exact framebuffer that the secondary command buffer will be
executed with may: result in better performance at command buffer execution
time.
====
  * pname:occlusionQueryEnable specifies whether the command buffer can: be
    executed while an occlusion query is active in the primary command
    buffer.
    If this is ename:VK_TRUE, then this command buffer can: be executed
    whether the primary command buffer has an occlusion query active or not.
    If this is ename:VK_FALSE, then the primary command buffer must: not
    have an occlusion query active.
  * pname:queryFlags specifies the query flags that can: be used by an
    active occlusion query in the primary command buffer when this secondary
    command buffer is executed.
    If this value includes the ename:VK_QUERY_CONTROL_PRECISE_BIT bit, then
    the active query can: return boolean results or actual sample counts.
    If this bit is not set, then the active query must: not use the
    ename:VK_QUERY_CONTROL_PRECISE_BIT bit.
  * pname:pipelineStatistics is a bitmask of
    elink:VkQueryPipelineStatisticFlagBits specifying the set of pipeline
    statistics that can: be counted by an active query in the primary
    command buffer when this secondary command buffer is executed.
    If this value includes a given bit, then this command buffer can: be
    executed whether the primary command buffer has a pipeline statistics
    query active that includes this bit or not.
    If this value excludes a given bit, then the active pipeline statistics
    query must: not be from a query pool that counts that statistic.

If the slink:VkCommandBuffer will not be executed within a render pass
instance,
ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
or if the render pass instance was begun with flink:vkCmdBeginRendering,
endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
pname:renderPass, pname:subpass, and pname:framebuffer are ignored.

.Valid Usage
****
  * [[VUID-VkCommandBufferInheritanceInfo-occlusionQueryEnable-00056]]
    If the <<features-inheritedQueries, pname:inheritedQueries>> feature is
    not enabled, pname:occlusionQueryEnable must: be ename:VK_FALSE
  * [[VUID-VkCommandBufferInheritanceInfo-queryFlags-00057]]
    If the <<features-inheritedQueries, pname:inheritedQueries>> feature is
    enabled, pname:queryFlags must: be a valid combination of
    elink:VkQueryControlFlagBits values
  * [[VUID-VkCommandBufferInheritanceInfo-queryFlags-02788]]
    If the <<features-inheritedQueries, pname:inheritedQueries>> feature is
    not enabled, pname:queryFlags must: be code:0
  * [[VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-02789]]
    If the <<features-pipelineStatisticsQuery,
    pname:pipelineStatisticsQuery>> feature is enabled,
    pname:pipelineStatistics must: be a valid combination of
    elink:VkQueryPipelineStatisticFlagBits values
  * [[VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-00058]]
    If the <<features-pipelineStatisticsQuery,
    pname:pipelineStatisticsQuery>> feature is not enabled,
    pname:pipelineStatistics must: be code:0
****

include::{generated}/validity/structs/VkCommandBufferInheritanceInfo.adoc[]
--

[NOTE]
.Note
====
On some implementations, not using the
ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT bit enables command
buffers to be patched in-place if needed, rather than creating a copy of the
command buffer.
====

If a command buffer is in the <<commandbuffers-lifecycle, invalid, or
executable state>>, and the command buffer was allocated from a command pool
with the ename:VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set,
then fname:vkBeginCommandBuffer implicitly resets the command buffer,
behaving as if fname:vkResetCommandBuffer had been called with
ename:VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT not set.
After the implicit reset, pname:commandBuffer is moved to the
<<commandbuffers-lifecycle, recording state>>.

ifdef::VK_EXT_conditional_rendering[]
[open,refpage='VkCommandBufferInheritanceConditionalRenderingInfoEXT',desc='Structure specifying command buffer inheritance information',type='structs']
--
If the pname:pNext chain of slink:VkCommandBufferInheritanceInfo includes a
sname:VkCommandBufferInheritanceConditionalRenderingInfoEXT structure, then
that structure controls whether a command buffer can: be executed while
conditional rendering is <<active-conditional-rendering,active>> in the
primary command buffer.

The sname:VkCommandBufferInheritanceConditionalRenderingInfoEXT structure is
defined as:

include::{generated}/api/structs/VkCommandBufferInheritanceConditionalRenderingInfoEXT.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:conditionalRenderingEnable specifies whether the command buffer
    can: be executed while conditional rendering is active in the primary
    command buffer.
    If this is ename:VK_TRUE, then this command buffer can: be executed
    whether the primary command buffer has active conditional rendering or
    not.
    If this is ename:VK_FALSE, then the primary command buffer must: not
    have conditional rendering active.

If this structure is not present, the behavior is as if
pname:conditionalRenderingEnable is ename:VK_FALSE.

.Valid Usage
****
  * [[VUID-VkCommandBufferInheritanceConditionalRenderingInfoEXT-conditionalRenderingEnable-01977]]
    If the <<features-inheritedConditionalRendering,
    pname:inheritedConditionalRendering>> feature is not enabled,
    pname:conditionalRenderingEnable must: be ename:VK_FALSE
****

include::{generated}/validity/structs/VkCommandBufferInheritanceConditionalRenderingInfoEXT.adoc[]
--
endif::VK_EXT_conditional_rendering[]

ifdef::VK_QCOM_render_pass_transform[]
[open,refpage='VkCommandBufferInheritanceRenderPassTransformInfoQCOM',desc='Structure describing transformed render pass parameters command buffer',type='structs']
--
To begin recording a secondary command buffer compatible with execution
inside a render pass using <<vertexpostproc-renderpass-transform, render
pass transform>>, add the
slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM to the
pname:pNext chain of slink:VkCommandBufferInheritanceInfo structure passed
to the flink:vkBeginCommandBuffer command specifying the parameters for
transformed rasterization.

The sname:VkCommandBufferInheritanceRenderPassTransformInfoQCOM structure is
defined as:

include::{generated}/api/structs/VkCommandBufferInheritanceRenderPassTransformInfoQCOM.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:transform is a elink:VkSurfaceTransformFlagBitsKHR value
    describing the transform to be applied to the render pass.
  * pname:renderArea is the render area that is affected by the command
    buffer.

When the secondary is recorded to execute within a render pass instance
using flink:vkCmdExecuteCommands, the render pass transform parameters of
the secondary command buffer must: be consistent with the render pass
transform parameters specified for the render pass instance.
In particular, the pname:transform and pname:renderArea for command buffer
must: be identical to the pname:transform and pname:renderArea of the render
pass instance.

.Valid Usage
****
  * [[VUID-VkCommandBufferInheritanceRenderPassTransformInfoQCOM-transform-02864]]
    pname:transform must: be ename:VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
    ename:VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR,
    ename:VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR, or
    ename:VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR
****

include::{generated}/validity/structs/VkCommandBufferInheritanceRenderPassTransformInfoQCOM.adoc[]
--
endif::VK_QCOM_render_pass_transform[]

ifdef::VK_NV_inherited_viewport_scissor[]
[open,refpage='VkCommandBufferInheritanceViewportScissorInfoNV',desc='Structure specifying command buffer inheritance information',type='structs']
--
The sname:VkCommandBufferInheritanceViewportScissorInfoNV structure is
defined as:

include::{generated}/api/structs/VkCommandBufferInheritanceViewportScissorInfoNV.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:viewportScissor2D specifies whether the listed dynamic state is
    inherited.
  * pname:viewportDepthCount specifies the maximum number of viewports to
    inherit.
    When pname:viewportScissor2D is ename:VK_FALSE, the behavior is as if
    this value is zero.
  * pname:pViewportDepths is a pointer to a slink:VkViewport structure
    specifying the expected depth range for each inherited viewport.

If the pname:pNext chain of slink:VkCommandBufferInheritanceInfo includes a
sname:VkCommandBufferInheritanceViewportScissorInfoNV structure, then that
structure controls whether a command buffer can: inherit the following state
from other command buffers:

  * ename:VK_DYNAMIC_STATE_SCISSOR
ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
  * ename:VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT
endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
ifdef::VK_EXT_discard_rectangles[]
  * ename:VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
  * ename:VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT
  * ename:VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT
endif::VK_EXT_discard_rectangles[]

as well as the following state, with restrictions on inherited depth values
and viewport count:

  * ename:VK_DYNAMIC_STATE_VIEWPORT
ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
  * ename:VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT
endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]

If pname:viewportScissor2D is ename:VK_FALSE, then the command buffer does
not inherit the listed dynamic state, and should: set this state itself.
If this structure is not present, the behavior is as if
pname:viewportScissor2D is ename:VK_FALSE.

If pname:viewportScissor2D is ename:VK_TRUE, then the listed dynamic state
is inherited, and the command buffer must: not set this
ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[state.]
ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
state, except that the viewport and scissor count may: be set by binding a
graphics pipeline that does not specify this state as dynamic.

[NOTE]
.Note
====
Due to this restriction, applications should: ensure either all or none of
the graphics pipelines bound in this secondary command buffer use dynamic
viewport/scissor counts.
====
endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]

When the command buffer is executed as part of a the execution of a
flink:vkCmdExecuteCommands command, the inherited state (if enabled) is
determined by the following procedure, performed separately for each dynamic
state, and separately for each value for dynamic state that consists of
multiple values (e.g. multiple viewports).

  * With [eq]#i# being the index of the executed command buffer in the
    pname:pCommandBuffers array of flink:vkCmdExecuteCommands, if [eq]#i >
    0# and any secondary command buffer from index [eq]#0# to [eq]#i-1#
    modifies the state, the inherited state is provisionally set to the
    final value set by the last such secondary command buffer.
    Binding a graphics pipeline defining the state statically is equivalent
    to setting the state to an undefined: value.
  * Otherwise, the tentatative inherited state is that of the primary
    command buffer at the point the flink:vkCmdExecuteCommands command was
    recorded; if the state is undefined:, then so is the provisional
    inherited state.
  * If the provisional inherited state is an undefined: value, then the
    state is not inherited.
  * If the provisional inherited state is a viewport, with [eq]#n# being its
    viewport index, then if [eq]#n {geq} pname:viewportDepthCount#, or if
    either slink:VkViewport::pname:minDepth or
    slink:VkViewport::pname:maxDepth are not equal to the respective values
    of the [eq]#n^th^# element of pname:pViewportDepths, then the state is
    not inherited.
  * If the provisional inherited state passes both checks, then it becomes
    the actual inherited state.

[NOTE]
.Note
====
There is no support for inheriting dynamic state from a secondary command
buffer executed as part of a different `vkCmdExecuteCommands` command.
====

.Valid Usage
****
  * [[VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04782]]
    If the <<features-inheritedViewportScissor2D,
    pname:inheritedViewportScissor2D>> feature is not enabled,
    pname:viewportScissor2D must: be ename:VK_FALSE
  * [[VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04783]]
    If the <<features-multiViewport, pname:multiViewport>> feature is not
    enabled and pname:viewportScissor2D is ename:VK_TRUE, then
    pname:viewportDepthCount must: be `1`
  * [[VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04784]]
    If pname:viewportScissor2D is ename:VK_TRUE, then
    pname:viewportDepthCount must: be greater than `0`
  * [[VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04785]]
    If pname:viewportScissor2D is ename:VK_TRUE, then pname:pViewportDepths
    must: be a valid pointer to an array of `viewportDepthCount` valid
    sname:VkViewport structures, except any requirements on `x`, `y`,
    `width`, and `height` do not apply
  * [[VUID-VkCommandBufferInheritanceViewportScissorInfoNV-viewportScissor2D-04786]]
    If pname:viewportScissor2D is ename:VK_TRUE, then the command buffer
    must: be recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
****

include::{generated}/validity/structs/VkCommandBufferInheritanceViewportScissorInfoNV.adoc[]
--
endif::VK_NV_inherited_viewport_scissor[]

ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
[open,refpage='VkCommandBufferInheritanceRenderingInfo',desc='Structure specifying command buffer inheritance info for dynamic render pass instances',type='structs',alias='VkCommandBufferInheritanceRenderingInfoKHR']
--
The sname:VkCommandBufferInheritanceRenderingInfo structure is defined as:

include::{generated}/api/structs/VkCommandBufferInheritanceRenderingInfo.adoc[]

ifdef::VK_KHR_dynamic_rendering[]
or the equivalent

include::{generated}/api/structs/VkCommandBufferInheritanceRenderingInfoKHR.adoc[]
endif::VK_KHR_dynamic_rendering[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure
  * pname:flags is a bitmask of elink:VkRenderingFlagBits used by the render
    pass instance.
  * pname:viewMask is the view mask used for rendering.
  * pname:colorAttachmentCount is the number of color attachments specified
    in the render pass instance.
  * pname:pColorAttachmentFormats is a pointer to an array of elink:VkFormat
    values defining the format of color attachments.
  * pname:depthAttachmentFormat is a elink:VkFormat value defining the
    format of the depth attachment.
  * pname:stencilAttachmentFormat is a elink:VkFormat value defining the
    format of the stencil attachment.
  * pname:rasterizationSamples is a elink:VkSampleCountFlagBits specifying
    the number of samples used in rasterization.

If the pname:pNext chain of slink:VkCommandBufferInheritanceInfo includes a
sname:VkCommandBufferInheritanceRenderingInfo structure, then that structure
controls parameters of dynamic render pass instances that the
slink:VkCommandBuffer can: be executed within.
If slink:VkCommandBufferInheritanceInfo::pname:renderPass is not
dlink:VK_NULL_HANDLE, or
ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT is not specified in
slink:VkCommandBufferBeginInfo::pname:flags, parameters of this structure
are ignored.

If pname:colorAttachmentCount is `0` and the
<<features-variableMultisampleRate, pname:variableMultisampleRate>> feature
is enabled, pname:rasterizationSamples is ignored.

If pname:depthAttachmentFormat, pname:stencilAttachmentFormat, or any
element of pname:pColorAttachmentFormats is ename:VK_FORMAT_UNDEFINED, it
indicates that the corresponding attachment is unused within the render pass
and writes to those attachments are discarded.

.Valid Usage
****
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-colorAttachmentCount-06004]]
    If pname:colorAttachmentCount is not `0`, pname:rasterizationSamples
    must: be a valid elink:VkSampleCountFlagBits value
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-variableMultisampleRate-06005]]
    If the <<features-variableMultisampleRate,
    pname:variableMultisampleRate>> feature is not enabled,
    pname:rasterizationSamples must: be a valid elink:VkSampleCountFlagBits
    value
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-depthAttachmentFormat-06540]]
    If pname:depthAttachmentFormat is not ename:VK_FORMAT_UNDEFINED, it
    must: be a format that includes a depth component
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-depthAttachmentFormat-06007]]
    If pname:depthAttachmentFormat is not ename:VK_FORMAT_UNDEFINED, it
    must: be a format with <<potential-format-features, potential format
    features>> that include
    ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-pColorAttachmentFormats-06492]]
    If any element of pname:pColorAttachmentFormats is not
    ename:VK_FORMAT_UNDEFINED, it must: be a format with
    <<potential-format-features, potential format features>> that include
    ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
ifdef::VK_NV_linear_color_attachment[]
    , or ename:VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV if the
    <<features-linearColorAttachment, pname:linearColorAttachment>> feature
    is enabled
endif::VK_NV_linear_color_attachment[]
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-stencilAttachmentFormat-06541]]
    If pname:stencilAttachmentFormat is not ename:VK_FORMAT_UNDEFINED, it
    must: be a format that includes a stencil aspect
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-stencilAttachmentFormat-06199]]
    If pname:stencilAttachmentFormat is not ename:VK_FORMAT_UNDEFINED, it
    must: be a format with <<potential-format-features, potential format
    features>> that include
    ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-depthAttachmentFormat-06200]]
    If pname:depthAttachmentFormat is not ename:VK_FORMAT_UNDEFINED and
    pname:stencilAttachmentFormat is not ename:VK_FORMAT_UNDEFINED,
    pname:depthAttachmentFormat must: equal pname:stencilAttachmentFormat
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-multiview-06008]]
    If the <<features-multiview, pname:multiview>> feature is not enabled,
    pname:viewMask must: be `0`
ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
  * [[VUID-VkCommandBufferInheritanceRenderingInfo-viewMask-06009]]
    The index of the most significant bit in pname:viewMask must: be less
    than <<limits-maxMultiviewViewCount, pname:maxMultiviewViewCount>>
endif::VK_VERSION_1_1,VK_KHR_multiview[]
****

include::{generated}/validity/structs/VkCommandBufferInheritanceRenderingInfo.adoc[]
--

ifdef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples[]
[open,refpage='VkAttachmentSampleCountInfoAMD',desc='Structure specifying command buffer inheritance info for dynamic render pass instances',type='structs',alias='VkAttachmentSampleCountInfoNV']
--
The
ifdef::VK_AMD_mixed_attachment_samples[sname:VkAttachmentSampleCountInfoAMD]
ifdef::VK_AMD_mixed_attachment_samples+VK_NV_framebuffer_mixed_samples[or]
ifdef::VK_NV_framebuffer_mixed_samples[sname:VkAttachmentSampleCountInfoNV]
structure is defined as:

ifdef::VK_AMD_mixed_attachment_samples[]
include::{generated}/api/structs/VkAttachmentSampleCountInfoAMD.adoc[]
endif::VK_AMD_mixed_attachment_samples[]

ifdef::VK_AMD_mixed_attachment_samples+VK_NV_framebuffer_mixed_samples[or the equivalent]

ifdef::VK_NV_framebuffer_mixed_samples[]
include::{generated}/api/structs/VkAttachmentSampleCountInfoNV.adoc[]
endif::VK_NV_framebuffer_mixed_samples[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure
  * pname:colorAttachmentCount is the number of color attachments specified
    in a render pass instance.
  * pname:pColorAttachmentSamples is a pointer to an array of
    elink:VkSampleCountFlagBits values defining the sample count of color
    attachments.
  * pname:depthStencilAttachmentSamples is a elink:VkSampleCountFlagBits
    value defining the sample count of a depth/stencil attachment.

If slink:VkCommandBufferInheritanceInfo::pname:renderPass is
dlink:VK_NULL_HANDLE, ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
is specified in slink:VkCommandBufferBeginInfo::pname:flags, and the
pname:pNext chain of slink:VkCommandBufferInheritanceInfo includes
sname:VkAttachmentSampleCountInfoAMD, then this structure defines the sample
counts of each attachment within the render pass instance.
If sname:VkAttachmentSampleCountInfoAMD is not included, the value of
slink:VkCommandBufferInheritanceRenderingInfo::pname:rasterizationSamples is
used as the sample count for each attachment.
If slink:VkCommandBufferInheritanceInfo::pname:renderPass is not
dlink:VK_NULL_HANDLE, or
ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT is not specified in
slink:VkCommandBufferBeginInfo::pname:flags, parameters of this structure
are ignored.

sname:VkAttachmentSampleCountInfoAMD can: also be included in the
pname:pNext chain of slink:VkGraphicsPipelineCreateInfo.
When a graphics pipeline is created without a slink:VkRenderPass, if this
structure is included in the pname:pNext chain of
slink:VkGraphicsPipelineCreateInfo, it specifies the sample count of
attachments used for rendering.
If this structure is not specified, and the pipeline does not include a
slink:VkRenderPass, the value of
slink:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples is
used as the sample count for each attachment.
If a graphics pipeline is created with a valid slink:VkRenderPass,
parameters of this structure are ignored.

include::{generated}/validity/structs/VkAttachmentSampleCountInfoAMD.adoc[]
--
endif::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples[]

endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]

Once recording starts, an application records a sequence of commands
(ftext:vkCmd*) to set state in the command buffer, draw, dispatch, and other
commands.

ifdef::VK_NV_device_generated_commands[]
Several commands can also be recorded indirectly from sname:VkBuffer
content, see <<device-generated-commands>>.
endif::VK_NV_device_generated_commands[]

[open,refpage='vkEndCommandBuffer',desc='Finish recording a command buffer',type='protos']
--

:refpage: vkEndCommandBuffer

To complete recording of a command buffer, call:

include::{generated}/api/protos/vkEndCommandBuffer.adoc[]

  * pname:commandBuffer is the command buffer to complete recording.

The command buffer must: have been in the <<commandbuffers-lifecycle,
recording state>>, and, if successful, is moved to the
<<commandbuffers-lifecycle, executable state>>.

If there was an error during recording, the application will be notified by
an unsuccessful return code returned by fname:vkEndCommandBuffer, and the
command buffer will be moved to the <<commandbuffers-lifecycle, invalid
state>>.

ifdef::VK_KHR_video_encode_queue[]
In case the application recorded one or more <<video-encode-operations,video
encode operations>> into the command buffer, implementations may: return the
ename:VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR error if any of the
specified Video Std parameters do not adhere to the syntactic or semantic
requirements of the used video compression standard, or if values derived
from parameters according to the rules defined by the used video compression
standard do not adhere to the capabilities of the video compression standard
or the implementation.

[NOTE]
.Note
====
Applications should: not rely on the
ename:VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR error being returned by any
command as a means to verify Video Std parameters, as implementations are
not required to report the error in any specific set of cases.
====
endif::VK_KHR_video_encode_queue[]

ifdef::VKSC_VERSION_1_0[]
If recording a command would exceed the amount of command pool memory
reserved by
slink:VkCommandPoolMemoryReservationCreateInfo::pname:commandPoolReservedSize,
the implementation may: report a ename:VK_FAULT_TYPE_COMMAND_BUFFER_FULL
fault.
The command buffer remains in the <<commandbuffers-lifecycle, recording
state>> until fname:vkEndCommandBuffer is called.
When fname:vkEndCommandBuffer is called on a command buffer for which the
command pool memory reservation was exceeded during recording, it must:
return ename:VK_ERROR_OUT_OF_DEVICE_MEMORY.
endif::VKSC_VERSION_1_0[]

include::{chapters}/commonvalidity/no_dynamic_allocations_common.adoc[]

.Valid Usage
****
  * [[VUID-vkEndCommandBuffer-commandBuffer-00059]]
    pname:commandBuffer must: be in the <<commandbuffers-lifecycle,
    recording state>>
  * [[VUID-vkEndCommandBuffer-commandBuffer-00060]]
    If pname:commandBuffer is a primary command buffer, there must: not be
    an active render pass instance
  * [[VUID-vkEndCommandBuffer-commandBuffer-00061]]
    All queries made <<queries-operation-active,active>> during the
    recording of pname:commandBuffer must: have been made inactive
ifdef::VK_EXT_conditional_rendering[]
  * [[VUID-vkEndCommandBuffer-None-01978]]
    Conditional rendering must: not be
    <<active-conditional-rendering,active>>
endif::VK_EXT_conditional_rendering[]
ifdef::VK_KHR_video_queue[]
  * [[VUID-vkEndCommandBuffer-None-06991]]
    There must: be no video session object bound
endif::VK_KHR_video_queue[]
ifdef::VK_EXT_debug_utils[]
  * [[VUID-vkEndCommandBuffer-commandBuffer-01815]]
    If pname:commandBuffer is a secondary command buffer, there must: not be
    an outstanding flink:vkCmdBeginDebugUtilsLabelEXT command recorded to
    pname:commandBuffer that has not previously been ended by a call to
    flink:vkCmdEndDebugUtilsLabelEXT
endif::VK_EXT_debug_utils[]
ifdef::VK_EXT_debug_marker[]
  * [[VUID-vkEndCommandBuffer-commandBuffer-00062]]
    If pname:commandBuffer is a secondary command buffer, there must: not be
    an outstanding flink:vkCmdDebugMarkerBeginEXT command recorded to
    pname:commandBuffer that has not previously been ended by a call to
    flink:vkCmdDebugMarkerEndEXT
endif::VK_EXT_debug_marker[]
****

include::{generated}/validity/protos/vkEndCommandBuffer.adoc[]
--

When a command buffer is in the executable state, it can: be submitted to a
queue for execution.


[[commandbuffers-submission]]
== Command Buffer Submission

[NOTE]
.Note
====
Submission can be a high overhead operation, and applications should:
attempt to batch work together into as few calls to fname:vkQueueSubmit
ifdef::VK_VERSION_1_3,VK_KHR_synchronization2[]
or fname:vkQueueSubmit2
endif::VK_VERSION_1_3,VK_KHR_synchronization2[]
as possible.
====

ifdef::VK_VERSION_1_3,VK_KHR_synchronization2[]
[open,refpage='vkQueueSubmit2',desc='Submits command buffers to a queue',type='protos',alias='vkQueueSubmit2KHR']
--

:refpage: vkQueueSubmit2KHR

To submit command buffers to a queue, call:

ifdef::VK_VERSION_1_3[]
include::{generated}/api/protos/vkQueueSubmit2.adoc[]
endif::VK_VERSION_1_3[]

ifdef::VK_VERSION_1_3+VK_KHR_synchronization2[or the equivalent command]

ifdef::VK_KHR_synchronization2[]
include::{generated}/api/protos/vkQueueSubmit2KHR.adoc[]
endif::VK_KHR_synchronization2[]

  * pname:queue is the queue that the command buffers will be submitted to.
  * pname:submitCount is the number of elements in the pname:pSubmits array.
  * pname:pSubmits is a pointer to an array of slink:VkSubmitInfo2
    structures, each specifying a command buffer submission batch.
  * pname:fence is an optional: handle to a fence to be signaled once all
    submitted command buffers have completed execution.
    If pname:fence is not dlink:VK_NULL_HANDLE, it defines a
    <<synchronization-fences-signaling, fence signal operation>>.

fname:vkQueueSubmit2 is a <<devsandqueues-submission,queue submission
command>>, with each batch defined by an element of pname:pSubmits.

Semaphore operations submitted with flink:vkQueueSubmit2 have additional
ordering constraints compared to other submission commands, with
dependencies involving previous and subsequent queue operations.
Information about these additional constraints can be found in the
<<synchronization-semaphores, semaphore>> section of <<synchronization, the
synchronization chapter>>.

If any command buffer submitted to this queue is in the
<<commandbuffers-lifecycle, executable state>>, it is moved to the
<<commandbuffers-lifecycle, pending state>>.
Once execution of all submissions of a command buffer complete, it moves
from the <<commandbuffers-lifecycle, pending state>>, back to the
<<commandbuffers-lifecycle, executable state>>.
If a command buffer was recorded with the
ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT flag, it instead moves
back to the <<commandbuffers-lifecycle, invalid state>>.

If fname:vkQueueSubmit2 fails, it may: return
ename:VK_ERROR_OUT_OF_HOST_MEMORY or ename:VK_ERROR_OUT_OF_DEVICE_MEMORY.
If it does, the implementation must: ensure that the state and contents of
any resources or synchronization primitives referenced by the submitted
command buffers and any semaphores referenced by pname:pSubmits is
unaffected by the call or its failure.
If fname:vkQueueSubmit2 fails in such a way that the implementation is
unable to make that guarantee, the implementation must: return
ename:VK_ERROR_DEVICE_LOST.
See <<devsandqueues-lost-device,Lost Device>>.

include::{chapters}/commonvalidity/no_dynamic_allocations_common.adoc[]

.Valid Usage
****
  * [[VUID-vkQueueSubmit2-fence-04894]]
    If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: be
    unsignaled
  * [[VUID-vkQueueSubmit2-fence-04895]]
    If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: not be
    associated with any other queue command that has not yet completed
    execution on that queue
  * [[VUID-vkQueueSubmit2-synchronization2-03866]]
    The <<features-synchronization2, pname:synchronization2>> feature must:
    be enabled
  * [[VUID-vkQueueSubmit2-commandBuffer-03867]]
    If a command recorded into the pname:commandBuffer member of any element
    of the pname:pCommandBufferInfos member of any element of pname:pSubmits
    referenced an slink:VkEvent, that event must: not be referenced by a
    command that has been submitted to another queue and is still in the
    _pending state_
  * [[VUID-vkQueueSubmit2-semaphore-03868]]
    The pname:semaphore member of any binary semaphore element of the
    pname:pSignalSemaphoreInfos member of any element of pname:pSubmits
    must: be unsignaled when the semaphore signal operation it defines is
    executed on the device
  * [[VUID-vkQueueSubmit2-stageMask-03869]]
    The pname:stageMask member of any element of the
    pname:pSignalSemaphoreInfos member of any element of pname:pSubmits
    must: only include pipeline stages that are supported by the queue
    family which pname:queue belongs to
  * [[VUID-vkQueueSubmit2-stageMask-03870]]
    The pname:stageMask member of any element of the
    pname:pWaitSemaphoreInfos member of any element of pname:pSubmits must:
    only include pipeline stages that are supported by the queue family
    which pname:queue belongs to
  * [[VUID-vkQueueSubmit2-semaphore-03871]]
    When a semaphore wait operation for a binary semaphore is executed, as
    defined by the pname:semaphore member of any element of the
    pname:pWaitSemaphoreInfos member of any element of pname:pSubmits, there
    must: be no other queues waiting on the same semaphore
  * [[VUID-vkQueueSubmit2-semaphore-03873]]
    The pname:semaphore member of any element of the
    pname:pWaitSemaphoreInfos member of any element of pname:pSubmits
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
    that was created with a elink:VkSemaphoreTypeKHR of
    ename:VK_SEMAPHORE_TYPE_BINARY_KHR
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
    must: reference a semaphore signal operation that has been submitted for
    execution and any <<synchronization-semaphores-signaling, semaphore
    signal operations>> on which it depends must: have also been submitted
    for execution
  * [[VUID-vkQueueSubmit2-commandBuffer-03874]]
    The pname:commandBuffer member of any element of the
    pname:pCommandBufferInfos member of any element of pname:pSubmits must:
    be in the <<commandbuffers-lifecycle, pending or executable state>>
  * [[VUID-vkQueueSubmit2-commandBuffer-03875]]
    If a command recorded into the pname:commandBuffer member of any element
    of the pname:pCommandBufferInfos member of any element of pname:pSubmits
    was not recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must: not be in
    the <<commandbuffers-lifecycle, pending state>>
  * [[VUID-vkQueueSubmit2-commandBuffer-03876]]
    Any <<commandbuffers-secondary, secondary command buffers recorded>>
    into the pname:commandBuffer member of any element of the
    pname:pCommandBufferInfos member of any element of pname:pSubmits must:
    be in the <<commandbuffers-lifecycle, pending or executable state>>
  * [[VUID-vkQueueSubmit2-commandBuffer-03877]]
    If any <<commandbuffers-secondary, secondary command buffers recorded>>
    into the pname:commandBuffer member of any element of the
    pname:pCommandBufferInfos member of any element of pname:pSubmits was
    not recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must: not be in
    the <<commandbuffers-lifecycle, pending state>>
  * [[VUID-vkQueueSubmit2-commandBuffer-03878]]
    The pname:commandBuffer member of any element of the
    pname:pCommandBufferInfos member of any element of pname:pSubmits must:
    have been allocated from a sname:VkCommandPool that was created for the
    same queue family pname:queue belongs to
  * [[VUID-vkQueueSubmit2-commandBuffer-03879]]
    If a command recorded into the pname:commandBuffer member of any element
    of the pname:pCommandBufferInfos member of any element of pname:pSubmits
    includes a <<synchronization-queue-transfers-acquire, Queue Family
    Transfer Acquire Operation>>, there must: exist a previously submitted
    <<synchronization-queue-transfers-release, Queue Family Transfer Release
    Operation>> on a queue in the queue family identified by the acquire
    operation, with parameters matching the acquire operation as defined in
    the definition of such <<synchronization-queue-transfers-acquire,
    acquire operations>>, and which happens before the acquire operation
ifdef::VK_KHR_performance_query[]
  * [[VUID-vkQueueSubmit2-commandBuffer-03880]]
    If a command recorded into the pname:commandBuffer member of any element
    of the pname:pCommandBufferInfos member of any element of pname:pSubmits
    was a flink:vkCmdBeginQuery whose pname:queryPool was created with a
    pname:queryType of ename:VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR, the
    <<profiling-lock, profiling lock>> must: have been held continuously on
    the sname:VkDevice that pname:queue was retrieved from, throughout
    recording of those command buffers
endif::VK_KHR_performance_query[]
ifdef::VK_VERSION_1_1[]
  * [[VUID-vkQueueSubmit2-queue-06447]]
    If pname:queue was not created with
    ename:VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, the pname:flags member of
    any element of pname:pSubmits must: not include
    ename:VK_SUBMIT_PROTECTED_BIT_KHR
endif::VK_VERSION_1_1[]
****

include::{generated}/validity/protos/vkQueueSubmit2.adoc[]
--

[open,refpage='VkSubmitInfo2',desc='Structure specifying a queue submit operation',type='structs',alias='VkSubmitInfo2KHR']
--
The sname:VkSubmitInfo2 structure is defined as:

include::{generated}/api/structs/VkSubmitInfo2.adoc[]

ifdef::VK_KHR_synchronization2[]
or the equivalent

include::{generated}/api/structs/VkSubmitInfo2KHR.adoc[]
endif::VK_KHR_synchronization2[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:flags is a bitmask of elink:VkSubmitFlagBits.
  * pname:waitSemaphoreInfoCount is the number of elements in
    pname:pWaitSemaphoreInfos.
  * pname:pWaitSemaphoreInfos is a pointer to an array of
    slink:VkSemaphoreSubmitInfo structures defining
    <<synchronization-semaphores-waiting, semaphore wait operations>>.
  * pname:commandBufferInfoCount is the number of elements in
    pname:pCommandBufferInfos and the number of command buffers to execute
    in the batch.
  * pname:pCommandBufferInfos is a pointer to an array of
    slink:VkCommandBufferSubmitInfo structures describing command buffers to
    execute in the batch.
  * pname:signalSemaphoreInfoCount is the number of elements in
    pname:pSignalSemaphoreInfos.
  * pname:pSignalSemaphoreInfos is a pointer to an array of
    slink:VkSemaphoreSubmitInfo describing
    <<synchronization-semaphores-signaling, semaphore signal operations>>.

.Valid Usage
****
ifdef::VK_KHR_timeline_semaphore[]
  * [[VUID-VkSubmitInfo2-semaphore-03881]]
    If the same semaphore is used as the pname:semaphore member of both an
    element of pname:pSignalSemaphoreInfos and pname:pWaitSemaphoreInfos,
    and that semaphore is a timeline semaphore, the pname:value member of
    the pname:pSignalSemaphoreInfos element must: be greater than the
    pname:value member of the pname:pWaitSemaphoreInfos element
  * [[VUID-VkSubmitInfo2-semaphore-03882]]
    If the pname:semaphore member of any element of
    pname:pSignalSemaphoreInfos is a timeline semaphore, the pname:value
    member of that element must: have a value greater than the current value
    of the semaphore when the <<synchronization-semaphores-signaling,
    semaphore signal operation>> is executed
  * [[VUID-VkSubmitInfo2-semaphore-03883]]
    If the pname:semaphore member of any element of
    pname:pSignalSemaphoreInfos is a timeline semaphore, the pname:value
    member of that element must: have a value which does not differ from the
    current value of the semaphore or the value of any outstanding semaphore
    wait or signal operation on that semaphore by more than
    <<limits-maxTimelineSemaphoreValueDifference,
    pname:maxTimelineSemaphoreValueDifference>>
  * [[VUID-VkSubmitInfo2-semaphore-03884]]
    If the pname:semaphore member of any element of
    pname:pWaitSemaphoreInfos is a timeline semaphore, the pname:value
    member of that element must: have a value which does not differ from the
    current value of the semaphore or the value of any outstanding semaphore
    wait or signal operation on that semaphore by more than
    <<limits-maxTimelineSemaphoreValueDifference,
    pname:maxTimelineSemaphoreValueDifference>>
endif::VK_KHR_timeline_semaphore[]
ifdef::VK_VERSION_1_1[]
  * [[VUID-VkSubmitInfo2-flags-03886]]
    If pname:flags includes ename:VK_SUBMIT_PROTECTED_BIT, all elements of
    pname:pCommandBuffers must: be protected command buffers
  * [[VUID-VkSubmitInfo2-flags-03887]]
    If pname:flags does not include ename:VK_SUBMIT_PROTECTED_BIT, each
    element of pname:pCommandBuffers must: not be a protected command buffer
endif::VK_VERSION_1_1[]
ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
  * [[VUID-VkSubmitInfo2KHR-commandBuffer-06192]]
    If any pname:commandBuffer member of an element of
    pname:pCommandBufferInfos contains any <<renderpass-suspension,resumed
    render pass instances>>, they must: be suspended by a render pass
    instance earlier in submission order within pname:pCommandBufferInfos
  * [[VUID-VkSubmitInfo2KHR-commandBuffer-06010]]
    If any pname:commandBuffer member of an element of
    pname:pCommandBufferInfos contains any <<renderpass-suspension,suspended
    render pass instances>>, they must: be resumed by a render pass instance
    later in submission order within pname:pCommandBufferInfos
  * [[VUID-VkSubmitInfo2KHR-commandBuffer-06011]]
    If any pname:commandBuffer member of an element of
    pname:pCommandBufferInfos contains any <<renderpass-suspension,suspended
    render pass instances>>, there must: be no action or synchronization
    commands between that render pass instance and the render pass instance
    that resumes it
  * [[VUID-VkSubmitInfo2KHR-commandBuffer-06012]]
    If any pname:commandBuffer member of an element of
    pname:pCommandBufferInfos contains any <<renderpass-suspension,suspended
    render pass instances>>, there must: be no render pass instances between
    that render pass instance and the render pass instance that resumes it
ifdef::VK_EXT_sample_locations[]
  * [[VUID-VkSubmitInfo2KHR-variableSampleLocations-06013]]
    If the <<limits-variableSampleLocations, pname:variableSampleLocations>>
    limit is not supported, and any pname:commandBuffer member of an element
    of pname:pCommandBufferInfos contains any <<renderpass-suspension,
    suspended render pass instances>>, where a graphics pipeline has been
    bound, any pipelines bound in the render pass instance that resumes it,
    or any subsequent render pass instances that resume from that one and so
    on, must: use the same sample locations
endif::VK_EXT_sample_locations[]
endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
****

include::{generated}/validity/structs/VkSubmitInfo2.adoc[]
--

[open,refpage='VkSubmitFlagBits',desc='Bitmask specifying behavior of a submission',type='enums',alias='VkSubmitFlagBitsKHR']
--
Bits which can: be set in slink:VkSubmitInfo2::pname:flags, specifying
submission behavior, are:

include::{generated}/api/enums/VkSubmitFlagBits.adoc[]

ifdef::VK_KHR_synchronization2[]
or the equivalent

include::{generated}/api/enums/VkSubmitFlagBitsKHR.adoc[]
endif::VK_KHR_synchronization2[]

  * ename:VK_SUBMIT_PROTECTED_BIT specifies that this batch is a protected
    submission.
--

[open,refpage='VkSubmitFlags',desc='Bitmask of VkSubmitFlagBits',type='flags',alias='VkSubmitFlagsKHR']
--
include::{generated}/api/flags/VkSubmitFlags.adoc[]

ifdef::VK_KHR_synchronization2[]
or the equivalent

include::{generated}/api/flags/VkSubmitFlagsKHR.adoc[]
endif::VK_KHR_synchronization2[]

tname:VkSubmitFlags is a bitmask type for setting a mask of zero or more
elink:VkSubmitFlagBits.
--

[open,refpage='VkSemaphoreSubmitInfo',desc='Structure specifying a semaphore signal or wait operation',type='structs',alias='VkSemaphoreSubmitInfoKHR']
--
:refpage: VkSemaphoreSubmitInfo

The sname:VkSemaphoreSubmitInfo structure is defined as:

include::{generated}/api/structs/VkSemaphoreSubmitInfo.adoc[]

ifdef::VK_KHR_synchronization2[]
or the equivalent

include::{generated}/api/structs/VkSemaphoreSubmitInfoKHR.adoc[]
endif::VK_KHR_synchronization2[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:semaphore is a slink:VkSemaphore affected by this operation.
  * pname:value is
ifdef::VK_KHR_timeline_semaphore[]
    either the value used to signal pname:semaphore or the value waited on
    by pname:semaphore, if pname:semaphore is a timeline semaphore.
    Otherwise it is
endif::VK_KHR_timeline_semaphore[]
    ignored.
  * pname:stageMask is a tlink:VkPipelineStageFlags2 mask of pipeline stages
    which limit the first synchronization scope of a semaphore signal
    operation, or second synchronization scope of a semaphore wait operation
    as described in the <<synchronization-semaphores-waiting, semaphore wait
    operation>> and <<synchronization-semaphores-signaling, semaphore signal
    operation>> sections of <<synchronization, the synchronization
    chapter>>.
  * pname:deviceIndex is the index of the device within a device group that
    executes the semaphore wait or signal operation.

Whether this structure defines a semaphore wait or signal operation is
defined by how it is used.

.Valid Usage
****
:stageMaskName: stageMask
include::{chapters}/commonvalidity/stage_mask_2_common.adoc[]
  * [[VUID-VkSemaphoreSubmitInfo-device-03888]]
    If the pname:device that pname:semaphore was created on is not a device
    group, pname:deviceIndex must: be `0`
ifdef::VK_KHR_device_group_creation,VK_VERSION_1_1[]
  * [[VUID-VkSemaphoreSubmitInfo-device-03889]]
    If the pname:device that pname:semaphore was created on is a device
    group, pname:deviceIndex must: be a valid device index
endif::VK_KHR_device_group_creation,VK_VERSION_1_1[]
ifdef::VK_NV_external_sci_sync,VK_NV_external_sci_sync2[]
  * [[VUID-VkSemaphoreSubmitInfoKHR-semaphore-05094]]
    If pname:semaphore has a payload of stext:NvSciSyncObj, pname:value
    must: be calculated by application via <<NvSciSync-extension-page,
    NvSciSync APIs>>.
endif::VK_NV_external_sci_sync,VK_NV_external_sci_sync2[]

****

include::{generated}/validity/structs/VkSemaphoreSubmitInfo.adoc[]
--

[open,refpage='VkCommandBufferSubmitInfo',desc='Structure specifying a command buffer submission',type='structs',alias='VkCommandBufferSubmitInfoKHR']
--
The sname:VkCommandBufferSubmitInfo structure is defined as:

include::{generated}/api/structs/VkCommandBufferSubmitInfo.adoc[]

ifdef::VK_KHR_synchronization2[]
or the equivalent

include::{generated}/api/structs/VkCommandBufferSubmitInfoKHR.adoc[]
endif::VK_KHR_synchronization2[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:commandBuffer is a slink:VkCommandBuffer to be submitted for
    execution.
  * pname:deviceMask is a bitmask indicating which devices in a device group
    execute the command buffer.
    A pname:deviceMask of `0` is equivalent to setting all bits
    corresponding to valid devices in the group to `1`.

.Valid Usage
****
  * [[VUID-VkCommandBufferSubmitInfo-commandBuffer-03890]]
    pname:commandBuffer must: not have been allocated with
    ename:VK_COMMAND_BUFFER_LEVEL_SECONDARY
ifdef::VK_KHR_device_group_creation,VK_VERSION_1_1[]
  * [[VUID-VkCommandBufferSubmitInfo-deviceMask-03891]]
    If pname:deviceMask is not `0`, it must: be a valid device mask
endif::VK_KHR_device_group_creation,VK_VERSION_1_1[]
ifdef::VK_ARM_render_pass_striped[]
  * [[VUID-VkCommandBufferSubmitInfo-commandBuffer-09445]]
    If any render pass instance in pname:commandBuffer was recorded with a
    slink:VkRenderPassStripeBeginInfoARM structure in its pNext chain, a
    slink:VkRenderPassStripeSubmitInfoARM must: be included in the
    pname:pNext chain
  * [[VUID-VkCommandBufferSubmitInfo-pNext-09446]]
    If a slink:VkRenderPassStripeSubmitInfoARM is included in the
    pname:pNext chain, the value of
    slink:VkRenderPassStripeSubmitInfoARM::pname:stripeSemaphoreInfoCount
    must: be equal to the sum of the
    slink:VkRenderPassStripeBeginInfoARM::pname:stripeInfoCount parameters
    provided to render pass instances recorded in pname:commandBuffer
endif::VK_ARM_render_pass_striped[]
****

include::{generated}/validity/structs/VkCommandBufferSubmitInfo.adoc[]
--
endif::VK_VERSION_1_3,VK_KHR_synchronization2[]

ifdef::VK_ARM_render_pass_striped[]
[open,refpage='VkRenderPassStripeSubmitInfoARM',desc='Structure specifying striped rendering submit information',type='structs']
--
The sname:VkRenderPassStripeSubmitInfoARM structure is defined as:

include::{generated}/api/structs/VkRenderPassStripeSubmitInfoARM.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:stripeSemaphoreInfoCount is the number of semaphores used to
    signal stripe completion in the render pass instances in the submitted
    command buffer.
  * pname:pStripeSemaphoreInfos is a pointer to an array of
    pname:stripeSemaphoreInfoCount slink:VkSemaphoreSubmitInfo structures
    describing the semaphores used to signal stripe completion.

This structure can be included in the pname:pNext chain of
slink:VkCommandBufferSubmitInfo to provide a set of semaphores to be
signaled for each striped render pass instance.

The elements of pname:pStripeSemaphoreInfos are mapped to render pass
instances in slink:VkCommandBufferSubmitInfo::pname:commandBuffer in
submission order and in stripe order within each render pass instance.
Each semaphore in pname:pStripeSemaphoreInfos is signaled when the
implementation has completed execution of the associated stripe.
In a render pass instance that has multiview enabled, the stripe includes
all views in the view mask.
In a render pass instance with pname:layerCount greater than 1, the stripe
includes all layers.

.Valid Usage
****
  * [[VUID-VkRenderPassStripeSubmitInfoARM-semaphore-09447]]
    The pname:semaphore member of each element of
    pname:pStripeSemaphoreInfos must: have been created with a
    elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY
****

include::{generated}/validity/structs/VkRenderPassStripeSubmitInfoARM.adoc[]
--
endif::VK_ARM_render_pass_striped[]

[open,refpage='vkQueueSubmit',desc='Submits a sequence of semaphores or command buffers to a queue',type='protos']
--

:refpage: vkQueueSubmit

To submit command buffers to a queue, call:

include::{generated}/api/protos/vkQueueSubmit.adoc[]

  * pname:queue is the queue that the command buffers will be submitted to.
  * pname:submitCount is the number of elements in the pname:pSubmits array.
  * pname:pSubmits is a pointer to an array of slink:VkSubmitInfo
    structures, each specifying a command buffer submission batch.
  * pname:fence is an optional: handle to a fence to be signaled once all
    submitted command buffers have completed execution.
    If pname:fence is not dlink:VK_NULL_HANDLE, it defines a
    <<synchronization-fences-signaling, fence signal operation>>.

fname:vkQueueSubmit is a <<devsandqueues-submission,queue submission
command>>, with each batch defined by an element of pname:pSubmits.
Batches begin execution in the order they appear in pname:pSubmits, but may:
complete out of order.

Fence and semaphore operations submitted with flink:vkQueueSubmit have
additional ordering constraints compared to other submission commands, with
dependencies involving previous and subsequent queue operations.
Information about these additional constraints can be found in the
<<synchronization-semaphores, semaphore>> and <<synchronization-fences,
fence>> sections of <<synchronization, the synchronization chapter>>.

Details on the interaction of pname:pWaitDstStageMask with synchronization
are described in the <<synchronization-semaphores-waiting, semaphore wait
operation>> section of <<synchronization, the synchronization chapter>>.

The order that batches appear in pname:pSubmits is used to determine
<<synchronization-submission-order, submission order>>, and thus all the
<<synchronization-implicit, implicit ordering guarantees>> that respect it.
Other than these implicit ordering guarantees and any <<synchronization,
explicit synchronization primitives>>, these batches may: overlap or
otherwise execute out of order.

If any command buffer submitted to this queue is in the
<<commandbuffers-lifecycle, executable state>>, it is moved to the
<<commandbuffers-lifecycle, pending state>>.
Once execution of all submissions of a command buffer complete, it moves
from the <<commandbuffers-lifecycle, pending state>>, back to the
<<commandbuffers-lifecycle, executable state>>.
If a command buffer was recorded with the
ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT flag, it instead moves to
the <<commandbuffers-lifecycle, invalid state>>.

If fname:vkQueueSubmit fails, it may: return
ename:VK_ERROR_OUT_OF_HOST_MEMORY or ename:VK_ERROR_OUT_OF_DEVICE_MEMORY.
If it does, the implementation must: ensure that the state and contents of
any resources or synchronization primitives referenced by the submitted
command buffers and any semaphores referenced by pname:pSubmits is
unaffected by the call or its failure.
If fname:vkQueueSubmit fails in such a way that the implementation is unable
to make that guarantee, the implementation must: return
ename:VK_ERROR_DEVICE_LOST.
See <<devsandqueues-lost-device,Lost Device>>.

include::{chapters}/commonvalidity/no_dynamic_allocations_common.adoc[]

.Valid Usage
****
  * [[VUID-vkQueueSubmit-fence-00063]]
    If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: be
    unsignaled
  * [[VUID-vkQueueSubmit-fence-00064]]
    If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: not be
    associated with any other queue command that has not yet completed
    execution on that queue
  * [[VUID-vkQueueSubmit-pCommandBuffers-00065]]
    Any calls to flink:vkCmdSetEvent, flink:vkCmdResetEvent or
    flink:vkCmdWaitEvents that have been recorded into any of the command
    buffer elements of the pname:pCommandBuffers member of any element of
    pname:pSubmits, must: not reference any slink:VkEvent that is referenced
    by any of those commands in a command buffer that has been submitted to
    another queue and is still in the _pending state_
  * [[VUID-vkQueueSubmit-pWaitDstStageMask-00066]]
    Any stage flag included in any element of the pname:pWaitDstStageMask
    member of any element of pname:pSubmits must: be a pipeline stage
    supported by one of the capabilities of pname:queue, as specified in the
    <<synchronization-pipeline-stages-supported, table of supported pipeline
    stages>>
  * [[VUID-vkQueueSubmit-pSignalSemaphores-00067]]
    Each binary semaphore element of the pname:pSignalSemaphores member of
    any element of pname:pSubmits must: be unsignaled when the semaphore
    signal operation it defines is executed on the device
  * [[VUID-vkQueueSubmit-pWaitSemaphores-00068]]
    When a semaphore wait operation referring to a binary semaphore defined
    by any element of the pname:pWaitSemaphores member of any element of
    pname:pSubmits executes on pname:queue, there must: be no other queues
    waiting on the same semaphore
  * [[VUID-vkQueueSubmit-pWaitSemaphores-03238]]
    All elements of the pname:pWaitSemaphores member of all elements of
    pname:pSubmits
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
    created with a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
    must: reference a semaphore signal operation that has been submitted for
    execution and any <<synchronization-semaphores-signaling, semaphore
    signal operations>> on which it depends must: have also been submitted
    for execution
  * [[VUID-vkQueueSubmit-pCommandBuffers-00070]]
    Each element of the pname:pCommandBuffers member of each element of
    pname:pSubmits must: be in the <<commandbuffers-lifecycle, pending or
    executable state>>
  * [[VUID-vkQueueSubmit-pCommandBuffers-00071]]
    If any element of the pname:pCommandBuffers member of any element of
    pname:pSubmits was not recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must: not be in
    the <<commandbuffers-lifecycle, pending state>>
  * [[VUID-vkQueueSubmit-pCommandBuffers-00072]]
    Any <<commandbuffers-secondary, secondary command buffers recorded>>
    into any element of the pname:pCommandBuffers member of any element of
    pname:pSubmits must: be in the <<commandbuffers-lifecycle, pending or
    executable state>>
  * [[VUID-vkQueueSubmit-pCommandBuffers-00073]]
    If any <<commandbuffers-secondary, secondary command buffers recorded>>
    into any element of the pname:pCommandBuffers member of any element of
    pname:pSubmits was not recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must: not be in
    the <<commandbuffers-lifecycle, pending state>>
  * [[VUID-vkQueueSubmit-pCommandBuffers-00074]]
    Each element of the pname:pCommandBuffers member of each element of
    pname:pSubmits must: have been allocated from a sname:VkCommandPool that
    was created for the same queue family pname:queue belongs to
  * [[VUID-vkQueueSubmit-pSubmits-02207]]
    If any element of pname:pSubmits->pCommandBuffers includes a
    <<synchronization-queue-transfers-acquire, Queue Family Transfer Acquire
    Operation>>, there must: exist a previously submitted
    <<synchronization-queue-transfers-release, Queue Family Transfer Release
    Operation>> on a queue in the queue family identified by the acquire
    operation, with parameters matching the acquire operation as defined in
    the definition of such <<synchronization-queue-transfers-acquire,
    acquire operations>>, and which happens-before the acquire operation
ifdef::VK_KHR_performance_query[]
  * [[VUID-vkQueueSubmit-pCommandBuffers-03220]]
    If a command recorded into any element of pname:pCommandBuffers was a
    flink:vkCmdBeginQuery whose pname:queryPool was created with a
    pname:queryType of ename:VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR, the
    <<profiling-lock, profiling lock>> must: have been held continuously on
    the sname:VkDevice that pname:queue was retrieved from, throughout
    recording of those command buffers
endif::VK_KHR_performance_query[]
  * [[VUID-vkQueueSubmit-pSubmits-02808]]
    Any resource created with ename:VK_SHARING_MODE_EXCLUSIVE that is read
    by an operation specified by pname:pSubmits must: not be owned by any
    queue family other than the one which pname:queue belongs to, at the
    time it is executed
  * [[VUID-vkQueueSubmit-pSubmits-04626]]
    Any resource created with ename:VK_SHARING_MODE_CONCURRENT that is
    accessed by an operation specified by pname:pSubmits must: have included
    the queue family of pname:queue at resource creation time
ifdef::VK_VERSION_1_1[]
  * [[VUID-vkQueueSubmit-queue-06448]]
    If pname:queue was not created with
    ename:VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, there must: be no element of
    pname:pSubmits that includes an slink:VkProtectedSubmitInfo structure in
    its pname:pNext chain with pname:protectedSubmit equal to ename:VK_TRUE
endif::VK_VERSION_1_1[]
****

include::{generated}/validity/protos/vkQueueSubmit.adoc[]
--

[open,refpage='VkSubmitInfo',desc='Structure specifying a queue submit operation',type='structs']
--
:refpage: VkSubmitInfo
The sname:VkSubmitInfo structure is defined as:

include::{generated}/api/structs/VkSubmitInfo.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:waitSemaphoreCount is the number of semaphores upon which to wait
    before executing the command buffers for the batch.
  * pname:pWaitSemaphores is a pointer to an array of slink:VkSemaphore
    handles upon which to wait before the command buffers for this batch
    begin execution.
    If semaphores to wait on are provided, they define a
    <<synchronization-semaphores-waiting, semaphore wait operation>>.
  * pname:pWaitDstStageMask is a pointer to an array of pipeline stages at
    which each corresponding semaphore wait will occur.
  * pname:commandBufferCount is the number of command buffers to execute in
    the batch.
  * pname:pCommandBuffers is a pointer to an array of slink:VkCommandBuffer
    handles to execute in the batch.
  * pname:signalSemaphoreCount is the number of semaphores to be signaled
    once the commands specified in pname:pCommandBuffers have completed
    execution.
  * pname:pSignalSemaphores is a pointer to an array of slink:VkSemaphore
    handles which will be signaled when the command buffers for this batch
    have completed execution.
    If semaphores to be signaled are provided, they define a
    <<synchronization-semaphores-signaling, semaphore signal operation>>.

The order that command buffers appear in pname:pCommandBuffers is used to
determine <<synchronization-submission-order, submission order>>, and thus
all the <<synchronization-implicit, implicit ordering guarantees>> that
respect it.
Other than these implicit ordering guarantees and any <<synchronization,
explicit synchronization primitives>>, these command buffers may: overlap or
otherwise execute out of order.


.Valid Usage
****
:stageMaskName: pWaitDstStageMask
include::{chapters}/commonvalidity/stage_mask_common.adoc[]

  * [[VUID-VkSubmitInfo-pCommandBuffers-00075]]
    Each element of pname:pCommandBuffers must: not have been allocated with
    ename:VK_COMMAND_BUFFER_LEVEL_SECONDARY
  * [[VUID-VkSubmitInfo-pWaitDstStageMask-00078]]
    Each element of pname:pWaitDstStageMask must: not include
    ename:VK_PIPELINE_STAGE_HOST_BIT
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
  * [[VUID-VkSubmitInfo-pWaitSemaphores-03239]]
    If any element of pname:pWaitSemaphores or pname:pSignalSemaphores was
    created with a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_TIMELINE, then the pname:pNext chain must:
    include a slink:VkTimelineSemaphoreSubmitInfo structure
  * [[VUID-VkSubmitInfo-pNext-03240]]
    If the pname:pNext chain of this structure includes a
    slink:VkTimelineSemaphoreSubmitInfo structure and any element of
    pname:pWaitSemaphores was created with a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_TIMELINE, then its pname:waitSemaphoreValueCount
    member must: equal pname:waitSemaphoreCount
  * [[VUID-VkSubmitInfo-pNext-03241]]
    If the pname:pNext chain of this structure includes a
    slink:VkTimelineSemaphoreSubmitInfo structure and any element of
    pname:pSignalSemaphores was created with a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_TIMELINE, then its
    pname:signalSemaphoreValueCount member must: equal
    pname:signalSemaphoreCount
  * [[VUID-VkSubmitInfo-pSignalSemaphores-03242]]
    For each element of pname:pSignalSemaphores created with a
    elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE the
    corresponding element of
    slink:VkTimelineSemaphoreSubmitInfo::pname:pSignalSemaphoreValues must:
    have a value greater than the current value of the semaphore when the
    <<synchronization-semaphores-signaling,semaphore signal operation>> is
    executed
  * [[VUID-VkSubmitInfo-pWaitSemaphores-03243]]
    For each element of pname:pWaitSemaphores created with a
    elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE the
    corresponding element of
    slink:VkTimelineSemaphoreSubmitInfo::pname:pWaitSemaphoreValues must:
    have a value which does not differ from the current value of the
    semaphore or the value of any outstanding semaphore wait or signal
    operation on that semaphore by more than
    <<limits-maxTimelineSemaphoreValueDifference,
    pname:maxTimelineSemaphoreValueDifference>>
  * [[VUID-VkSubmitInfo-pSignalSemaphores-03244]]
    For each element of pname:pSignalSemaphores created with a
    elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE the
    corresponding element of
    slink:VkTimelineSemaphoreSubmitInfo::pname:pSignalSemaphoreValues must:
    have a value which does not differ from the current value of the
    semaphore or the value of any outstanding semaphore wait or signal
    operation on that semaphore by more than
    <<limits-maxTimelineSemaphoreValueDifference,
    pname:maxTimelineSemaphoreValueDifference>>
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
ifdef::VK_VERSION_1_1[]
  * [[VUID-VkSubmitInfo-pNext-04120]]
    If the pname:pNext chain of this structure does not include a
    sname:VkProtectedSubmitInfo structure with pname:protectedSubmit set to
    ename:VK_TRUE, then each element of the pname:pCommandBuffers array
    must: be an unprotected command buffer
  * [[VUID-VkSubmitInfo-pNext-04148]]
    If the pname:pNext chain of this structure includes a
    sname:VkProtectedSubmitInfo structure with pname:protectedSubmit set to
    ename:VK_TRUE, then each element of the pname:pCommandBuffers array
    must: be a protected command buffer
endif::VK_VERSION_1_1[]
ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
  * [[VUID-VkSubmitInfo-pCommandBuffers-06193]]
    If pname:pCommandBuffers contains any <<renderpass-suspension,resumed
    render pass instances>>, they must: be suspended by a render pass
    instance earlier in submission order within pname:pCommandBuffers
  * [[VUID-VkSubmitInfo-pCommandBuffers-06014]]
    If pname:pCommandBuffers contains any <<renderpass-suspension,suspended
    render pass instances>>, they must: be resumed by a render pass instance
    later in submission order within pname:pCommandBuffers
  * [[VUID-VkSubmitInfo-pCommandBuffers-06015]]
    If pname:pCommandBuffers contains any <<renderpass-suspension,suspended
    render pass instances>>, there must: be no action or synchronization
    commands executed in a primary or <<commandbuffers-secondary,
    secondary>> command buffer between that render pass instance and the
    render pass instance that resumes it
  * [[VUID-VkSubmitInfo-pCommandBuffers-06016]]
    If pname:pCommandBuffers contains any <<renderpass-suspension,suspended
    render pass instances>>, there must: be no render pass instances between
    that render pass instance and the render pass instance that resumes it
ifdef::VK_EXT_sample_locations[]
  * [[VUID-VkSubmitInfo-variableSampleLocations-06017]]
    If the <<limits-variableSampleLocations, pname:variableSampleLocations>>
    limit is not supported, and any element of pname:pCommandBuffers
    contains any <<renderpass-suspension, suspended render pass instances>>,
    where a graphics pipeline has been bound, any pipelines bound in the
    render pass instance that resumes it, or any subsequent render pass
    instances that resume from that one and so on, must: use the same sample
    locations
endif::VK_EXT_sample_locations[]
endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
****

include::{generated}/validity/structs/VkSubmitInfo.adoc[]
--

ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
[open,refpage='VkTimelineSemaphoreSubmitInfo',desc='Structure specifying signal and wait values for timeline semaphores',type='structs',alias='VkTimelineSemaphoreSubmitInfoKHR']
--
To specify the values to use when waiting for and signaling semaphores
created with a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE,
add a slink:VkTimelineSemaphoreSubmitInfo structure to the pname:pNext chain
of the slink:VkSubmitInfo structure when using flink:vkQueueSubmit
ifndef::VKSC_VERSION_1_0[or the slink:VkBindSparseInfo structure when using flink:vkQueueBindSparse]
.
The sname:VkTimelineSemaphoreSubmitInfo structure is defined as:

include::{generated}/api/structs/VkTimelineSemaphoreSubmitInfo.adoc[]

ifdef::VK_KHR_timeline_semaphore[]
or the equivalent

include::{generated}/api/structs/VkTimelineSemaphoreSubmitInfoKHR.adoc[]
endif::VK_KHR_timeline_semaphore[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:waitSemaphoreValueCount is the number of semaphore wait values
    specified in pname:pWaitSemaphoreValues.
  * pname:pWaitSemaphoreValues is a pointer to an array of
    pname:waitSemaphoreValueCount values for the corresponding semaphores in
    slink:VkSubmitInfo::pname:pWaitSemaphores to wait for.
  * pname:signalSemaphoreValueCount is the number of semaphore signal values
    specified in pname:pSignalSemaphoreValues.
  * pname:pSignalSemaphoreValues is a pointer to an array
    pname:signalSemaphoreValueCount values for the corresponding semaphores
    in slink:VkSubmitInfo::pname:pSignalSemaphores to set when signaled.

If the semaphore in slink:VkSubmitInfo::pname:pWaitSemaphores or
slink:VkSubmitInfo::pname:pSignalSemaphores corresponding to an entry in
pname:pWaitSemaphoreValues or pname:pSignalSemaphoreValues respectively was
not created with a elink:VkSemaphoreType of
ename:VK_SEMAPHORE_TYPE_TIMELINE, the implementation must: ignore the value
in the pname:pWaitSemaphoreValues or pname:pSignalSemaphoreValues entry.

ifdef::VK_NV_external_sci_sync,VK_NV_external_sci_sync2[]
If the semaphore in slink:VkSubmitInfo::pname:pWaitSemaphores or
slink:VkSubmitInfo::pname:pSignalSemaphores corresponding to an entry in
pname:pWaitSemaphoreValues or pname:pSignalSemaphoreValues respectively was
created with a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_TIMELINE,
and has stext:NvSciSyncObj as the payload, the value in the
pname:pWaitSemaphoreValues or pname:pSignalSemaphoreValues entry must: be
calculated by application via <<NvSciSync-extension-page, NvSciSync APIs>>.
endif::VK_NV_external_sci_sync,VK_NV_external_sci_sync2[]

include::{generated}/validity/structs/VkTimelineSemaphoreSubmitInfo.adoc[]
--
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]

ifdef::VK_KHR_external_semaphore_win32[]
[open,refpage='VkD3D12FenceSubmitInfoKHR',desc='Structure specifying values for Direct3D 12 fence-backed semaphores',type='structs']
--
To specify the values to use when waiting for and signaling semaphores whose
<<synchronization-semaphores-importing,current payload>> refers to a
Direct3D 12 fence, add a slink:VkD3D12FenceSubmitInfoKHR structure to the
pname:pNext chain of the slink:VkSubmitInfo structure.
The sname:VkD3D12FenceSubmitInfoKHR structure is defined as:

include::{generated}/api/structs/VkD3D12FenceSubmitInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:waitSemaphoreValuesCount is the number of semaphore wait values
    specified in pname:pWaitSemaphoreValues.
  * pname:pWaitSemaphoreValues is a pointer to an array of
    pname:waitSemaphoreValuesCount values for the corresponding semaphores
    in slink:VkSubmitInfo::pname:pWaitSemaphores to wait for.
  * pname:signalSemaphoreValuesCount is the number of semaphore signal
    values specified in pname:pSignalSemaphoreValues.
  * pname:pSignalSemaphoreValues is a pointer to an array of
    pname:signalSemaphoreValuesCount values for the corresponding semaphores
    in slink:VkSubmitInfo::pname:pSignalSemaphores to set when signaled.

If the semaphore in slink:VkSubmitInfo::pname:pWaitSemaphores or
slink:VkSubmitInfo::pname:pSignalSemaphores corresponding to an entry in
pname:pWaitSemaphoreValues or pname:pSignalSemaphoreValues respectively does
not currently have a <<synchronization-semaphores-payloads, payload>>
referring to a Direct3D 12 fence, the implementation must: ignore the value
in the pname:pWaitSemaphoreValues or pname:pSignalSemaphoreValues entry.

ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
[NOTE]
.Note
====
As the introduction of the external semaphore handle type
ename:VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT predates that of
timeline semaphores, support for importing semaphore payloads from external
handles of that type into semaphores created (implicitly or explicitly) with
a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY is preserved for
backwards compatibility.
However, applications should: prefer importing such handle types into
semaphores created with a elink:VkSemaphoreType of
ename:VK_SEMAPHORE_TYPE_TIMELINE, and use the
slink:VkTimelineSemaphoreSubmitInfo structure instead of the
sname:VkD3D12FenceSubmitInfoKHR structure to specify the values to use when
waiting for and signaling such semaphores.
====
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]

.Valid Usage
****
  * [[VUID-VkD3D12FenceSubmitInfoKHR-waitSemaphoreValuesCount-00079]]
    pname:waitSemaphoreValuesCount must: be the same value as
    sname:VkSubmitInfo::pname:waitSemaphoreCount, where this structure is in
    the pname:pNext chain of a sname:VkSubmitInfo structure
  * [[VUID-VkD3D12FenceSubmitInfoKHR-signalSemaphoreValuesCount-00080]]
    pname:signalSemaphoreValuesCount must: be the same value as
    sname:VkSubmitInfo::pname:signalSemaphoreCount, where this structure is
    in the pname:pNext chain of a sname:VkSubmitInfo structure
****

include::{generated}/validity/structs/VkD3D12FenceSubmitInfoKHR.adoc[]
--
endif::VK_KHR_external_semaphore_win32[]

ifdef::VK_KHR_win32_keyed_mutex[]
[open,refpage='VkWin32KeyedMutexAcquireReleaseInfoKHR',desc='Use the Windows keyed mutex mechanism to synchronize work',type='structs']
--
When submitting work that operates on memory imported from a Direct3D 11
resource to a queue, the keyed mutex mechanism may: be used in addition to
Vulkan semaphores to synchronize the work.
Keyed mutexes are a property of a properly created shareable Direct3D 11
resource.
They can: only be used if the imported resource was created with the
etext:D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX flag.

To acquire keyed mutexes before submitted work and/or release them after,
add a slink:VkWin32KeyedMutexAcquireReleaseInfoKHR structure to the
pname:pNext chain of the slink:VkSubmitInfo structure.

The sname:VkWin32KeyedMutexAcquireReleaseInfoKHR structure is defined as:

include::{generated}/api/structs/VkWin32KeyedMutexAcquireReleaseInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:acquireCount is the number of entries in the pname:pAcquireSyncs,
    pname:pAcquireKeys, and pname:pAcquireTimeouts arrays.
  * pname:pAcquireSyncs is a pointer to an array of slink:VkDeviceMemory
    objects which were imported from Direct3D 11 resources.
  * pname:pAcquireKeys is a pointer to an array of mutex key values to wait
    for prior to beginning the submitted work.
    Entries refer to the keyed mutex associated with the corresponding
    entries in pname:pAcquireSyncs.
  * pname:pAcquireTimeouts is a pointer to an array of timeout values, in
    millisecond units, for each acquire specified in pname:pAcquireKeys.
  * pname:releaseCount is the number of entries in the pname:pReleaseSyncs
    and pname:pReleaseKeys arrays.
  * pname:pReleaseSyncs is a pointer to an array of slink:VkDeviceMemory
    objects which were imported from Direct3D 11 resources.
  * pname:pReleaseKeys is a pointer to an array of mutex key values to set
    when the submitted work has completed.
    Entries refer to the keyed mutex associated with the corresponding
    entries in pname:pReleaseSyncs.

.Valid Usage
****
  * [[VUID-VkWin32KeyedMutexAcquireReleaseInfoKHR-pAcquireSyncs-00081]]
    Each member of pname:pAcquireSyncs and pname:pReleaseSyncs must: be a
    device memory object imported by setting
    slink:VkImportMemoryWin32HandleInfoKHR::pname:handleType to
    ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT or
    ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT
****

include::{generated}/validity/structs/VkWin32KeyedMutexAcquireReleaseInfoKHR.adoc[]
--
endif::VK_KHR_win32_keyed_mutex[]

ifdef::VK_NV_win32_keyed_mutex[]
include::{chapters}/VK_NV_win32_keyed_mutex/keyed_mutex_submit.adoc[]
endif::VK_NV_win32_keyed_mutex[]

ifdef::VK_VERSION_1_1[]
[open,refpage='VkProtectedSubmitInfo',desc='Structure indicating whether the submission is protected',type='structs']
--
If the pname:pNext chain of slink:VkSubmitInfo includes a
sname:VkProtectedSubmitInfo structure, then the structure indicates whether
the batch is protected.
The sname:VkProtectedSubmitInfo structure is defined as:

include::{generated}/api/structs/VkProtectedSubmitInfo.adoc[]

  * pname:protectedSubmit specifies whether the batch is protected.
    If pname:protectedSubmit is ename:VK_TRUE, the batch is protected.
    If pname:protectedSubmit is ename:VK_FALSE, the batch is unprotected.
    If the sname:VkSubmitInfo::pname:pNext chain does not include this
    structure, the batch is unprotected.

include::{generated}/validity/structs/VkProtectedSubmitInfo.adoc[]
--
endif::VK_VERSION_1_1[]

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
[open,refpage='VkDeviceGroupSubmitInfo',desc='Structure indicating which physical devices execute semaphore operations and command buffers',type='structs']
--
If the pname:pNext chain of slink:VkSubmitInfo includes a
sname:VkDeviceGroupSubmitInfo structure, then that structure includes device
indices and masks specifying which physical devices execute semaphore
operations and command buffers.

The sname:VkDeviceGroupSubmitInfo structure is defined as:

include::{generated}/api/structs/VkDeviceGroupSubmitInfo.adoc[]

ifdef::VK_KHR_device_group[]
or the equivalent

include::{generated}/api/structs/VkDeviceGroupSubmitInfoKHR.adoc[]
endif::VK_KHR_device_group[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:waitSemaphoreCount is the number of elements in the
    pname:pWaitSemaphoreDeviceIndices array.
  * pname:pWaitSemaphoreDeviceIndices is a pointer to an array of
    pname:waitSemaphoreCount device indices indicating which physical device
    executes the semaphore wait operation in the corresponding element of
    slink:VkSubmitInfo::pname:pWaitSemaphores.
  * pname:commandBufferCount is the number of elements in the
    pname:pCommandBufferDeviceMasks array.
  * pname:pCommandBufferDeviceMasks is a pointer to an array of
    pname:commandBufferCount device masks indicating which physical devices
    execute the command buffer in the corresponding element of
    slink:VkSubmitInfo::pname:pCommandBuffers.
    A physical device executes the command buffer if the corresponding bit
    is set in the mask.
  * pname:signalSemaphoreCount is the number of elements in the
    pname:pSignalSemaphoreDeviceIndices array.
  * pname:pSignalSemaphoreDeviceIndices is a pointer to an array of
    pname:signalSemaphoreCount device indices indicating which physical
    device executes the semaphore signal operation in the corresponding
    element of slink:VkSubmitInfo::pname:pSignalSemaphores.

If this structure is not present, semaphore operations and command buffers
execute on device index zero.

.Valid Usage
****
  * [[VUID-VkDeviceGroupSubmitInfo-waitSemaphoreCount-00082]]
    pname:waitSemaphoreCount must: equal
    slink:VkSubmitInfo::pname:waitSemaphoreCount
  * [[VUID-VkDeviceGroupSubmitInfo-commandBufferCount-00083]]
    pname:commandBufferCount must: equal
    slink:VkSubmitInfo::pname:commandBufferCount
  * [[VUID-VkDeviceGroupSubmitInfo-signalSemaphoreCount-00084]]
    pname:signalSemaphoreCount must: equal
    slink:VkSubmitInfo::pname:signalSemaphoreCount
  * [[VUID-VkDeviceGroupSubmitInfo-pWaitSemaphoreDeviceIndices-00085]]
    All elements of pname:pWaitSemaphoreDeviceIndices and
    pname:pSignalSemaphoreDeviceIndices must: be valid device indices
  * [[VUID-VkDeviceGroupSubmitInfo-pCommandBufferDeviceMasks-00086]]
    All elements of pname:pCommandBufferDeviceMasks must: be valid device
    masks
****

include::{generated}/validity/structs/VkDeviceGroupSubmitInfo.adoc[]
--
endif::VK_VERSION_1_1,VK_KHR_device_group[]

ifdef::VK_KHR_performance_query[]
If the pname:pNext chain of slink:VkSubmitInfo includes a
slink:VkPerformanceQuerySubmitInfoKHR structure, then the structure
indicates which counter pass is active for the batch in that submit.

[open,refpage='VkPerformanceQuerySubmitInfoKHR',desc='Structure indicating which counter pass index is active for performance queries',type='structs']
--
The sname:VkPerformanceQuerySubmitInfoKHR structure is defined as:

include::{generated}/api/structs/VkPerformanceQuerySubmitInfoKHR.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:counterPassIndex specifies which counter pass index is active.

If the sname:VkSubmitInfo::pname:pNext chain does not include this
structure, the batch defaults to use counter pass index 0.

.Valid Usage
****
  * [[VUID-VkPerformanceQuerySubmitInfoKHR-counterPassIndex-03221]]
    pname:counterPassIndex must: be less than the number of counter passes
    required by any queries within the batch.
    The required number of counter passes for a performance query is
    obtained by calling
    flink:vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR
****

include::{generated}/validity/structs/VkPerformanceQuerySubmitInfoKHR.adoc[]
--
endif::VK_KHR_performance_query[]


[[commandbuffers-submission-progress]]
== Queue Forward Progress

When using binary semaphores, the application must: ensure that command
buffer submissions will be able to complete without any subsequent
operations by the application on any queue.
After any call to fname:vkQueueSubmit (or other queue operation), for every
queued wait on a semaphore
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
created with a elink:VkSemaphoreType of ename:VK_SEMAPHORE_TYPE_BINARY
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
there must: be a prior signal of that semaphore that will not be consumed by
a different wait on the semaphore.

ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
When using timeline semaphores, wait-before-signal behavior is well-defined
and applications can: submit work via fname:vkQueueSubmit defining a
<<synchronization-semaphores-waiting, timeline semaphore wait operation>>
before submitting a corresponding <<synchronization-semaphores-signaling,
semaphore signal operation>>.
For each <<synchronization-semaphores-waiting, timeline semaphore wait
operation>> defined by a call to fname:vkQueueSubmit, the application must:
ensure that a corresponding <<synchronization-semaphores-signaling,
semaphore signal operation>> is executed before forward progress can be
made.
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]

If a command buffer submission waits for any events to be signaled, the
application must: ensure that command buffer submissions will be able to
complete without any subsequent operations by the application.
Events signaled by the host must: be signaled before the command buffer
waits on those events.

[NOTE]
.Note
====
The ability for commands to wait on the host to set an events was originally
added to allow low-latency updates to resources between host and device.
However, to ensure quality of service, implementations would necessarily
detect extended stalls in execution and timeout after a short period.
As this period is not defined in the Vulkan specification, it is impossible
to correctly validate any application with any wait period.
Since the original users of this functionality were highly limited and
platform-specific, this functionality is now considered defunct and should
not be used.
====


[[commandbuffers-secondary]]
== Secondary Command Buffer Execution

[open,refpage='vkCmdExecuteCommands',desc='Execute a secondary command buffer from a primary command buffer',type='protos']
--
Secondary command buffers must: not be directly submitted to a queue.
To record a secondary command buffer to execute as part of a primary command
buffer, call:

include::{generated}/api/protos/vkCmdExecuteCommands.adoc[]

  * pname:commandBuffer is a handle to a primary command buffer that the
    secondary command buffers are executed in.
  * pname:commandBufferCount is the length of the pname:pCommandBuffers
    array.
  * pname:pCommandBuffers is a pointer to an array of
    pname:commandBufferCount secondary command buffer handles, which are
    recorded to execute in the primary command buffer in the order they are
    listed in the array.

If any element of pname:pCommandBuffers was not recorded with the
ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, and it was recorded
into any other primary command buffer which is currently in the
<<commandbuffers-lifecycle, executable or recording state>>, that primary
command buffer becomes <<commandbuffers-lifecycle, invalid>>.

ifdef::VK_EXT_nested_command_buffer[]
If the <<features-nestedCommandBuffer, pname:nestedCommandBuffer>> feature
is enabled it is valid usage for fname:vkCmdExecuteCommands to also be
recorded to a <<glossary, secondary command buffer>>.
endif::VK_EXT_nested_command_buffer[]

.Valid Usage
****
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00088]]
    Each element of pname:pCommandBuffers must: have been allocated with a
    pname:level of ename:VK_COMMAND_BUFFER_LEVEL_SECONDARY
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00089]]
    Each element of pname:pCommandBuffers must: be in the
    <<commandbuffers-lifecycle, pending or executable state>>
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00091]]
    If any element of pname:pCommandBuffers was not recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, it must: not be
    in the <<commandbuffers-lifecycle, pending state>>
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00092]]
    If any element of pname:pCommandBuffers was not recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, it must: not
    have already been recorded to pname:commandBuffer
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00093]]
    If any element of pname:pCommandBuffers was not recorded with the
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, it must: not
    appear more than once in pname:pCommandBuffers
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00094]]
    Each element of pname:pCommandBuffers must: have been allocated from a
    sname:VkCommandPool that was created for the same queue family as the
    sname:VkCommandPool from which pname:commandBuffer was allocated
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00096]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance, each element of pname:pCommandBuffers must: have been recorded
    with the ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00099]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance, and any element of pname:pCommandBuffers was recorded with
    slink:VkCommandBufferInheritanceInfo::pname:framebuffer not equal to
    dlink:VK_NULL_HANDLE, that sname:VkFramebuffer must: match the
    sname:VkFramebuffer used in the current render pass instance
  * [[VUID-vkCmdExecuteCommands-contents-06018]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRenderPass, its pname:contents
    parameter must: have been set to
    ename:VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
ifdef::VK_EXT_nested_command_buffer[, or ename:VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT]
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-06019]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRenderPass, each element of
    pname:pCommandBuffers must: have been recorded with
    slink:VkCommandBufferInheritanceInfo::pname:subpass set to the index of
    the subpass which the given command buffer will be executed in
  * [[VUID-vkCmdExecuteCommands-pBeginInfo-06020]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRenderPass, the render passes
    specified in the pname:pBeginInfo->pInheritanceInfo->renderPass members
    of the flink:vkBeginCommandBuffer commands used to begin recording each
    element of pname:pCommandBuffers must: be
    <<renderpass-compatibility,compatible>> with the current render pass
ifdef::VK_QCOM_render_pass_transform[]
  * [[VUID-vkCmdExecuteCommands-pNext-02865]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance that included slink:VkRenderPassTransformBeginInfoQCOM in the
    pname:pNext chain of slink:VkRenderPassBeginInfo, then each element of
    pname:pCommandBuffers must: have been recorded with
    slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM in the
    pname:pNext chain of slink:VkCommandBufferBeginInfo
  * [[VUID-vkCmdExecuteCommands-pNext-02866]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance that included slink:VkRenderPassTransformBeginInfoQCOM in the
    pname:pNext chain of slink:VkRenderPassBeginInfo, then each element of
    pname:pCommandBuffers must: have been recorded with
    slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM::pname:transform
    identical to slink:VkRenderPassTransformBeginInfoQCOM::pname:transform
  * [[VUID-vkCmdExecuteCommands-pNext-02867]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance that included slink:VkRenderPassTransformBeginInfoQCOM in the
    pname:pNext chain of slink:VkRenderPassBeginInfo, then each element of
    pname:pCommandBuffers must: have been recorded with
    slink:VkCommandBufferInheritanceRenderPassTransformInfoQCOM::pname:renderArea
    identical to slink:VkRenderPassBeginInfo::pname:renderArea
endif::VK_QCOM_render_pass_transform[]
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00100]]
    If fname:vkCmdExecuteCommands is not being called within a render pass
    instance, each element of pname:pCommandBuffers must: not have been
    recorded with the ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
  * [[VUID-vkCmdExecuteCommands-commandBuffer-00101]]
    If the <<features-inheritedQueries, pname:inheritedQueries>> feature is
    not enabled, pname:commandBuffer must: not have any queries
    <<queries-operation-active,active>>
  * [[VUID-vkCmdExecuteCommands-commandBuffer-00102]]
    If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query
    <<queries-operation-active,active>>, then each element of
    pname:pCommandBuffers must: have been recorded with
    sname:VkCommandBufferInheritanceInfo::pname:occlusionQueryEnable set to
    ename:VK_TRUE
  * [[VUID-vkCmdExecuteCommands-commandBuffer-00103]]
    If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query
    <<queries-operation-active,active>>, then each element of
    pname:pCommandBuffers must: have been recorded with
    sname:VkCommandBufferInheritanceInfo::pname:queryFlags having all bits
    set that are set for the query
  * [[VUID-vkCmdExecuteCommands-commandBuffer-00104]]
    If pname:commandBuffer has a ename:VK_QUERY_TYPE_PIPELINE_STATISTICS
    query <<queries-operation-active,active>>, then each element of
    pname:pCommandBuffers must: have been recorded with
    sname:VkCommandBufferInheritanceInfo::pname:pipelineStatistics having
    all bits set that are set in the sname:VkQueryPool the query uses
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-00105]]
    Each element of pname:pCommandBuffers must: not begin any query types
    that are <<queries-operation-active,active>> in pname:commandBuffer
  * [[VUID-vkCmdExecuteCommands-commandBuffer-07594]]
    pname:commandBuffer must: not have any queries other than
    ename:VK_QUERY_TYPE_OCCLUSION and
    ename:VK_QUERY_TYPE_PIPELINE_STATISTICS
    <<queries-operation-active,active>>
ifdef::VK_VERSION_1_1[]
  * [[VUID-vkCmdExecuteCommands-commandBuffer-01820]]
    If pname:commandBuffer is a protected command buffer and
    <<limits-protectedNoFault, pname:protectedNoFault>> is not supported,
    each element of pname:pCommandBuffers must: be a protected command
    buffer
  * [[VUID-vkCmdExecuteCommands-commandBuffer-01821]]
    If pname:commandBuffer is an unprotected command buffer and
    <<limits-protectedNoFault, pname:protectedNoFault>> is not supported,
    each element of pname:pCommandBuffers must: be an unprotected command
    buffer
endif::VK_VERSION_1_1[]
ifdef::VK_EXT_transform_feedback[]
  * [[VUID-vkCmdExecuteCommands-None-02286]]
    This command must: not be recorded when transform feedback is active
endif::VK_EXT_transform_feedback[]
  * [[VUID-vkCmdExecuteCommands-commandBuffer-06533]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance and any recorded command in pname:commandBuffer in the current
    subpass will write to an image subresource as an attachment, commands
    recorded in elements of pname:pCommandBuffers must: not read from the
    memory backing that image subresource in any other way
  * [[VUID-vkCmdExecuteCommands-commandBuffer-06534]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance and any recorded command in pname:commandBuffer in the current
    subpass will read from an image subresource used as an attachment in any
    way other than as an attachment, commands recorded in elements of
    pname:pCommandBuffers must: not write to that image subresource as an
    attachment
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-06535]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance and any recorded command in a given element of
    pname:pCommandBuffers will write to an image subresource as an
    attachment, commands recorded in elements of pname:pCommandBuffers at a
    higher index must: not read from the memory backing that image
    subresource in any other way
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-06536]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance and any recorded command in a given element of
    pname:pCommandBuffers will read from an image subresource used as an
    attachment in any way other than as an attachment, commands recorded in
    elements of pname:pCommandBuffers at a higher index must: not write to
    that image subresource as an attachment
ifdef::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-06021]]
    If pname:pCommandBuffers contains any <<renderpass-suspension,suspended
    render pass instances>>, there must: be no action or synchronization
    commands between that render pass instance and any render pass instance
    that resumes it
  * [[VUID-vkCmdExecuteCommands-pCommandBuffers-06022]]
    If pname:pCommandBuffers contains any <<renderpass-suspension,suspended
    render pass instances>>, there must: be no render pass instances between
    that render pass instance and any render pass instance that resumes it
ifdef::VK_EXT_sample_locations[]
  * [[VUID-vkCmdExecuteCommands-variableSampleLocations-06023]]
    If the <<limits-variableSampleLocations, pname:variableSampleLocations>>
    limit is not supported, and any element of pname:pCommandBuffers
    contains any <<renderpass-suspension, suspended render pass instances>>,
    where a graphics pipeline has been bound, any pipelines bound in the
    render pass instance that resumes it, or any subsequent render pass
    instances that resume from that one and so on, must: use the same sample
    locations
endif::VK_EXT_sample_locations[]
  * [[VUID-vkCmdExecuteCommands-flags-06024]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, its
    slink:VkRenderingInfo::pname:flags parameter must: have included
    ename:VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT
  * [[VUID-vkCmdExecuteCommands-pBeginInfo-06025]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, the render passes
    specified in the pname:pBeginInfo->pInheritanceInfo->renderPass members
    of the flink:vkBeginCommandBuffer commands used to begin recording each
    element of pname:pCommandBuffers must: be dlink:VK_NULL_HANDLE
  * [[VUID-vkCmdExecuteCommands-flags-06026]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, the pname:flags member of
    the slink:VkCommandBufferInheritanceRenderingInfo structure included in
    the pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    slink:VkRenderingInfo::pname:flags parameter to
    flink:vkCmdBeginRendering, excluding
    ename:VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT
  * [[VUID-vkCmdExecuteCommands-colorAttachmentCount-06027]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, the
    pname:colorAttachmentCount member of the
    slink:VkCommandBufferInheritanceRenderingInfo structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    slink:VkRenderingInfo::pname:colorAttachmentCount parameter to
    flink:vkCmdBeginRendering
  * [[VUID-vkCmdExecuteCommands-imageView-06028]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, if the pname:imageView
    member of an element of the
    slink:VkRenderingInfo::pname:pColorAttachments parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the corresponding
    element of the pname:pColorAttachmentFormats member of the
    slink:VkCommandBufferInheritanceRenderingInfo structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    format used to create that image view
  * [[VUID-vkCmdExecuteCommands-imageView-07606]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, if the pname:imageView
    member of an element of the
    slink:VkRenderingInfo::pname:pColorAttachments parameter to
    flink:vkCmdBeginRendering is dlink:VK_NULL_HANDLE, the corresponding
    element of the pname:pColorAttachmentFormats member of the
    slink:VkCommandBufferInheritanceRenderingInfo structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be
    ename:VK_FORMAT_UNDEFINED
  * [[VUID-vkCmdExecuteCommands-pDepthAttachment-06029]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, if the
    slink:VkRenderingInfo::pname:pDepthAttachment->imageView parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the value of the
    pname:depthAttachmentFormat member of the
    slink:VkCommandBufferInheritanceRenderingInfo structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    format used to create that image view
  * [[VUID-vkCmdExecuteCommands-pStencilAttachment-06030]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, if the
    slink:VkRenderingInfo::pname:pStencilAttachment->imageView parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the value of the
    pname:stencilAttachmentFormat member of the
    slink:VkCommandBufferInheritanceRenderingInfo structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    format used to create that image view
  * [[VUID-vkCmdExecuteCommands-pDepthAttachment-06774]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the
    slink:VkRenderingInfo::pname:pDepthAttachment->imageView parameter to
    flink:vkCmdBeginRendering was dlink:VK_NULL_HANDLE, the value of the
    pname:depthAttachmentFormat member of the
    slink:VkCommandBufferInheritanceRenderingInfo structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be
    ename:VK_FORMAT_UNDEFINED
  * [[VUID-vkCmdExecuteCommands-pStencilAttachment-06775]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the
    slink:VkRenderingInfo::pname:pStencilAttachment->imageView parameter to
    flink:vkCmdBeginRendering was dlink:VK_NULL_HANDLE, the value of the
    pname:stencilAttachmentFormat member of the
    slink:VkCommandBufferInheritanceRenderingInfo structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be
    ename:VK_FORMAT_UNDEFINED
ifdef::VK_KHR_multiview,VK_VERSION_1_1[]
  * [[VUID-vkCmdExecuteCommands-viewMask-06031]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, the pname:viewMask member
    of the slink:VkCommandBufferInheritanceRenderingInfo structure included
    in the pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    slink:VkRenderingInfo::pname:viewMask parameter to
    flink:vkCmdBeginRendering
endif::VK_KHR_multiview,VK_VERSION_1_1[]
ifdef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples[]
  * [[VUID-vkCmdExecuteCommands-pNext-06032]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the pname:pNext chain
    of slink:VkCommandBufferInheritanceInfo includes a
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure, if the pname:imageView
    member of an element of the
    slink:VkRenderingInfo::pname:pColorAttachments parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the corresponding
    element of the pname:pColorAttachmentSamples member of the
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    sample count used to create that image view
  * [[VUID-vkCmdExecuteCommands-pNext-06033]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the pname:pNext chain
    of slink:VkCommandBufferInheritanceInfo includes a
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure, if the
    slink:VkRenderingInfo::pname:pDepthAttachment->imageView parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the value of the
    pname:depthStencilAttachmentSamples member of the
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    sample count used to create that image view
  * [[VUID-vkCmdExecuteCommands-pNext-06034]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the pname:pNext chain
    of slink:VkCommandBufferInheritanceInfo includes a
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure, if the
    slink:VkRenderingInfo::pname:pStencilAttachment->imageView parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the value of the
    pname:depthStencilAttachmentSamples member of the
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure included in the
    pname:pNext chain of
    slink:VkCommandBufferBeginInfo::pname:pInheritanceInfo used to begin
    recording each element of pname:pCommandBuffers must: be equal to the
    sample count used to create that image view
  * [[VUID-vkCmdExecuteCommands-pNext-06035]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the pname:pNext chain
    of slink:VkCommandBufferInheritanceInfo does not include a
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure, if the pname:imageView
    member of an element of the
    slink:VkRenderingInfo::pname:pColorAttachments parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the value of
    slink:VkCommandBufferInheritanceRenderingInfo::pname:rasterizationSamples
    must: be equal to the sample count used to create that image view
  * [[VUID-vkCmdExecuteCommands-pNext-06036]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the pname:pNext chain
    of slink:VkCommandBufferInheritanceInfo does not include a
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure, if the
    slink:VkRenderingInfo::pname:pDepthAttachment->imageView parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the value of
    slink:VkCommandBufferInheritanceRenderingInfo::pname:rasterizationSamples
    must: be equal to the sample count used to create that image view
  * [[VUID-vkCmdExecuteCommands-pNext-06037]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering and the pname:pNext chain
    of slink:VkCommandBufferInheritanceInfo does not include a
    slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure, if the
    slink:VkRenderingInfo::pname:pStencilAttachment->imageView parameter to
    flink:vkCmdBeginRendering is not dlink:VK_NULL_HANDLE, the value of
    slink:VkCommandBufferInheritanceRenderingInfo::pname:rasterizationSamples
    must: be equal to the sample count used to create that image view
endif::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples[]
ifdef::VK_ANDROID_external_format_resolve[]
  * [[VUID-vkCmdExecuteCommands-pNext-09299]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering, with any color attachment
    using a resolve mode of
    ename:VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, the
    pname:pNext chain of slink:VkCommandBufferInheritanceInfo used to create
    each element of pname:pCommandBuffers must: include a
    slink:VkExternalFormatANDROID structure with a pname:externalFormat
    matching that used to create the resolve attachment in the render pass
  * [[VUID-vkCmdExecuteCommands-pNext-09300]]
    If fname:vkCmdExecuteCommands is being called within a render pass
    instance begun with flink:vkCmdBeginRendering with any color attachment
    using a resolve mode of
    ename:VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, and the
    pname:pNext chain of slink:VkCommandBufferInheritanceInfo does not
    include a slink:VkAttachmentSampleCountInfoAMD or
    slink:VkAttachmentSampleCountInfoNV structure, the value of
    slink:VkCommandBufferInheritanceRenderingInfo::pname:rasterizationSamples
    must: be ename:VK_SAMPLE_COUNT_1_BIT
endif::VK_ANDROID_external_format_resolve[]
endif::VK_VERSION_1_3,VK_KHR_dynamic_rendering[]
  * [[VUID-vkCmdExecuteCommands-commandBuffer-09375]]
    pname:commandBuffer must: not be a <<glossary, secondary command
    buffer>>
ifdef::VK_EXT_nested_command_buffer[]
    unless the <<features-nestedCommandBuffer, pname:nestedCommandBuffer>>
    feature is enabled
  * [[VUID-vkCmdExecuteCommands-nestedCommandBuffer-09376]]
    If the <<features-nestedCommandBuffer, pname:nestedCommandBuffer>>
    feature is enabled, the <<glossary, command buffer nesting level>> of
    each element of pname:pCommandBuffers must: be less than
    <<limits-maxCommandBufferNestingLevel,
    pname:maxCommandBufferNestingLevel>>
  * [[VUID-vkCmdExecuteCommands-nestedCommandBufferRendering-09377]]
    If the <<features-nestedCommandBufferRendering,
    pname:nestedCommandBufferRendering>> feature is not enabled, and
    pname:commandBuffer is a <<glossary, secondary command buffer>>,
    pname:commandBuffer must: not have been recorded with
    ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
  * [[VUID-vkCmdExecuteCommands-nestedCommandBufferSimultaneousUse-09378]]
    If the <<features-nestedCommandBufferSimultaneousUse,
    pname:nestedCommandBufferSimultaneousUse>> feature is not enabled, and
    pname:commandBuffer is a <<glossary, secondary command buffer>>, each
    element of pname:pCommandBuffers must: not have been recorded with
    ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
endif::VK_EXT_nested_command_buffer[]
****

include::{generated}/validity/protos/vkCmdExecuteCommands.adoc[]
--

ifdef::VK_EXT_nested_command_buffer[]
[[commandbuffers-nested]]
== Nested Command Buffers

In addition to secondary command buffer execution from primary command
buffers, an implementation may: support <<glossary, nested command
buffers>>, which enable secondary command buffers to be executed from other
secondary command buffers.
If the <<features-nestedCommandBuffer, pname:nestedCommandBuffer>> feature
is enabled, the implementation supports <<glossary, nested command
buffers>>.

Nested command buffer execution works the same as primary-to-secondary
execution, except that it is subject to some additional
implementation-defined limits.

Each secondary command buffer has a <<glossary, command buffer nesting
level>>, which is determined at flink:vkEndCommandBuffer time and evaluated
at flink:vkCmdExecuteCommands time.
A secondary command buffer that executes no other secondary command buffers
has a <<glossary, command buffer nesting level>> of zero.
Otherwise, the <<glossary, command buffer nesting level>> of a secondary
command buffer is equal to the maximum nesting level of all secondary
command buffers executed by that command buffer plus one.
Some implementations may: have a limit on the maximum nesting level of
secondary command buffers that can: be recorded.
This limit is advertised in <<limits-maxCommandBufferNestingLevel,
pname:maxCommandBufferNestingLevel>>.

If the <<features-nestedCommandBufferRendering,
pname:nestedCommandBufferRendering>> feature is enabled, the implementation
supports calling flink:vkCmdExecuteCommands inside secondary command buffers
recorded with ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT.
If the <<features-nestedCommandBufferSimultaneousUse,
pname:nestedCommandBufferSimultaneousUse>> feature is enabled, the
implementation supports calling flink:vkCmdExecuteCommands with secondary
command buffers recorded with
ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT.

Whenever flink:vkCmdExecuteCommands is recorded inside a secondary command
buffer recorded with ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
each member of pname:pCommandBuffers must: have been recorded with a
slink:VkCommandBufferBeginInfo with slink:VkCommandBufferInheritanceInfo
compatible with the slink:VkCommandBufferInheritanceInfo of the command
buffer into which the flink:vkCmdExecuteCommands call is being recorded.
The slink:VkCommandBufferInheritanceRenderingInfo structures are compatible
when the sname:VkCommandBufferInheritanceRenderingInfo::pname:renderpass are
<<renderpass-compatibility, compatible>>, or if they are
dlink:VK_NULL_HANDLE then the slink:VkCommandBufferInheritanceRenderingInfo
members match, and all other members of
sname:VkCommandBufferInheritanceRenderingInfo match.
This requirement applies recursively, down to the most nested command buffer
and up to the command buffer where the render pass was originally begun.

endif::VK_EXT_nested_command_buffer[]

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
[[commandbuffers-devicemask]]
== Command Buffer Device Mask

Each command buffer has a piece of state storing the current device mask of
the command buffer.
This mask controls which physical devices within the logical device all
subsequent commands will execute on, including state-setting commands,
action commands, and synchronization commands.

ifndef::VK_NV_scissor_exclusive[]
Scissor
endif::VK_NV_scissor_exclusive[]
ifdef::VK_NV_scissor_exclusive[]
Scissor, exclusive scissor,
endif::VK_NV_scissor_exclusive[]
and viewport state
ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
(excluding the count of each)
endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[]
can: be set to different values on each physical device (only when set as
dynamic state), and each physical device will render using its local copy of
the state.
Other state is shared between physical devices, such that all physical
devices use the most recently set values for the state.
However, when recording an action command that uses a piece of state, the
most recent command that set that state must: have included all physical
devices that execute the action command in its current device mask.

The command buffer's device mask is orthogonal to the
pname:pCommandBufferDeviceMasks member of slink:VkDeviceGroupSubmitInfo.
Commands only execute on a physical device if the device index is set in
both device masks.

[open,refpage='VkDeviceGroupCommandBufferBeginInfo',desc='Set the initial device mask for a command buffer',type='structs']
--
If the pname:pNext chain of slink:VkCommandBufferBeginInfo includes a
sname:VkDeviceGroupCommandBufferBeginInfo structure, then that structure
includes an initial device mask for the command buffer.

The sname:VkDeviceGroupCommandBufferBeginInfo structure is defined as:

include::{generated}/api/structs/VkDeviceGroupCommandBufferBeginInfo.adoc[]

ifdef::VK_KHR_device_group[]
or the equivalent

include::{generated}/api/structs/VkDeviceGroupCommandBufferBeginInfoKHR.adoc[]
endif::VK_KHR_device_group[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:deviceMask is the initial value of the command buffer's device
    mask.

The initial device mask also acts as an upper bound on the set of devices
that can: ever be in the device mask in the command buffer.

If this structure is not present, the initial value of a command buffer's
device mask is set to include all physical devices in the logical device
when the command buffer begins recording.

.Valid Usage
****
  * [[VUID-VkDeviceGroupCommandBufferBeginInfo-deviceMask-00106]]
    pname:deviceMask must: be a valid device mask value
  * [[VUID-VkDeviceGroupCommandBufferBeginInfo-deviceMask-00107]]
    pname:deviceMask must: not be zero
****

include::{generated}/validity/structs/VkDeviceGroupCommandBufferBeginInfo.adoc[]
--

[open,refpage='vkCmdSetDeviceMask',desc='Modify device mask of a command buffer',type='protos']
--
To update the current device mask of a command buffer, call:

ifdef::VK_VERSION_1_1[]
include::{generated}/api/protos/vkCmdSetDeviceMask.adoc[]
endif::VK_VERSION_1_1[]

ifdef::VK_VERSION_1_1+VK_KHR_device_group[or the equivalent command]

ifdef::VK_KHR_device_group[]
include::{generated}/api/protos/vkCmdSetDeviceMaskKHR.adoc[]
endif::VK_KHR_device_group[]

  * pname:commandBuffer is command buffer whose current device mask is
    modified.
  * pname:deviceMask is the new value of the current device mask.

pname:deviceMask is used to filter out subsequent commands from executing on
all physical devices whose bit indices are not set in the mask, except
commands beginning a render pass instance, commands transitioning to the
next subpass in the render pass instance, and commands ending a render pass
instance, which always execute on the set of physical devices whose bit
indices are included in the pname:deviceMask member of the
slink:VkDeviceGroupRenderPassBeginInfo structure passed to the command
beginning the corresponding render pass instance.

.Valid Usage
****
  * [[VUID-vkCmdSetDeviceMask-deviceMask-00108]]
    pname:deviceMask must: be a valid device mask value
  * [[VUID-vkCmdSetDeviceMask-deviceMask-00109]]
    pname:deviceMask must: not be zero
  * [[VUID-vkCmdSetDeviceMask-deviceMask-00110]]
    pname:deviceMask must: not include any set bits that were not in the
    slink:VkDeviceGroupCommandBufferBeginInfo::pname:deviceMask value when
    the command buffer began recording
  * [[VUID-vkCmdSetDeviceMask-deviceMask-00111]]
    If fname:vkCmdSetDeviceMask is called inside a render pass instance,
    pname:deviceMask must: not include any set bits that were not in the
    slink:VkDeviceGroupRenderPassBeginInfo::pname:deviceMask value when the
    render pass instance began recording
****

include::{generated}/validity/protos/vkCmdSetDeviceMask.adoc[]
--
endif::VK_VERSION_1_1,VK_KHR_device_group[]
