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

VkSurfaceKHROpaque handle to a surface object

Android Platform

vkCreateAndroidSurfaceKHRCreate a VkSurfaceKHR object for an Android native window
VkAndroidSurfaceCreateInfoKHRStructure specifying parameters of a newly created Android surface object
ANativeWindowAndroid native window type
VkAndroidSurfaceCreateFlagsKHRReserved for future use

Wayland Platform

vkCreateWaylandSurfaceKHRCreate a VkSurfaceKHR object for a Wayland window
VkWaylandSurfaceCreateInfoKHRStructure specifying parameters of a newly created Wayland surface object

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

VkWaylandSurfaceCreateFlagsKHRReserved for future use

Win32 Platform

vkCreateWin32SurfaceKHRCreate a VkSurfaceKHR object for an Win32 native window
VkWin32SurfaceCreateInfoKHRStructure specifying parameters of a newly created Win32 surface object

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.

VkWin32SurfaceCreateFlagsKHRReserved for future use

XCB Platform

vkCreateXcbSurfaceKHRCreate a VkSurfaceKHR object for a X11 window, using the XCB client-side library
VkXcbSurfaceCreateInfoKHRStructure specifying parameters of a newly created Xcb surface object

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.
VkXcbSurfaceCreateFlagsKHRReserved for future use

Xlib Platform

vkCreateXlibSurfaceKHRCreate a VkSurfaceKHR object for an X11 window, using the Xlib client-side library
VkXlibSurfaceCreateInfoKHRStructure specifying parameters of a newly created Xlib surface object

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.

VkXlibSurfaceCreateFlagsKHRReserved for future use

DirectFB Platform

vkCreateDirectFBSurfaceEXTCreate a VkSurfaceKHR object for a DirectFB surface
VkDirectFBSurfaceCreateInfoEXTStructure specifying parameters of a newly created DirectFB surface object

With DirectFB, minImageExtent, maxImageExtent, and currentExtent must always equal the surface size.

VkDirectFBSurfaceCreateFlagsEXTReserved for future use

Fuchsia Platform

vkCreateImagePipeSurfaceFUCHSIACreate a VkSurfaceKHR object for a Fuchsia ImagePipe
VkImagePipeSurfaceCreateInfoFUCHSIAStructure specifying parameters of a newly created ImagePipe surface object

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.

VkImagePipeSurfaceCreateFlagsFUCHSIAReserved for future use

Google Games Platform

vkCreateStreamDescriptorSurfaceGGPCreate a VkSurfaceKHR object for a Google Games Platform stream
VkStreamDescriptorSurfaceCreateInfoGGPStructure specifying parameters of a newly created Google Games Platform stream surface object

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.

VkStreamDescriptorSurfaceCreateFlagsGGPReserved for future use

iOS Platform

vkCreateIOSSurfaceMVKCreate a VkSurfaceKHR object for an iOS UIView
VkIOSSurfaceCreateInfoMVKStructure specifying parameters of a newly created iOS surface object
VkIOSSurfaceCreateFlagsMVKReserved for future use

macOS Platform

vkCreateMacOSSurfaceMVKCreate a VkSurfaceKHR object for a macOS NSView
VkMacOSSurfaceCreateInfoMVKStructure specifying parameters of a newly created macOS surface object
VkMacOSSurfaceCreateFlagsMVKReserved for future use

VI Platform

vkCreateViSurfaceNNCreate a VkSurfaceKHR object for a VI layer
VkViSurfaceCreateInfoNNStructure specifying parameters of a newly created VI surface object
VkViSurfaceCreateFlagsNNReserved for future use

Metal Platform

vkCreateMetalSurfaceEXTCreate a VkSurfaceKHR object for CAMetalLayer
VkMetalSurfaceCreateInfoEXTStructure specifying parameters of a newly created Metal surface object
CAMetalLayerCoreAnimation native layer type for Metal
VkMetalSurfaceCreateFlagsEXTReserved for future use

QNX Screen Platform

vkCreateScreenSurfaceQNXCreate a VkSurfaceKHR object for a QNX Screen window
VkScreenSurfaceCreateInfoQNXStructure specifying parameters of a newly created QNX Screen surface object
VkScreenSurfaceCreateFlagsQNXReserved for future use

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.

vkDestroySurfaceKHRDestroy a VkSurfaceKHR object

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

VkDisplayKHROpaque handle to a display object
vkGetPhysicalDeviceDisplayPropertiesKHRQuery information about the available displays
VkDisplayPropertiesKHRStructure describing an available display device
vkGetPhysicalDeviceDisplayProperties2KHRQuery information about the available displays
VkDisplayProperties2KHRStructure describing an available display device

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.

