blob: e3c67bd969213e13d09cb6a4b48434a198dbf05c [file] [log] [blame]
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
Ian Elliott8f78daa2016-01-26 10:51:10 -07004 * Copyright (C) 2015-2016 Google Inc.
Ian Elliott0b4d6242015-09-22 10:51:24 -06005 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
Ian Elliott0b4d6242015-09-22 10:51:24 -06009 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060010 * http://www.apache.org/licenses/LICENSE-2.0
Ian Elliott0b4d6242015-09-22 10:51:24 -060011 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060012 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
Ian Elliott0b4d6242015-09-22 10:51:24 -060017 *
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060018 * Author: Ian Elliott <ian@lunarg.com>
Ian Elliott578e7e22016-01-05 14:03:16 -070019 * Author: Ian Elliott <ianelliott@google.com>
Ian Elliott0b4d6242015-09-22 10:51:24 -060020 */
21
22#ifndef SWAPCHAIN_H
23#define SWAPCHAIN_H
24
David Pinedo9316d3b2015-11-06 12:54:48 -070025#include "vulkan/vk_layer.h"
Tobin Ehlis711ff312015-10-29 12:58:13 -060026#include "vk_layer_config.h"
27#include "vk_layer_logging.h"
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -060028#include <vector>
Tobin Ehlis711ff312015-10-29 12:58:13 -060029#include <unordered_map>
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -060030
Ian Elliott0b4d6242015-09-22 10:51:24 -060031using namespace std;
32
Ian Elliottb0f474c2015-09-25 15:50:55 -060033// Swapchain ERROR codes
Mark Lobodzinski3ae55162016-05-19 17:01:48 -060034enum SWAPCHAIN_ERROR {
Jon Ashburn5484e0c2016-03-08 17:48:44 -070035 SWAPCHAIN_INVALID_HANDLE, // Handle used that isn't currently valid
36 SWAPCHAIN_NULL_POINTER, // Pointer set to NULL, instead of being a valid pointer
37 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, // Did not enable WSI extension, but called WSI function
38 SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, // Called vkDestroyDevice() before vkDestroySwapchainKHR()
39 SWAPCHAIN_CREATE_UNSUPPORTED_SURFACE, // Called vkCreateSwapchainKHR() with a pCreateInfo->surface that wasn't seen as supported
40 // by vkGetPhysicalDeviceSurfaceSupportKHR for the device
41 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, // Called vkCreateSwapchainKHR() without calling a query (e.g.
42 // vkGetPhysicalDeviceSurfaceCapabilitiesKHR())
Jon Ashburn5484e0c2016-03-08 17:48:44 -070043 SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS, // Called vkCreateSwapchainKHR() with out-of-bounds imageExtent
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070044 SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN, // Called vkCreateSwapchainKHR() with imageExtent that doesn't match window's extent
45 SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM, // Called vkCreateSwapchainKHR() with a non-supported preTransform
46 SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA, // Called vkCreateSwapchainKHR() with a non-supported compositeAlpha
David McFarlande22cfb02016-05-20 18:26:28 -030047 SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_LAYERS, // Called vkCreateSwapchainKHR() with a non-supported imageArrayLayers
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070048 SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS, // Called vkCreateSwapchainKHR() with a non-supported imageUsageFlags
49 SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE, // Called vkCreateSwapchainKHR() with a non-supported imageColorSpace
50 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT, // Called vkCreateSwapchainKHR() with a non-supported imageFormat
51 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP, // Called vkCreateSwapchainKHR() with a non-supported imageColorSpace
52 SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE, // Called vkCreateSwapchainKHR() with a non-supported presentMode
53 SWAPCHAIN_CREATE_SWAP_BAD_SHARING_MODE, // Called vkCreateSwapchainKHR() with a non-supported imageSharingMode
Jon Ashburn5484e0c2016-03-08 17:48:44 -070054 SWAPCHAIN_CREATE_SWAP_BAD_SHARING_VALUES, // Called vkCreateSwapchainKHR() with bad values when imageSharingMode is
55 // VK_SHARING_MODE_CONCURRENT
Jon Ashburn5484e0c2016-03-08 17:48:44 -070056 SWAPCHAIN_BAD_BOOL, // VkBool32 that doesn't have value of VK_TRUE or VK_FALSE (e.g. is a non-zero form of true)
Ian Elliottfdf3ffa2016-05-05 14:06:53 -060057 SWAPCHAIN_PRIOR_COUNT, // Query must be called first to get value of pCount, then called second time
Jon Ashburn5484e0c2016-03-08 17:48:44 -070058 SWAPCHAIN_INVALID_COUNT, // Second time a query called, the pCount value didn't match first time
59 SWAPCHAIN_WRONG_STYPE, // The sType for a struct has the wrong value
60 SWAPCHAIN_WRONG_NEXT, // The pNext for a struct is not NULL
61 SWAPCHAIN_ZERO_VALUE, // A value should be non-zero
Jon Ashburn5484e0c2016-03-08 17:48:44 -070062 SWAPCHAIN_DID_NOT_QUERY_QUEUE_FAMILIES, // A function using a queueFamilyIndex was called before
63 // vkGetPhysicalDeviceQueueFamilyProperties() was called
64 SWAPCHAIN_QUEUE_FAMILY_INDEX_TOO_LARGE, // A queueFamilyIndex value is not less than pQueueFamilyPropertyCount returned by
65 // vkGetPhysicalDeviceQueueFamilyProperties()
66 SWAPCHAIN_SURFACE_NOT_SUPPORTED_WITH_QUEUE, // A surface is not supported by a given queueFamilyIndex, as seen by
67 // vkGetPhysicalDeviceSurfaceSupportKHR()
Petros Bantolas2b40be72016-04-15 11:02:59 +010068 SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY, // vkGetDisplayPlaneSupportedDisplaysKHR should be called after querying
69 // device display plane properties
70 SWAPCHAIN_PLANE_INDEX_TOO_LARGE, // a planeIndex value is larger than what vkGetDisplayPlaneSupportedDisplaysKHR returns
Mark Lobodzinski3ae55162016-05-19 17:01:48 -060071};
Ian Elliottb0f474c2015-09-25 15:50:55 -060072
Ian Elliott0b4d6242015-09-22 10:51:24 -060073// The following is for logging error messages:
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -060074const char * swapchain_layer_name = "Swapchain";
75
Ian Elliott0b4d6242015-09-22 10:51:24 -060076#define LAYER_NAME (char *) "Swapchain"
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -060077
Ian Elliott0b4d6242015-09-22 10:51:24 -060078// NOTE: The following struct's/typedef's are for keeping track of
79// info that is used for validating the WSI extensions.
80
81// Forward declarations:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -060082struct SwpInstance;
83struct SwpSurface;
84struct SwpPhysicalDevice;
85struct SwpDevice;
86struct SwpSwapchain;
87struct SwpImage;
88struct SwpQueue;
Ian Elliott0b4d6242015-09-22 10:51:24 -060089
90// Create one of these for each VkInstance:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -060091struct SwpInstance {
Ian Elliott0b4d6242015-09-22 10:51:24 -060092 // The actual handle for this VkInstance:
93 VkInstance instance;
94
Ian Elliott1f6bb802016-01-20 16:33:34 -070095 // Remember the VkSurfaceKHR's that are created for this VkInstance:
Jon Ashburn5484e0c2016-03-08 17:48:44 -070096 unordered_map<VkSurfaceKHR, SwpSurface *> surfaces;
Ian Elliott1f6bb802016-01-20 16:33:34 -070097
Ian Elliott0b4d6242015-09-22 10:51:24 -060098 // When vkEnumeratePhysicalDevices is called, the VkPhysicalDevice's are
99 // remembered:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700100 unordered_map<const void *, SwpPhysicalDevice *> physicalDevices;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600101
Petros Bantolas2b40be72016-04-15 11:02:59 +0100102 // Set to true if VK_KHR_DISPLAY_EXTENSION_NAME was enabled for this VkInstance:
103 bool displayExtensionEnabled;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600104};
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700105
Ian Elliott1f6bb802016-01-20 16:33:34 -0700106// Create one of these for each VkSurfaceKHR:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -0600107struct SwpSurface {
Ian Elliott1f6bb802016-01-20 16:33:34 -0700108 // The actual handle for this VkSurfaceKHR:
109 VkSurfaceKHR surface;
110
111 // VkInstance that this VkSurfaceKHR is associated with:
112 SwpInstance *pInstance;
113
114 // When vkCreateSwapchainKHR is called, the VkSwapchainKHR's are
115 // remembered:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700116 unordered_map<VkSwapchainKHR, SwpSwapchain *> swapchains;
Ian Elliott680825b2016-01-21 12:42:19 -0700117
Ian Elliottc4db6952016-01-21 14:29:45 -0700118 // Value of pQueueFamilyPropertyCount that was returned by the
119 // vkGetPhysicalDeviceQueueFamilyProperties() function:
120 uint32_t numQueueFamilyIndexSupport;
121 // Array of VkBool32's that is intialized by the
122 // vkGetPhysicalDeviceSurfaceSupportKHR() function. First call for a given
123 // surface allocates and initializes this array to false for all
124 // queueFamilyIndex's (and sets numQueueFamilyIndexSupport to non-zero).
125 // All calls set the entry for a given queueFamilyIndex:
126 VkBool32 *pQueueFamilyIndexSupport;
Ian Elliott1f6bb802016-01-20 16:33:34 -0700127};
Ian Elliott0b4d6242015-09-22 10:51:24 -0600128
129// Create one of these for each VkPhysicalDevice within a VkInstance:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -0600130struct SwpPhysicalDevice {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600131 // The actual handle for this VkPhysicalDevice:
132 VkPhysicalDevice physicalDevice;
133
134 // Corresponding VkDevice (and info) to this VkPhysicalDevice:
135 SwpDevice *pDevice;
136
137 // VkInstance that this VkPhysicalDevice is associated with:
138 SwpInstance *pInstance;
139
Ian Elliottaeafe232016-01-20 10:50:33 -0700140 // Records results of vkGetPhysicalDeviceQueueFamilyProperties()'s
Ian Elliottc4db6952016-01-21 14:29:45 -0700141 // numOfQueueFamilies parameter when pQueueFamilyProperties is NULL:
Ian Elliottaeafe232016-01-20 10:50:33 -0700142 bool gotQueueFamilyPropertyCount;
Ian Elliottc4db6952016-01-21 14:29:45 -0700143 uint32_t numOfQueueFamilies;
Ian Elliottaeafe232016-01-20 10:50:33 -0700144
Ian Elliottc4db6952016-01-21 14:29:45 -0700145 // Record all surfaces that vkGetPhysicalDeviceSurfaceSupportKHR() was
146 // called for:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700147 unordered_map<VkSurfaceKHR, SwpSurface *> supportedSurfaces;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600148
Petros Bantolas2b40be72016-04-15 11:02:59 +0100149 // Count returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR():
150 uint32_t displayPlanePropertyCount;
151 bool gotDisplayPlanePropertyCount;
Ian Elliott27d39c72015-11-20 16:39:34 -0700152};
153
154// Create one of these for each VkDevice within a VkInstance:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -0600155struct SwpDevice {
Ian Elliott27d39c72015-11-20 16:39:34 -0700156 // The actual handle for this VkDevice:
157 VkDevice device;
158
159 // Corresponding VkPhysicalDevice (and info) to this VkDevice:
160 SwpPhysicalDevice *pPhysicalDevice;
161
Ian Elliott0b4d6242015-09-22 10:51:24 -0600162 // When vkCreateSwapchainKHR is called, the VkSwapchainKHR's are
163 // remembered:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700164 unordered_map<VkSwapchainKHR, SwpSwapchain *> swapchains;
Ian Elliottc4db6952016-01-21 14:29:45 -0700165
166 // When vkGetDeviceQueue is called, the VkQueue's are remembered:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700167 unordered_map<VkQueue, SwpQueue *> queues;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600168};
169
170// Create one of these for each VkImage within a VkSwapchainKHR:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -0600171struct SwpImage {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600172 // The actual handle for this VkImage:
173 VkImage image;
174
175 // Corresponding VkSwapchainKHR (and info) to this VkImage:
176 SwpSwapchain *pSwapchain;
177
Ian Elliotta5d13a92016-04-07 09:05:45 -0600178 // true if application acquired this image from vkAcquireNextImageKHR(),
179 // and hasn't yet called vkQueuePresentKHR() for it; otherwise false:
180 bool acquiredByApp;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600181};
182
183// Create one of these for each VkSwapchainKHR within a VkDevice:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -0600184struct SwpSwapchain {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600185 // The actual handle for this VkSwapchainKHR:
186 VkSwapchainKHR swapchain;
187
188 // Corresponding VkDevice (and info) to this VkSwapchainKHR:
189 SwpDevice *pDevice;
190
Ian Elliottf7f8ff02015-12-30 14:55:41 -0700191 // Corresponding VkSurfaceKHR to this VkSwapchainKHR:
Ian Elliott1f6bb802016-01-20 16:33:34 -0700192 SwpSurface *pSurface;
Ian Elliottf7f8ff02015-12-30 14:55:41 -0700193
Ian Elliott0b4d6242015-09-22 10:51:24 -0600194 // When vkGetSwapchainImagesKHR is called, the VkImage's are
195 // remembered:
196 uint32_t imageCount;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600197};
198
Ian Elliottc4db6952016-01-21 14:29:45 -0700199// Create one of these for each VkQueue within a VkDevice:
Mark Lobodzinski3ae55162016-05-19 17:01:48 -0600200struct SwpQueue {
Ian Elliottc4db6952016-01-21 14:29:45 -0700201 // The actual handle for this VkQueue:
202 VkQueue queue;
203
204 // Corresponding VkDevice (and info) to this VkSwapchainKHR:
205 SwpDevice *pDevice;
206
207 // Which queueFamilyIndex this VkQueue is associated with:
208 uint32_t queueFamilyIndex;
209};
210
Tobin Ehlis711ff312015-10-29 12:58:13 -0600211struct layer_data {
Chia-I Wua6737532016-04-28 16:04:15 +0800212 VkInstance instance;
213
Tobin Ehlis711ff312015-10-29 12:58:13 -0600214 debug_report_data *report_data;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700215 std::vector<VkDebugReportCallbackEXT> logging_callback;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700216 VkLayerDispatchTable *device_dispatch_table;
217 VkLayerInstanceDispatchTable *instance_dispatch_table;
Ian Elliotted6b5ac2016-04-28 09:08:13 -0600218
219 // The following are for keeping track of the temporary callbacks that can
220 // be used in vkCreateInstance and vkDestroyInstance:
221 uint32_t num_tmp_callbacks;
222 VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
223 VkDebugReportCallbackEXT *tmp_callbacks;
224
Tobin Ehlis711ff312015-10-29 12:58:13 -0600225 // NOTE: The following are for keeping track of info that is used for
226 // validating the WSI extensions.
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700227 std::unordered_map<void *, SwpInstance> instanceMap;
228 std::unordered_map<VkSurfaceKHR, SwpSurface> surfaceMap;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600229 std::unordered_map<void *, SwpPhysicalDevice> physicalDeviceMap;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700230 std::unordered_map<void *, SwpDevice> deviceMap;
231 std::unordered_map<VkSwapchainKHR, SwpSwapchain> swapchainMap;
232 std::unordered_map<void *, SwpQueue> queueMap;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600233
Ian Elliotted6b5ac2016-04-28 09:08:13 -0600234 layer_data()
235 : report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr), num_tmp_callbacks(0),
236 tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr){};
Tobin Ehlis711ff312015-10-29 12:58:13 -0600237};
238
Ian Elliott0b4d6242015-09-22 10:51:24 -0600239#endif // SWAPCHAIN_H