// Copyright 2014-2023 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

== WSI Swapchain

[open,refpage='VkSwapchainKHR',desc='Opaque handle to a swapchain object',type='handles',xrefs='vkQueuePresentKHR']
--
A swapchain object (a.k.a.
swapchain) provides the ability to present rendering results to a surface.
Swapchain objects are represented by sname:VkSwapchainKHR handles:

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

A swapchain is an abstraction for an array of presentable images that are
associated with a surface.
The presentable images are represented by sname:VkImage objects created by
the platform.
One image (which can: be an array image for multiview/stereoscopic-3D
surfaces) is displayed at a time, but multiple images can: be queued for
presentation.
An application renders to the image, and then queues the image for
presentation to the surface.

A native window cannot: be associated with more than one non-retired
swapchain at a time.
Further, swapchains cannot: be created for native windows that have a
non-Vulkan graphics API surface associated with them.

[NOTE]
.Note
====
The presentation engine is an abstraction for the platform's compositor or
display engine.

The presentation engine may: be synchronous or asynchronous with respect to
the application and/or logical device.

Some implementations may: use the device's graphics queue or dedicated
presentation hardware to perform presentation.
====

The presentable images of a swapchain are owned by the presentation engine.
An application can: acquire use of a presentable image from the presentation
engine.
Use of a presentable image must: occur only after the image is returned by
flink:vkAcquireNextImageKHR, and before it is released by
flink:vkQueuePresentKHR.
This includes transitioning the image layout and rendering commands.

An application can: acquire use of a presentable image with
flink:vkAcquireNextImageKHR.
After acquiring a presentable image and before modifying it, the application
must: use a synchronization primitive to ensure that the presentation engine
has finished reading from the image.
The application can: then transition the image's layout, queue rendering
commands to it, etc.
Finally, the application presents the image with flink:vkQueuePresentKHR,
which releases the acquisition of the image.
ifdef::VK_EXT_swapchain_maintenance1[]
The application can: also release the acquisition of the image through
flink:vkReleaseSwapchainImagesEXT, if the image is not in use by the device,
and skip the present operation.
endif::VK_EXT_swapchain_maintenance1[]

The presentation engine controls the order in which presentable images are
acquired for use by the application.

[NOTE]
.Note
====
This allows the platform to handle situations which require out-of-order
return of images after presentation.
At the same time, it allows the application to generate command buffers
referencing all of the images in the swapchain at initialization time,
rather than in its main loop.
====
--

How this all works is described below.

ifdef::VK_KHR_shared_presentable_image[]
include::{chapters}/VK_KHR_shared_presentable_image/wsi.adoc[]
endif::VK_KHR_shared_presentable_image[]

[open,refpage='vkCreateSwapchainKHR',desc='Create a swapchain',type='protos']
--
:refpage: vkCreateSwapchainKHR
:objectnameplural: swapchains
:objectnamecamelcase: swapchain
:objectcount: 1

To create a swapchain, call:

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

  * pname:device is the device to create the swapchain for.
  * pname:pCreateInfo is a pointer to a slink:VkSwapchainCreateInfoKHR
    structure specifying the parameters of the created swapchain.
  * pname:pAllocator is the allocator used for host memory allocated for the
    swapchain object when there is no more specific allocator available (see
    <<memory-allocation,Memory Allocation>>).
  * pname:pSwapchain is a pointer to a slink:VkSwapchainKHR handle in which
    the created swapchain object will be returned.

As mentioned above, if fname:vkCreateSwapchainKHR succeeds, it will return a
handle to a swapchain containing an array of at least
pname:pCreateInfo->minImageCount presentable images.

While acquired by the application, presentable images can: be used in any
way that equivalent non-presentable images can: be used.
A presentable image is equivalent to a non-presentable image created with
the following slink:VkImageCreateInfo parameters:

[[swapchain-wsi-image-create-info]]
[options="header"]
|====
| sname:VkImageCreateInfo Field | Value
ifndef::VK_VERSION_1_1,VK_KHR_device_group,VK_KHR_swapchain_mutable_format[]
| pname:flags                   | 0
endif::VK_VERSION_1_1,VK_KHR_device_group,VK_KHR_swapchain_mutable_format[]
ifdef::VK_VERSION_1_1,VK_KHR_device_group,VK_KHR_swapchain_mutable_format[]
| pname:flags                   |
ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
ename:VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT is set if
ename:VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR is set

endif::VK_VERSION_1_1,VK_KHR_device_group[]
ifdef::VK_VERSION_1_1[]
ename:VK_IMAGE_CREATE_PROTECTED_BIT is set if
ename:VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR is set

endif::VK_VERSION_1_1[]
ifdef::VK_KHR_swapchain_mutable_format[]
ename:VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT and
ename:VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR are both set if
ename:VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR is set

endif::VK_KHR_swapchain_mutable_format[]
all other bits are unset
endif::VK_VERSION_1_1,VK_KHR_device_group,VK_KHR_swapchain_mutable_format[]
| pname:imageType               | ename:VK_IMAGE_TYPE_2D
| pname:format                  | pname:pCreateInfo->imageFormat
| pname:extent                  | {pname:pCreateInfo->imageExtent.width, pname:pCreateInfo->imageExtent.height, `1`}
| pname:mipLevels               | 1
| pname:arrayLayers             | pname:pCreateInfo->imageArrayLayers
| pname:samples                 | ename:VK_SAMPLE_COUNT_1_BIT
| pname:tiling                  | ename:VK_IMAGE_TILING_OPTIMAL
| pname:usage                   | pname:pCreateInfo->imageUsage
| pname:sharingMode             | pname:pCreateInfo->imageSharingMode
| pname:queueFamilyIndexCount   | pname:pCreateInfo->queueFamilyIndexCount
| pname:pQueueFamilyIndices     | pname:pCreateInfo->pQueueFamilyIndices
| pname:initialLayout           | ename:VK_IMAGE_LAYOUT_UNDEFINED
|====

The pname:pCreateInfo->surface must: not be destroyed until after the
swapchain is destroyed.

ifdef::VKSC_VERSION_1_0[If]
ifndef::VKSC_VERSION_1_0[If pname:oldSwapchain is dlink:VK_NULL_HANDLE, and]
the native window referred to by pname:pCreateInfo->surface is already
associated with a Vulkan swapchain, ename:VK_ERROR_NATIVE_WINDOW_IN_USE_KHR
must: be returned.

If the native window referred to by pname:pCreateInfo->surface is already
associated with a non-Vulkan graphics API surface,
ename:VK_ERROR_NATIVE_WINDOW_IN_USE_KHR must: be returned.

The native window referred to by pname:pCreateInfo->surface must: not become
associated with a non-Vulkan graphics API surface before all associated
Vulkan swapchains have been destroyed.

fname:vkCreateSwapchainKHR will return ename:VK_ERROR_DEVICE_LOST if the
logical device was lost.
ifndef::VKSC_VERSION_1_0[]
The sname:VkSwapchainKHR is a child of the pname:device, and must: be
destroyed before the pname:device.
endif::VKSC_VERSION_1_0[]
However, sname:VkSurfaceKHR is not a child of any sname:VkDevice and is not
affected by the lost device.
After successfully recreating a sname:VkDevice, the same sname:VkSurfaceKHR
can: be used to create a new sname:VkSwapchainKHR, provided the previous one
was destroyed.

ifdef::VK_EXT_full_screen_exclusive[]
If the pname:oldSwapchain parameter of pname:pCreateInfo is a valid
swapchain, which has exclusive full-screen access, that access is released
from pname:pCreateInfo->oldSwapchain.
If the command succeeds in this case, the newly created swapchain will
automatically acquire exclusive full-screen access from
pname:pCreateInfo->oldSwapchain.

[NOTE]
.Note
====
This implicit transfer is intended to avoid exiting and entering full-screen
exclusive mode, which may otherwise cause unwanted visual updates to the
display.
====

In some cases, swapchain creation may: fail if exclusive full-screen mode is
requested for application control, but for some implementation-specific
reason exclusive full-screen access is unavailable for the particular
combination of parameters provided.
If this occurs, ename:VK_ERROR_INITIALIZATION_FAILED will be returned.

[NOTE]
.Note
====
In particular, it will fail if the pname:imageExtent member of
pname:pCreateInfo does not match the extents of the monitor.
ifdef::VK_KHR_win32_surface[]
Other reasons for failure may include the app not being set as high-dpi
aware, or if the physical device and monitor are not compatible in this
mode.
endif::VK_KHR_win32_surface[]
====

endif::VK_EXT_full_screen_exclusive[]

ifdef::VK_NV_present_barrier[]
If the pname:pNext chain of slink:VkSwapchainCreateInfoKHR includes a
slink:VkSwapchainPresentBarrierCreateInfoNV structure, then that structure
includes additional swapchain creation parameters specific to the present
barrier.
Swapchain creation may: fail if the state of the current system restricts
the usage of the present barrier feature
slink:VkSurfaceCapabilitiesPresentBarrierNV, or a swapchain itself does not
satisfy all the required conditions.
In this scenario ename:VK_ERROR_INITIALIZATION_FAILED is returned.
endif::VK_NV_present_barrier[]

