Window System Integration (WSI)
This chapter discusses the window system integration (WSI) between the Vulkan API and the various forms of displaying the results of rendering to a user. Since the Vulkan API can be used without displaying results, WSI is provided through the use of optional Vulkan extensions. This chapter provides an overview of WSI. See the appendix for additional details of each WSI extension, including which extensions must be enabled in order to use each of the functions described in this chapter.
WSI Platform
A platform is an abstraction for a window system, OS, etc. Some examples include MS Windows, Android, and Wayland. The Vulkan API may be integrated in a unique manner for each platform.
The Vulkan API does not define any type of platform object. Platform-specific WSI extensions are defined, each containing platform-specific functions for using WSI. Use of these extensions is guarded by preprocessor symbols as defined in the Window System-Specific Header Control appendix.
In order for an application to be compiled to use WSI with a given platform, it must either:
#define
the appropriate preprocessor symbol prior to including thevulkan.h
header file, or- include
vulkan_core.h
and any native platform headers, followed by the appropriate platform-specific header.
The preprocessor symbols and platform-specific headers are defined in the Window System Extensions and Headers table.
Each platform-specific extension is an instance extension.
The application must enable instance extensions with vkCreateInstance
before using them.
WSI Surface
Android Platform
Wayland Platform
On Wayland, currentExtent
is the special value (0xFFFFFFFF,
0xFFFFFFFF), indicating that the surface size will be determined by the
extent of a swapchain targeting the surface.
Whatever the application sets a swapchain’s imageExtent
to will be the
size of the window, after the first image is presented.
minImageExtent
is (1,1), and maxImageExtent
is the maximum
supported surface size.
Any calls to vkGetPhysicalDeviceSurfacePresentModesKHR on a surface
created with vkCreateWaylandSurfaceKHR
are required to return
VK_PRESENT_MODE_MAILBOX_KHR
as one of the valid present modes.
Some Vulkan functions may send protocol over the specified wl_display
connection when using a swapchain or presentable images created from a
VkSurfaceKHR
referring to a wl_surface
.
Applications must therefore ensure that both the wl_display
and the
wl_surface
remain valid for the lifetime of any VkSwapchainKHR
objects created from a particular wl_display
and wl_surface
.
Also, calling vkQueuePresentKHR will result in Vulkan sending
wl_surface.commit
requests to the underlying wl_surface
of each
The wl_surface.attach
, wl_surface.damage
, and
wl_surface.commit
requests must be issued by the implementation during
the call to vkQueuePresentKHR and must not be issued by the
implementation outside of vkQueuePresentKHR.
This ensures that any Wayland requests sent by the client after the call to
vkQueuePresentKHR returns will be received by the compositor after the
wl_surface.commit
.
Regardless of the mode of swapchain creation, a new wl_event_queue
must be created for each successful vkCreateWaylandSurfaceKHR call,
and every Wayland object created by the implementation must be assigned to
this event queue.
If the platform provides Wayland 1.11 or greater, this must be implemented
by the use of Wayland proxy object wrappers, to avoid race conditions.
If the application wishes to synchronize any window changes with a particular frame, such requests must be sent to the Wayland display server prior to calling vkQueuePresentKHR.
Win32 Platform
With Win32, minImageExtent
, maxImageExtent
, and
currentExtent
must always equal the window size.
The currentExtent
of a Win32 surface must have both width
and
height
greater than 0, or both of them 0.
Due to above restrictions,
unless VkSwapchainPresentScalingCreateInfoEXT is used to specify
handling of disparities between surface and swapchain dimensions,
it is only possible to create a new swapchain on this platform with
imageExtent
being equal to the current size of the window, as reported
in VkSurfaceCapabilitiesKHR::currentExtent
.
The window size may become (0, 0) on this platform (e.g. when the window is minimized), and so a swapchain cannot be created until the size changes.
XCB Platform
With Xcb, minImageExtent
, maxImageExtent
, and
currentExtent
must always equal the window size.
The currentExtent
of an Xcb surface must have both width
and
height
greater than 0, or both of them 0.
Due to above restrictions,
unless VkSwapchainPresentScalingCreateInfoEXT is used to specify
handling of disparities between surface and swapchain dimensions,
it is only possible to create a new swapchain on this platform with
imageExtent
being equal to the current size of the window, as reported
in VkSurfaceCapabilitiesKHR::currentExtent
.
The window size may become (0, 0) on this platform (e.g. when the window is minimized), and so a swapchain cannot be created until the size changes.
Some Vulkan functions may send protocol over the specified xcb connection when using a swapchain or presentable images created from a VkSurfaceKHR referring to an xcb window. Applications must therefore ensure the xcb connection is available to Vulkan for the duration of any functions that manipulate such swapchains or their presentable images, and any functions that build or queue command buffers that operate on such presentable images. Specifically, applications using Vulkan with xcb-based swapchains must
- Avoid holding a server grab on an xcb connection while waiting for Vulkan operations to complete using a swapchain derived from a different xcb connection referring to the same X server instance. Failing to do so may result in deadlock.
Xlib Platform
With Xlib, minImageExtent
, maxImageExtent
, and
currentExtent
must always equal the window size.
The currentExtent
of an Xlib surface must have both width
and
height
greater than 0, or both of them 0.
Due to above restrictions,
unless VkSwapchainPresentScalingCreateInfoEXT is used to specify
handling of disparities between surface and swapchain dimensions,
it is only possible to create a new swapchain on this platform with
imageExtent
being equal to the current size of the window, as reported
in VkSurfaceCapabilitiesKHR::currentExtent
.
The window size may become (0, 0) on this platform (e.g. when the window is minimized), and so a swapchain cannot be created until the size changes.
Some Vulkan functions may send protocol over the specified Xlib
Display
connection when using a swapchain or presentable images created
from a VkSurfaceKHR referring to an Xlib window.
Applications must therefore ensure the display connection is available to
Vulkan for the duration of any functions that manipulate such swapchains or
their presentable images, and any functions that build or queue command
buffers that operate on such presentable images.
Specifically, applications using Vulkan with Xlib-based swapchains must
- Avoid holding a server grab on a display connection while waiting for Vulkan operations to complete using a swapchain derived from a different display connection referring to the same X server instance. Failing to do so may result in deadlock.
Some implementations may require threads to implement some presentation
modes so applications must call XInitThreads
() before calling any
other Xlib functions.
DirectFB Platform
With DirectFB, minImageExtent
, maxImageExtent
, and
currentExtent
must always equal the surface size.
Fuchsia Platform
On Fuchsia, the surface currentExtent
is the special value
(0xFFFFFFFF, 0xFFFFFFFF), indicating that the surface size will be
determined by the extent of a swapchain targeting the surface.
Google Games Platform
On Google Games Platform, the surface extents are dynamic.
The minImageExtent
will never be greater than 1080p and the
maxImageExtent
will never be less than 1080p.
The currentExtent
will reflect the current optimal resolution.
Applications are expected to choose an appropriate size for the swapchain’s
imageExtent
, within the bounds of the surface.
Using the surface’s currentExtent
will offer the best performance and
quality.
When a swapchain’s imageExtent
does not match the surface’s
currentExtent
, the presentable images are scaled to the surface’s
dimensions during presentation if possible and VK_SUBOPTIMAL_KHR
is
returned, otherwise presentation fails with VK_ERROR_OUT_OF_DATE_KHR
.
iOS Platform
macOS Platform
VI Platform
Metal Platform
QNX Screen Platform
Platform-Independent Information
Once created, VkSurfaceKHR
objects can be used in this and other
extensions, in particular the VK_KHR_swapchain extension.
Several WSI functions return VK_ERROR_SURFACE_LOST_KHR
if the surface
becomes no longer available.
After such an error, the surface (and any child swapchain, if one exists)
should be destroyed, as there is no way to restore them to a not-lost
state.
Applications may attempt to create a new VkSurfaceKHR
using the same
native platform window object, but whether such re-creation will succeed is
platform-dependent and may depend on the reason the surface became
unavailable.
A lost surface does not otherwise cause devices to be
lost.
Presenting Directly to Display Devices
In some environments applications can also present Vulkan rendering
directly to display devices without using an intermediate windowing system.
This can be useful for embedded applications, or implementing the
rendering/presentation backend of a windowing system using Vulkan.
The VK_KHR_display extension provides the functionality necessary
to enumerate display devices and create VkSurfaceKHR
objects that
target displays.
Display Enumeration
Acquiring and Releasing Displays
On some platforms, access to displays is limited to a single process or native driver instance. On such platforms, some or all of the displays may not be available to Vulkan if they are already in use by a native windowing system or other application.
Display Planes
Additional properties of displays are queried using specialized query functions.
Display Modes
Display Control
Display Surfaces
Presenting to Headless Surfaces
Vulkan rendering can be presented to a headless surface, where the presentation operation is a no-op producing no externally-visible result.
Because there is no real presentation target, the headless presentation engine may be extended to impose an arbitrary or customizable set of restrictions and features. This makes it a useful portable test target for applications targeting a wide range of presentation engines where the actual target presentation engines might be scarce, unavailable or otherwise undesirable or inconvenient to use for general Vulkan application development.
The usual surface query mechanisms must be used to determine the actual restrictions and features of the implementation.
For headless surfaces, currentExtent
is the reserved value
(0xFFFFFFFF, 0xFFFFFFFF).
Whatever the application sets a swapchain’s imageExtent
to will be the
size of the surface, after the first image is presented.
Querying for WSI Support
Not all physical devices will include WSI support. Within a physical device, not all queue families will support presentation. WSI support and compatibility can be determined in a platform-neutral manner (which determines support for presentation to a particular surface object) and additionally may be determined in platform-specific manners (which determine support for presentation on the specified physical device but do not guarantee support for presentation to a particular surface object).
Android Platform
On Android, all physical devices and queue families must be capable of presentation with any native window. As a result there is no Android-specific query for these capabilities.
Wayland Platform
Win32 Platform
XCB Platform
Xlib Platform
DirectFB Platform
Fuchsia Platform
On Fuchsia, all physical devices and queue families must be capable of presentation with any ImagePipe. As a result there is no Fuchsia-specific query for these capabilities.
Google Games Platform
On Google Games Platform, all physical devices and queue families with the
VK_QUEUE_GRAPHICS_BIT
or VK_QUEUE_COMPUTE_BIT
capabilities must
be capable of presentation with any Google Games Platform stream descriptor.
As a result, there is no query specific to Google Games Platform for these
capabilities.
iOS Platform
On iOS, all physical devices and queue families must be capable of presentation with any layer. As a result there is no iOS-specific query for these capabilities.
macOS Platform
On macOS, all physical devices and queue families must be capable of presentation with any layer. As a result there is no macOS-specific query for these capabilities.
VI Platform
On VI, all physical devices and queue families must be capable of presentation with any layer. As a result there is no VI-specific query for these capabilities.
QNX Screen Platform
Surface Queries
The capabilities of a swapchain targeting a surface are the intersection of the capabilities of the WSI platform, the native window or display, and the physical device. The resulting capabilities can be obtained with the queries listed below in this section.
In addition to the surface capabilities as obtained by surface queries below, swapchain images are also subject to ordinary image creation limits as reported by vkGetPhysicalDeviceImageFormatProperties. As an application is instructed by the appropriate Valid Usage sections, both the surface capabilities and the image creation limits have to be satisfied whenever swapchain images are created.
Surface Capabilities
Surface Format Support
While the format
of a presentable image refers to the encoding of each
pixel, the colorSpace
determines how the presentation engine
interprets the pixel values.
A color space in this document refers to a specific color space (defined by
the chromaticities of its primaries and a white point in CIE Lab), and
transfer functions indicating the mapping between the image data and the
colorimetry with respect to the given color space.
Surface Presentation Mode Support
Full Screen Exclusive Control
Swapchains created with fullScreenExclusive
set to
VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT
must acquire and
release exclusive full-screen access explicitly, using the following
commands.
Device Group Queries
Display Timing Queries
Traditional game and real-time-animation applications frequently use
VK_PRESENT_MODE_FIFO_KHR
so that presentable images are updated during
the vertical blanking period of a given refresh cycle (RC) of the
presentation engine’s display.
This avoids the visual anomaly known as tearing.
However, synchronizing the presentation of images with the RC does not prevent all forms of visual anomalies. Stuttering occurs when the geometry for each presentable image is not accurately positioned for when that image will be displayed. The geometry may appear to move too little some RCs, and too much for others. Sometimes the animation appears to freeze, when the same image is used for more than one RC.
In order to minimize stuttering, an application needs to correctly position their geometry for when the presentable image will be displayed to the user. To accomplish this, applications need various timing information about the presentation engine’s display. They need to know when presentable images were actually presented, and when they could have been presented. Applications also need to tell the presentation engine to display an image no sooner than a given time. This can allow the application’s animation to look smooth to the user, with no stuttering. The VK_GOOGLE_display_timing extension allows an application to satisfy these needs.
The presentation engine’s display typically refreshes the pixels that are displayed to the user on a periodic basis. The period may be fixed or variable. In many cases, the presentation engine is associated with fixed refresh rate (FRR) display technology, with a fixed refresh rate (RR, e.g. 60Hz). In some cases, the presentation engine is associated with variable refresh rate (VRR) display technology, where each refresh cycle (RC) can vary in length. This extension treats VRR displays as if they are FRR.
The rate at which an application renders and presents new images is known as
the image present rate (IPR, aka frame rate).
The inverse of IPR, or the duration between each image present, is the image
present duration (IPD).
In order to provide a smooth, stutter-free animation, an application will
want its IPD to be a multiple of refreshDuration
.
For example, if a display has a 60Hz refresh rate, refreshDuration
will be a value in nanoseconds that is approximately equal to 16.67ms.
In such a case, an application will want an IPD of 16.67ms (1X multiplier of
refreshDuration
), or 33.33ms (2X multiplier of refreshDuration
),
or 50.0ms (3X multiplier of refreshDuration
), etc.
In order to determine a target IPD for a display (i.e. a multiple of
refreshDuration
), an application needs to determine when its images
are actually displayed.
Suppose an application has an initial target IPD of 16.67ms (1X multiplier
of refreshDuration
).
It will therefore position the geometry of a new image 16.67ms later than
the previous image.
But suppose this application is running on slower hardware, so that it
actually takes 20ms to render each new image.
This will create visual anomalies, because the images will not be displayed
to the user every 16.67ms, nor every 20ms.
In this case, it is better for the application to adjust its target IPD to
33.33ms (i.e. a 2X multiplier of refreshDuration
), and tell the
presentation engine to not present images any sooner than every 33.33ms.
This will allow the geometry to be correctly positioned for each presentable
image.
Adjustments to an application’s IPD may be needed because different views of
an application’s geometry can take different amounts of time to render.
For example, looking at the sky may take less time to render than looking at
multiple, complex items in a room.
In general, it is good to not frequently change IPD, as that can cause
visual anomalies.
Adjustments to a larger IPD because of late images should happen quickly,
but adjustments to a smaller IPD should only happen if the
actualPresentTime
and earliestPresentTime
members of the
VkPastPresentationTimingGOOGLE structure are consistently different,
and if presentMargin
is consistently large, over multiple images.
The full VK_GOOGLE_display_timing extension semantics are described
for swapchains created with VK_PRESENT_MODE_FIFO_KHR
.
For example, non-zero values of
VkPresentTimeGOOGLE
::desiredPresentTime
must be honored, and
vkGetPastPresentationTimingGOOGLE
should return a
VkPastPresentationTimingGOOGLE
structure with valid values for all
images presented with vkQueuePresentKHR
.
The semantics for other present modes are as follows:
VK_PRESENT_MODE_IMMEDIATE_KHR
. The presentation engine may ignore non-zero values ofVkPresentTimeGOOGLE
::desiredPresentTime
in favor of presenting immediately. The value ofVkPastPresentationTimingGOOGLE
::earliestPresentTime
must be the same asVkPastPresentationTimingGOOGLE
::actualPresentTime
, which should be when the presentation engine displayed the image.VK_PRESENT_MODE_MAILBOX_KHR
. The intention of using this present mode with this extension is to handle cases where an image is presented late, and the next image is presented soon enough to replace it at the next vertical blanking period. For images that are displayed to the user, the value ofVkPastPresentationTimingGOOGLE
::actualPresentTime
must be when the image was displayed. For images that are not displayed to the user,vkGetPastPresentationTimingGOOGLE
may not return aVkPastPresentationTimingGOOGLE
structure, or it may return aVkPastPresentationTimingGOOGLE
structure with the value of zero for bothVkPastPresentationTimingGOOGLE
::actualPresentTime
andVkPastPresentationTimingGOOGLE
::earliestPresentTime
. It is possible that an application can submit images withVkPresentTimeGOOGLE
::desiredPresentTime
values such that new images may not be displayed. For example, ifVkPresentTimeGOOGLE
::desiredPresentTime
is far enough in the future that an image is not presented beforevkQueuePresentKHR
is called to present another image, the first image will not be displayed to the user. If the application continues to do that, the presentation may not display new images.VK_PRESENT_MODE_FIFO_RELAXED_KHR
. For images that are presented in time to be displayed at the next vertical blanking period, the semantics are identical as forVK_PRESENT_MODE_FIFO_KHR
. For images that are presented late, and are displayed after the start of the vertical blanking period (i.e. with tearing), the values ofVkPastPresentationTimingGOOGLE
may be treated as if the image was displayed at the start of the vertical blanking period, or may be treated the same as forVK_PRESENT_MODE_IMMEDIATE_KHR
.
Present Wait
Applications wanting to control the pacing of the application by monitoring when presentation processes have completed to limit the number of outstanding images queued for presentation, need to have a method of being signaled during the presentation process.
Using the VK_GOOGLE_display_timing extension applications can discover when images were presented, but only asynchronously.
Providing a mechanism which allows applications to block, waiting for a specific step of the presentation process to complete allows them to control the amount of outstanding work (and hence the potential lag in responding to user input or changes in the rendering environment).
The VK_KHR_present_wait extension allows applications to tell the
presentation engine at the vkQueuePresentKHR call that it plans on
waiting for presentation by passing a VkPresentIdKHR structure.
The presentId
passed in that structure may then be passed to a future
vkWaitForPresentKHR call to cause the application to block until that
presentation is finished.
WSI Swapchain
How this all works is described below.
If a swapchain is created with presentMode
set to either
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR
or
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR
, a single presentable
image can be acquired, referred to as a shared presentable image.
A shared presentable image may be concurrently accessed by the application
and the presentation engine, without transitioning the image’s layout after
it is initially presented.
- With
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR
, the presentation engine is only required to update to the latest contents of a shared presentable image after a present. The application must callvkQueuePresentKHR
to guarantee an update. However, the presentation engine may update from it at any time. - With
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR
, the presentation engine will automatically present the latest contents of a shared presentable image during every refresh cycle. The application is only required to make one initial call tovkQueuePresentKHR
, after which the presentation engine will update from it without any need for further present calls. The application can indicate the image contents have been updated by callingvkQueuePresentKHR
, but this does not guarantee the timing of when updates will occur.
The presentation engine may access a shared presentable image at any time after it is first presented. To avoid tearing, an application should coordinate access with the presentation engine. This requires presentation engine timing information through platform-specific mechanisms and ensuring that color attachment writes are made available during the portion of the presentation engine’s refresh cycle they are intended for.
The VK_KHR_shared_presentable_image extension does not provide functionality for determining the timing of the presentation engine’s refresh cycles.
The possible return values for vkGetSwapchainStatusKHR
should be
interpreted as follows:
VK_SUCCESS
specifies the presentation engine is presenting the contents of the shared presentable image, as per the swapchain’s VkPresentModeKHR.VK_SUBOPTIMAL_KHR
the swapchain no longer matches the surface properties exactly, but the presentation engine is presenting the contents of the shared presentable image, as per the swapchain’s VkPresentModeKHR.VK_ERROR_OUT_OF_DATE_KHR
the surface has changed in such a way that it is no longer compatible with the swapchain.VK_ERROR_SURFACE_LOST_KHR
the surface is no longer available.
The swapchain state may be cached by implementations, so applications
should regularly call vkGetSwapchainStatusKHR
when using a swapchain
with VkPresentModeKHR equal to
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR
.
If the pNext
chain of VkSwapchainCreateInfoKHR includes a
VkSurfaceFullScreenExclusiveInfoEXT structure, then that structure
specifies the application’s preferred full-screen presentation behavior.
If this structure is not present, fullScreenExclusive
is considered to
be VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT
.
To specify compression properties for the swapchain images in this
swapchain, add a VkImageCompressionControlEXT structure to the
pNext
chain of the VkSwapchainCreateInfoKHR structure.
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.
However, command buffers are not allowed to reference presentable images
created with VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT
until their indices have been returned from vkAcquireNextImageKHR at
least once.
Images returned by 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 VkDeviceMemory
object
, unless the swapchain is created with the
VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT
flag
.
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 applications must not destroy a presentable image. See vkDestroySwapchainKHR for further details on the lifetime of presentable images.
Images can also be created by using vkCreateImage with
VkImageSwapchainCreateInfoKHR and bound to swapchain memory using
vkBindImageMemory2 with 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 vkGetSwapchainImagesKHR
, these images
must be destroyed with vkDestroyImage.
If an image is acquired successfully, vkAcquireNextImageKHR
must
either return VK_SUCCESS
or VK_SUBOPTIMAL_KHR
.
The implementation may return VK_SUBOPTIMAL_KHR
if the swapchain no
longer matches the surface properties exactly, but can still be used for
presentation.
When successful, vkAcquireNextImageKHR
acquires a presentable image
from swapchain
that an application can use, and sets
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 semaphore
and/or
fence
to ensure that the image layout and contents are not modified
until the presentation engine reads have completed.
Once vkAcquireNextImageKHR
successfully acquires an image, the
semaphore signal operation referenced by semaphore
, if not
VK_NULL_HANDLE, and the fence signal operation referenced by
fence
, if not VK_NULL_HANDLE, are submitted for execution.
If vkAcquireNextImageKHR
does not successfully acquire an image,
semaphore
and 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 timeout
is zero, then vkAcquireNextImageKHR
does not wait,
and will either successfully acquire an image, or fail and return
VK_NOT_READY
if no image is available.
If the specified timeout period expires before an image is acquired,
vkAcquireNextImageKHR
returns VK_TIMEOUT
.
If timeout
is UINT64_MAX
, the timeout period is treated as
infinite, and vkAcquireNextImageKHR
will block until an image is
acquired or an error occurs.
Let S be the number of images in swapchain
.
If swapchain
is created with
VkSwapchainPresentModesCreateInfoEXT, let M be the maximum of
the values in VkSurfaceCapabilitiesKHR::minImageCount
when
queried with each present mode in
VkSwapchainPresentModesCreateInfoEXT::pPresentModes
in
VkSurfacePresentModeEXT.
Otherwise, let M be the value of
VkSurfaceCapabilitiesKHR::minImageCount
without a
VkSurfacePresentModeEXT as part of the query input.
vkAcquireNextImageKHR
should not be called if the number of images
that the application has currently acquired is greater than S-M.
If vkAcquireNextImageKHR
is called when the number of images that the
application has currently acquired is less than or equal to S-M,
vkAcquireNextImageKHR
must return in finite time with an allowed
VkResult
code.
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 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.
If the swapchain images no longer match native surface properties, either
VK_SUBOPTIMAL_KHR
or VK_ERROR_OUT_OF_DATE_KHR
must be returned.
If 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 VK_ERROR_OUT_OF_DATE_KHR
.
Applications need to create a new swapchain for the surface to continue
presenting if VK_ERROR_OUT_OF_DATE_KHR
is returned.
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 device loss occurs (see Lost Device) before
the timeout has expired, vkAcquireNextImageKHR
must return in finite
time with either one of the allowed success codes, or
VK_ERROR_DEVICE_LOST
.
If semaphore
is not 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.
Use of 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, with no signal operations pending.
It will become signaled when the application can use the image.
Applications should not rely on 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 fence
to meter their frame generation
work to match the presentation rate.
An application must wait until either the semaphore
or fence
is
signaled before accessing the image’s data.
When the presentable image will be accessed by some stage S, the recommended idiom for ensuring correct synchronization is:
- The VkSubmitInfo used to submit the image layout transition for
execution includes
vkAcquireNextImageKHR
::semaphore
in itspWaitSemaphores
member, with the corresponding element ofpWaitDstStageMask
including S. - The synchronization command that performs any
necessary image layout transition includes S in both the
srcStageMask
anddstStageMask
.
After a successful return, the image indicated by pImageIndex
and its
data will be unmodified compared to when it was presented.
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
is returned if the surface becomes no longer available.VK_NOT_READY
is returned iftimeout
is zero and no image was available.VK_TIMEOUT
is returned iftimeout
is greater than zero and less thanUINT64_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.
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.
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
unless the swapchain is created with a non-zero value in
VkSwapchainPresentScalingCreateInfoEXT::scalingBehavior
.
If presentation does succeed, the mapping from the presented image to the
native surface is
defined by the VkSwapchainPresentScalingCreateInfoEXT structure if
provided.
Otherwise it is
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 VK_ERROR_OUT_OF_DATE_KHR
error will be returned.
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.
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 a
VkDisplayPresentInfoKHR structure.
HDR Metadata
This section describes how to improve color reproduction of content to better reproduce colors as seen on the display used to originally optimize the content.
Lag Control
Some implementations support extensions to reduce display latency and control the swapchain present interval, as described in the remainder of this section.
Anti-Lag
The VK_AMD_anti_lag extension lowers latency between receiving input and displaying on the screen. It adds a command to indicate when input is being processed for a frame, and when that frame’s images are presented.
Latency Reduction
Present Barrier
The VK_NV_present_barrier extension allows applications to
synchronize corresponding presentation requests across multiple swapchains
using the present barrier.
A swapchain is said to be using the present barrier if the swapchain is
created by adding a VkSwapchainPresentBarrierCreateInfoNV structure to
the pNext
chain of the VkSwapchainCreateInfoKHR structure, and
setting
VkSwapchainPresentBarrierCreateInfoNV::presentBarrierEnable
to
true.
A set of corresponding presentation requests is defined as exactly one queued presentation request associated with each swapchain using the present barrier, whether or not that queued request has executed. A given presentation request is added, when created by calling vkQueuePresentKHR and specifying a swapchain using the present barrier, either to the oldest existing set of corresponding requests for which there is no existing member associated with the request’s swapchain, or to a new set of corresponding requests if no such set exists.
A set of corresponding requests is said to be full when it contains one request from each swapchain using the present barrier. Queued presentation of an image to a swapchain using the present barrier is deferred by the implementation until the set of corresponding requests is full, and the visibility operations associated with all requests in that set, as described by vkQueuePresentKHR, have completed.
Additionally, the set of swapchains using the present barrier can be in the same process, or different processes running under the same operating system. And if the required synchronization hardware is connected and correctly configured, this extension also supports applications to synchronize corresponding presentation requests using the present barrier across distributed systems. However, the configuration mechanism of the required hardware is outside the scope of the Vulkan specification and this extension.