## 29.6. WSI Swapchain

A `VkSwapchainKHR` object (a.k.a. swapchain) provides the ability to present rendering results to a surface. A swapchain is an abstraction for an array of presentable images that are associated with a surface. The swapchain images are represented by `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 swapchain at a time. Further, swapchains cannot be created for native windows that have a non-Vulkan graphics API surface associated with them.

The presentation engine is an abstraction for the platform’s compositor or hardware/software display engine.

| Note
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 `vkAcquireNextImageKHR`, and before it is presented by `vkQueuePresentKHR`. This includes transitioning the image layout and rendering commands.

An application can acquire use of a presentable image with `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 `vkQueuePresentKHR`, which releases the acquisition of the image.

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

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

To create a swapchain, call:

    VkResult vkCreateSwapchainKHR(
        VkDevice                                    device,
        const VkSwapchainCreateInfoKHR*             pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkSwapchainKHR*                             pSwapchain);

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

The `VkSwapchainCreateInfoKHR` structure is defined as:

    typedef struct VkSwapchainCreateInfoKHR {
        VkStructureType                  sType;
        const void*                      pNext;
        VkSwapchainCreateFlagsKHR        flags;
        VkSurfaceKHR                     surface;
        uint32_t                         minImageCount;
        VkFormat                         imageFormat;
        VkColorSpaceKHR                  imageColorSpace;
        VkExtent2D                       imageExtent;
        uint32_t                         imageArrayLayers;
        VkImageUsageFlags                imageUsage;
        VkSharingMode                    imageSharingMode;
        uint32_t                         queueFamilyIndexCount;
        const uint32_t*                  pQueueFamilyIndices;
        VkSurfaceTransformFlagBitsKHR    preTransform;
        VkCompositeAlphaFlagBitsKHR      compositeAlpha;
        VkPresentModeKHR                 presentMode;
        VkBool32                         clipped;
        VkSwapchainKHR                   oldSwapchain;
    } VkSwapchainCreateInfoKHR;

- `sType` is the type of this structure and must be `VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR`.
- `pNext` is `NULL` or a pointer to an extension-specific structure.
- `flags` is reserved for future use, and must be zero.
- `surface` is the surface that the swapchain will present images to.
- `minImageCount` is the minimum number of presentable images that the application needs. The platform will either create the swapchain with at least that many images, or will fail to create the swapchain.
- `imageFormat` is a `VkFormat` that is valid for swapchains on the specified surface.
- `imageColorSpace` is a `VkColorSpaceKHR` that is valid for swapchains on the specified surface.
- `imageExtent` is the size (in pixels) of the swapchain. Behavior is platform-dependent when the image extent does not match the surface’s `currentExtent` as returned by `vkGetPhysicalDeviceSurfaceCapabilitiesKHR`.
- `imageArrayLayers` is the number of views in a multiview/stereo surface. For non-stereoscopic-3D applications, this value is 1.
- `imageUsage` is a bitmask of `VkImageUsageFlagBits`, indicating how the application will use the swapchain’s presentable images.
- `imageSharingMode` is the sharing mode used for the images of the swapchain.
- `queueFamilyIndexCount` is the number of queue families having access to the images of the swapchain in case `imageSharingMode` is `VK_SHARING_MODE_CONCURRENT`.
- `pQueueFamilyIndices` is an array of queue family indices having access to the images of the swapchain in case `imageSharingMode` is `VK_SHARING_MODE_CONCURRENT`.
- `preTransform` is a bitmask of `VkSurfaceTransformFlagBitsKHR`, 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 `currentTransform` value returned by `vkGetPhysicalDeviceSurfaceCapabilitiesKHR`, the presentation engine will transform the image content as part of the presentation operation.
- `compositeAlpha` is a bitmask of `VkCompositeAlphaFlagBitsKHR`, indicating the alpha compositing mode to use when this surface is composited together with other surfaces on certain window systems.
- `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.

- `clipped` indicates whether the Vulkan implementation is allowed to discard rendering operations that affect regions of the surface which are not visible.

  - If set to `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. Pixel shaders may not execute for these pixels, and thus any side affects they would have had will not occur.
  - If set to `VK_FALSE`, presentable images associated with the swapchain will own all the pixels they contain. Setting this value to `VK_TRUE` does not guarantee any clipping will occur, but allows more optimal presentation methods to be used on some platforms.