ifdef::VK_NV_acquire_winrt_display[]
When the slink:VkSurfaceKHR in slink:VkSwapchainCreateInfoKHR is a display
surface, then the slink:VkDisplayModeKHR in display surface's
slink:VkDisplaySurfaceCreateInfoKHR is associated with a particular
slink:VkDisplayKHR.
Swapchain creation may: fail if that slink:VkDisplayKHR is not acquired by
the application.
In this scenario ename:VK_ERROR_INITIALIZATION_FAILED is returned.
endif::VK_NV_acquire_winrt_display[]

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

ifdef::VKSC_VERSION_1_0[]
.Valid Usage
****
include::{chapters}/commonvalidity/memory_reservation_request_count_common.adoc[]
****
endif::VKSC_VERSION_1_0[]

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

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

include::{generated}/api/structs/VkSwapchainCreateInfoKHR.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:VkSwapchainCreateFlagBitsKHR
    indicating parameters of the swapchain creation.
  * pname:surface is the surface onto which the swapchain will present
    images.
    If the creation succeeds, the swapchain becomes associated with
    pname:surface.
  * pname:minImageCount is the minimum number of presentable images that the
    application needs.
    The implementation will either create the swapchain with at least that
    many images, or it will fail to create the swapchain.
  * pname:imageFormat is a elink:VkFormat value specifying the format the
    swapchain image(s) will be created with.
  * pname:imageColorSpace is a elink:VkColorSpaceKHR value specifying the
    way the swapchain interprets image data.
  * pname:imageExtent is the size (in pixels) of the swapchain image(s).
    The behavior is platform-dependent if the image extent does not match
    the surface's pname:currentExtent as returned by
    fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR.
+
[NOTE]
.Note
====
On some platforms, it is normal that pname:maxImageExtent may: become `(0,
0)`, for example when the window is minimized.
In such a case, it is not possible to create a swapchain due to the Valid
Usage requirements
ifdef::VK_EXT_swapchain_maintenance1[]
, unless scaling is selected through
slink:VkSwapchainPresentScalingCreateInfoEXT, if supported
endif::VK_EXT_swapchain_maintenance1[]
.
====
  * pname:imageArrayLayers is the number of views in a multiview/stereo
    surface.
    For non-stereoscopic-3D applications, this value is 1.
  * pname:imageUsage is a bitmask of elink:VkImageUsageFlagBits describing
    the intended usage of the (acquired) swapchain images.
  * pname:imageSharingMode is the sharing mode used for the image(s) of the
    swapchain.
  * pname:queueFamilyIndexCount is the number of queue families having
    access to the image(s) of the swapchain when pname:imageSharingMode is
    ename:VK_SHARING_MODE_CONCURRENT.
  * pname:pQueueFamilyIndices is a pointer to an array of queue family
    indices having access to the images(s) of the swapchain when
    pname:imageSharingMode is ename:VK_SHARING_MODE_CONCURRENT.
  * pname:preTransform is a elink:VkSurfaceTransformFlagBitsKHR value
    describing the transform, relative to the presentation engine's natural
    orientation, applied to the image content prior to presentation.
    If it does not match the pname:currentTransform value returned by
    fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR, the presentation engine
    will transform the image content as part of the presentation operation.
  * pname:compositeAlpha is a elink:VkCompositeAlphaFlagBitsKHR value
    indicating the alpha compositing mode to use when this surface is
    composited together with other surfaces on certain window systems.
  * pname:presentMode is the presentation mode the swapchain will use.
    A swapchain's present mode determines how incoming present requests will
    be processed and queued internally.
  * pname:clipped specifies whether the Vulkan implementation is allowed to
    discard rendering operations that affect regions of the surface that are
    not visible.
  ** If set to ename:VK_TRUE, the presentable images associated with the
     swapchain may: not own all of their pixels.
     Pixels in the presentable images that correspond to regions of the
     target surface obscured by another window on the desktop, or subject to
     some other clipping mechanism will have undefined: content when read
     back.
     Fragment shaders may: not execute for these pixels, and thus any side
     effects they would have had will not occur.
     Setting ename:VK_TRUE does not guarantee any clipping will occur, but
     allows more efficient presentation methods to be used on some
     platforms.
  ** If set to ename:VK_FALSE, presentable images associated with the
     swapchain will own all of the pixels they contain.
+
[NOTE]
.Note
====
Applications should: set this value to ename:VK_TRUE if they do not expect
to read back the content of presentable images before presenting them or
after reacquiring them, and if their fragment shaders do not have any side
effects that require them to run for all pixels in the presentable image.
====
ifdef::VKSC_VERSION_1_0[]
  * pname:oldSwapchain must: be dlink:VK_NULL_HANDLE in Vulkan SC
    <<SCID-4>>.
endif::VKSC_VERSION_1_0[]
ifndef::VKSC_VERSION_1_0[]
  * pname:oldSwapchain is dlink:VK_NULL_HANDLE, or the existing non-retired
    swapchain currently associated with pname:surface.
    Providing a valid pname:oldSwapchain may: aid in the resource reuse, and
    also allows the application to still present any images that are already
    acquired from it.
endif::VKSC_VERSION_1_0[]

ifndef::VKSC_VERSION_1_0[]
Upon calling fname:vkCreateSwapchainKHR with an pname:oldSwapchain that is
not dlink:VK_NULL_HANDLE, pname:oldSwapchain is retired -- even if creation
of the new swapchain fails.
The new swapchain is created in the non-retired state whether or not
pname:oldSwapchain is dlink:VK_NULL_HANDLE.

Upon calling fname:vkCreateSwapchainKHR with an pname:oldSwapchain that is
not dlink:VK_NULL_HANDLE, any images from pname:oldSwapchain that are not
acquired by the application may: be freed by the implementation, which may:
occur even if creation of the new swapchain fails.
The application can: destroy pname:oldSwapchain to free all memory
associated with pname:oldSwapchain.

[NOTE]
.Note
====
Multiple retired swapchains can: be associated with the same
sname:VkSurfaceKHR through multiple uses of pname:oldSwapchain that
outnumber calls to flink:vkDestroySwapchainKHR.

After pname:oldSwapchain is retired, the application can: pass to
flink:vkQueuePresentKHR any images it had already acquired from
pname:oldSwapchain.
E.g., an application may present an image from the old swapchain before an
image from the new swapchain is ready to be presented.
As usual, flink:vkQueuePresentKHR may: fail if pname:oldSwapchain has
entered a state that causes ename:VK_ERROR_OUT_OF_DATE_KHR to be returned.

ifdef::VK_KHR_shared_presentable_image[]
The application can: continue to use a shared presentable image obtained
from pname:oldSwapchain until a presentable image is acquired from the new
swapchain, as long as it has not entered a state that causes it to return
ename:VK_ERROR_OUT_OF_DATE_KHR.
endif::VK_KHR_shared_presentable_image[]
====
endif::VKSC_VERSION_1_0[]

.Valid Usage
****
  * [[VUID-VkSwapchainCreateInfoKHR-surface-01270]]
    pname:surface must: be a surface that is supported by the device as
    determined using flink:vkGetPhysicalDeviceSurfaceSupportKHR
ifndef::VK_KHR_shared_presentable_image[]
  * [[VUID-VkSwapchainCreateInfoKHR-minImageCount-01271]]
    pname:minImageCount must: be greater than or equal to the value returned
    in the pname:minImageCount member of the sname:VkSurfaceCapabilitiesKHR
    structure returned by flink:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    for the surface
endif::VK_KHR_shared_presentable_image[]
  * [[VUID-VkSwapchainCreateInfoKHR-minImageCount-01272]]
    pname:minImageCount must: be less than or equal to the value returned in
    the pname:maxImageCount member of the sname:VkSurfaceCapabilitiesKHR
    structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    for the surface if the returned pname:maxImageCount is not zero
ifdef::VK_KHR_shared_presentable_image[]
  * [[VUID-VkSwapchainCreateInfoKHR-presentMode-02839]]
    If pname:presentMode is not
    ename:VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR nor
    ename:VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, then
    pname:minImageCount must: be greater than or equal to the value returned
    in the pname:minImageCount member of the sname:VkSurfaceCapabilitiesKHR
    structure returned by flink:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    for the surface
  * [[VUID-VkSwapchainCreateInfoKHR-minImageCount-01383]]
    pname:minImageCount must: be `1` if pname:presentMode is either
    ename:VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR or
    ename:VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR
endif::VK_KHR_shared_presentable_image[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageFormat-01273]]
    pname:imageFormat and pname:imageColorSpace must: match the pname:format
    and pname:colorSpace members, respectively, of one of the
    sname:VkSurfaceFormatKHR structures returned by
    fname:vkGetPhysicalDeviceSurfaceFormatsKHR for the surface
ifndef::VK_EXT_swapchain_maintenance1[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageExtent-01274]]
    pname:imageExtent must: be between pname:minImageExtent and
    pname:maxImageExtent, inclusive, where pname:minImageExtent and
    pname:maxImageExtent are members of the sname:VkSurfaceCapabilitiesKHR
    structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    for the surface