vkAcquireXlibDisplayEXTAcquire access to a VkDisplayKHR using Xlib
vkGetRandROutputDisplayEXTQuery the VkDisplayKHR corresponding to an X11 RandR Output
vkAcquireWinrtDisplayNVAcquire access to a VkDisplayKHR
vkGetWinrtDisplayNVQuery the VkDisplayKHR corresponding to a WinRT DisplayTarget
vkAcquireDrmDisplayEXTAcquire access to a VkDisplayKHR using DRM
vkGetDrmDisplayEXTQuery the VkDisplayKHR corresponding to a DRM connector ID
vkReleaseDisplayEXTRelease access to an acquired VkDisplayKHR

Display Planes

vkGetPhysicalDeviceDisplayPlanePropertiesKHRQuery the plane properties
VkDisplayPlanePropertiesKHRStructure describing display plane properties
vkGetPhysicalDeviceDisplayPlaneProperties2KHRQuery information about the available display planes.
VkDisplayPlaneProperties2KHRStructure describing an available display plane
vkGetDisplayPlaneSupportedDisplaysKHRQuery the list of displays a plane supports

Additional properties of displays are queried using specialized query functions.

Display Modes

VkDisplayModeKHROpaque handle to a display mode object
vkGetDisplayModePropertiesKHRQuery the set of mode properties supported by the display
VkDisplayModePropertiesKHRStructure describing display mode properties
VkDisplayModeCreateFlagsKHRReserved for future use
vkGetDisplayModeProperties2KHRQuery information about the available display modes.
VkDisplayModeProperties2KHRStructure describing an available display mode
VkDisplayModeParametersKHRStructure describing display parameters associated with a display mode
vkCreateDisplayModeKHRCreate a display mode
VkDisplayModeCreateInfoKHRStructure specifying parameters of a newly created display mode object
vkGetDisplayPlaneCapabilitiesKHRQuery capabilities of a mode and plane combination
VkDisplayPlaneCapabilitiesKHRStructure describing capabilities of a mode and plane combination
vkGetDisplayPlaneCapabilities2KHRQuery capabilities of a mode and plane combination
VkDisplayPlaneInfo2KHRStructure defining the intended configuration of a display plane
VkDisplayPlaneCapabilities2KHRStructure describing the capabilities of a mode and plane combination

Display Control

vkDisplayPowerControlEXTSet the power state of a display
VkDisplayPowerInfoEXTDescribe the power state of a display
VkDisplayPowerStateEXTPossible power states for a display

Display Surfaces

vkCreateDisplayPlaneSurfaceKHRCreate a VkSurfaceKHR structure representing a display plane and mode
VkDisplaySurfaceCreateInfoKHRStructure specifying parameters of a newly created display plane surface object
VkDisplaySurfaceCreateFlagsKHRReserved for future use
VkDisplayPlaneAlphaFlagBitsKHRAlpha blending type
VkDisplayPlaneAlphaFlagsKHRBitmask of VkDisplayPlaneAlphaFlagBitsKHR

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.

vkCreateHeadlessSurfaceEXTCreate a headless VkSurfaceKHR object
VkHeadlessSurfaceCreateInfoEXTStructure specifying parameters of a newly created headless surface object

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.

VkHeadlessSurfaceCreateFlagsEXTReserved for future use

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

vkGetPhysicalDeviceSurfaceSupportKHRQuery if presentation is supported

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

vkGetPhysicalDeviceWaylandPresentationSupportKHRQuery physical device for presentation to Wayland

Win32 Platform

vkGetPhysicalDeviceWin32PresentationSupportKHRQuery queue family support for presentation on a Win32 display

XCB Platform

vkGetPhysicalDeviceXcbPresentationSupportKHRQuery physical device for presentation to X11 server using XCB

Xlib Platform

vkGetPhysicalDeviceXlibPresentationSupportKHRQuery physical device for presentation to X11 server using Xlib

DirectFB Platform

vkGetPhysicalDeviceDirectFBPresentationSupportEXTQuery physical device for presentation with DirectFB

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

vkGetPhysicalDeviceScreenPresentationSupportQNXQuery physical device for presentation to QNX Screen

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