| Note
Applications should set this value to `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 pixel shaders do not have any side effects that require them to run for all pixels in the presentable image.

- `oldSwapchain`, if not `VK_NULL_HANDLE`, specifies the swapchain that will be replaced by the new swapchain being created. The new swapchain will be a descendant of `oldSwapchain`. Further, any descendants of the new swapchain will also be descendants of `oldSwapchain`. Upon calling `vkCreateSwapchainKHR` with a `oldSwapchain` that is not `VK_NULL_HANDLE`, any images not acquired by the application may be freed by the implementation, which may occur even if creation of the new swapchain fails. The application must destroy the old swapchain to free all memory associated with the old swapchain. The application must wait for the completion of any outstanding rendering to images it currently has acquired at the time the swapchain is destroyed. The application can continue to present any images it acquired and has not yet presented using the old swapchain, as long as it has not entered a state that causes it to return `VK_ERROR_OUT_OF_DATE_KHR`. However, the application cannot acquire any more images from the old swapchain regardless of whether or not creation of the new swapchain succeeds.

As mentioned above, if `vkCreateSwapchainKHR` succeeds, it will return a handle to a swapchain that contains an array of at least `minImageCount` presentable images.

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

`VkImageCreateInfo` Field | Value
--- | ---
`flags` | 0
`imageType` | `VK_IMAGE_TYPE_2D`
`format` | `pCreateInfo->imageFormat`
`extent` | `{pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, 1}`
`mipLevels` | 1
`arrayLayers` | `pCreateInfo->imageArrayLayers`
`samples` | `VK_SAMPLE_COUNT_1_BIT`
`tiling` | `VK_IMAGE_TILING_OPTIMAL`
`usage` | `pCreateInfo->imageUsage`
`sharingMode` | `pCreateInfo->imageSharingMode`
`queueFamilyIndexCount` | `pCreateInfo->queueFamilyIndexCount`
`pQueueFamilyIndices` | `pCreateInfo->pQueueFamilyIndices`
`initialLayout` | `VK_IMAGE_LAYOUT_UNDEFINED`

The `VkSurfaceKHR` associated with a swapchain must not be destroyed until after the swapchain is destroyed.

The native window referred to by `surface` must not already be associated with a swapchain other than `oldSwapchain`, or with a non-Vulkan graphics API surface.

Like core functions, several WSI functions, including `vkCreateSwapchainKHR` return `VK_ERROR_DEVICE_LOST` if the logical device was lost. See Lost Device. As with most core objects, `VkSwapchainKHR` is a child of the device and is affected by the lost state; it must be destroyed before destroying the `VkDevice`. However, `VkSurfaceKHR` is not a child of any `VkDevice` and is not otherwise affected by the lost device. After successfully recreating a `VkDevice`, the same `VkSurfaceKHR` can be used to create a new `VkSwapchainKHR`, provided the previous one was destroyed.

| Note
As mentioned in Lost Device, after a lost device event, the `VkPhysicalDevice` may also be lost. If other `VkPhysicalDevice` are available, they can be used together with the same `VkSurfaceKHR` to create the new `VkSwapchainKHR`, however the application must query the surface capabilities again, because they may differ on a per-physical device basis.

To destroy a swapchain object call:

    void vkDestroySwapchainKHR(
        VkDevice                                    device,
        VkSwapchainKHR                              swapchain,
        const VkAllocationCallbacks*                pAllocator);

- `device` is the `VkDevice` associated with `swapchain`.
- `swapchain` is the swapchain to destroy.
- `pAllocator` is the allocator used for host memory allocated for the swapchain object when there is no more specific allocator available (see Memory Allocation).

`swapchain` and all associated `VkImage` handles are destroyed, and must not be acquired or used any more by the application. The memory of each `VkImage` will only be freed after that image is no longer used by the platform. 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 `VkSurfaceKHR`, and a new swapchain can be created with it.

If a swapchain associated with a display surface is destroyed and there are no valid descendants of that swapchain, the implementation must either revert any display resources modified by presenting images with the swapchain to their state prior to the first present performed with the swapchain and its ancestors, or leave such resources in their current state.

When the `VK_KHR_display_swapchain` extension is enabled, multiple swapchains that share presentable images are created by calling:

    VkResult vkCreateSharedSwapchainsKHR(
        VkDevice                                    device,
        uint32_t                                    swapchainCount,
        const VkSwapchainCreateInfoKHR*             pCreateInfos,
        const VkAllocationCallbacks*                pAllocator,
        VkSwapchainKHR*                             pSwapchains);

- `device` is the device to create the swapchains for.
- `swapchainCount` is the number of swapchains to create.
- `pCreateInfos` is a pointer to an array of `VkSwapchainCreateInfoKHR` structures specifying the parameters of the created swapchains.
- `pAllocator` is the allocator used for host memory allocated for the swapchain objects when there is no more specific allocator available (see Memory Allocation).
- `pSwapchains` is a pointer to an array of `VkSwapchainKHR` handles in which the created swapchain objects will be returned.

`vkCreateSharedSwapchains` is similar to `vkCreateSwapchainKHR`, except that it takes an array of `VkSwapchainCreateInfoKHR` structures, and returns an array of swapchain objects.

The swapchain creation parameters that affect the properties and number of presentable images must match between all the swapchains. If the displays used by any of the swapchains do not use the same presentable image layout or are incompatible in a way that prevents sharing images, swapchain creation will fail with the result code `VK_ERROR_INCOMPATIBLE_DISPLAY_KHR`. If any error occurs, no swapchains will be created. Images presented to multiple swapchains must be re-acquired from all of them before transitioning away from `VK_IMAGE_LAYOUT_PRESENT_SRC_KHR`. After destroying one or more of the swapchains, the remaining swapchains and the presentable images can continue to be used.

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

    VkResult vkGetSwapchainImagesKHR(
        VkDevice                                    device,
        VkSwapchainKHR                              swapchain,
        uint32_t*                                   pSwapchainImageCount,
        VkImage*                                    pSwapchainImages);

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

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

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

The implementation will have already allocated and bound the memory backing the `VkImages` returned by `vkGetSwapchainImagesKHR`. The memory for each image will not alias with the memory for other images or with any `VkDeviceMemory` object. As such, performing any operation affecting the binding of memory to a presentable image results in undefined behavior. All presentable images are initially in the `VK_IMAGE_LAYOUT_UNDEFINED` layout, thus before using presentable images, the application must transition them to a valid layout for the intended use.

Further, the lifetime of presentable images is controlled by the implementation so destroying a presentable image with `vkDestroyImage` results in undefined behavior. See `vkDestroySwapchainKHR` for further details on the lifetime of presentable images.

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

    VkResult vkAcquireNextImageKHR(
        VkDevice                                    device,
        VkSwapchainKHR                              swapchain,
        uint64_t                                    timeout,
        VkSemaphore                                 semaphore,
        VkFence                                     fence,
        uint32_t*                                   pImageIndex);

- `device` is the device associated with `swapchain`.
- `swapchain` is the swapchain from which an image is being acquired.
- `timeout` indicates how long the function waits, in nanoseconds, if no image is available.
- `semaphore` is `VK_NULL_HANDLE` or a semaphore to signal.
- `fence` is `VK_NULL_HANDLE` or a fence to signal.
- `pImageIndex` is a pointer to a `uint32_t` that is set to the index of the next image to use (i.e. an index into the array of images returned by `vkGetSwapchainImagesKHR`).

When successful, `vkAcquireNextImageKHR` acquires a presentable image that the application can use, and sets `pImageIndex` to the index of that image. The presentation engine may not have finished reading from the image at the time it is acquired, so the application must use `semaphore` and/or `fence` to ensure that the image layout and contents are not modified until the presentation engine reads have completed.

As mentioned above, the presentation engine controls the order in which presentable images are made available to the application. This allows the platform to handle special situations. The order in which images are acquired is implementation-dependent. Images may be acquired in a seemingly random order that is not a simple round-robin.

If a swapchain has enough presentable images, applications can acquire multiple images without an intervening `vkQueuePresentKHR`. Applications can present images in a different order than the order in which they were acquired.

If `timeout` is 0, `vkAcquireNextImageKHR` will not block, but will either succeed or return `VK_NOT_READY`. If `timeout` is `UINT64_MAX`, the function will not return until an image is acquired from the presentation engine. Other values for `timeout` will cause the function to return when an image becomes available, or when the specified number of nanoseconds have passed (in which case it will return `VK_TIMEOUT`). An error can also cause `vkAcquireNextImageKHR` to return early.

| Note
As mentioned above, the presentation engine may be asynchronous with respect to the application and/or logical device. `vkAcquireNextImageKHR` may return as soon as it can identify which image will be acquired, and can guarantee that `semaphore` and `fence` will be signaled by the presentation engine; and may not successfully return sooner. The application uses `timeout` to specify how long `vkAcquireNextImageKHR` waits for an image to become acquired.

Applications cannot rely on `vkAcquireNextImageKHR` blocking in order to meter their rendering speed. Various factors can interrupt `vkAcquireNextImageKHR` from blocking.

| Note
For example, if an error occurs, `vkAcquireNextImageKHR` may return even though no image is available. As another example, some presentation engines are able to enqueue an unbounded number of presentation and acquire next image operations such that `vkAcquireNextImageKHR` never needs to wait for completion of outstanding present operations before returning.

The availability of presentable images is influenced by factors such as the implementation of the presentation engine, the `VkPresentModeKHR` being used, the number of images in the swapchain, the number of images that the application has acquired at any given time, and the performance of the application. The value of `VkSurfaceCapabilitiesKHR`::`minImageCount` indicates how many images must be in the swapchain in order for `vkAcquireNextImageKHR` to acquire an image if the application currently has no acquired images.

Let n be the total number of images in the swapchain, m be the value of `VkSurfaceCapabilitiesKHR`::`minImageCount`, and a be the number of presentable images that the application has currently acquired (i.e. images acquired with `vkAcquireNextImageKHR`, but not yet presented with `vkQueuePresentKHR`). `vkAcquireNextImageKHR` can always succeed if a ≤ n - m at the time `vkAcquireNextImageKHR` is called. `vkAcquireNextImageKHR` should not be called if a > n - m with a `timeout` of `UINT64_MAX`; in such a case, `vkAcquireNextImageKHR` may block indefinitely.

| Note
For example, if the `minImageCount` member of `VkSurfaceCapabilitiesKHR` is 2, and the application creates a swapchain with 2 presentable images, the application can acquire one image, and must present it before trying to acquire another image. If we modify this example so that the application wishes to acquire up to 3 presentable images simultaneously, it must request a minimum image count of 4 when creating the swapchain.

If `semaphore` is not `VK_NULL_HANDLE`, the semaphore must be unsignaled and not have any uncompleted signal or wait operations pending. It will become signaled when the application can use the image. Queue operations that access the image contents must wait until the semaphore signals; typically applications should include the semaphore in the `pWaitSemaphores` list for the queue submission that transitions the image away from the `VK_IMAGE_LAYOUT_PRESENT_SRC_KHR` layout. Use of the semaphore allows rendering operations to be recorded and submitted before the presentation engine has completed its use of the image.

If `fence` is not equal to `VK_NULL_HANDLE`, the fence must be unsignaled and not have any uncompleted signal operations pending. It will become signaled when the application can use the image. Applications can use this to meter their frame generation work to match the presentation rate.

`semaphore` and `fence` must not both be equal to `VK_NULL_HANDLE`. An application must wait until either the `semaphore` or `fence` is signaled before using the presentable image.

`semaphore` and `fence` may already be signaled when `vkAcquireNextImageKHR` returns, if the image is being acquired for the first time, or if the presentable image is immediately ready for use.

A successful call to `vkAcquireNextImageKHR` counts as a signal operation on `semaphore` for the purposes of queue forward-progress requirements. The semaphore is guaranteed to signal, so a wait operation can be queued for the semaphore without risk of deadlock.

The `vkCmdWaitEvents` or `vkCmdPipelineBarrier` used to transition the image away from `VK_IMAGE_LAYOUT_PRESENT_SRC_KHR` layout must have `dstStageMask` and `dstAccessMask` parameters set based on the next use of the image. The application must use implicit ordering guarantees and execution dependencies to prevent the image transition from occurring before the semaphore passed to `vkAcquireNextImageKHR` has signaled.

| Note
When the swapchain image will be written by some stage S, the recommended idiom for ensuring the semaphore signals before the transition occurs is: The batch that contains the transition includes the image-acquire semaphore in the list of semaphores to wait for, with a wait stage mask that includes S. The pipeline barrier that performs the transition includes S in both the `srcStageMask` and `dstStageMask`. This causes the pipeline barrier to wait at S until the semaphore signals before performing the transition and memory barrier, while allowing earlier pipeline stages of subsequent commands to proceed.

After a successful return, the image indicated by `pImageIndex` will still be in the `VK_IMAGE_LAYOUT_PRESENT_SRC_KHR` layout if it was previously presented, or in the `VK_IMAGE_LAYOUT_UNDEFINED` layout if this is the first time it has been acquired.

| Note
Exclusive ownership of presentable images corresponding to a swapchain created with `VK_SHARING_MODE_EXCLUSIVE` as defined in Resource Sharing is not altered by a call to `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 `vkAcquireNextImageKHR`() depend on the `timeout` provided:

- `VK_SUCCESS` is returned if an image became available.
- `VK_ERROR_SURFACE_LOST_KHR` if the surface becomes no longer available.
- `VK_NOT_READY` is returned if `timeout` is zero and no image was available.
- `VK_TIMEOUT` is returned if `timeout` is greater than zero and less than `UINT64_MAX`, and no image became available within the time allowed.
- `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
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 applications to decide whether they prefer 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.

- `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. If presentation does succeed, parts of the native surface may be undefined, parts of the presented image may have been clipped before presentation, and/or the image may have been scaled (uniformly or not uniformly) before presentation. 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 `VK_ERROR_OUT_OF_DATE_KHR` error will be returned.

Before an application can present an image, the image’s layout must be transitioned to the `VK_IMAGE_LAYOUT_PRESENT_SRC_KHR` layout.

| Note
When transitioning the image to `VK_IMAGE_LAYOUT_PRESENT_SRC_KHR`, there is no need to delay subsequent processing, or perform any visibility operations (as `vkQueuePresentKHR` performs automatic visibility operations). To achieve this, the `dstAccessMask` member of the `VkImageMemoryBarrier` should be set to `0`, and the `dstStageMask` parameter should be set to `VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT`.

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

    VkResult vkQueuePresentKHR(
        VkQueue                                     queue,
        const VkPresentInfoKHR*                     pPresentInfo);