endif::VK_EXT_swapchain_maintenance1[]
ifdef::VK_EXT_swapchain_maintenance1[]
  * [[VUID-VkSwapchainCreateInfoKHR-pNext-07781]]
    If a slink:VkSwapchainPresentScalingCreateInfoEXT structure was not
    included in the pname:pNext chain, or it is included and
    slink:VkSwapchainPresentScalingCreateInfoEXT::pname:scalingBehavior is
    zero then pname:imageExtent must: be between pname:minImageExtent and
    pname:maxImageExtent, inclusive, where pname:minImageExtent and
    pname:maxImageExtent are members of the sname:VkSurfaceCapabilitiesKHR
    structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    for the surface
  * [[VUID-VkSwapchainCreateInfoKHR-pNext-07782]]
    If a slink:VkSwapchainPresentScalingCreateInfoEXT structure was included
    in the pname:pNext chain and
    slink:VkSwapchainPresentScalingCreateInfoEXT::pname:scalingBehavior is
    not zero then pname:imageExtent must: be between
    pname:minScaledImageExtent and pname:maxScaledImageExtent, inclusive,
    where pname:minScaledImageExtent and pname:maxScaledImageExtent are
    members of the sname:VkSurfacePresentScalingCapabilitiesEXT structure
    returned by fname:vkGetPhysicalDeviceSurfaceCapabilities2KHR for the
    surface and pname:presentMode
endif::VK_EXT_swapchain_maintenance1[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageExtent-01689]]
    pname:imageExtent members pname:width and pname:height must: both be
    non-zero
  * [[VUID-VkSwapchainCreateInfoKHR-imageArrayLayers-01275]]
    pname:imageArrayLayers must: be greater than `0` and less than or equal
    to the pname:maxImageArrayLayers member of the
    sname:VkSurfaceCapabilitiesKHR structure returned by
    fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface
  * [[VUID-VkSwapchainCreateInfoKHR-presentMode-01427]]
    If pname:presentMode is ename:VK_PRESENT_MODE_IMMEDIATE_KHR,
    ename:VK_PRESENT_MODE_MAILBOX_KHR, ename:VK_PRESENT_MODE_FIFO_KHR or
    ename:VK_PRESENT_MODE_FIFO_RELAXED_KHR, pname:imageUsage must: be a
    subset of the supported usage flags present in the
    pname:supportedUsageFlags member of the slink:VkSurfaceCapabilitiesKHR
    structure returned by flink:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    for pname:surface
ifdef::VK_KHR_shared_presentable_image[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageUsage-01384]]
    If pname:presentMode is ename:VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR
    or ename:VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, pname:imageUsage
    must: be a subset of the supported usage flags present in the
    pname:sharedPresentSupportedUsageFlags member of the
    slink:VkSharedPresentSurfaceCapabilitiesKHR structure returned by
    flink:vkGetPhysicalDeviceSurfaceCapabilities2KHR for pname:surface
endif::VK_KHR_shared_presentable_image[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01277]]
    If pname:imageSharingMode is ename:VK_SHARING_MODE_CONCURRENT,
    pname:pQueueFamilyIndices must: be a valid pointer to an array of
    pname:queueFamilyIndexCount code:uint32_t values
  * [[VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278]]
    If pname:imageSharingMode is ename:VK_SHARING_MODE_CONCURRENT,
    pname:queueFamilyIndexCount must: be greater than `1`
ifndef::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01393]]
    If pname:imageSharingMode is ename:VK_SHARING_MODE_CONCURRENT, each
    element of pname:pQueueFamilyIndices must: be unique and must: be less
    than pname:pQueueFamilyPropertyCount returned by
    flink:vkGetPhysicalDeviceQueueFamilyProperties for the
    pname:physicalDevice that was used to create pname:device
endif::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[]
ifdef::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428]]
    If pname:imageSharingMode is ename:VK_SHARING_MODE_CONCURRENT, each
    element of pname:pQueueFamilyIndices must: be unique and must: be less
    than pname:pQueueFamilyPropertyCount returned by either
    flink:vkGetPhysicalDeviceQueueFamilyProperties or
    flink:vkGetPhysicalDeviceQueueFamilyProperties2 for the
    pname:physicalDevice that was used to create pname:device
endif::VK_VERSION_1_1,VK_KHR_get_physical_device_properties2[]
  * [[VUID-VkSwapchainCreateInfoKHR-preTransform-01279]]
    pname:preTransform must: be one of the bits present in the
    pname:supportedTransforms member of the sname:VkSurfaceCapabilitiesKHR
    structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    for the surface
  * [[VUID-VkSwapchainCreateInfoKHR-compositeAlpha-01280]]
    pname:compositeAlpha must: be one of the bits present in the
    pname:supportedCompositeAlpha member of the
    sname:VkSurfaceCapabilitiesKHR structure returned by
    fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface
  * [[VUID-VkSwapchainCreateInfoKHR-presentMode-01281]]
    pname:presentMode must: be one of the elink:VkPresentModeKHR values
    returned by fname:vkGetPhysicalDeviceSurfacePresentModesKHR for the
    surface
ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
ifndef::VKSC_VERSION_1_0[]
  * [[VUID-VkSwapchainCreateInfoKHR-physicalDeviceCount-01429]]
    If the logical device was created with
    slink:VkDeviceGroupDeviceCreateInfo::pname:physicalDeviceCount equal to
    1, pname:flags must: not contain
    ename:VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[]
  * [[VUID-VkSwapchainCreateInfoKHR-flags-05072]]
    pname:flags must: not contain
    ename:VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR
endif::VKSC_VERSION_1_0[]
endif::VK_VERSION_1_1,VK_KHR_device_group[]
ifndef::VKSC_VERSION_1_0[]
  * [[VUID-VkSwapchainCreateInfoKHR-oldSwapchain-01933]]
    If pname:oldSwapchain is not dlink:VK_NULL_HANDLE, pname:oldSwapchain
    must: be a non-retired swapchain associated with native window referred
    to by pname:surface
endif::VKSC_VERSION_1_0[]
ifdef::VKSC_VERSION_1_0[]
  * [[VUID-VkSwapchainCreateInfoKHR-oldSwapchain-05073]]
    pname:oldSwapchain must: be dlink:VK_NULL_HANDLE
endif::VKSC_VERSION_1_0[]
  * [[VUID-VkSwapchainCreateInfoKHR-imageFormat-01778]]
    The <<swapchain-wsi-image-create-info, implied image creation
    parameters>> of the swapchain must: be supported as reported by
    flink:vkGetPhysicalDeviceImageFormatProperties
ifdef::VK_KHR_swapchain_mutable_format[]
  * [[VUID-VkSwapchainCreateInfoKHR-flags-03168]]
    If pname:flags contains ename:VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR
    then the pname:pNext chain must: include a
    slink:VkImageFormatListCreateInfo structure with a pname:viewFormatCount
    greater than zero and pname:pViewFormats must: have an element equal to
    pname:imageFormat
  * [[VUID-VkSwapchainCreateInfoKHR-pNext-04099]]
    If a slink:VkImageFormatListCreateInfo structure was included in the
    pname:pNext chain and
    slink:VkImageFormatListCreateInfo::pname:viewFormatCount is not zero
    then all of the formats in
    slink:VkImageFormatListCreateInfo::pname:pViewFormats must: be
    compatible with the pname:format as described in the
    <<formats-compatibility,compatibility table>>
  * [[VUID-VkSwapchainCreateInfoKHR-flags-04100]]
    If pname:flags does not contain
    ename:VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR and the pname:pNext
    chain include a slink:VkImageFormatListCreateInfo structure then
    slink:VkImageFormatListCreateInfo::pname:viewFormatCount must: be `0` or
    `1`
endif::VK_KHR_swapchain_mutable_format[]
ifdef::VK_KHR_surface_protected_capabilities[]
  * [[VUID-VkSwapchainCreateInfoKHR-flags-03187]]
    If pname:flags contains ename:VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR,
    then sname:VkSurfaceProtectedCapabilitiesKHR::pname:supportsProtected
    must: be ename:VK_TRUE in the slink:VkSurfaceProtectedCapabilitiesKHR
    structure returned by flink:vkGetPhysicalDeviceSurfaceCapabilities2KHR
    for pname:surface
endif::VK_KHR_surface_protected_capabilities[]
ifdef::VK_EXT_full_screen_exclusive+VK_KHR_win32_surface[]
  * [[VUID-VkSwapchainCreateInfoKHR-pNext-02679]]
    If the pname:pNext chain includes a
    slink:VkSurfaceFullScreenExclusiveInfoEXT structure with its
    pname:fullScreenExclusive member set to
    ename:VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT, and
    pname:surface was created using flink:vkCreateWin32SurfaceKHR, a
    slink:VkSurfaceFullScreenExclusiveWin32InfoEXT structure must: be
    included in the pname:pNext chain
endif::VK_EXT_full_screen_exclusive+VK_KHR_win32_surface[]
ifdef::VK_EXT_image_compression_control[]
ifndef::VK_EXT_image_compression_control_swapchain[]
  * [[VUID-VkSwapchainCreateInfoKHR-pNext-06751]]
    The pname:pNext chain must: not include an
    slink:VkImageCompressionControlEXT structure
endif::VK_EXT_image_compression_control_swapchain[]
ifdef::VK_EXT_image_compression_control_swapchain[]
  * [[VUID-VkSwapchainCreateInfoKHR-pNext-06752]]
    If the <<features-imageCompressionControlSwapchain,
    pname:imageCompressionControlSwapchain>> feature is not enabled, the
    pname:pNext chain must: not include an
    slink:VkImageCompressionControlEXT structure
endif::VK_EXT_image_compression_control_swapchain[]
endif::VK_EXT_image_compression_control[]
****
ifdef::VKSC_VERSION_1_0[]
ifdef::hidden[]
// tag::scdeviation[]
  * slink:VkSwapchainCreateInfoKHR::pname:flags must: not contain
    ename:VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR
    <<SCID-8>>.
  * slink:VkSwapchainCreateInfoKHR::pname:oldSwapchain must: be
    dlink:VK_NULL_HANDLE <<SCID-4>>.