vkGetPhysicalDeviceSurfaceCapabilitiesKHRQuery surface capabilities
VkSurfaceCapabilitiesKHRStructure describing capabilities of a surface
vkGetPhysicalDeviceSurfaceCapabilities2KHRReports capabilities of a surface on a physical device
VkPhysicalDeviceSurfaceInfo2KHRStructure specifying a surface and related swapchain creation parameters
VkSurfaceFullScreenExclusiveInfoEXTStructure specifying the preferred full-screen transition behavior
VkFullScreenExclusiveEXTHint values an application can specify affecting full-screen transition behavior
VkSurfaceFullScreenExclusiveWin32InfoEXTStructure specifying additional creation parameters specific to Win32 fullscreen exclusive mode
VkSurfaceCapabilities2KHRStructure describing capabilities of a surface
VkSurfaceProtectedCapabilitiesKHRStructure describing capability of a surface to be protected
VkSurfacePresentScalingCapabilitiesEXTStructure describing the presentation scaling capabilities of the surface
VkPresentScalingFlagBitsEXTBitmask specifying presentation scaling methods
VkPresentScalingFlagsEXTBitmask of VkPresentScalingFlagBitsEXT
VkPresentGravityFlagBitsEXTBitmask specifying presentation pixel gravity on either the x or y axis
VkPresentGravityFlagsEXTBitmask of VkPresentGravityFlagBitsEXT
VkSurfacePresentModeEXTStructure describing present mode of a surface
VkSurfacePresentModeCompatibilityEXTStructure describing the subset of compatible presentation modes for the purposes of switching without swapchain recreation
VkSharedPresentSurfaceCapabilitiesKHRStructure describing capabilities of a surface for shared presentation
VkDisplayNativeHdrSurfaceCapabilitiesAMDStructure describing display native HDR specific capabilities of a surface
VkSurfaceCapabilitiesFullScreenExclusiveEXTStructure describing full screen exclusive capabilities of a surface
VkSurfaceCapabilitiesPresentBarrierNVStructure describing present barrier capabilities of a surface
vkGetPhysicalDeviceSurfaceCapabilities2EXTQuery surface capabilities
VkSurfaceCapabilities2EXTStructure describing capabilities of a surface
VkSurfaceCounterFlagBitsEXTSurface-relative counter types
VkSurfaceCounterFlagsEXTBitmask of VkSurfaceCounterFlagBitsEXT
VkSurfaceTransformFlagBitsKHRPresentation transforms supported on a device
VkSurfaceTransformFlagsKHRBitmask of VkSurfaceTransformFlagBitsKHR
VkCompositeAlphaFlagBitsKHRAlpha compositing modes supported on a device
VkCompositeAlphaFlagsKHRBitmask of VkCompositeAlphaFlagBitsKHR

Surface Format Support

vkGetPhysicalDeviceSurfaceFormatsKHRQuery color formats supported by surface
VkSurfaceFormatKHRStructure describing a supported swapchain format-color space pair
vkGetPhysicalDeviceSurfaceFormats2KHRQuery color formats supported by surface
VkSurfaceFormat2KHRStructure describing a supported swapchain format tuple

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 a transfer function that is applied before storing or transmitting color data in the given color space.

VkColorSpaceKHRSupported color space of the presentation engine

Surface Presentation Mode Support

vkGetPhysicalDeviceSurfacePresentModesKHRQuery supported presentation modes
vkGetPhysicalDeviceSurfacePresentModes2EXTQuery supported presentation modes
VkPresentModeKHRPresentation mode supported for a surface

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.

vkAcquireFullScreenExclusiveModeEXTAcquire full-screen exclusive mode for a swapchain
vkReleaseFullScreenExclusiveModeEXTRelease full-screen exclusive mode from a swapchain

Device Group Queries

vkGetDeviceGroupPresentCapabilitiesKHRQuery present capabilities from other physical devices
VkDeviceGroupPresentCapabilitiesKHRPresent capabilities from other physical devices
VkDeviceGroupPresentModeFlagBitsKHRBitmask specifying supported device group present modes
VkDeviceGroupPresentModeFlagsKHRBitmask of VkDeviceGroupPresentModeFlagBitsKHR
vkGetDeviceGroupSurfacePresentModesKHRQuery present capabilities for a surface
vkGetDeviceGroupSurfacePresentModes2EXTQuery device group present capabilities for a surface
vkGetPhysicalDevicePresentRectanglesKHRQuery present rectangles for a surface on a physical device

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.

vkGetRefreshCycleDurationGOOGLEObtain the RC duration of the PE’s display
VkRefreshCycleDurationGOOGLEStructure containing the RC duration of a display

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.