- `queue` is a queue that is capable of presentation to the target surface’s platform on the same device as the image’s swapchain.
- `pPresentInfo` is a pointer to an instance of the `VkPresentInfoKHR` structure specifying the parameters of the presentation.

Any writes to memory backing the images referenced by the `pImageIndices` and `pSwapchains` members of `pPresentInfo`, that are available before `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.

The `VkPresentInfoKHR` structure is defined as:

    typedef struct VkPresentInfoKHR {
        VkStructureType          sType;
        const void*              pNext;
        uint32_t                 waitSemaphoreCount;
        const VkSemaphore*       pWaitSemaphores;
        uint32_t                 swapchainCount;
        const VkSwapchainKHR*    pSwapchains;
        const uint32_t*          pImageIndices;
        VkResult*                pResults;
    } VkPresentInfoKHR;

- `sType` is the type of this structure and must be `VK_STRUCTURE_TYPE_PRESENT_INFO_KHR`.
- `pNext` is `NULL` or a pointer to an extension-specific structure.
- `waitSemaphoreCount` is the number of semaphores to wait for before issuing the present request. The number may be zero.
- `pWaitSemaphores`, if not `VK_NULL_HANDLE`, is an array of `VkSemaphore` objects with `waitSemaphoreCount` entries, and specifies the semaphores to wait for before issuing the present request.
- `swapchainCount` is the number of swapchains being presented to by this command.
- `pSwapchains` is an array of `VkSwapchainKHR` objects with `swapchainCount` entries. A given swapchain must not appear in this list more than once.
- `pImageIndices` is an array of indices into the array of each swapchain’s presentable images, with `swapchainCount` entries. Each entry in this array identifies the image to present on the corresponding entry in the `pSwapchains` array.
- `pResults` is an array of `VkResult` typed elements with `swapchainCount` entries. Applications that do not need per-swapchain results can use `NULL` for `pResults`. If non-`NULL`, each entry in `pResults` will be set to the `VkResult` for presenting the swapchain corresponding to the same index in `pSwapchains`.

When the `VK_KHR_display_swapchain` extension is enabled additional fields can be specified when presenting an image to a swapchain by setting `VkPresentInfoKHR`::`pNext` to point to an instance of the `VkDisplayPresentInfoKHR` structure.

The `VkDisplayPresentInfoKHR` structure is defined as:

    typedef struct VkDisplayPresentInfoKHR {
        VkStructureType    sType;
        const void*        pNext;
        VkRect2D           srcRect;
        VkRect2D           dstRect;
        VkBool32           persistent;
    } VkDisplayPresentInfoKHR;

- `sType` is the type of this structure and must be `VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR`.
- `pNext` is `NULL` or a pointer to an extension-specific structure.
- `srcRect` is a rectangular region of pixels to present. It must be a subset of the image being presented. If `VkDisplayPresentInfoKHR` is not specified, this region will be assumed to be the entire presentable image.
- `dstRect` is a rectangular region within the visible region of the swapchain’s display mode. If `VkDisplayPresentInfoKHR` is not specified, this region will be assumed to be the entire visible region of the visible region of the swapchain’s mode. If the specified rectangle is a subset of the display mode’s visible region, content from display planes below the swapchain’s plane will be visible outside the rectangle. If there are no planes below the swapchain’s, the area outside the specified rectangle will be black. If portions of the specified rectangle are outside of the display’s visible region, pixels mapping only to those portions of the rectangle will be discarded.
- `persistent`: If this is `VK_TRUE`, the display engine will enable buffered mode on displays that support it. This allows the display engine to stop sending content to the display until a new image is presented. The display will instead maintain a copy of the last presented image. This allows less power to be used, but may increase presentation latency. If `VkDisplayPresentInfoKHR` is not specified, persistent mode will not be used.

If the extent of the `srcRect` and `dstRect` are not equal, the presented pixels will be scaled accordingly.

`vkQueuePresentKHR`, releases the acquisition of the images referenced by `imageIndices`. The queue family corresponding to the queue `vkQueuePresentKHR` is executed on must have ownership of the presented images as defined in Resource Sharing. `vkQueuePresentKHR` does not alter the queue family ownership, but the presented images must not be used again before they have been reacquired using `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.

If an image is presented to a swapchain created from a display surface, the mode of the associated display will be updated, if necessary, to match the mode specified when creating the display surface. The mode switch and presentation of the specified image will be performed as one atomic operation.

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

- If the device is lost, `VK_ERROR_DEVICE_LOST` is returned.
- If any of the target surfaces are no longer available the error `VK_ERROR_SURFACE_LOST_KHR` is returned.
- If any of the presents would have a result of `VK_ERROR_OUT_OF_DATE_KHR` if issued separately then `VK_ERROR_OUT_OF_DATE_KHR` is returned.
- If any of the presents would have a result of `VK_SUBOPTIMAL_KHR` if issued separately then `VK_SUBOPTIMAL_KHR` is returned.
- Otherwise `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 `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.