// end::scdeviation[]
endif::hidden[]
endif::VKSC_VERSION_1_0[]

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

[open,refpage='VkSwapchainCreateFlagBitsKHR',desc='Bitmask controlling swapchain creation',type='enums']
--
Bits which can: be set in slink:VkSwapchainCreateInfoKHR::pname:flags,
specifying parameters of swapchain creation, are:

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

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
  * ename:VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR specifies
    that images created from the swapchain (i.e. with the pname:swapchain
    member of slink:VkImageSwapchainCreateInfoKHR set to this swapchain's
    handle) must: use ename:VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT.
ifdef::VKSC_VERSION_1_0[]
    This flag is not supported in Vulkan SC <<SCID-8>>.
endif::VKSC_VERSION_1_0[]
endif::VK_VERSION_1_1,VK_KHR_device_group[]
ifdef::VK_VERSION_1_1[]
  * ename:VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR specifies that images
    created from the swapchain are protected images.
endif::VK_VERSION_1_1[]
ifdef::VK_KHR_swapchain_mutable_format[]
  * ename:VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR specifies that the
    images of the swapchain can: be used to create a sname:VkImageView with
    a different format than what the swapchain was created with.
    The list of allowed image view formats is specified by adding a
    slink:VkImageFormatListCreateInfo structure to the pname:pNext chain of
    slink:VkSwapchainCreateInfoKHR.
    In addition, this flag also specifies that the swapchain can: be created
    with usage flags that are not supported for the format the swapchain is
    created with but are supported for at least one of the allowed image
    view formats.
endif::VK_KHR_swapchain_mutable_format[]
ifdef::VK_EXT_swapchain_maintenance1[]
  * ename:VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT specifies
    that the implementation may: defer allocation of memory associated with
    each swapchain image until its index is to be returned from
    flink:vkAcquireNextImageKHR
ifdef::VK_VERSION_1_1,VK_KHR_device_group[or flink:vkAcquireNextImage2KHR]
    for the first time.
endif::VK_EXT_swapchain_maintenance1[]
--

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

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

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
[open,refpage='VkDeviceGroupSwapchainCreateInfoKHR',desc='Structure specifying parameters of a newly created swapchain object',type='structs']
--
If the pname:pNext chain of slink:VkSwapchainCreateInfoKHR includes a
sname:VkDeviceGroupSwapchainCreateInfoKHR structure, then that structure
includes a set of device group present modes that the swapchain can: be used
with.

The sname:VkDeviceGroupSwapchainCreateInfoKHR structure is defined as:

include::{generated}/api/structs/VkDeviceGroupSwapchainCreateInfoKHR.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:modes is a bitfield of modes that the swapchain can: be used with.

If this structure is not present, pname:modes is considered to be
ename:VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR.

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

ifdef::VK_AMD_display_native_hdr[]
[open,refpage='VkSwapchainDisplayNativeHdrCreateInfoAMD',desc='Structure specifying display native HDR parameters of a newly created swapchain object',type='structs']
--
If the pname:pNext chain of slink:VkSwapchainCreateInfoKHR includes a
sname:VkSwapchainDisplayNativeHdrCreateInfoAMD structure, then that
structure includes additional swapchain creation parameters specific to
display native HDR support.

The sname:VkSwapchainDisplayNativeHdrCreateInfoAMD structure is defined as:

include::{generated}/api/structs/VkSwapchainDisplayNativeHdrCreateInfoAMD.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:localDimmingEnable specifies whether local dimming is enabled for
    the swapchain.

If the pname:pNext chain of slink:VkSwapchainCreateInfoKHR does not include
this structure, the default value for pname:localDimmingEnable is
ename:VK_TRUE, meaning local dimming is initially enabled for the swapchain.

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

.Valid Usage
****
  * [[VUID-VkSwapchainDisplayNativeHdrCreateInfoAMD-localDimmingEnable-04449]]
    It is only valid to set pname:localDimmingEnable to ename:VK_TRUE if
    slink:VkDisplayNativeHdrSurfaceCapabilitiesAMD::pname:localDimmingSupport
    is supported
****
--

[open,refpage='vkSetLocalDimmingAMD',desc='Set Local Dimming',type='protos']
--
The local dimming HDR setting may also be changed over the life of a
swapchain by calling:

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

  * pname:device is the device associated with pname:swapChain.
  * pname:swapChain handle to enable local dimming.
  * pname:localDimmingEnable specifies whether local dimming is enabled for
    the swapchain.

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

.Valid Usage
****
  * [[VUID-vkSetLocalDimmingAMD-localDimmingSupport-04618]]
    slink:VkDisplayNativeHdrSurfaceCapabilitiesAMD::pname:localDimmingSupport
    must: be supported
****
--
endif::VK_AMD_display_native_hdr[]

ifdef::VK_EXT_full_screen_exclusive[]
If the pname:pNext chain of slink:VkSwapchainCreateInfoKHR includes a
slink:VkSurfaceFullScreenExclusiveInfoEXT structure, then that structure
specifies the application's preferred full-screen presentation behavior.
If this structure is not present, pname:fullScreenExclusive is considered to
be ename:VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT.
endif::VK_EXT_full_screen_exclusive[]

ifdef::VK_EXT_display_control[]
include::{chapters}/VK_EXT_display_control/swapchain_counters.adoc[]
endif::VK_EXT_display_control[]

ifdef::VK_EXT_image_compression_control[]
ifdef::VK_EXT_image_compression_control_swapchain[]
To specify compression properties for the swapchain images in this
swapchain, add a slink:VkImageCompressionControlEXT structure to the
pname:pNext chain of the slink:VkSwapchainCreateInfoKHR structure.
endif::VK_EXT_image_compression_control_swapchain[]
endif::VK_EXT_image_compression_control[]

ifdef::VK_EXT_swapchain_maintenance1[]
include::{chapters}/VK_EXT_swapchain_maintenance1/SwapchainPresentModesCreateInfo.adoc[]
include::{chapters}/VK_EXT_swapchain_maintenance1/SwapchainPresentScalingCreateInfo.adoc[]
endif::VK_EXT_swapchain_maintenance1[]

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

Swapchains cannot: be destroyed <<SCID-4>>.
If
slink:VkPhysicalDeviceVulkanSC10Properties::<<limits-deviceDestroyFreesMemory,pname:deviceDestroyFreesMemory>>
is ename:VK_TRUE, the memory for swapchain images is returned to the system
when the device is destroyed.

endif::VKSC_VERSION_1_0[]
ifndef::VKSC_VERSION_1_0[]
[open,refpage='vkDestroySwapchainKHR',desc='Destroy a swapchain object',type='protos']
--
To destroy a swapchain object call:

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

  * pname:device is the slink:VkDevice associated with pname:swapchain.
  * pname:swapchain is the swapchain to destroy.
  * pname:pAllocator is the allocator used for host memory allocated for the
    swapchain object when there is no more specific allocator available (see
    <<memory-allocation,Memory Allocation>>).

The application must: not destroy a swapchain until after completion of all
outstanding operations on images that were acquired from the swapchain.
pname:swapchain and all associated sname:VkImage handles are destroyed, and
must: not be acquired or used any more by the application.
The memory of each sname:VkImage will only be freed after that image is no
longer used by the presentation engine.
For example, if one image of the swapchain is being displayed in a window,
the memory for that image may: not be freed until the window is destroyed,
or another swapchain is created for the window.
Destroying the swapchain does not invalidate the parent sname:VkSurfaceKHR,
and a new swapchain can: be created with it.

ifdef::VK_KHR_display_swapchain[]
include::{chapters}/VK_KHR_display_swapchain/destroy_swapchain_interactions.adoc[]
endif::VK_KHR_display_swapchain[]

ifdef::VK_EXT_full_screen_exclusive[]
If pname:swapchain has exclusive full-screen access, it is released before
the swapchain is destroyed.
endif::VK_EXT_full_screen_exclusive[]

.Valid Usage
****
  * [[VUID-vkDestroySwapchainKHR-swapchain-01282]]
    All uses of presentable images acquired from pname:swapchain must: have
    completed execution
ifndef::VKSC_VERSION_1_0[]
  * [[VUID-vkDestroySwapchainKHR-swapchain-01283]]
    If sname:VkAllocationCallbacks were provided when pname:swapchain was
    created, a compatible set of callbacks must: be provided here
  * [[VUID-vkDestroySwapchainKHR-swapchain-01284]]
    If no sname:VkAllocationCallbacks were provided when pname:swapchain was
    created, pname:pAllocator must: be `NULL`
endif::VKSC_VERSION_1_0[]
****

include::{generated}/validity/protos/vkDestroySwapchainKHR.adoc[]
--
endif::VKSC_VERSION_1_0[]

ifdef::VK_KHR_display_swapchain[]
include::{chapters}/VK_KHR_display_swapchain/create_shared_swapchains.adoc[]
endif::VK_KHR_display_swapchain[]

[open,refpage='vkGetSwapchainImagesKHR',desc='Obtain the array of presentable images associated with a swapchain',type='protos']
--
:refpage: vkGetSwapchainImagesKHR

