blob: 7ae6d76ba76fdc8f086cd6b9686c4000f2b535ac [file] [log] [blame]
Ian Elliott0b4d6242015-09-22 10:51:24 -06001/*
Ian Elliott0b4d6242015-09-22 10:51:24 -06002 *
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Michael Lentine03107b42015-12-11 10:49:51 -08004 * Copyright (C) 2015 Google Inc.
Ian Elliott0b4d6242015-09-22 10:51:24 -06005 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060024 * Author: Ian Elliott <ian@lunarg.com>
25 *
Ian Elliott0b4d6242015-09-22 10:51:24 -060026 */
27
28#ifndef SWAPCHAIN_H
29#define SWAPCHAIN_H
30
David Pinedo9316d3b2015-11-06 12:54:48 -070031#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070032#include "vulkan/vk_ext_debug_report.h"
Tobin Ehlis711ff312015-10-29 12:58:13 -060033#include "vk_layer_config.h"
34#include "vk_layer_logging.h"
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -060035#include <vector>
Tobin Ehlis711ff312015-10-29 12:58:13 -060036#include <unordered_map>
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -060037
Ian Elliottd8c5db12015-10-07 11:32:31 -060038static const VkLayerProperties globalLayerProps[] = {
39 {
Michael Lentine03107b42015-12-11 10:49:51 -080040 "VK_LAYER_LUNARG_swapchain",
Ian Elliottd8c5db12015-10-07 11:32:31 -060041 VK_API_VERSION, // specVersion
Chia-I Wu3432a0c2015-10-27 18:04:07 +080042 VK_MAKE_VERSION(0, 1, 0), // implementationVersion
Mark Lobodzinski0d054fe2015-12-30 08:16:12 -070043 "layer: swapchain",
Ian Elliottd8c5db12015-10-07 11:32:31 -060044 }
45};
46
47static const VkLayerProperties deviceLayerProps[] = {
48 {
Michael Lentine03107b42015-12-11 10:49:51 -080049 "VK_LAYER_LUNARG_swapchain",
Ian Elliottd8c5db12015-10-07 11:32:31 -060050 VK_API_VERSION, // specVersion
Chia-I Wu3432a0c2015-10-27 18:04:07 +080051 VK_MAKE_VERSION(0, 1, 0), // implementationVersion
Mark Lobodzinski0d054fe2015-12-30 08:16:12 -070052 "layer: swapchain",
Ian Elliottd8c5db12015-10-07 11:32:31 -060053 }
54};
55
Ian Elliott0b4d6242015-09-22 10:51:24 -060056
57using namespace std;
58
Ian Elliottb0f474c2015-09-25 15:50:55 -060059
60// Swapchain ERROR codes
61typedef enum _SWAPCHAIN_ERROR
62{
63 SWAPCHAIN_INVALID_HANDLE, // Handle used that isn't currently valid
64 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, // Did not enable WSI extension, but called WSI function
65 SWAPCHAIN_DEL_DEVICE_BEFORE_SWAPCHAINS, // Called vkDestroyDevice() before vkDestroySwapchainKHR()
Ian Elliott1dcd1092015-11-17 17:29:40 -070066 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, // Called vkCreateSwapchainKHR() without calling a query (e.g. vkGetPhysicalDeviceSurfaceCapabilitiesKHR())
Ian Elliottb0f474c2015-09-25 15:50:55 -060067 SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT, // Called vkCreateSwapchainKHR() with out-of-bounds minImageCount
68 SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS,// Called vkCreateSwapchainKHR() with out-of-bounds imageExtent
69 SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN, // Called vkCreateSwapchainKHR() with imageExtent that doesn't match window's extent
70 SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM, // Called vkCreateSwapchainKHR() with a non-supported preTransform
71 SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE, // Called vkCreateSwapchainKHR() with a non-supported imageArraySize
72 SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS, // Called vkCreateSwapchainKHR() with a non-supported imageUsageFlags
73 SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE, // Called vkCreateSwapchainKHR() with a non-supported imageColorSpace
74 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT, // Called vkCreateSwapchainKHR() with a non-supported imageFormat
75 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP, // Called vkCreateSwapchainKHR() with a non-supported imageColorSpace
76 SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE, // Called vkCreateSwapchainKHR() with a non-supported presentMode
77 SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, // Called vkDestroySwapchainKHR() with a different VkDevice than vkCreateSwapchainKHR()
78 SWAPCHAIN_APP_OWNS_TOO_MANY_IMAGES, // vkAcquireNextImageKHR() asked for more images than are available
79 SWAPCHAIN_INDEX_TOO_LARGE, // Index is too large for swapchain
Ian Elliottb0f474c2015-09-25 15:50:55 -060080 SWAPCHAIN_INDEX_NOT_IN_USE, // vkQueuePresentKHR() given index that is not owned by app
81} SWAPCHAIN_ERROR;
82
83
Ian Elliott0b4d6242015-09-22 10:51:24 -060084// The following is for logging error messages:
Ian Elliott0b4d6242015-09-22 10:51:24 -060085#define LAYER_NAME (char *) "Swapchain"
86#define LOG_ERROR_NON_VALID_OBJ(objType, type, obj) \
Ian Elliott68124ac2015-10-07 16:18:35 -060087 (my_data) ? \
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070088 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (objType), \
Mark Lobodzinski80e774f2016-01-04 15:54:59 -070089 (uint64_t) (obj), __LINE__, SWAPCHAIN_INVALID_HANDLE, LAYER_NAME, \
Ian Elliott68124ac2015-10-07 16:18:35 -060090 "%s() called with a non-valid %s.", __FUNCTION__, (obj)) \
91 : VK_FALSE
Ian Elliott0b4d6242015-09-22 10:51:24 -060092
Ian Elliottb0f474c2015-09-25 15:50:55 -060093#define LOG_ERROR(objType, type, obj, enm, fmt, ...) \
Ian Elliott68124ac2015-10-07 16:18:35 -060094 (my_data) ? \
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070095 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (objType), \
Mark Lobodzinski80e774f2016-01-04 15:54:59 -070096 (uint64_t) (obj), __LINE__, (enm), LAYER_NAME, (fmt), __VA_ARGS__) \
Ian Elliott68124ac2015-10-07 16:18:35 -060097 : VK_FALSE
Ian Elliottb0f474c2015-09-25 15:50:55 -060098#define LOG_PERF_WARNING(objType, type, obj, enm, fmt, ...) \
Ian Elliott68124ac2015-10-07 16:18:35 -060099 (my_data) ? \
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700100 log_msg(my_data->report_data, VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, (objType), \
Mark Lobodzinski80e774f2016-01-04 15:54:59 -0700101 (uint64_t) (obj), __LINE__, (enm), LAYER_NAME, (fmt), __VA_ARGS__) \
Ian Elliott68124ac2015-10-07 16:18:35 -0600102 : VK_FALSE
Ian Elliott0b4d6242015-09-22 10:51:24 -0600103
104
105// NOTE: The following struct's/typedef's are for keeping track of
106// info that is used for validating the WSI extensions.
107
108// Forward declarations:
109struct _SwpInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700110struct _SwpSurface;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600111struct _SwpPhysicalDevice;
112struct _SwpDevice;
113struct _SwpSwapchain;
114struct _SwpImage;
115
116typedef _SwpInstance SwpInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700117typedef _SwpSurface SwpSurface;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600118typedef _SwpPhysicalDevice SwpPhysicalDevice;
119typedef _SwpDevice SwpDevice;
120typedef _SwpSwapchain SwpSwapchain;
121typedef _SwpImage SwpImage;
122
123// Create one of these for each VkInstance:
124struct _SwpInstance {
125 // The actual handle for this VkInstance:
126 VkInstance instance;
127
Ian Elliotta983e9a2015-12-22 12:18:12 -0700128 // Remember the VkSurfaceKHR's that are created for this VkInstance:
129 unordered_map<const void*, SwpSurface*> surfaces;
130
Ian Elliott0b4d6242015-09-22 10:51:24 -0600131 // When vkEnumeratePhysicalDevices is called, the VkPhysicalDevice's are
132 // remembered:
133 unordered_map<const void*, SwpPhysicalDevice*> physicalDevices;
134
Ian Elliott1dcd1092015-11-17 17:29:40 -0700135 // Set to true if VK_KHR_SURFACE_EXTENSION_NAME was enabled for this VkInstance:
Ian Elliott0b4d6242015-09-22 10:51:24 -0600136 bool swapchainExtensionEnabled;
137
138 // TODO: Add additional booleans for platform-specific extensions:
139};
140
Ian Elliotta983e9a2015-12-22 12:18:12 -0700141// Create one of these for each VkSurfaceKHR:
142struct _SwpSurface {
143 // The actual handle for this VkSurfaceKHR:
144 VkSurfaceKHR surface;
145
146 // VkInstance that this VkSurfaceKHR is associated with:
147 SwpInstance *pInstance;
148
149 // Which platform this VkSurfaceKHR is associated with:
150 VkIcdWsiPlatform platform;
151
152 // TODO: Add additional platform-specific info:
153};
154
Ian Elliott0b4d6242015-09-22 10:51:24 -0600155// Create one of these for each VkPhysicalDevice within a VkInstance:
156struct _SwpPhysicalDevice {
157 // The actual handle for this VkPhysicalDevice:
158 VkPhysicalDevice physicalDevice;
159
160 // Corresponding VkDevice (and info) to this VkPhysicalDevice:
161 SwpDevice *pDevice;
162
163 // VkInstance that this VkPhysicalDevice is associated with:
164 SwpInstance *pInstance;
165
166 // Which queueFamilyIndices support presenting with WSI swapchains:
167 unordered_map<uint32_t, VkBool32> queueFamilyIndexSupport;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600168
169// TODO: Record/use this info per-surface, not per-device, once a
170// non-dispatchable surface object is added to WSI:
Ian Elliott1dcd1092015-11-17 17:29:40 -0700171 // Results of vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
Ian Elliott27d39c72015-11-20 16:39:34 -0700172 bool gotSurfaceCapabilities;
173 VkSurfaceCapabilitiesKHR surfaceCapabilities;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600174
175// TODO: Record/use this info per-surface, not per-device, once a
176// non-dispatchable surface object is added to WSI:
Ian Elliott1dcd1092015-11-17 17:29:40 -0700177 // Count and VkSurfaceFormatKHR's returned by vkGetPhysicalDeviceSurfaceFormatsKHR():
Ian Elliott0b4d6242015-09-22 10:51:24 -0600178 uint32_t surfaceFormatCount;
179 VkSurfaceFormatKHR* pSurfaceFormats;
180
181// TODO: Record/use this info per-surface, not per-device, once a
182// non-dispatchable surface object is added to WSI:
Ian Elliott1dcd1092015-11-17 17:29:40 -0700183 // Count and VkPresentModeKHR's returned by vkGetPhysicalDeviceSurfacePresentModesKHR():
Ian Elliott0b4d6242015-09-22 10:51:24 -0600184 uint32_t presentModeCount;
185 VkPresentModeKHR* pPresentModes;
Ian Elliott27d39c72015-11-20 16:39:34 -0700186};
187
188// Create one of these for each VkDevice within a VkInstance:
189struct _SwpDevice {
190 // The actual handle for this VkDevice:
191 VkDevice device;
192
193 // Corresponding VkPhysicalDevice (and info) to this VkDevice:
194 SwpPhysicalDevice *pPhysicalDevice;
195
196 // Set to true if VK_KHR_SWAPCHAIN_EXTENSION_NAME was enabled:
197 bool deviceSwapchainExtensionEnabled;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600198
199 // When vkCreateSwapchainKHR is called, the VkSwapchainKHR's are
200 // remembered:
Chia-I Wue2fc5522015-10-26 20:04:44 +0800201 unordered_map<VkSwapchainKHR, SwpSwapchain*> swapchains;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600202};
203
204// Create one of these for each VkImage within a VkSwapchainKHR:
205struct _SwpImage {
206 // The actual handle for this VkImage:
207 VkImage image;
208
209 // Corresponding VkSwapchainKHR (and info) to this VkImage:
210 SwpSwapchain *pSwapchain;
211
212 // true if application got this image from vkAcquireNextImageKHR(), and
213 // hasn't yet called vkQueuePresentKHR() for it; otherwise false:
214 bool ownedByApp;
215};
216
217// Create one of these for each VkSwapchainKHR within a VkDevice:
218struct _SwpSwapchain {
219 // The actual handle for this VkSwapchainKHR:
220 VkSwapchainKHR swapchain;
221
222 // Corresponding VkDevice (and info) to this VkSwapchainKHR:
223 SwpDevice *pDevice;
224
225 // When vkGetSwapchainImagesKHR is called, the VkImage's are
226 // remembered:
227 uint32_t imageCount;
228 unordered_map<int, SwpImage> images;
229};
230
Tobin Ehlis711ff312015-10-29 12:58:13 -0600231struct layer_data {
232 debug_report_data *report_data;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700233 std::vector<VkDebugReportCallbackEXT> logging_callback;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600234 VkLayerDispatchTable* device_dispatch_table;
235 VkLayerInstanceDispatchTable* instance_dispatch_table;
236 // NOTE: The following are for keeping track of info that is used for
237 // validating the WSI extensions.
238 std::unordered_map<void *, SwpInstance> instanceMap;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700239 std::unordered_map<void *, SwpSurface> surfaceMap;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600240 std::unordered_map<void *, SwpPhysicalDevice> physicalDeviceMap;
241 std::unordered_map<void *, SwpDevice> deviceMap;
242 std::unordered_map<VkSwapchainKHR, SwpSwapchain> swapchainMap;
243
244 layer_data() :
245 report_data(nullptr),
246 device_dispatch_table(nullptr),
247 instance_dispatch_table(nullptr)
248 {};
249};
250
Ian Elliott0b4d6242015-09-22 10:51:24 -0600251#endif // SWAPCHAIN_H