vkGetPastPresentationTimingGOOGLEObtain timing of a previously-presented image
VkPastPresentationTimingGOOGLEStructure containing timing information about a previously-presented image

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 of VkPresentTimeGOOGLE::desiredPresentTime in favor of presenting immediately. The value of VkPastPresentationTimingGOOGLE::earliestPresentTime must be the same as VkPastPresentationTimingGOOGLE::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 of VkPastPresentationTimingGOOGLE::actualPresentTime must be when the image was displayed. For images that are not displayed to the user, vkGetPastPresentationTimingGOOGLE may not return a VkPastPresentationTimingGOOGLE structure, or it may return a VkPastPresentationTimingGOOGLE structure with the value of zero for both VkPastPresentationTimingGOOGLE::actualPresentTime and VkPastPresentationTimingGOOGLE::earliestPresentTime. It is possible that an application can submit images with VkPresentTimeGOOGLE::desiredPresentTime values such that new images may not be displayed. For example, if VkPresentTimeGOOGLE::desiredPresentTime is far enough in the future that an image is not presented before vkQueuePresentKHR 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 for VK_PRESENT_MODE_FIFO_RELAXED_KHR. For images that are presented late, and are displayed after the start of the vertical blanking period (i.e. with tearing), the values of VkPastPresentationTimingGOOGLE may be treated as if the image was displayed at the start of the vertical blanking period, or may be treated the same as for VK_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

VkSwapchainKHROpaque handle to a swapchain object

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 call vkQueuePresentKHR 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 to vkQueuePresentKHR, 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 calling vkQueuePresentKHR, 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.

vkGetSwapchainStatusKHRGet a swapchain’s status

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 set to VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR.

vkCreateSwapchainKHRCreate a swapchain
VkSwapchainCreateInfoKHRStructure specifying parameters of a newly created swapchain object
VkSwapchainCreateFlagBitsKHRBitmask controlling swapchain creation
VkSwapchainCreateFlagsKHRBitmask of VkSwapchainCreateFlagBitsKHR
VkDeviceGroupSwapchainCreateInfoKHRStructure specifying parameters of a newly created swapchain object
VkSwapchainDisplayNativeHdrCreateInfoAMDStructure specifying display native HDR parameters of a newly created swapchain object
vkSetLocalDimmingAMDSet Local Dimming

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.

VkSwapchainCounterCreateInfoEXTSpecify the surface counters desired
vkGetSwapchainCounterEXTQuery the current value of a surface counter

To specify compression properties for the swapchain images in this swapchain, add a VkImageCompressionControlEXT structure to the pNext chain of the VkSwapchainCreateInfoKHR structure.

VkSwapchainPresentModesCreateInfoEXTAll presentation modes usable by the swapchain
VkSwapchainPresentScalingCreateInfoEXTScaling behavior when presenting to the surface
vkDestroySwapchainKHRDestroy a swapchain object
vkCreateSharedSwapchainsKHRCreate multiple swapchains that share presentable images
vkGetSwapchainImagesKHRObtain the array of presentable images associated with a swapchain

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.

vkAcquireNextImageKHRRetrieve the index of the next available presentable image

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 its pWaitSemaphores member, with the corresponding element of pWaitDstStageMask including S.
  • The synchronization command that performs any necessary image layout transition includes S in both the srcStageMask and dstStageMask.

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

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.

vkAcquireNextImage2KHRRetrieve the index of the next available presentable image
VkAcquireNextImageInfoKHRStructure specifying parameters of the acquire
vkQueuePresentKHRQueue an image for presentation
VkPresentInfoKHRStructure describing parameters of a queue presentation
VkPresentRegionsKHRStructure hint of rectangular regions changed by vkQueuePresentKHR
VkPresentRegionKHRStructure containing rectangular region changed by vkQueuePresentKHR for a given VkImage
VkRectLayerKHRStructure containing a rectangle, including layer, changed by vkQueuePresentKHR for a given VkImage

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.

VkDisplayPresentInfoKHRStructure describing parameters of a queue presentation to a swapchain
VkDeviceGroupPresentInfoKHRMode and mask controlling which physical devices' images are presented
VkPresentTimesInfoGOOGLEThe earliest time each image should be presented
VkPresentTimeGOOGLEThe earliest time image should be presented
VkPresentIdKHRThe list of presentation identifiers
vkWaitForPresentKHRWait for presentation
VkPresentFrameTokenGGPThe Google Games Platform frame token
VkSwapchainPresentModeInfoEXTPresentation modes for a vkQueuePresentKHR operation
VkSwapchainPresentFenceInfoEXTFences associated with a vkQueuePresentKHR operation
vkReleaseSwapchainImagesEXTRelease previously acquired but unused images
VkReleaseSwapchainImagesInfoEXTStructure describing a list of swapchain image indices to be released

Hdr Metadata

This section describes how to improve color reproduction of content to better reproduce colors as seen on the reference monitor. Definitions below are from the associated SMPTE 2086, CTA 861.3 and CIE 15:2004 specifications.

vkSetHdrMetadataEXTSet Hdr metadata
VkHdrMetadataEXTSpecify Hdr metadata
VkXYColorEXTSpecify X,Y chromaticity coordinates

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.

VkSwapchainPresentBarrierCreateInfoNVspecify the present barrier membership of this swapchain