To obtain the array of presentable images associated with a swapchain, call:

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

  * pname:device is the device associated with pname:swapchain.
  * pname:swapchain is the swapchain to query.
  * pname:pSwapchainImageCount is a pointer to an integer related to the
    number of presentable images available or queried, as described below.
  * pname:pSwapchainImages is either `NULL` or a pointer to an array of
    sname:VkImage handles.

If pname:pSwapchainImages is `NULL`, then the number of presentable images
for pname:swapchain is returned in pname:pSwapchainImageCount.
Otherwise, pname:pSwapchainImageCount must: point to a variable set by the
user to the number of elements in the pname:pSwapchainImages array, and on
return the variable is overwritten with the number of structures actually
written to pname:pSwapchainImages.
If the value of pname:pSwapchainImageCount is less than the number of
presentable images for pname:swapchain, at most pname:pSwapchainImageCount
structures will be written, and ename:VK_INCOMPLETE will be returned instead
of ename:VK_SUCCESS, to indicate that not all the available presentable
images were returned.

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

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

[NOTE]
.Note
====
By knowing all presentable images used in the swapchain, the application can
create command buffers that reference these images prior to entering its
main rendering loop.
ifdef::VK_EXT_swapchain_maintenance1[]
However, command buffers are not allowed to reference presentable images
created with ename:VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT
until their indices have been returned from flink:vkAcquireNextImageKHR at
least once.
endif::VK_EXT_swapchain_maintenance1[]
====

Images returned by flink:vkGetSwapchainImagesKHR are fully backed by memory
before they are passed to the application, as if they are each bound
completely and contiguously to a single sname:VkDeviceMemory object
ifdef::VK_EXT_swapchain_maintenance1[]
, unless the swapchain is created with the
ename:VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT flag
endif::VK_EXT_swapchain_maintenance1[]
.
All presentable images are initially in the ename:VK_IMAGE_LAYOUT_UNDEFINED
layout, thus before using presentable images, the application must:
transition them to a valid layout for the intended use.

ifndef::VKSC_VERSION_1_0[]

Further, the lifetime of presentable images is controlled by the
implementation, so applications must: not destroy a presentable image.
See flink:vkDestroySwapchainKHR for further details on the lifetime of
presentable images.

endif::VKSC_VERSION_1_0[]

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]

Images can: also be created by using flink:vkCreateImage with
slink:VkImageSwapchainCreateInfoKHR and bound to swapchain memory using
flink:vkBindImageMemory2 with slink:VkBindImageMemorySwapchainInfoKHR.
These images can: be used anywhere swapchain images are used, and are useful
in logical devices with multiple physical devices to create peer memory
bindings of swapchain memory.
These images and bindings have no effect on what memory is presented.
Unlike images retrieved from fname:vkGetSwapchainImagesKHR, these images
must: be destroyed with flink:vkDestroyImage.

endif::VK_VERSION_1_1,VK_KHR_device_group[]

[open,refpage='vkAcquireNextImageKHR',desc='Retrieve the index of the next available presentable image',type='protos']
--
:refpage: vkAcquireNextImageKHR

To acquire an available presentable image to use, and retrieve the index of
that image, call:

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

  * pname:device is the device associated with pname:swapchain.
  * pname:swapchain is the non-retired swapchain from which an image is
    being acquired.
  * pname:timeout specifies how long the function waits, in nanoseconds, if
    no image is available.
  * pname:semaphore is dlink:VK_NULL_HANDLE or a semaphore to signal.
  * pname:fence is dlink:VK_NULL_HANDLE or a fence to signal.
  * pname:pImageIndex is a pointer to a code:uint32_t in which the index of
    the next image to use (i.e. an index into the array of images returned
    by fname:vkGetSwapchainImagesKHR) is returned.

ifdef::VK_EXT_swapchain_maintenance1[]
If the pname:swapchain has been created with the
ename:VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT flag, the image
whose index is returned in pname:pImageIndex will be fully backed by memory
before this call returns to the application, as if it is bound completely
and contiguously to a single sname:VkDeviceMemory object.
endif::VK_EXT_swapchain_maintenance1[]

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

.Valid Usage
****
  * [[VUID-vkAcquireNextImageKHR-swapchain-01285]]
    pname:swapchain must: not be in the retired state
  * [[VUID-vkAcquireNextImageKHR-semaphore-01286]]
    If pname:semaphore is not dlink:VK_NULL_HANDLE it must: be unsignaled
  * [[VUID-vkAcquireNextImageKHR-semaphore-01779]]
    If pname:semaphore is not dlink:VK_NULL_HANDLE it must: not have any
    uncompleted signal or wait operations pending
  * [[VUID-vkAcquireNextImageKHR-fence-01287]]
    If pname:fence is not dlink:VK_NULL_HANDLE it must: be unsignaled and
    must: not be associated with any other queue command that has not yet
    completed execution on that queue
  * [[VUID-vkAcquireNextImageKHR-semaphore-01780]]
    pname:semaphore and pname:fence must: not both be equal to
    dlink:VK_NULL_HANDLE
  * [[VUID-vkAcquireNextImageKHR-surface-07783]]
    If <<swapchain-acquire-forward-progress,forward progress>> cannot be
    guaranteed for the pname:surface used to create the pname:swapchain
    member of pname:pAcquireInfo, the pname:timeout member of
    pname:pAcquireInfo must: not be code:UINT64_MAX
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
  * [[VUID-vkAcquireNextImageKHR-semaphore-03265]]
    pname:semaphore must: have a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_BINARY
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
****

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

If an image is acquired successfully, fname:vkAcquireNextImageKHR must:
either return ename:VK_SUCCESS or ename:VK_SUBOPTIMAL_KHR.
The implementation may: return ename:VK_SUBOPTIMAL_KHR if the swapchain no
longer matches the surface properties exactly, but can: still be used for
presentation.

When successful, fname:vkAcquireNextImageKHR acquires a presentable image
from pname:swapchain that an application can: use, and sets
pname:pImageIndex to the index of that image within the swapchain.
The presentation engine may: not have finished reading from the image at the
time it is acquired, so the application must: use pname:semaphore and/or
pname:fence to ensure that the image layout and contents are not modified
until the presentation engine reads have completed.
Once fname:vkAcquireNextImageKHR successfully acquires an image, the
semaphore signal operation referenced by pname:semaphore, if not
dlink:VK_NULL_HANDLE, and the fence signal operation referenced by
pname:fence, if not dlink:VK_NULL_HANDLE, are submitted for execution.
If fname:vkAcquireNextImageKHR does not successfully acquire an image,
pname:semaphore and pname:fence are unaffected.
The order in which images are acquired is implementation-dependent, and may:
be different than the order the images were presented.

If pname:timeout is zero, then fname:vkAcquireNextImageKHR does not wait,
and will either successfully acquire an image, or fail and return
ename:VK_NOT_READY if no image is available.

If the specified timeout period expires before an image is acquired,
fname:vkAcquireNextImageKHR returns ename:VK_TIMEOUT.
If pname:timeout is code:UINT64_MAX, the timeout period is treated as
infinite, and fname:vkAcquireNextImageKHR will block until an image is
acquired or an error occurs.

[[swapchain-acquire-forward-progress]]
Let [eq]#S# be the number of images in pname:swapchain.
ifndef::VK_EXT_swapchain_maintenance1[]
Let [eq]#M# be the value of
slink:VkSurfaceCapabilitiesKHR::pname:minImageCount.
endif::VK_EXT_swapchain_maintenance1[]
ifdef::VK_EXT_swapchain_maintenance1[]
If pname:swapchain is created with
slink:VkSwapchainPresentModesCreateInfoEXT, let [eq]#M# be the maximum of
the values in slink:VkSurfaceCapabilitiesKHR::pname:minImageCount when
queried with each present mode in
slink:VkSwapchainPresentModesCreateInfoEXT::pname:pPresentModes in
slink:VkSurfacePresentModeEXT.
Otherwise, let [eq]#M# be the value of
slink:VkSurfaceCapabilitiesKHR::pname:minImageCount without a
slink:VkSurfacePresentModeEXT as part of the query input.
endif::VK_EXT_swapchain_maintenance1[]

fname:vkAcquireNextImageKHR should: not be called if the number of images
that the application has currently acquired is greater than [eq]#S-M#.
If fname:vkAcquireNextImageKHR is called when the number of images that the
application has currently acquired is less than or equal to [eq]#S-M#,
fname:vkAcquireNextImageKHR must: return in finite time with an allowed
ename:VkResult code.

[NOTE]
.Note
====
Returning a result in finite time guarantees that the implementation cannot
deadlock an application, or suspend its execution indefinitely with correct
API usage.
Acquiring too many images at once may block indefinitely, which is covered
by valid usage when attempting to use code:UINT64_MAX.
For example, a scenario here is when a compositor holds on to images which
are currently being presented, and there are not any vacant images left to
be acquired.
====

[NOTE]
.Note
====
ename:VK_SUBOPTIMAL_KHR may: happen, for example, if the platform surface
has been resized but the platform is able to scale the presented images to
the new size to produce valid surface updates.
It is up to the application to decide whether it prefers to continue using
the current swapchain in this state, or to re-create the swapchain to better
match the platform surface properties.
====

If the swapchain images no longer match native surface properties, either
ename:VK_SUBOPTIMAL_KHR or ename:VK_ERROR_OUT_OF_DATE_KHR must: be returned.
If ename:VK_ERROR_OUT_OF_DATE_KHR is returned, no image is acquired and
attempts to present previously acquired images to the swapchain will also
fail with ename:VK_ERROR_OUT_OF_DATE_KHR.
Applications need to create a new swapchain for the surface to continue
presenting if ename:VK_ERROR_OUT_OF_DATE_KHR is returned.

