• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2022 The Khronos Group Inc.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5= VK_EXT_surface_maintenance1
6:toc: left
7:refpage: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/
8:sectnums:
9
10This proposal investigates and addresses a number of practical issues with the
11`VK_KHR_surface` specification.
12
13== Problem Statement
14
15The following is a list of issues considered in this proposal:
16
17  * Min and max image count as reported in `VkSurfaceCapabilitiesKHR` depend on
18    present mode.
19  * The scaling behavior of the surface is undefined when the swapchain and
20    the surface dimensions do not match.
21  * Switching between some present modes technically should not require
22    recreating the swapchain
23
24=== Image Count Query Per Present Mode
25
26The implementation may require a different number of images, as reported in
27`VkSurfaceCapabilitiesKHR::minImageCount` and
28`VkSurfaceCapabilitiesKHR::maxImageCount` depending on the desired present mode.
29However, there is currently no way to specify the present mode when calling
30`vkGetPhysicalDeviceSurfaceCapabilitiesKHR`.
31
32=== Undefined Scaling Behavior
33
34Currently, a few of the surface extensions (such as `VK_KHR_xcb_surface` and
35`VK_KHR_win32_surface`) require the swapchain's extents to match the surface's.
36A mismatch between the swapchain and the surface dimensions, as the window is
37resized, would result in `VK_ERROR_OUT_OF_DATE_KHR`, which can be undesirable
38behavior.
39On other surfaces where scaling happens, it is undefined how the image is
40scaled.
41The image may stretch, scale with fixed aspect ratio, snap to a corner or be
42centered.
43
44=== Switching Present Modes
45
46Certain present modes are compatible, such that a swapchain operating under one
47mode can be easily switched to another.
48In such a case, recreating the swapchain is undesirable.
49
50See the proposal for `VK_EXT_swapchain_maintenance1` for details.
51
52== Solution Space
53
54=== Image Count Query Per Present Mode
55
56This issue can be rectified by providing the desired present mode when querying
57surface capabilities.
58
59=== Undefined Scaling Behavior
60
61This issue can be resolved by the application querying and opting in to a
62specific supported scaling behavior.  Potential behaviors are:
63
64  * Stretch the swapchain image to the dimensions of the surface
65  * Stretch the swapchain image while maintaining the aspect ratio to fit
66    within the surface
67  * No scaling applied, and swapchain pixels are mapped one-to-one to the
68    surface
69
70When the resulting image does not cover the entire surface, additional behavior
71can be specified for each of the X and Y axes:
72
73  * Gravitate to left/top
74  * Gravitate to right/bottom
75  * Center
76
77This extension allows the supported behavior to be queried, while
78`VK_EXT_swapchain_maintenance1` would be used to select the desired behavior at
79swapchain creation time.
80
81=== Switching Present Modes
82
83To support the `VK_EXT_swapchain_maintenance1` extension and allow creating
84swapchains that may change present modes, it should be possible to query the
85set of compatible present modes for this purpose.
86
87This can be done by providing one present mode and querying the list of
88compatible present modes from the surface.
89
90== Proposal
91
92Introduced by this API are:
93
94=== Image Count Query Per Present Mode
95
96To query the min and max image counts for a specific present mode, chain the
97following to `VkPhysicalDeviceSurfaceInfo2KHR` when calling
98`vkGetPhysicalDeviceSurfaceCapabilities2KHR`:
99
100[source,c]
101----
102typedef struct VkSurfacePresentModeEXT {
103    VkStructureType    sType;
104    void*              pNext;
105    VkPresentModeKHR   presentMode;
106} VkSurfacePresentModeEXT;
107----
108
109The returned values in `VkSurfaceCapabilitiesKHR::minImageCount` and
110`VkSurfaceCapabilitiesKHR::maxImageCount` would then be specific to the given
111present mode.
112
113=== Undefined Scaling Behavior
114
115To query supported scaling behavior, chain `VkSurfacePresentModeEXT` to
116`VkPhysicalDeviceSurfaceInfo2KHR` and chain the following to
117`VkSurfaceCapabilities2KHR`:
118
119[source,c]
120----
121typedef struct VkSurfacePresentScalingCapabilitiesEXT {
122    VkStructureType           sType;
123    void*                     pNext;
124    VkPresentScalingFlagsEXT  supportedPresentScaling;
125    VkPresentGravityFlagsEXT  supportedPresentGravityX;
126    VkPresentGravityFlagsEXT  supportedPresentGravityY;
127    VkExtent2D                minScaledImageExtent;
128    VkExtent2D                maxScaledImageExtent;
129} VkSurfacePresentScalingCapabilitiesEXT;
130----
131
132Where `VkPresentScalingFlagsEXT` is defined as:
133
134[source,c]
135----
136typedef enum VkPresentScalingFlagBitsEXT {
137    VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT = 0x00000001,
138    VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_EXT = 0x00000002,
139    VK_PRESENT_SCALING_STRETCH_BIT_EXT = 0x00000004,
140} VkPresentScalingFlagBitsEXT;
141
142typedef VkFlags VkPresentScalingFlagsEXT;
143----
144
145And `VkPresentGravityFlagsEXT` is defined as:
146
147[source,c]
148----
149typedef enum VkPresentGravityFlagBitsEXT {
150    VK_PRESENT_GRAVITY_MIN_BIT_EXT = 0x00000001,
151    VK_PRESENT_GRAVITY_MAX_BIT_EXT = 0x00000002,
152    VK_PRESENT_GRAVITY_CENTERED_BIT_EXT = 0x00000004,
153} VkPresentGravityFlagBitsEXT;
154
155typedef VkFlags VkPresentGravityFlagsEXT;
156----
157
158Note that scaling may not be supported for certain present modes.
159
160The `VK_EXT_swapchain_maintenance1` extension must be used to create a
161swapchain with a supported behavior.
162Swapchains created with scaling enabled, must use image extents that are
163bounded by `minScaledImageExtent` and `maxScaledImageExtent`.
164
165=== Switching Present Modes
166
167To query the list of compatible present modes with a given present mode for the
168purposes of mode switching, chain `VkSurfacePresentModeEXT` to
169`VkPhysicalDeviceSurfaceInfo2KHR` and chain the following to
170`VkSurfaceCapabilities2KHR`:
171
172[source,c]
173----
174typedef struct VkSurfacePresentModeCompatibilityEXT {
175    VkStructureType    sType;
176    void*              pNext;
177    uint32_t           presentModeCount;
178    VkPresentMode*     pPresentModes;
179} VkSurfacePresentModeCompatibilityEXT;
180----
181
182The implementation will return the count of compatible present modes in
183`presentModeCount`, and if provided, the list of them in `pPresentModes`.
184
185== Issues
186