If device loss occurs (see <<devsandqueues-lost-device,Lost Device>>) before
the timeout has expired, fname:vkAcquireNextImageKHR must: return in finite
time with either one of the allowed success codes, or
ename:VK_ERROR_DEVICE_LOST.

If pname:semaphore is not dlink:VK_NULL_HANDLE, the semaphore must: be
unsignaled, with no signal or wait operations pending.
It will become signaled when the application can: use the image.

[NOTE]
.Note
====
Use of pname:semaphore allows rendering operations to be recorded and
submitted before the presentation engine has completed its use of the image.
====

If pname:fence is not equal to dlink:VK_NULL_HANDLE, the fence must: be
unsignaled, with no signal operations pending.
It will become signaled when the application can: use the image.

[NOTE]
.Note
====
Applications should: not rely on fname:vkAcquireNextImageKHR blocking in
order to meter their rendering speed.
The implementation may: return from this function immediately regardless of
how many presentation requests are queued, and regardless of when queued
presentation requests will complete relative to the call.
Instead, applications can: use pname:fence to meter their frame generation
work to match the presentation rate.
====

An application must: wait until either the pname:semaphore or pname:fence is
signaled before accessing the image's data.

[NOTE]
.Note
====
When the presentable image will be accessed by some stage [eq]#S#, the
recommended idiom for ensuring correct synchronization is:

  * The slink:VkSubmitInfo used to submit the image layout transition for
    execution includes fname:vkAcquireNextImageKHR::pname:semaphore in its
    pname:pWaitSemaphores member, with the corresponding element of
    pname:pWaitDstStageMask including [eq]#S#.
  * The <<synchronization, synchronization command>> that performs any
    necessary image layout transition includes [eq]#S# in both the
    pname:srcStageMask and pname:dstStageMask.
====

After a successful return, the image indicated by pname:pImageIndex and its
data will be unmodified compared to when it was presented.

[NOTE]
.Note
====
Exclusive ownership of presentable images corresponding to a swapchain
created with ename:VK_SHARING_MODE_EXCLUSIVE as defined in
<<resources-sharing,Resource Sharing>> is not altered by a call to
fname:vkAcquireNextImageKHR.
That means upon the first acquisition from such a swapchain presentable
images are not owned by any queue family, while at subsequent acquisitions
the presentable images remain owned by the queue family the image was
previously presented on.
====

The possible return values for fname:vkAcquireNextImageKHR depend on the
pname:timeout provided:

  * ename:VK_SUCCESS is returned if an image became available.
  * ename:VK_ERROR_SURFACE_LOST_KHR is returned if the surface becomes no
    longer available.
  * ename:VK_NOT_READY is returned if pname:timeout is zero and no image was
    available.
  * ename:VK_TIMEOUT is returned if pname:timeout is greater than zero and
    less than code:UINT64_MAX, and no image became available within the time
    allowed.
  * ename:VK_SUBOPTIMAL_KHR is returned if an image became available, and
    the swapchain no longer matches the surface properties exactly, but can:
    still be used to present to the surface successfully.

[NOTE]
.Note
====
This may: happen, for example, if the platform surface has been resized but
the platform is able to scale the presented images to the new size to
produce valid surface updates.
It is up to the application to decide whether it prefers to continue using
the current swapchain indefinitely or temporarily in this state, or to
re-create the swapchain to better match the platform surface properties.
====

  * ename:VK_ERROR_OUT_OF_DATE_KHR is returned if the surface has changed in
    such a way that it is no longer compatible with the swapchain, and
    further presentation requests using the swapchain will fail.
    Applications must: query the new surface properties and recreate their
    swapchain if they wish to continue presenting to the surface.

If the native surface and presented image sizes no longer match,
presentation may: fail
ifdef::VK_EXT_swapchain_maintenance1[]
unless the swapchain is created with a non-zero value in
slink:VkSwapchainPresentScalingCreateInfoEXT::pname:scalingBehavior
endif::VK_EXT_swapchain_maintenance1[]
.
If presentation does succeed, the mapping from the presented image to the
native surface is
ifdef::VK_EXT_swapchain_maintenance1[]
defined by the slink:VkSwapchainPresentScalingCreateInfoEXT structure if
provided.
Otherwise it is
endif::VK_EXT_swapchain_maintenance1[]
implementation-defined.
It is the application's responsibility to detect surface size changes and
react appropriately.
If presentation fails because of a mismatch in the surface and presented
image sizes, a ename:VK_ERROR_OUT_OF_DATE_KHR error will be returned.

[NOTE]
.Note
====
For example, consider a 4x3 window/surface that gets resized to be 3x4
(taller than wider).
On some window systems, the portion of the window/surface that was
previously and still is visible (the 3x3 part) will contain the same
contents as before, while the remaining parts of the window will have
undefined: contents.
Other window systems may: squash/stretch the image to fill the new window
size without any undefined: contents, or apply some other mapping.
====

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
[open,refpage='vkAcquireNextImage2KHR',desc='Retrieve the index of the next available presentable image',type='protos']
--
:refpage: vkAcquireNextImage2KHR

To acquire an available presentable image to use, and retrieve the index of
that image, call:

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

  * pname:device is the device associated with pname:swapchain.
  * pname:pAcquireInfo is a pointer to a slink:VkAcquireNextImageInfoKHR
    structure containing parameters of the acquire.
  * pname:pImageIndex is a pointer to a code:uint32_t that is set to the
    index of the next image to use.

ifdef::VK_EXT_swapchain_maintenance1[]
If the pname:swapchain has been created with the
ename:VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT flag, the image
whose index is returned in pname:pImageIndex will be fully backed by memory
before this call returns to the application.
endif::VK_EXT_swapchain_maintenance1[]

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

.Valid Usage
****
  * [[VUID-vkAcquireNextImage2KHR-surface-07784]]
    If <<swapchain-acquire-forward-progress,forward progress>> cannot be
    guaranteed for the pname:surface used to create pname:swapchain, the
    pname:timeout member of pname:pAcquireInfo must: not be code:UINT64_MAX
****

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

[open,refpage='VkAcquireNextImageInfoKHR',desc='Structure specifying parameters of the acquire',type='structs']
--
The sname:VkAcquireNextImageInfoKHR structure is defined as:

include::{generated}/api/structs/VkAcquireNextImageInfoKHR.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:swapchain is a non-retired swapchain from which an image is
    acquired.
  * pname:timeout specifies how long the function waits, in nanoseconds, if
    no image is available.
  * pname:semaphore is dlink:VK_NULL_HANDLE or a semaphore to signal.
  * pname:fence is dlink:VK_NULL_HANDLE or a fence to signal.
  * pname:deviceMask is a mask of physical devices for which the swapchain
    image will be ready to use when the semaphore or fence is signaled.

If flink:vkAcquireNextImageKHR is used, the device mask is considered to
include all physical devices in the logical device.

[NOTE]
.Note
====
flink:vkAcquireNextImage2KHR signals at most one semaphore, even if the
application requests waiting for multiple physical devices to be ready via
the pname:deviceMask.
However, only a single physical device can: wait on that semaphore, since
the semaphore becomes unsignaled when the wait succeeds.
For other physical devices to wait for the image to be ready, it is
necessary for the application to submit semaphore signal operation(s) to
that first physical device to signal additional semaphore(s) after the wait
succeeds, which the other physical device(s) can: wait upon.
====

.Valid Usage
****
  * [[VUID-VkAcquireNextImageInfoKHR-swapchain-01675]]
    pname:swapchain must: not be in the retired state
  * [[VUID-VkAcquireNextImageInfoKHR-semaphore-01288]]
    If pname:semaphore is not dlink:VK_NULL_HANDLE it must: be unsignaled
  * [[VUID-VkAcquireNextImageInfoKHR-semaphore-01781]]
    If pname:semaphore is not dlink:VK_NULL_HANDLE it must: not have any
    uncompleted signal or wait operations pending
  * [[VUID-VkAcquireNextImageInfoKHR-fence-01289]]
    If pname:fence is not dlink:VK_NULL_HANDLE it must: be unsignaled and
    must: not be associated with any other queue command that has not yet
    completed execution on that queue
  * [[VUID-VkAcquireNextImageInfoKHR-semaphore-01782]]
    pname:semaphore and pname:fence must: not both be equal to
    dlink:VK_NULL_HANDLE
  * [[VUID-VkAcquireNextImageInfoKHR-deviceMask-01290]]
    pname:deviceMask must: be a valid device mask
  * [[VUID-VkAcquireNextImageInfoKHR-deviceMask-01291]]
    pname:deviceMask must: not be zero
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
  * [[VUID-VkAcquireNextImageInfoKHR-semaphore-03266]]
    pname:semaphore must: have a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_BINARY
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
****

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

[open,refpage='vkQueuePresentKHR',desc='Queue an image for presentation',type='protos']
--
:refpage: vkQueuePresentKHR

After queueing all rendering commands and transitioning the image to the
correct layout, to queue an image for presentation, call:

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

  * pname:queue is a queue that is capable of presentation to the target
    surface's platform on the same device as the image's swapchain.
  * pname:pPresentInfo is a pointer to a slink:VkPresentInfoKHR structure
    specifying parameters of the presentation.

.Note
[NOTE]
====
There is no requirement for an application to present images in the same
order that they were acquired - applications can arbitrarily present any
image that is currently acquired.
====

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

.Valid Usage
****
  * [[VUID-vkQueuePresentKHR-pSwapchains-01292]]
    Each element of pname:pSwapchains member of pname:pPresentInfo must: be
    a swapchain that is created for a surface for which presentation is
    supported from pname:queue as determined using a call to
    fname:vkGetPhysicalDeviceSurfaceSupportKHR
ifdef::VK_KHR_display_swapchain[]
  * [[VUID-vkQueuePresentKHR-pSwapchains-01293]]
    If more than one member of pname:pSwapchains was created from a display
    surface, all display surfaces referenced that refer to the same display
    must: use the same display mode
endif::VK_KHR_display_swapchain[]
  * [[VUID-vkQueuePresentKHR-pWaitSemaphores-01294]]
    When a semaphore wait operation referring to a binary semaphore defined
    by the elements of the pname:pWaitSemaphores member of
    pname:pPresentInfo executes on pname:queue, there must: be no other
    queues waiting on the same semaphore
ifndef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
  * [[VUID-vkQueuePresentKHR-pWaitSemaphores-01295]]
    All elements of the pname:pWaitSemaphores member of pname:pPresentInfo
    must: be semaphores that are signaled, or have
    <<synchronization-semaphores-signaling, semaphore signal operations>>
    previously submitted for execution
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
ifdef::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
  * [[VUID-vkQueuePresentKHR-pWaitSemaphores-03267]]
    All elements of the pname:pWaitSemaphores member of pname:pPresentInfo
    must: be created with a elink:VkSemaphoreType of
    ename:VK_SEMAPHORE_TYPE_BINARY
  * [[VUID-vkQueuePresentKHR-pWaitSemaphores-03268]]
    All elements of the pname:pWaitSemaphores member of pname:pPresentInfo
    must: reference a semaphore signal operation that has been submitted for
    execution and any <<synchronization-semaphores-signaling, semaphore
    signal operations>> on which it depends (if any) must: have also been
    submitted for execution
endif::VK_VERSION_1_2,VK_KHR_timeline_semaphore[]
****

Any writes to memory backing the images referenced by the
pname:pImageIndices and pname:pSwapchains members of pname:pPresentInfo,
that are available before flink:vkQueuePresentKHR is executed, are
automatically made visible to the read access performed by the presentation
engine.
This automatic visibility operation for an image happens-after the semaphore
signal operation, and happens-before the presentation engine accesses the
image.

Queueing an image for presentation defines a set of _queue operations_,
including waiting on the semaphores and submitting a presentation request to
the presentation engine.
However, the scope of this set of queue operations does not include the
actual processing of the image by the presentation engine.

.Note
[NOTE]
====
The origin of the native orientation of the surface coordinate system is not
specified in the Vulkan specification; it depends on the platform.
For most platforms the origin is by default upper-left, meaning the pixel of
the presented slink:VkImage at coordinates [eq]#(0,0)# would appear at the
upper left pixel of the platform surface (assuming
ename:VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, and the display standing the
right way up).
====

If fname:vkQueuePresentKHR fails to enqueue the corresponding set of queue
operations, 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 is unaffected by the
call or its failure.

If fname:vkQueuePresentKHR fails in such a way that the implementation is
unable to make that guarantee, the implementation must: return
ename:VK_ERROR_DEVICE_LOST.

However, if the presentation request is rejected by the presentation engine
with an error ename:VK_ERROR_OUT_OF_DATE_KHR,
ifdef::VK_EXT_full_screen_exclusive[]
ename:VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT,
endif::VK_EXT_full_screen_exclusive[]
or ename:VK_ERROR_SURFACE_LOST_KHR, the set of queue operations are still
considered to be enqueued and thus any semaphore wait operation specified in
slink:VkPresentInfoKHR will execute when the corresponding queue operation
is complete.

Calls to fname:vkQueuePresentKHR may: block, but must: return in finite
time.

ifdef::VK_EXT_full_screen_exclusive[]
If any pname:swapchain member of pname:pPresentInfo was created with
ename:VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT,
ename:VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT will be returned if that
swapchain does not have exclusive full-screen access, possibly for
implementation-specific reasons outside of the application's control.
endif::VK_EXT_full_screen_exclusive[]

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

[open,refpage='VkPresentInfoKHR',desc='Structure describing parameters of a queue presentation',type='structs']
--
The sname:VkPresentInfoKHR structure is defined as:

include::{generated}/api/structs/VkPresentInfoKHR.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 to wait for before
    issuing the present request.
    The number may: be zero.
  * pname:pWaitSemaphores is `NULL` or a pointer to an array of
    slink:VkSemaphore objects with pname:waitSemaphoreCount entries, and
    specifies the semaphores to wait for before issuing the present request.
  * pname:swapchainCount is the number of swapchains being presented to by
    this command.
  * pname:pSwapchains is a pointer to an array of slink:VkSwapchainKHR
    objects with pname:swapchainCount entries.
  * pname:pImageIndices is a pointer to an array of indices into the array
    of each swapchain's presentable images, with pname:swapchainCount
    entries.
    Each entry in this array identifies the image to present on the
    corresponding entry in the pname:pSwapchains array.
  * pname:pResults is a pointer to an array of elink:VkResult typed elements
    with pname:swapchainCount entries.
    Applications that do not need per-swapchain results can: use `NULL` for
    pname:pResults.
    If non-`NULL`, each entry in pname:pResults will be set to the
    elink:VkResult for presenting the swapchain corresponding to the same
    index in pname:pSwapchains.

Before an application can: present an image, the image's layout must: be
transitioned to the ename:VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
ifdef::VK_KHR_shared_presentable_image[]
layout, or for a shared presentable image the
ename:VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR
endif::VK_KHR_shared_presentable_image[]
layout.

.Note
[NOTE]
====
When transitioning the image to
ifdef::VK_KHR_shared_presentable_image[]
ename:VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or
endif::VK_KHR_shared_presentable_image[]
ename:VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, there is no need to delay subsequent
processing, or perform any visibility operations (as flink:vkQueuePresentKHR
performs automatic visibility operations).
To achieve this, the pname:dstAccessMask member of the
slink:VkImageMemoryBarrier should: be set to `0`, and the pname:dstStageMask
parameter should: be set to ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT.
====

.Valid Usage
****
  * [[VUID-VkPresentInfoKHR-pSwapchain-09231]]
    Elements of pname:pSwapchain must: be unique
ifndef::VK_KHR_shared_presentable_image[]
  * [[VUID-VkPresentInfoKHR-pImageIndices-01296]]
    Each element of pname:pImageIndices must: be the index of a presentable
    image acquired from the swapchain specified by the corresponding element
    of the pname:pSwapchains array, and the presented image subresource
    must: be in the ename:VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout at the time
    the operation is executed on a sname:VkDevice
endif::VK_KHR_shared_presentable_image[]
ifdef::VK_KHR_shared_presentable_image[]
  * [[VUID-VkPresentInfoKHR-pImageIndices-01430]]
    Each element of pname:pImageIndices must: be the index of a presentable
    image acquired from the swapchain specified by the corresponding element
    of the pname:pSwapchains array, and the presented image subresource
    must: be in the ename:VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or
    ename:VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR layout at the time the
    operation is executed on a sname:VkDevice
endif::VK_KHR_shared_presentable_image[]
ifdef::VK_KHR_present_id[]
  * [[VUID-VkPresentInfoKHR-pNext-06235]]
    If a slink:VkPresentIdKHR structure is included in the pname:pNext
    chain, and the <<features-presentId, pname:presentId>> feature is not
    enabled, each pname:presentIds entry in that structure must: be NULL
endif::VK_KHR_present_id[]
ifdef::VK_EXT_swapchain_maintenance1[]
  * [[VUID-VkPresentInfoKHR-pSwapchains-09199]]
    If any element of the pname:pSwapchains array has been created with
    slink:VkSwapchainPresentModesCreateInfoEXT, all of the elements of this
    array must: be created with slink:VkSwapchainPresentModesCreateInfoEXT
endif::VK_EXT_swapchain_maintenance1[]
****

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

ifdef::VK_KHR_incremental_present[]
include::{chapters}/VK_KHR_incremental_present/wsi.adoc[]
endif::VK_KHR_incremental_present[]

ifdef::VK_KHR_display_swapchain[]
include::{chapters}/VK_KHR_display_swapchain/display_swapchain_present.adoc[]
endif::VK_KHR_display_swapchain[]

ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
[open,refpage='VkDeviceGroupPresentInfoKHR',desc='Mode and mask controlling which physical devices\' images are presented',type='structs']
--
If the pname:pNext chain of slink:VkPresentInfoKHR includes a
sname:VkDeviceGroupPresentInfoKHR structure, then that structure includes an
array of device masks and a device group present mode.

The sname:VkDeviceGroupPresentInfoKHR structure is defined as:

include::{generated}/api/structs/VkDeviceGroupPresentInfoKHR.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:swapchainCount is zero or the number of elements in
    pname:pDeviceMasks.
  * pname:pDeviceMasks is a pointer to an array of device masks, one for
    each element of slink:VkPresentInfoKHR::pname:pSwapchains.
  * pname:mode is a elink:VkDeviceGroupPresentModeFlagBitsKHR value
    specifying the device group present mode that will be used for this
    present.

If pname:mode is ename:VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR, then each
element of pname:pDeviceMasks selects which instance of the swapchain image
is presented.
Each element of pname:pDeviceMasks must: have exactly one bit set, and the
corresponding physical device must: have a presentation engine as reported
by slink:VkDeviceGroupPresentCapabilitiesKHR.

If pname:mode is ename:VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR, then
each element of pname:pDeviceMasks selects which instance of the swapchain
image is presented.
Each element of pname:pDeviceMasks must: have exactly one bit set, and some
physical device in the logical device must: include that bit in its
slink:VkDeviceGroupPresentCapabilitiesKHR::pname:presentMask.

If pname:mode is ename:VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR, then each
element of pname:pDeviceMasks selects which instances of the swapchain image
are component-wise summed and the sum of those images is presented.
If the sum in any component is outside the representable range, the value of
that component is undefined:.
Each element of pname:pDeviceMasks must: have a value for which all set bits
are set in one of the elements of
slink:VkDeviceGroupPresentCapabilitiesKHR::pname:presentMask.

If pname:mode is
ename:VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR, then each
element of pname:pDeviceMasks selects which instance(s) of the swapchain
images are presented.
For each bit set in each element of pname:pDeviceMasks, the corresponding
physical device must: have a presentation engine as reported by
slink:VkDeviceGroupPresentCapabilitiesKHR.

If sname:VkDeviceGroupPresentInfoKHR is not provided or pname:swapchainCount
is zero then the masks are considered to be `1`.
If sname:VkDeviceGroupPresentInfoKHR is not provided, pname:mode is
considered to be ename:VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR.

.Valid Usage
****
  * [[VUID-VkDeviceGroupPresentInfoKHR-swapchainCount-01297]]
    pname:swapchainCount must: equal `0` or
    slink:VkPresentInfoKHR::pname:swapchainCount
  * [[VUID-VkDeviceGroupPresentInfoKHR-mode-01298]]
    If pname:mode is ename:VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR, then
    each element of pname:pDeviceMasks must: have exactly one bit set, and
    the corresponding element of
    slink:VkDeviceGroupPresentCapabilitiesKHR::pname:presentMask must: be
    non-zero
  * [[VUID-VkDeviceGroupPresentInfoKHR-mode-01299]]
    If pname:mode is ename:VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR, then
    each element of pname:pDeviceMasks must: have exactly one bit set, and
    some physical device in the logical device must: include that bit in its
    slink:VkDeviceGroupPresentCapabilitiesKHR::pname:presentMask
  * [[VUID-VkDeviceGroupPresentInfoKHR-mode-01300]]
    If pname:mode is ename:VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR, then
    each element of pname:pDeviceMasks must: have a value for which all set
    bits are set in one of the elements of
    slink:VkDeviceGroupPresentCapabilitiesKHR::pname:presentMask
  * [[VUID-VkDeviceGroupPresentInfoKHR-mode-01301]]
    If pname:mode is
    ename:VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR, then for
    each bit set in each element of pname:pDeviceMasks, the corresponding
    element of slink:VkDeviceGroupPresentCapabilitiesKHR::pname:presentMask
    must: be non-zero
  * [[VUID-VkDeviceGroupPresentInfoKHR-pDeviceMasks-01302]]
    The value of each element of pname:pDeviceMasks must: be equal to the
    device mask passed in slink:VkAcquireNextImageInfoKHR::pname:deviceMask
    when the image index was last acquired
  * [[VUID-VkDeviceGroupPresentInfoKHR-mode-01303]]
    pname:mode must: have exactly one bit set, and that bit must: have been
    included in slink:VkDeviceGroupSwapchainCreateInfoKHR::pname:modes
****

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

ifdef::VK_GOOGLE_display_timing[]
include::{chapters}/VK_GOOGLE_display_timing/PresentTimeInfo.adoc[]
endif::VK_GOOGLE_display_timing[]

ifdef::VK_KHR_present_id[]
include::{chapters}/VK_KHR_swapchain/PresentId.adoc[]
endif::VK_KHR_present_id[]

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

ifdef::VK_EXT_swapchain_maintenance1[]
include::{chapters}/VK_EXT_swapchain_maintenance1/SwapchainPresentModeInfo.adoc[]
include::{chapters}/VK_EXT_swapchain_maintenance1/SwapchainPresentFenceInfo.adoc[]
endif::VK_EXT_swapchain_maintenance1[]

fname:vkQueuePresentKHR releases the acquisition of the images referenced by
pname:imageIndices.
The queue family corresponding to the queue fname:vkQueuePresentKHR is
executed on must: have ownership of the presented images as defined in
<<resources-sharing,Resource Sharing>>.
fname:vkQueuePresentKHR does not alter the queue family ownership, but the
presented images must: not be used again before they have been reacquired
using fname:vkAcquireNextImageKHR.

The processing of the presentation happens in issue order with other queue
operations, but semaphores have to be used to ensure that prior rendering
and other commands in the specified queue complete before the presentation
begins.
The presentation command itself does not delay processing of subsequent
commands on the queue, however, presentation requests sent to a particular
queue are always performed in order.
Exact presentation timing is controlled by the semantics of the presentation
engine and native platform in use.

ifdef::VK_KHR_display_swapchain[]
include::{chapters}/VK_KHR_display_swapchain/queue_present_interactions.adoc[]
endif::VK_KHR_display_swapchain[]

The result codes ename:VK_ERROR_OUT_OF_DATE_KHR and ename:VK_SUBOPTIMAL_KHR
have the same meaning when returned by fname:vkQueuePresentKHR as they do
when returned by fname:vkAcquireNextImageKHR.
If multiple swapchains are presented, the result code is determined applying
the following rules in order:

  * If the device is lost, ename:VK_ERROR_DEVICE_LOST is returned.
  * If any of the target surfaces are no longer available the error
    ename:VK_ERROR_SURFACE_LOST_KHR is returned.
  * If any of the presents would have a result of
    ename:VK_ERROR_OUT_OF_DATE_KHR if issued separately then
    ename:VK_ERROR_OUT_OF_DATE_KHR is returned.
ifdef::VK_EXT_full_screen_exclusive[]
  * If any of the presents would have a result of
    ename:VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT if issued separately
    then ename:VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT is returned.
endif::VK_EXT_full_screen_exclusive[]
  * If any of the presents would have a result of ename:VK_SUBOPTIMAL_KHR if
    issued separately then ename:VK_SUBOPTIMAL_KHR is returned.
  * Otherwise ename:VK_SUCCESS is returned.

Presentation is a read-only operation that will not affect the content of
the presentable images.
Upon reacquiring the image and transitioning it away from the
ename:VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout, the contents will be the same
as they were prior to transitioning the image to the present source layout
and presenting it.
However, if a mechanism other than Vulkan is used to modify the platform
window associated with the swapchain, the content of all presentable images
in the swapchain becomes undefined:.

[NOTE]
.Note
====
The application can: continue to present any acquired images from a retired
swapchain as long as the swapchain has not entered a state that causes
flink:vkQueuePresentKHR to return ename:VK_ERROR_OUT_OF_DATE_KHR.
====

ifdef::VK_EXT_swapchain_maintenance1[]
[open,refpage='vkReleaseSwapchainImagesEXT',desc='Release previously acquired but unused images',type='protos']
--
To release images previously acquired through
ifdef::VK_VERSION_1_1,VK_KHR_device_group[flink:vkAcquireNextImage2KHR or]
flink:vkAcquireNextImageKHR, call:

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

  * pname:device is the device associated with
    slink:VkReleaseSwapchainImagesInfoEXT::pname:swapchain.
  * pname:pReleaseInfo is a pointer to a
    slink:VkReleaseSwapchainImagesInfoEXT structure containing parameters of
    the release.

Only images that are not in use by the device can: be released.

Releasing images is a read-only operation that will not affect the content
of the released images.
Upon reacquiring the image, the image contents and its layout will be the
same as they were prior to releasing it.
However, if a mechanism other than Vulkan is used to modify the platform
window associated with the swapchain, the content of all presentable images
in the swapchain becomes undefined:.

.Note
[NOTE]
====
This functionality is useful during swapchain recreation, where acquired
images from the old swapchain can be released instead of presented.
====

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

[open,refpage='VkReleaseSwapchainImagesInfoEXT',desc='Structure describing a list of swapchain image indices to be released',type='structs']
--
The sname:VkReleaseSwapchainImagesInfoEXT structure is defined as:

include::{generated}/api/structs/VkReleaseSwapchainImagesInfoEXT.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:swapchain is a swapchain to which images are being released.
  * pname:imageIndexCount is the number of image indices to be released.
  * pname:pImageIndices is a pointer to an array of indices into the array
    of pname:swapchain's presentable images, with pname:imageIndexCount
    entries.

.Valid Usage
****
  * [[VUID-VkReleaseSwapchainImagesInfoEXT-pImageIndices-07785]]
    Each element of pname:pImageIndices must: be the index of a presentable
    image acquired from the swapchain specified by pname:swapchain
  * [[VUID-VkReleaseSwapchainImagesInfoEXT-pImageIndices-07786]]
    All uses of presentable images identified by elements of
    pname:pImageIndices must: have completed execution
****

include::{generated}/validity/structs/VkReleaseSwapchainImagesInfoEXT.adoc[]
--
endif::VK_EXT_swapchain_maintenance1[]

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