blob: c86219b265093a7ff5f0339835e1a8f15db25be5 [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
Ian Elliott0b4d6242015-09-22 10:51:24 -06004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060023 * Author: Ian Elliott <ian@lunarg.com>
24 *
Ian Elliott0b4d6242015-09-22 10:51:24 -060025 */
26
Ian Elliottd8c5db12015-10-07 11:32:31 -060027#include <stdio.h>
28#include <string.h>
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -070029#include <vk_loader_platform.h>
Ian Elliotta983e9a2015-12-22 12:18:12 -070030#include <vk_icd.h>
Ian Elliott0b4d6242015-09-22 10:51:24 -060031#include "swapchain.h"
Tobin Ehlis711ff312015-10-29 12:58:13 -060032#include "vk_layer_extension_utils.h"
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070033#include "vk_enum_string_helper.h"
Ian Elliott68124ac2015-10-07 16:18:35 -060034
Ian Elliott0b4d6242015-09-22 10:51:24 -060035// FIXME/TODO: Make sure this layer is thread-safe!
36
Ian Elliott68124ac2015-10-07 16:18:35 -060037
Ian Elliott0b4d6242015-09-22 10:51:24 -060038// The following is for logging error messages:
Ian Elliott68124ac2015-10-07 16:18:35 -060039static std::unordered_map<void *, layer_data *> layer_data_map;
Ian Elliott0b4d6242015-09-22 10:51:24 -060040
Ian Elliott68124ac2015-10-07 16:18:35 -060041template layer_data *get_my_data_ptr<layer_data>(
42 void *data_key,
43 std::unordered_map<void *, layer_data *> &data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -060044
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070045static const VkExtensionProperties instance_extensions[] = {
46 {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070047 VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
48 VK_EXT_DEBUG_REPORT_REVISION
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070049 }
50};
51
52VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
53 const char *pLayerName,
54 uint32_t *pCount,
55 VkExtensionProperties* pProperties)
56{
57 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
58}
59
60static const VkLayerProperties swapchain_global_layers[] = {
61 {
Mark Lobodzinski0d054fe2015-12-30 08:16:12 -070062 "swapchain",
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070063 VK_API_VERSION,
64 VK_MAKE_VERSION(0, 1, 0),
Mark Lobodzinski0d054fe2015-12-30 08:16:12 -070065 "Validation layer: swapchain",
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070066 }
67};
68
69VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
70 uint32_t *pCount,
71 VkLayerProperties* pProperties)
72{
73 return util_GetLayerProperties(ARRAY_SIZE(swapchain_global_layers),
74 swapchain_global_layers,
75 pCount, pProperties);
76}
77
Ian Elliott0b4d6242015-09-22 10:51:24 -060078static void createDeviceRegisterExtensions(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
79{
80 uint32_t i;
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070081 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
82 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -060083
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070084 VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table;
85 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
86
87 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
88 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
89 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
90 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
91 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
92
93 SwpPhysicalDevice *pPhysicalDevice = &my_instance_data->physicalDeviceMap[physicalDevice];
Ian Elliott0b4d6242015-09-22 10:51:24 -060094 if (pPhysicalDevice) {
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070095 my_device_data->deviceMap[device].pPhysicalDevice = pPhysicalDevice;
96 pPhysicalDevice->pDevice = &my_device_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -060097 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070098 log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Mark Lobodzinski80e774f2016-01-04 15:54:59 -070099 (uint64_t)physicalDevice , __LINE__, SWAPCHAIN_INVALID_HANDLE, "Swapchain",
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -0700100 "vkCreateDevice() called with a non-valid VkPhysicalDevice.");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600101 }
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -0700102 my_device_data->deviceMap[device].device = device;
Ian Elliott427058f2015-12-29 16:45:49 -0700103 my_device_data->deviceMap[device].swapchainExtensionEnabled = false;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600104
105 // Record whether the WSI device extension was enabled for this VkDevice.
106 // No need to check if the extension was advertised by
107 // vkEnumerateDeviceExtensionProperties(), since the loader handles that.
Chia-I Wud50a7d72015-10-26 20:48:51 +0800108 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700109 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600110
Ian Elliott427058f2015-12-29 16:45:49 -0700111 my_device_data->deviceMap[device].swapchainExtensionEnabled = true;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600112 }
113 }
114}
115
116static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreateInfo, VkInstance instance)
117{
118 uint32_t i;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600119 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
120 VkLayerInstanceDispatchTable *pDisp = my_data->instance_dispatch_table;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600121 PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700122#ifdef VK_USE_PLATFORM_ANDROID_KHR
123 pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) gpa(instance, "vkCreateAndroidSurfaceKHR");
124#endif // VK_USE_PLATFORM_ANDROID_KHR
125#ifdef VK_USE_PLATFORM_MIR_KHR
126 pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR) gpa(instance, "vkCreateMirSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700127 pDisp->GetPhysicalDeviceMirPresentationSupportKHR = (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700128#endif // VK_USE_PLATFORM_MIR_KHR
129#ifdef VK_USE_PLATFORM_WAYLAND_KHR
130 pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR) gpa(instance, "vkCreateWaylandSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700131 pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700132#endif // VK_USE_PLATFORM_WAYLAND_KHR
133#ifdef VK_USE_PLATFORM_WIN32_KHR
134 pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) gpa(instance, "vkCreateWin32SurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700135 pDisp->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700136#endif // VK_USE_PLATFORM_WIN32_KHR
137#ifdef VK_USE_PLATFORM_XCB_KHR
138 pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700139 pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700140#endif // VK_USE_PLATFORM_XCB_KHR
141#ifdef VK_USE_PLATFORM_XLIB_KHR
142 pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) gpa(instance, "vkCreateXlibSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700143 pDisp->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700144#endif // VK_USE_PLATFORM_XLIB_KHR
145 pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) gpa(instance, "vkDestroySurfaceKHR");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600146 pDisp->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
Ian Elliott27d39c72015-11-20 16:39:34 -0700147 pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
148 pDisp->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
149 pDisp->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600150
Ian Elliott1dcd1092015-11-17 17:29:40 -0700151 // Remember this instance, and whether the VK_KHR_surface extension
Ian Elliott0b4d6242015-09-22 10:51:24 -0600152 // was enabled for it:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600153 my_data->instanceMap[instance].instance = instance;
Ian Elliott1cb77a62015-12-29 16:44:39 -0700154 my_data->instanceMap[instance].surfaceExtensionEnabled = false;
Ian Elliott8dffaf32016-01-04 14:10:30 -0700155#ifdef VK_USE_PLATFORM_ANDROID_KHR
156 my_data->instanceMap[instance].androidSurfaceExtensionEnabled = false;
157#endif // VK_USE_PLATFORM_ANDROID_KHR
158#ifdef VK_USE_PLATFORM_MIR_KHR
159 my_data->instanceMap[instance].mirSurfaceExtensionEnabled = false;
160#endif // VK_USE_PLATFORM_MIR_KHR
161#ifdef VK_USE_PLATFORM_WAYLAND_KHR
162 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = false;
163#endif // VK_USE_PLATFORM_WAYLAND_KHR
164#ifdef VK_USE_PLATFORM_WIN32_KHR
165 my_data->instanceMap[instance].win32SurfaceExtensionEnabled = false;
166#endif // VK_USE_PLATFORM_WIN32_KHR
167#ifdef VK_USE_PLATFORM_XCB_KHR
168 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = false;
169#endif // VK_USE_PLATFORM_XCB_KHR
170#ifdef VK_USE_PLATFORM_XLIB_KHR
171 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = false;
172#endif // VK_USE_PLATFORM_XLIB_KHR
173
Ian Elliott0b4d6242015-09-22 10:51:24 -0600174
175 // Record whether the WSI instance extension was enabled for this
176 // VkInstance. No need to check if the extension was advertised by
177 // vkEnumerateInstanceExtensionProperties(), since the loader handles that.
Chia-I Wud50a7d72015-10-26 20:48:51 +0800178 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700179 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600180
Ian Elliott1cb77a62015-12-29 16:44:39 -0700181 my_data->instanceMap[instance].surfaceExtensionEnabled = true;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600182 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700183#ifdef VK_USE_PLATFORM_ANDROID_KHR
184 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
185
186 my_data->instanceMap[instance].androidSurfaceExtensionEnabled = true;
187#endif // VK_USE_PLATFORM_ANDROID_KHR
188#ifdef VK_USE_PLATFORM_MIR_KHR
189 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
190
191 my_data->instanceMap[instance].mirSurfaceExtensionEnabled = true;
192#endif // VK_USE_PLATFORM_MIR_KHR
193#ifdef VK_USE_PLATFORM_WAYLAND_KHR
194 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
195
196 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = true;
197#endif // VK_USE_PLATFORM_WAYLAND_KHR
198#ifdef VK_USE_PLATFORM_WIN32_KHR
199 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
200
201 my_data->instanceMap[instance].win32SurfaceExtensionEnabled = true;
202#endif // VK_USE_PLATFORM_WIN32_KHR
203#ifdef VK_USE_PLATFORM_XCB_KHR
204 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
205
206 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = true;
207#endif // VK_USE_PLATFORM_XCB_KHR
208#ifdef VK_USE_PLATFORM_XLIB_KHR
209 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
210
211 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = true;
212#endif // VK_USE_PLATFORM_XLIB_KHR
213 }
Ian Elliott0b4d6242015-09-22 10:51:24 -0600214 }
215}
216
217
218#include "vk_dispatch_table_helper.h"
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700219static void initSwapchain(layer_data *my_data, const VkAllocationCallbacks *pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600220{
221 uint32_t report_flags = 0;
222 uint32_t debug_action = 0;
223 FILE *log_output = NULL;
224 const char *option_str;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700225 VkDebugReportCallbackEXT callback;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600226
227 // Initialize Swapchain options:
228 report_flags = getLayerOptionFlags("SwapchainReportFlags", 0);
229 getLayerOptionEnum("SwapchainDebugAction", (uint32_t *) &debug_action);
230
231 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
232 {
233 // Turn on logging, since it was requested:
234 option_str = getLayerOption("SwapchainLogFilename");
235 log_output = getLayerLogOutput(option_str, "Swapchain");
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700236 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700237 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700238 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700239 dbgInfo.pfnCallback = log_callback;
240 dbgInfo.pUserData = log_output;
241 dbgInfo.flags = report_flags;
242 layer_create_msg_callback(my_data->report_data,
243 &dbgInfo,
244 pAllocator,
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600245 &callback);
246 my_data->logging_callback.push_back(callback);
247 }
248 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700249 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700250 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700251 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700252 dbgInfo.pfnCallback = win32_debug_output_msg;
253 dbgInfo.pUserData = log_output;
254 dbgInfo.flags = report_flags;
255 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600256 my_data->logging_callback.push_back(callback);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600257 }
258}
259
Ian Elliott27d39c72015-11-20 16:39:34 -0700260static const char *surfaceTransformStr(VkSurfaceTransformFlagBitsKHR value)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600261{
Ian Elliott0b4d6242015-09-22 10:51:24 -0600262 // Return a string corresponding to the value:
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -0700263 return string_VkSurfaceTransformFlagBitsKHR(value);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600264}
265
Ian Elliotta2a89c52015-12-28 15:23:57 -0700266static const char *surfaceCompositeAlphaStr(VkCompositeAlphaFlagBitsKHR value)
267{
268 // Return a string corresponding to the value:
269 return string_VkCompositeAlphaFlagBitsKHR(value);
270}
271
Ian Elliott0b4d6242015-09-22 10:51:24 -0600272static const char *presentModeStr(VkPresentModeKHR value)
273{
Ian Elliott0b4d6242015-09-22 10:51:24 -0600274 // Return a string corresponding to the value:
Ian Elliott24491af2015-12-28 15:04:49 -0700275 return string_VkPresentModeKHR(value);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600276}
277
Ian Elliotta2a89c52015-12-28 15:23:57 -0700278static const char *sharingModeStr(VkSharingMode value)
279{
280 // Return a string corresponding to the value:
281 return string_VkSharingMode(value);
282}
283
Ian Elliott0b4d6242015-09-22 10:51:24 -0600284
Chia-I Wu9ab61502015-11-06 06:42:02 +0800285VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600286{
Tobin Ehlis711ff312015-10-29 12:58:13 -0600287 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600288 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600289 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800290 VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600291 if (result == VK_SUCCESS) {
292 // Since it succeeded, do layer-specific work:
Ian Elliott68124ac2015-10-07 16:18:35 -0600293 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
294 my_data->report_data = debug_report_create_instance(
Tobin Ehlis711ff312015-10-29 12:58:13 -0600295 pTable,
Ian Elliott68124ac2015-10-07 16:18:35 -0600296 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800297 pCreateInfo->enabledExtensionNameCount,
Ian Elliott68124ac2015-10-07 16:18:35 -0600298 pCreateInfo->ppEnabledExtensionNames);
299 // Call the following function after my_data is initialized:
Ian Elliott0b4d6242015-09-22 10:51:24 -0600300 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700301 initSwapchain(my_data, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600302 }
303 return result;
304}
305
Chia-I Wu9ab61502015-11-06 06:42:02 +0800306VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600307{
308 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600309 dispatch_key key = get_dispatch_key(instance);
310 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Tobin Ehlis711ff312015-10-29 12:58:13 -0600311 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600312
313 if (VK_FALSE == skipCall) {
314 // Call down the call chain:
Chia-I Wuf7458c52015-10-26 21:10:41 +0800315 my_data->instance_dispatch_table->DestroyInstance(instance, pAllocator);
Ian Elliott68124ac2015-10-07 16:18:35 -0600316
317 // Clean up logging callback, if any
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600318 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700319 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700320 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600321 my_data->logging_callback.pop_back();
Ian Elliott68124ac2015-10-07 16:18:35 -0600322 }
323 layer_debug_report_destroy_instance(my_data->report_data);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600324 }
325
326 // Regardless of skipCall value, do some internal cleanup:
327 if (pInstance) {
328 // Delete all of the SwpPhysicalDevice's and the SwpInstance associated
329 // with this instance:
330 for (auto it = pInstance->physicalDevices.begin() ;
331 it != pInstance->physicalDevices.end() ; it++) {
Ian Elliott27d39c72015-11-20 16:39:34 -0700332
333 // Free memory that was allocated for/by this SwpPhysicalDevice:
334 SwpPhysicalDevice *pPhysicalDevice = it->second;
335 free(pPhysicalDevice->pSurfaceFormats);
336 free(pPhysicalDevice->pPresentModes);
337
Tobin Ehlis711ff312015-10-29 12:58:13 -0600338 // Erase the SwpPhysicalDevice's from the my_data->physicalDeviceMap (which
Ian Elliott0b4d6242015-09-22 10:51:24 -0600339 // are simply pointed to by the SwpInstance):
Tobin Ehlis711ff312015-10-29 12:58:13 -0600340 my_data->physicalDeviceMap.erase(it->second->physicalDevice);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600341 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600342 my_data->instanceMap.erase(instance);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600343 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600344 delete my_data->instance_dispatch_table;
345 layer_data_map.erase(key);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600346}
347
Ian Elliotta983e9a2015-12-22 12:18:12 -0700348#ifdef VK_USE_PLATFORM_ANDROID_KHR
349VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
350 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700351 const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700352 const VkAllocationCallbacks* pAllocator,
353 VkSurfaceKHR* pSurface)
354{
355 VkResult result = VK_SUCCESS;
356 VkBool32 skipCall = VK_FALSE;
357 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
358
Ian Elliottf5758292015-12-30 17:39:02 -0700359 if (!pCreateInfo) {
360 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
361 device,
362 "pCreateInfo");
363 } else {
364 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR) {
365 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
366 device,
367 "pCreateInfo",
368 "VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR");
369 }
370 if (pCreateInfo->pNext != NULL) {
371 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
372 device,
373 "pCreateInfo");
374 }
375 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700376
377 if (VK_FALSE == skipCall) {
378 // Call down the call chain:
379 result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700380 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700381 return result;
382 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700383 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700384}
385#endif // VK_USE_PLATFORM_ANDROID_KHR
386
387#ifdef VK_USE_PLATFORM_MIR_KHR
388VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
389 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700390 const VkMirSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700391 const VkAllocationCallbacks* pAllocator,
392 VkSurfaceKHR* pSurface)
393{
394 VkResult result = VK_SUCCESS;
395 VkBool32 skipCall = VK_FALSE;
396 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
397
Ian Elliottf5758292015-12-30 17:39:02 -0700398 if (!pCreateInfo) {
399 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
400 device,
401 "pCreateInfo");
402 } else {
403 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR) {
404 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
405 device,
406 "pCreateInfo",
407 "VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR");
408 }
409 if (pCreateInfo->pNext != NULL) {
410 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
411 device,
412 "pCreateInfo");
413 }
414 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700415
416 if (VK_FALSE == skipCall) {
417 // Call down the call chain:
418 result = my_data->instance_dispatch_table->CreateMirSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700419 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700420 return result;
421 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700422 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700423}
Ian Elliott55ff7962015-12-30 10:18:47 -0700424
425VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
426 VkPhysicalDevice physicalDevice,
427 uint32_t queueFamilyIndex,
428 MirConnection* connection)
429{
430 VkBool32 result = VK_FALSE;
431 VkBool32 skipCall = VK_FALSE;
432 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
433
Ian Elliott8dffaf32016-01-04 14:10:30 -0700434 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700435 // extension was enabled:
436 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
437 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
438 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
439 physicalDevice,
440 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700441 } else if (!pPhysicalDevice->pInstance->mirSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700442 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
443 pPhysicalDevice->pInstance,
444 "VkInstance",
445 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
446 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700447 __FUNCTION__, VK_KHR_MIR_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700448 }
449
450 if (VK_FALSE == skipCall) {
451 // Call down the call chain:
452 result = my_data->instance_dispatch_table->GetPhysicalDeviceMirPresentationSupportKHR(
453 physicalDevice, queueFamilyIndex, connection);
454
455 if (pPhysicalDevice) {
456 // Record the result of this query:
457 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
458 }
459 }
460 return result;
461}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700462#endif // VK_USE_PLATFORM_MIR_KHR
463
464#ifdef VK_USE_PLATFORM_WAYLAND_KHR
465VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
466 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700467 const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700468 const VkAllocationCallbacks* pAllocator,
469 VkSurfaceKHR* pSurface)
470{
471 VkResult result = VK_SUCCESS;
472 VkBool32 skipCall = VK_FALSE;
473 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
474
Ian Elliottf5758292015-12-30 17:39:02 -0700475 if (!pCreateInfo) {
476 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
477 device,
478 "pCreateInfo");
479 } else {
480 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR) {
481 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
482 device,
483 "pCreateInfo",
484 "VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR");
485 }
486 if (pCreateInfo->pNext != NULL) {
487 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
488 device,
489 "pCreateInfo");
490 }
491 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700492
493 if (VK_FALSE == skipCall) {
494 // Call down the call chain:
495 result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700496 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700497 return result;
498 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700499 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700500}
Ian Elliott55ff7962015-12-30 10:18:47 -0700501
502VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(
503 VkPhysicalDevice physicalDevice,
504 uint32_t queueFamilyIndex,
505 struct wl_display* display)
506{
507 VkBool32 result = VK_FALSE;
508 VkBool32 skipCall = VK_FALSE;
509 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
510
Ian Elliott8dffaf32016-01-04 14:10:30 -0700511 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700512 // extension was enabled:
513 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
514 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
515 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
516 physicalDevice,
517 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700518 } else if (!pPhysicalDevice->pInstance->waylandSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700519 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
520 pPhysicalDevice->pInstance,
521 "VkInstance",
522 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
523 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700524 __FUNCTION__, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700525 }
526
527 if (VK_FALSE == skipCall) {
528 // Call down the call chain:
529 result = my_data->instance_dispatch_table->GetPhysicalDeviceWaylandPresentationSupportKHR(
530 physicalDevice, queueFamilyIndex, display);
531
532 if (pPhysicalDevice) {
533 // Record the result of this query:
534 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
535 }
536 }
537 return result;
538}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700539#endif // VK_USE_PLATFORM_WAYLAND_KHR
540
541#ifdef VK_USE_PLATFORM_WIN32_KHR
542VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
543 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700544 const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700545 const VkAllocationCallbacks* pAllocator,
546 VkSurfaceKHR* pSurface)
547{
548 VkResult result = VK_SUCCESS;
549 VkBool32 skipCall = VK_FALSE;
550 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
551
Ian Elliottf5758292015-12-30 17:39:02 -0700552 if (!pCreateInfo) {
553 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
554 device,
555 "pCreateInfo");
556 } else {
557 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR) {
558 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
559 device,
560 "pCreateInfo",
561 "VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR");
562 }
563 if (pCreateInfo->pNext != NULL) {
564 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
565 device,
566 "pCreateInfo");
567 }
568 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700569
570 if (VK_FALSE == skipCall) {
571 // Call down the call chain:
572 result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700573 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700574 return result;
575 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700576 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700577}
Ian Elliott55ff7962015-12-30 10:18:47 -0700578
579VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
580 VkPhysicalDevice physicalDevice,
581 uint32_t queueFamilyIndex)
582{
583 VkBool32 result = VK_FALSE;
584 VkBool32 skipCall = VK_FALSE;
585 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
586
Ian Elliott8dffaf32016-01-04 14:10:30 -0700587 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700588 // extension was enabled:
589 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
590 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
591 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
592 physicalDevice,
593 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700594 } else if (!pPhysicalDevice->pInstance->win32SurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700595 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
596 pPhysicalDevice->pInstance,
597 "VkInstance",
598 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
599 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700600 __FUNCTION__, VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700601 }
602
603 if (VK_FALSE == skipCall) {
604 // Call down the call chain:
605 result = my_data->instance_dispatch_table->GetPhysicalDeviceWin32PresentationSupportKHR(
606 physicalDevice, queueFamilyIndex);
607
608 if (pPhysicalDevice) {
609 // Record the result of this query:
610 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
611 }
612 }
613 return result;
614}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700615#endif // VK_USE_PLATFORM_WIN32_KHR
616
617#ifdef VK_USE_PLATFORM_XCB_KHR
618VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
619 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700620 const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700621 const VkAllocationCallbacks* pAllocator,
622 VkSurfaceKHR* pSurface)
623{
624 VkResult result = VK_SUCCESS;
625 VkBool32 skipCall = VK_FALSE;
626 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
627
Ian Elliottf5758292015-12-30 17:39:02 -0700628 if (!pCreateInfo) {
629 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
630 device,
631 "pCreateInfo");
632 } else {
633 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) {
634 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
635 device,
636 "pCreateInfo",
637 "VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR");
638 }
639 if (pCreateInfo->pNext != NULL) {
640 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
641 device,
642 "pCreateInfo");
643 }
644 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700645
646 if (VK_FALSE == skipCall) {
647 // Call down the call chain:
648 result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700649 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700650 return result;
651 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700652 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700653}
Ian Elliott55ff7962015-12-30 10:18:47 -0700654
655VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(
656 VkPhysicalDevice physicalDevice,
657 uint32_t queueFamilyIndex,
658 xcb_connection_t* connection,
659 xcb_visualid_t visual_id)
660{
661 VkBool32 result = VK_FALSE;
662 VkBool32 skipCall = VK_FALSE;
663 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
664
Ian Elliott8dffaf32016-01-04 14:10:30 -0700665 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700666 // extension was enabled:
667 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
668 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
669 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
670 physicalDevice,
671 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700672 } else if (!pPhysicalDevice->pInstance->xcbSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700673 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
674 pPhysicalDevice->pInstance,
675 "VkInstance",
676 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
677 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700678 __FUNCTION__, VK_KHR_XCB_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700679 }
680
681 if (VK_FALSE == skipCall) {
682 // Call down the call chain:
683 result = my_data->instance_dispatch_table->GetPhysicalDeviceXcbPresentationSupportKHR(
684 physicalDevice, queueFamilyIndex, connection, visual_id);
685
686 if (pPhysicalDevice) {
687 // Record the result of this query:
688 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
689 }
690 }
691 return result;
692}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700693#endif // VK_USE_PLATFORM_XCB_KHR
694
695#ifdef VK_USE_PLATFORM_XLIB_KHR
696VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
697 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700698 const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700699 const VkAllocationCallbacks* pAllocator,
700 VkSurfaceKHR* pSurface)
701{
702 VkResult result = VK_SUCCESS;
703 VkBool32 skipCall = VK_FALSE;
704 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
705
Ian Elliottf5758292015-12-30 17:39:02 -0700706 if (!pCreateInfo) {
707 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
708 device,
709 "pCreateInfo");
710 } else {
711 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR) {
712 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
713 device,
714 "pCreateInfo",
715 "VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR");
716 }
717 if (pCreateInfo->pNext != NULL) {
718 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
719 device,
720 "pCreateInfo");
721 }
722 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700723
724 if (VK_FALSE == skipCall) {
725 // Call down the call chain:
726 result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700727 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700728 return result;
729 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700730 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700731}
Ian Elliott55ff7962015-12-30 10:18:47 -0700732
733VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(
734 VkPhysicalDevice physicalDevice,
735 uint32_t queueFamilyIndex,
736 Display* dpy,
737 VisualID visualID)
738{
739 VkBool32 result = VK_FALSE;
740 VkBool32 skipCall = VK_FALSE;
741 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
742
Ian Elliott8dffaf32016-01-04 14:10:30 -0700743 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700744 // extension was enabled:
745 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
746 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
747 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
748 physicalDevice,
749 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700750 } else if (!pPhysicalDevice->pInstance->xlibSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700751 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
752 pPhysicalDevice->pInstance,
753 "VkInstance",
754 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
755 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700756 __FUNCTION__, VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700757 }
758
759 if (VK_FALSE == skipCall) {
760 // Call down the call chain:
761 result = my_data->instance_dispatch_table->GetPhysicalDeviceXlibPresentationSupportKHR(
762 physicalDevice, queueFamilyIndex, dpy, visualID);
763
764 if (pPhysicalDevice) {
765 // Record the result of this query:
766 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
767 }
768 }
769 return result;
770}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700771#endif // VK_USE_PLATFORM_XLIB_KHR
772
773VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator)
774{
775 VkBool32 skipCall = VK_FALSE;
776 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
777
Ian Elliotta983e9a2015-12-22 12:18:12 -0700778 if (VK_FALSE == skipCall) {
Ian Elliotta983e9a2015-12-22 12:18:12 -0700779 // Call down the call chain:
780 my_data->instance_dispatch_table->DestroySurfaceKHR(
781 instance, surface, pAllocator);
782 }
783
Ian Elliott6b9941a2016-01-05 12:03:06 -0700784 // No need to do any cleanup--rely on object_tracker to track VkSurfaceKHR
Ian Elliotta983e9a2015-12-22 12:18:12 -0700785}
786
Chia-I Wu9ab61502015-11-06 06:42:02 +0800787VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600788{
789 VkResult result = VK_SUCCESS;
790 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600791 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehlis711ff312015-10-29 12:58:13 -0600792 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600793
794 if (VK_FALSE == skipCall) {
795 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600796 result = my_data->instance_dispatch_table->EnumeratePhysicalDevices(
Ian Elliott0b4d6242015-09-22 10:51:24 -0600797 instance, pPhysicalDeviceCount, pPhysicalDevices);
798
799 if ((result == VK_SUCCESS) && pInstance && pPhysicalDevices &&
800 (*pPhysicalDeviceCount > 0)) {
801 // Record the VkPhysicalDevices returned by the ICD:
Courtney Goeltzenleuchterdad30df2015-10-07 09:00:34 -0600802 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Tobin Ehlis711ff312015-10-29 12:58:13 -0600803 my_data->physicalDeviceMap[pPhysicalDevices[i]].physicalDevice =
Ian Elliott0b4d6242015-09-22 10:51:24 -0600804 pPhysicalDevices[i];
Tobin Ehlis711ff312015-10-29 12:58:13 -0600805 my_data->physicalDeviceMap[pPhysicalDevices[i]].pInstance = pInstance;
806 my_data->physicalDeviceMap[pPhysicalDevices[i]].pDevice = NULL;
Ian Elliott27d39c72015-11-20 16:39:34 -0700807 my_data->physicalDeviceMap[pPhysicalDevices[i]].gotSurfaceCapabilities = false;
808 my_data->physicalDeviceMap[pPhysicalDevices[i]].surfaceFormatCount = 0;
809 my_data->physicalDeviceMap[pPhysicalDevices[i]].pSurfaceFormats = NULL;
810 my_data->physicalDeviceMap[pPhysicalDevices[i]].presentModeCount = 0;
811 my_data->physicalDeviceMap[pPhysicalDevices[i]].pPresentModes = NULL;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600812 // Point to the associated SwpInstance:
Ian Elliott4f07d082016-01-05 12:18:50 -0700813 if (pInstance) {
814 pInstance->physicalDevices[pPhysicalDevices[i]] =
815 &my_data->physicalDeviceMap[pPhysicalDevices[i]];
816 }
Ian Elliott0b4d6242015-09-22 10:51:24 -0600817 }
818 }
819
820 return result;
821 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700822 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600823}
824
Chia-I Wu9ab61502015-11-06 06:42:02 +0800825VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600826{
827 VkResult result = VK_SUCCESS;
828 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -0600829 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600830
831 // Validate that a valid VkPhysicalDevice was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600832 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
Ian Elliott0b4d6242015-09-22 10:51:24 -0600833 if (!pPhysicalDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700834 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Mark Lobodzinski6c1cb5a2015-11-05 15:27:03 -0700835 physicalDevice, "VkPhysicalDevice");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600836 }
837
Tobin Ehlis711ff312015-10-29 12:58:13 -0600838 if (VK_TRUE == skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700839 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600840
841 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
842 // Call down the call chain:
843 result = my_device_data->device_dispatch_table->CreateDevice(
Chia-I Wuf7458c52015-10-26 21:10:41 +0800844 physicalDevice, pCreateInfo, pAllocator, pDevice);
Tobin Ehlis711ff312015-10-29 12:58:13 -0600845 if (result == VK_SUCCESS) {
846 // Since it succeeded, do layer-specific work:
Mark Lobodzinski6c1cb5a2015-11-05 15:27:03 -0700847 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
848 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
849 createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600850 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600851 return result;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600852}
853
Chia-I Wu9ab61502015-11-06 06:42:02 +0800854VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600855{
856 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600857 dispatch_key key = get_dispatch_key(device);
858 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600859 // Validate that a valid VkDevice was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600860 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -0600861 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700862 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -0600863 device,
864 "VkDevice");
865 }
866
867 if (VK_FALSE == skipCall) {
868 // Call down the call chain:
Chia-I Wuf7458c52015-10-26 21:10:41 +0800869 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600870 }
871
872 // Regardless of skipCall value, do some internal cleanup:
873 if (pDevice) {
874 // Delete the SwpDevice associated with this device:
875 if (pDevice->pPhysicalDevice) {
876 pDevice->pPhysicalDevice->pDevice = NULL;
877 }
Ian Elliott0b4d6242015-09-22 10:51:24 -0600878 if (!pDevice->swapchains.empty()) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700879 LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -0600880 SWAPCHAIN_DEL_DEVICE_BEFORE_SWAPCHAINS,
Ian Elliott0b4d6242015-09-22 10:51:24 -0600881 "%s() called before all of its associated "
882 "VkSwapchainKHRs were destroyed.",
883 __FUNCTION__);
884 // Empty and then delete all SwpSwapchain's
885 for (auto it = pDevice->swapchains.begin() ;
886 it != pDevice->swapchains.end() ; it++) {
887 // Delete all SwpImage's
888 it->second->images.clear();
889 }
890 pDevice->swapchains.clear();
891 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600892 my_data->deviceMap.erase(device);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600893 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600894 delete my_data->device_dispatch_table;
895 layer_data_map.erase(key);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600896}
897
Ian Elliott27d39c72015-11-20 16:39:34 -0700898VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(
899 VkPhysicalDevice physicalDevice,
900 uint32_t queueFamilyIndex,
901 VkSurfaceKHR surface,
902 VkBool32* pSupported)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600903{
Ian Elliott320d0fc2015-12-30 12:04:43 -0700904// TODOs:
905//
906// - Ensure that queueFamilyIndex is a valid queue family index for
907// physicalDevice. How? Probably need to record data from another function
908// call(s).
Ian Elliott0b4d6242015-09-22 10:51:24 -0600909 VkResult result = VK_SUCCESS;
910 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -0600911 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600912
913 // Validate that a valid VkPhysicalDevice was used, and that the instance
914 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600915 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
Ian Elliott0b4d6242015-09-22 10:51:24 -0600916 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700917 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -0600918 physicalDevice,
919 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -0700920 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700921 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -0600922 pPhysicalDevice->pInstance,
923 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -0600924 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -0800925 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott1dcd1092015-11-17 17:29:40 -0700926 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600927 }
Ian Elliottf955d682015-12-30 12:00:54 -0700928 if (!pSupported) {
929 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
930 physicalDevice,
931 "pSupported");
932 }
Ian Elliott0b4d6242015-09-22 10:51:24 -0600933
934 if (VK_FALSE == skipCall) {
935 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600936 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceSupportKHR(
Ian Elliott27d39c72015-11-20 16:39:34 -0700937 physicalDevice, queueFamilyIndex, surface,
Ian Elliott0b4d6242015-09-22 10:51:24 -0600938 pSupported);
939
940 if ((result == VK_SUCCESS) && pSupported && pPhysicalDevice) {
941 // Record the result of this query:
942 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] =
943 *pSupported;
944 // TODO: We need to compare this with the actual queue used for
945 // presentation, to ensure it was advertised to the application as
946 // supported for presentation.
947 }
948
949 return result;
950 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700951 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600952}
953
Ian Elliott27d39c72015-11-20 16:39:34 -0700954VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
955 VkPhysicalDevice physicalDevice,
956 VkSurfaceKHR surface,
957 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600958{
959 VkResult result = VK_SUCCESS;
960 VkBool32 skipCall = VK_FALSE;
Ian Elliott27d39c72015-11-20 16:39:34 -0700961 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600962
Ian Elliott27d39c72015-11-20 16:39:34 -0700963 // Validate that a valid VkPhysicalDevice was used, and that the instance
Ian Elliott0b4d6242015-09-22 10:51:24 -0600964 // extension was enabled:
Ian Elliott27d39c72015-11-20 16:39:34 -0700965 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
966 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700967 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -0700968 physicalDevice,
969 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -0700970 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700971 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -0700972 pPhysicalDevice->pInstance,
973 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -0600974 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Ian Elliott27d39c72015-11-20 16:39:34 -0700975 "%s() called even though the %s extension was not enabled for this VkInstance.",
976 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600977 }
Ian Elliottf955d682015-12-30 12:00:54 -0700978 if (!pSurfaceCapabilities) {
979 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
980 physicalDevice,
981 "pSurfaceCapabilities");
982 }
Ian Elliott0b4d6242015-09-22 10:51:24 -0600983
984 if (VK_FALSE == skipCall) {
985 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -0700986 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceCapabilitiesKHR(
987 physicalDevice, surface, pSurfaceCapabilities);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600988
Ian Elliott27d39c72015-11-20 16:39:34 -0700989 if ((result == VK_SUCCESS) && pPhysicalDevice) {
Ian Elliottf955d682015-12-30 12:00:54 -0700990 // Record the result of this query:
Ian Elliott27d39c72015-11-20 16:39:34 -0700991 pPhysicalDevice->gotSurfaceCapabilities = true;
992// FIXME: NEED TO COPY THIS DATA, BECAUSE pSurfaceCapabilities POINTS TO APP-ALLOCATED DATA
993 pPhysicalDevice->surfaceCapabilities = *pSurfaceCapabilities;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600994 }
995
996 return result;
997 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700998 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600999}
1000
Ian Elliott27d39c72015-11-20 16:39:34 -07001001VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(
1002 VkPhysicalDevice physicalDevice,
1003 VkSurfaceKHR surface,
Ian Elliottf955d682015-12-30 12:00:54 -07001004 uint32_t* pSurfaceFormatCount,
Ian Elliott27d39c72015-11-20 16:39:34 -07001005 VkSurfaceFormatKHR* pSurfaceFormats)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001006{
1007 VkResult result = VK_SUCCESS;
1008 VkBool32 skipCall = VK_FALSE;
Ian Elliott27d39c72015-11-20 16:39:34 -07001009 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001010
Ian Elliott27d39c72015-11-20 16:39:34 -07001011 // Validate that a valid VkPhysicalDevice was used, and that the instance
Ian Elliott0b4d6242015-09-22 10:51:24 -06001012 // extension was enabled:
Ian Elliott27d39c72015-11-20 16:39:34 -07001013 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
1014 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001015 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001016 physicalDevice,
1017 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -07001018 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001019 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001020 pPhysicalDevice->pInstance,
1021 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001022 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Ian Elliott27d39c72015-11-20 16:39:34 -07001023 "%s() called even though the %s extension was not enabled for this VkInstance.",
1024 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001025 }
Ian Elliottf955d682015-12-30 12:00:54 -07001026 if (!pSurfaceFormatCount) {
1027 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1028 physicalDevice,
1029 "pSurfaceFormatCount");
1030 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001031
1032 if (VK_FALSE == skipCall) {
1033 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -07001034 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceFormatsKHR(
Ian Elliottf955d682015-12-30 12:00:54 -07001035 physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001036
Ian Elliottf955d682015-12-30 12:00:54 -07001037 if ((result == VK_SUCCESS) && pPhysicalDevice && !pSurfaceFormats &&
1038 pSurfaceFormatCount) {
1039 // Record the result of this preliminary query:
1040 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
1041 }
Ian Elliott9059b302015-12-30 13:14:36 -07001042 else if ((result == VK_SUCCESS) && pPhysicalDevice && pSurfaceFormats &&
1043 pSurfaceFormatCount) {
Ian Elliottf955d682015-12-30 12:00:54 -07001044 // Compare the preliminary value of *pSurfaceFormatCount with the
1045 // value this time:
1046 if (*pSurfaceFormatCount != pPhysicalDevice->surfaceFormatCount) {
1047 LOG_ERROR_INVALID_COUNT(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1048 physicalDevice,
1049 "pSurfaceFormatCount",
1050 "pSurfaceFormats",
1051 pPhysicalDevice->surfaceFormatCount);
1052 }
Ian Elliott9059b302015-12-30 13:14:36 -07001053 else if (*pSurfaceFormatCount > 0) {
1054 // Record the result of this query:
1055 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
1056 pPhysicalDevice->pSurfaceFormats = (VkSurfaceFormatKHR *)
1057 malloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
1058 if (pPhysicalDevice->pSurfaceFormats) {
1059 for (uint32_t i = 0 ; i < *pSurfaceFormatCount ; i++) {
1060 pPhysicalDevice->pSurfaceFormats[i] = pSurfaceFormats[i];
1061 }
1062 } else {
1063 pPhysicalDevice->surfaceFormatCount = 0;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001064 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001065 }
1066 }
1067
1068 return result;
1069 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001070 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001071}
1072
Ian Elliott27d39c72015-11-20 16:39:34 -07001073VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(
1074 VkPhysicalDevice physicalDevice,
1075 VkSurfaceKHR surface,
Ian Elliottf955d682015-12-30 12:00:54 -07001076 uint32_t* pPresentModeCount,
Ian Elliott27d39c72015-11-20 16:39:34 -07001077 VkPresentModeKHR* pPresentModes)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001078{
1079 VkResult result = VK_SUCCESS;
1080 VkBool32 skipCall = VK_FALSE;
Ian Elliott27d39c72015-11-20 16:39:34 -07001081 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001082
Ian Elliott27d39c72015-11-20 16:39:34 -07001083 // Validate that a valid VkPhysicalDevice was used, and that the instance
Ian Elliott0b4d6242015-09-22 10:51:24 -06001084 // extension was enabled:
Ian Elliott27d39c72015-11-20 16:39:34 -07001085 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
1086 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001087 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001088 physicalDevice,
1089 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -07001090 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001091 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001092 pPhysicalDevice->pInstance,
1093 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001094 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Ian Elliott27d39c72015-11-20 16:39:34 -07001095 "%s() called even though the %s extension was not enabled for this VkInstance.",
1096 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001097 }
Ian Elliottf955d682015-12-30 12:00:54 -07001098 if (!pPresentModeCount) {
1099 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1100 physicalDevice,
1101 "pPresentModeCount");
1102 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001103
1104 if (VK_FALSE == skipCall) {
1105 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -07001106 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfacePresentModesKHR(
Ian Elliottf955d682015-12-30 12:00:54 -07001107 physicalDevice, surface, pPresentModeCount, pPresentModes);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001108
Ian Elliottf955d682015-12-30 12:00:54 -07001109 if ((result == VK_SUCCESS) && pPhysicalDevice && !pPresentModes &&
1110 pPresentModeCount) {
1111 // Record the result of this preliminary query:
1112 pPhysicalDevice->presentModeCount = *pPresentModeCount;
1113 }
Ian Elliott9059b302015-12-30 13:14:36 -07001114 else if ((result == VK_SUCCESS) && pPhysicalDevice && pPresentModes &&
1115 pPresentModeCount) {
Ian Elliottf955d682015-12-30 12:00:54 -07001116 // Compare the preliminary value of *pPresentModeCount with the
1117 // value this time:
1118 if (*pPresentModeCount != pPhysicalDevice->presentModeCount) {
1119 LOG_ERROR_INVALID_COUNT(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1120 physicalDevice,
1121 "pPresentModeCount",
1122 "pPresentModes",
1123 pPhysicalDevice->presentModeCount);
1124 }
Ian Elliott9059b302015-12-30 13:14:36 -07001125 else if (*pPresentModeCount > 0) {
1126 // Record the result of this query:
1127 pPhysicalDevice->presentModeCount = *pPresentModeCount;
1128 pPhysicalDevice->pPresentModes = (VkPresentModeKHR *)
1129 malloc(*pPresentModeCount * sizeof(VkPresentModeKHR));
1130 if (pPhysicalDevice->pSurfaceFormats) {
1131 for (uint32_t i = 0 ; i < *pPresentModeCount ; i++) {
1132 pPhysicalDevice->pPresentModes[i] = pPresentModes[i];
1133 }
1134 } else {
1135 pPhysicalDevice->presentModeCount = 0;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001136 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001137 }
1138 }
1139
1140 return result;
1141 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001142 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001143}
1144
1145// This function does the up-front validation work for vkCreateSwapchainKHR(),
1146// and returns VK_TRUE if a logging callback indicates that the call down the
1147// chain should be skipped:
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001148static VkBool32 validateCreateSwapchainKHR(
1149 VkDevice device,
1150 const VkSwapchainCreateInfoKHR* pCreateInfo,
1151 VkSwapchainKHR* pSwapchain)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001152{
1153// TODO: Validate cases of re-creating a swapchain (the current code
1154// assumes a new swapchain is being created).
1155 VkResult result = VK_SUCCESS;
1156 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001157 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001158 char fn[] = "vkCreateSwapchainKHR";
1159
1160 // Validate that a valid VkDevice was used, and that the device
1161 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001162 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001163 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001164 return LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001165 SWAPCHAIN_INVALID_HANDLE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001166 "%s() called with a non-valid %s.",
1167 fn, "VkDevice");
1168
Ian Elliott427058f2015-12-29 16:45:49 -07001169 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001170 return LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001171 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001172 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001173 fn, VK_KHR_SWAPCHAIN_EXTENSION_NAME );
Ian Elliott0b4d6242015-09-22 10:51:24 -06001174 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001175 if (!pCreateInfo) {
1176 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1177 device,
1178 "pCreateInfo");
Ian Elliottf5758292015-12-30 17:39:02 -07001179 } else {
1180 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR) {
1181 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1182 device,
1183 "pCreateInfo",
1184 "VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR");
1185 }
1186 if (pCreateInfo->pNext != NULL) {
1187 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1188 device,
1189 "pCreateInfo");
1190 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001191 }
1192 if (!pSwapchain) {
1193 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1194 device,
1195 "pSwapchain");
1196 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001197
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001198 // Keep around a useful pointer to pPhysicalDevice:
1199 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
1200
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001201 // Validate pCreateInfo values with the results of
1202 // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
1203 if (!pPhysicalDevice || !pPhysicalDevice->gotSurfaceCapabilities) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001204 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001205 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001206 "%s() called before calling "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001207 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001208 fn);
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001209 } else if (pCreateInfo) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001210 // Validate pCreateInfo->minImageCount against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001211 // VkSurfaceCapabilitiesKHR::{min|max}ImageCount:
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001212 VkSurfaceCapabilitiesKHR *pCapabilities = &pPhysicalDevice->surfaceCapabilities;
Ian Elliott27d39c72015-11-20 16:39:34 -07001213 if ((pCreateInfo->minImageCount < pCapabilities->minImageCount) ||
1214 ((pCapabilities->maxImageCount > 0) &&
1215 (pCreateInfo->minImageCount > pCapabilities->maxImageCount))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001216 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001217 SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001218 "%s() called with pCreateInfo->minImageCount "
1219 "= %d, which is outside the bounds returned "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001220 "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. "
Ian Elliott0b4d6242015-09-22 10:51:24 -06001221 "minImageCount = %d, maxImageCount = %d).",
1222 fn,
1223 pCreateInfo->minImageCount,
Ian Elliott27d39c72015-11-20 16:39:34 -07001224 pCapabilities->minImageCount,
1225 pCapabilities->maxImageCount);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001226 }
1227 // Validate pCreateInfo->imageExtent against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001228 // VkSurfaceCapabilitiesKHR::{current|min|max}ImageExtent:
Ian Elliott27d39c72015-11-20 16:39:34 -07001229 if ((pCapabilities->currentExtent.width == -1) &&
1230 ((pCreateInfo->imageExtent.width < pCapabilities->minImageExtent.width) ||
1231 (pCreateInfo->imageExtent.width > pCapabilities->maxImageExtent.width) ||
1232 (pCreateInfo->imageExtent.height < pCapabilities->minImageExtent.height) ||
1233 (pCreateInfo->imageExtent.height > pCapabilities->maxImageExtent.height))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001234 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001235 SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001236 "%s() called with pCreateInfo->imageExtent = "
1237 "(%d,%d), which is outside the bounds "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001238 "returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): "
Ian Elliott0b4d6242015-09-22 10:51:24 -06001239 "currentExtent = (%d,%d), minImageExtent = "
1240 "(%d,%d), maxImageExtent = (%d,%d).",
1241 fn,
1242 pCreateInfo->imageExtent.width,
1243 pCreateInfo->imageExtent.height,
Ian Elliott27d39c72015-11-20 16:39:34 -07001244 pCapabilities->currentExtent.width,
1245 pCapabilities->currentExtent.height,
1246 pCapabilities->minImageExtent.width,
1247 pCapabilities->minImageExtent.height,
1248 pCapabilities->maxImageExtent.width,
1249 pCapabilities->maxImageExtent.height);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001250 }
Ian Elliott27d39c72015-11-20 16:39:34 -07001251 if ((pCapabilities->currentExtent.width != -1) &&
1252 ((pCreateInfo->imageExtent.width != pCapabilities->currentExtent.width) ||
1253 (pCreateInfo->imageExtent.height != pCapabilities->currentExtent.height))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001254 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001255 SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001256 "%s() called with pCreateInfo->imageExtent = "
1257 "(%d,%d), which is not equal to the "
1258 "currentExtent = (%d,%d) returned by "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001259 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001260 fn,
1261 pCreateInfo->imageExtent.width,
1262 pCreateInfo->imageExtent.height,
Ian Elliott27d39c72015-11-20 16:39:34 -07001263 pCapabilities->currentExtent.width,
1264 pCapabilities->currentExtent.height);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001265 }
1266 // Validate pCreateInfo->preTransform against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001267 // VkSurfaceCapabilitiesKHR::supportedTransforms:
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -07001268 if (!((pCreateInfo->preTransform) & pCapabilities->supportedTransforms)) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001269 // This is an error situation; one for which we'd like to give
1270 // the developer a helpful, multi-line error message. Build it
1271 // up a little at a time, and then log it:
1272 std::string errorString = "";
1273 char str[1024];
1274 // Here's the first part of the message:
1275 sprintf(str, "%s() called with a non-supported "
1276 "pCreateInfo->preTransform (i.e. %s). "
1277 "Supported values are:\n",
1278 fn,
1279 surfaceTransformStr(pCreateInfo->preTransform));
1280 errorString += str;
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -07001281 for (int i = 0; i < 32; i++) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001282 // Build up the rest of the message:
Ian Elliott27d39c72015-11-20 16:39:34 -07001283 if ((1 << i) & pCapabilities->supportedTransforms) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001284 const char *newStr =
Ian Elliott27d39c72015-11-20 16:39:34 -07001285 surfaceTransformStr((VkSurfaceTransformFlagBitsKHR) (1 << i));
Ian Elliott0b4d6242015-09-22 10:51:24 -06001286 sprintf(str, " %s\n", newStr);
1287 errorString += str;
1288 }
1289 }
1290 // Log the message that we've built up:
Ian Elliott68124ac2015-10-07 16:18:35 -06001291 skipCall |= debug_report_log_msg(my_data->report_data,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001292 VK_DEBUG_REPORT_ERROR_BIT_EXT,
1293 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Mark Lobodzinski80e774f2016-01-04 15:54:59 -07001294 (uint64_t) device, __LINE__,
Ian Elliottb0f474c2015-09-25 15:50:55 -06001295 SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM,
1296 LAYER_NAME,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001297 errorString.c_str());
1298 }
Ian Elliotta2a89c52015-12-28 15:23:57 -07001299 // Validate pCreateInfo->compositeAlpha against
1300 // VkSurfaceCapabilitiesKHR::supportedCompositeAlpha:
1301 if (!((pCreateInfo->compositeAlpha) & pCapabilities->supportedCompositeAlpha)) {
1302 // This is an error situation; one for which we'd like to give
1303 // the developer a helpful, multi-line error message. Build it
1304 // up a little at a time, and then log it:
1305 std::string errorString = "";
1306 char str[1024];
1307 // Here's the first part of the message:
1308 sprintf(str, "%s() called with a non-supported "
1309 "pCreateInfo->compositeAlpha (i.e. %s). "
1310 "Supported values are:\n",
1311 fn,
1312 surfaceCompositeAlphaStr(pCreateInfo->compositeAlpha));
1313 errorString += str;
1314 for (int i = 0; i < 32; i++) {
1315 // Build up the rest of the message:
1316 if ((1 << i) & pCapabilities->supportedCompositeAlpha) {
1317 const char *newStr =
1318 surfaceCompositeAlphaStr((VkCompositeAlphaFlagBitsKHR) (1 << i));
1319 sprintf(str, " %s\n", newStr);
1320 errorString += str;
1321 }
1322 }
1323 // Log the message that we've built up:
1324 skipCall |= debug_report_log_msg(my_data->report_data,
Ian Elliott1bf155f2015-12-29 17:35:46 -07001325 VK_DEBUG_REPORT_ERROR_BIT_EXT,
1326 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliotta2a89c52015-12-28 15:23:57 -07001327 (uint64_t) device, 0,
1328 SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA,
1329 LAYER_NAME,
1330 errorString.c_str());
1331 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001332 // Validate pCreateInfo->imageArraySize against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001333 // VkSurfaceCapabilitiesKHR::maxImageArraySize:
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001334 if ((pCreateInfo->imageArrayLayers > 0) &&
1335 (pCreateInfo->imageArrayLayers > pCapabilities->maxImageArrayLayers)) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001336 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001337 SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001338 "%s() called with a non-supported "
1339 "pCreateInfo->imageArraySize (i.e. %d). "
1340 "Maximum value is %d.",
1341 fn,
Ian Elliott27d39c72015-11-20 16:39:34 -07001342 pCreateInfo->imageArrayLayers,
1343 pCapabilities->maxImageArrayLayers);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001344 }
Ian Elliott27d39c72015-11-20 16:39:34 -07001345 // Validate pCreateInfo->imageUsage against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001346 // VkSurfaceCapabilitiesKHR::supportedUsageFlags:
Ian Elliott27d39c72015-11-20 16:39:34 -07001347 if (pCreateInfo->imageUsage &&
1348 (pCreateInfo->imageUsage !=
1349 (pCreateInfo->imageUsage & pCapabilities->supportedUsageFlags))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001350 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001351 SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001352 "%s() called with a non-supported "
Ian Elliott27d39c72015-11-20 16:39:34 -07001353 "pCreateInfo->imageUsage (i.e. 0x%08x)."
Ian Elliott0b4d6242015-09-22 10:51:24 -06001354 " Supported flag bits are 0x%08x.",
1355 fn,
Ian Elliott27d39c72015-11-20 16:39:34 -07001356 pCreateInfo->imageUsage,
1357 pCapabilities->supportedUsageFlags);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001358 }
1359 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001360
1361 // Validate pCreateInfo values with the results of
1362 // vkGetPhysicalDeviceSurfaceFormatsKHR():
1363 if (!pPhysicalDevice || !pPhysicalDevice->surfaceFormatCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001364 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001365 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001366 "%s() called before calling "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001367 "vkGetPhysicalDeviceSurfaceFormatsKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001368 fn);
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001369 } else if (pCreateInfo) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001370 // Validate pCreateInfo->imageFormat against
1371 // VkSurfaceFormatKHR::format:
1372 bool foundFormat = false;
1373 bool foundColorSpace = false;
1374 bool foundMatch = false;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001375 for (uint32_t i = 0 ; i < pPhysicalDevice->surfaceFormatCount ; i++) {
1376 if (pCreateInfo->imageFormat == pPhysicalDevice->pSurfaceFormats[i].format) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001377 // Validate pCreateInfo->imageColorSpace against
1378 // VkSurfaceFormatKHR::colorSpace:
1379 foundFormat = true;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001380 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001381 foundMatch = true;
1382 break;
1383 }
1384 } else {
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001385 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001386 foundColorSpace = true;
1387 }
1388 }
1389 }
1390 if (!foundMatch) {
1391 if (!foundFormat) {
1392 if (!foundColorSpace) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001393 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001394 "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001395 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001396 "%s() called with neither a "
1397 "supported pCreateInfo->imageFormat "
1398 "(i.e. %d) nor a supported "
1399 "pCreateInfo->imageColorSpace "
1400 "(i.e. %d).",
1401 fn,
1402 pCreateInfo->imageFormat,
1403 pCreateInfo->imageColorSpace);
1404 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001405 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device,
Ian Elliottb0f474c2015-09-25 15:50:55 -06001406 "VkDevice",
1407 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001408 "%s() called with a non-supported "
1409 "pCreateInfo->imageFormat (i.e. %d).",
1410 fn, pCreateInfo->imageFormat);
1411 }
1412 } else if (!foundColorSpace) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001413 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001414 SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001415 "%s() called with a non-supported "
1416 "pCreateInfo->imageColorSpace (i.e. %d).",
1417 fn, pCreateInfo->imageColorSpace);
1418 }
1419 }
1420 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001421
1422 // Validate pCreateInfo values with the results of
1423 // vkGetPhysicalDeviceSurfacePresentModesKHR():
1424 if (!pPhysicalDevice || !pPhysicalDevice->presentModeCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001425 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001426 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001427 "%s() called before calling "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001428 "vkGetPhysicalDeviceSurfacePresentModesKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001429 fn);
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001430 } else if (pCreateInfo) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001431 // Validate pCreateInfo->presentMode against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001432 // vkGetPhysicalDeviceSurfacePresentModesKHR():
Ian Elliott0b4d6242015-09-22 10:51:24 -06001433 bool foundMatch = false;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001434 for (uint32_t i = 0 ; i < pPhysicalDevice->presentModeCount ; i++) {
1435 if (pPhysicalDevice->pPresentModes[i] == pCreateInfo->presentMode) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001436 foundMatch = true;
1437 break;
1438 }
1439 }
1440 if (!foundMatch) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001441 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001442 SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001443 "%s() called with a non-supported "
1444 "pCreateInfo->presentMode (i.e. %s).",
1445 fn,
1446 presentModeStr(pCreateInfo->presentMode));
1447 }
1448 }
1449
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001450 // Validate pCreateInfo->imageSharingMode and related values:
Ian Elliotta2a89c52015-12-28 15:23:57 -07001451 if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
1452 if ((pCreateInfo->queueFamilyIndexCount <= 1) ||
1453 !pCreateInfo->pQueueFamilyIndices) {
Ian Elliott1bf155f2015-12-29 17:35:46 -07001454 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001455 SWAPCHAIN_CREATE_SWAP_BAD_SHARING_VALUES,
1456 "%s() called with a supported "
1457 "pCreateInfo->sharingMode of (i.e. %s),"
1458 "but with a bad value(s) for "
1459 "pCreateInfo->queueFamilyIndexCount or "
1460 "pCreateInfo->pQueueFamilyIndices).",
1461 fn,
1462 sharingModeStr(pCreateInfo->imageSharingMode));
1463 }
1464 } else if (pCreateInfo->imageSharingMode != VK_SHARING_MODE_EXCLUSIVE) {
Ian Elliott1bf155f2015-12-29 17:35:46 -07001465 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001466 SWAPCHAIN_CREATE_SWAP_BAD_SHARING_MODE,
1467 "%s() called with a non-supported "
1468 "pCreateInfo->imageSharingMode (i.e. %s).",
1469 fn,
1470 sharingModeStr(pCreateInfo->imageSharingMode));
1471 }
1472
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001473 // Validate pCreateInfo->clipped:
1474 if (pCreateInfo &&
1475 (pCreateInfo->clipped != VK_FALSE) &&
Ian Elliotta2a89c52015-12-28 15:23:57 -07001476 (pCreateInfo->clipped != VK_TRUE)) {
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001477 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1478 device, "VkDevice",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001479 SWAPCHAIN_BAD_BOOL,
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001480 "%s() called with a VkBool32 value that is "
1481 "neither VK_TRUE nor VK_FALSE, but has the "
1482 "numeric value of %d.",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001483 fn,
1484 pCreateInfo->clipped);
1485 }
1486
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001487 // Validate pCreateInfo->oldSwapchain:
1488 if (pCreateInfo && pCreateInfo->oldSwapchain) {
1489 SwpSwapchain *pOldSwapchain = &my_data->swapchainMap[pCreateInfo->oldSwapchain];
1490 if (pOldSwapchain) {
1491 if (device != pOldSwapchain->pDevice->device) {
1492 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1493 device, "VkDevice",
1494 SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE,
1495 "%s() called with a different VkDevice "
1496 "than the VkSwapchainKHR was created with.",
1497 __FUNCTION__);
1498 }
1499 if (pCreateInfo->surface != pOldSwapchain->surface) {
1500 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1501 device, "VkDevice",
1502 SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE,
1503 "%s() called with pCreateInfo->oldSwapchain "
1504 "that has a different VkSurfaceKHR than "
1505 "pCreateInfo->surface.",
1506 fn);
Ian Elliotta2a89c52015-12-28 15:23:57 -07001507 }
1508 } else {
Ian Elliott1bf155f2015-12-29 17:35:46 -07001509 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliotta2a89c52015-12-28 15:23:57 -07001510 pCreateInfo->oldSwapchain,
1511 "VkSwapchainKHR");
1512 }
1513 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001514
1515 return skipCall;
1516}
1517
Ian Elliott27d39c72015-11-20 16:39:34 -07001518VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
1519 VkDevice device,
1520 const VkSwapchainCreateInfoKHR* pCreateInfo,
1521 const VkAllocationCallbacks* pAllocator,
1522 VkSwapchainKHR* pSwapchain)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001523{
1524 VkResult result = VK_SUCCESS;
Tobin Ehlis711ff312015-10-29 12:58:13 -06001525 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001526 VkBool32 skipCall = validateCreateSwapchainKHR(device, pCreateInfo,
1527 pSwapchain);
1528
1529 if (VK_FALSE == skipCall) {
1530 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001531 result = my_data->device_dispatch_table->CreateSwapchainKHR(
Ian Elliott27d39c72015-11-20 16:39:34 -07001532 device, pCreateInfo, pAllocator, pSwapchain);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001533
1534 if (result == VK_SUCCESS) {
1535 // Remember the swapchain's handle, and link it to the device:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001536 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001537
Tobin Ehlis711ff312015-10-29 12:58:13 -06001538 my_data->swapchainMap[*pSwapchain].swapchain = *pSwapchain;
Chia-I Wue2fc5522015-10-26 20:04:44 +08001539 pDevice->swapchains[*pSwapchain] =
Tobin Ehlis711ff312015-10-29 12:58:13 -06001540 &my_data->swapchainMap[*pSwapchain];
1541 my_data->swapchainMap[*pSwapchain].pDevice = pDevice;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001542 my_data->swapchainMap[*pSwapchain].surface =
1543 (pCreateInfo) ? pCreateInfo->surface : 0;
Tobin Ehlis711ff312015-10-29 12:58:13 -06001544 my_data->swapchainMap[*pSwapchain].imageCount = 0;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001545 }
1546
1547 return result;
1548 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001549 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001550}
1551
Ian Elliott27d39c72015-11-20 16:39:34 -07001552VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(
1553 VkDevice device,
1554 VkSwapchainKHR swapchain,
1555 const VkAllocationCallbacks* pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001556{
1557 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001558 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001559
1560 // Validate that a valid VkDevice was used, and that the device
1561 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001562 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001563 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001564 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001565 device,
1566 "VkDevice");
Ian Elliott427058f2015-12-29 16:45:49 -07001567 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001568 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001569 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001570 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001571 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001572 }
1573
1574 // Regardless of skipCall value, do some internal cleanup:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001575 SwpSwapchain *pSwapchain = &my_data->swapchainMap[swapchain];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001576 if (pSwapchain) {
1577 // Delete the SwpSwapchain associated with this swapchain:
1578 if (pSwapchain->pDevice) {
Chia-I Wue2fc5522015-10-26 20:04:44 +08001579 pSwapchain->pDevice->swapchains.erase(swapchain);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001580 if (device != pSwapchain->pDevice->device) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001581 LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001582 SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001583 "%s() called with a different VkDevice than the "
1584 "VkSwapchainKHR was created with.",
1585 __FUNCTION__);
1586 }
1587 }
1588 if (pSwapchain->imageCount) {
1589 pSwapchain->images.clear();
1590 }
Tobin Ehlis711ff312015-10-29 12:58:13 -06001591 my_data->swapchainMap.erase(swapchain);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001592 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001593 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Chia-I Wue2fc5522015-10-26 20:04:44 +08001594 swapchain,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001595 "VkSwapchainKHR");
1596 }
1597
1598 if (VK_FALSE == skipCall) {
1599 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -07001600 my_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001601 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001602}
1603
Ian Elliottf955d682015-12-30 12:00:54 -07001604VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
1605 VkDevice device,
1606 VkSwapchainKHR swapchain,
1607 uint32_t* pSwapchainImageCount,
1608 VkImage* pSwapchainImages)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001609{
1610 VkResult result = VK_SUCCESS;
1611 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001612 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001613
1614 // Validate that a valid VkDevice was used, and that the device
1615 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001616 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001617 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001618 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001619 device,
1620 "VkDevice");
Ian Elliott427058f2015-12-29 16:45:49 -07001621 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001622 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001623 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001624 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001625 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001626 }
Tobin Ehlis711ff312015-10-29 12:58:13 -06001627 SwpSwapchain *pSwapchain = &my_data->swapchainMap[swapchain];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001628 if (!pSwapchain) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001629 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001630 swapchain.handle,
1631 "VkSwapchainKHR");
1632 }
Ian Elliottf955d682015-12-30 12:00:54 -07001633 if (!pSwapchainImageCount) {
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001634 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1635 device,
Ian Elliottf955d682015-12-30 12:00:54 -07001636 "pSwapchainImageCount");
1637 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001638
1639 if (VK_FALSE == skipCall) {
1640 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001641 result = my_data->device_dispatch_table->GetSwapchainImagesKHR(
Ian Elliottf955d682015-12-30 12:00:54 -07001642 device, swapchain, pSwapchainImageCount, pSwapchainImages);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001643
Ian Elliottf955d682015-12-30 12:00:54 -07001644 if ((result == VK_SUCCESS) && pSwapchain && !pSwapchainImages &&
1645 pSwapchainImageCount) {
1646 // Record the result of this preliminary query:
1647 pSwapchain->imageCount = *pSwapchainImageCount;
1648 }
Ian Elliott9059b302015-12-30 13:14:36 -07001649 else if ((result == VK_SUCCESS) && pSwapchain && pSwapchainImages &&
1650 pSwapchainImageCount) {
Ian Elliottf955d682015-12-30 12:00:54 -07001651 // Compare the preliminary value of *pSwapchainImageCount with the
1652 // value this time:
1653 if (*pSwapchainImageCount != pSwapchain->imageCount) {
1654 LOG_ERROR_INVALID_COUNT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1655 device,
1656 "pSwapchainImageCount",
1657 "pSwapchainImages",
1658 pSwapchain->imageCount);
1659 }
Ian Elliott9059b302015-12-30 13:14:36 -07001660 else if (*pSwapchainImageCount > 0) {
1661 // Record the images and their state:
1662 pSwapchain->imageCount = *pSwapchainImageCount;
1663 for (uint32_t i = 0 ; i < *pSwapchainImageCount ; i++) {
1664 pSwapchain->images[i].image = pSwapchainImages[i];
1665 pSwapchain->images[i].pSwapchain = pSwapchain;
1666 pSwapchain->images[i].ownedByApp = false;
1667 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001668 }
1669 }
1670
1671 return result;
1672 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001673 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001674}
1675
Ian Elliott27d39c72015-11-20 16:39:34 -07001676VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
1677 VkDevice device,
1678 VkSwapchainKHR swapchain,
1679 uint64_t timeout,
1680 VkSemaphore semaphore,
1681 VkFence fence,
1682 uint32_t* pImageIndex)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001683{
Ian Elliottdd45e462015-12-29 17:52:10 -07001684// TODOs:
1685//
1686// - Address the timeout. Possibilities include looking at the state of the
1687// swapchain's images, depending on the timeout value.
1688// - Validate that semaphore and fence are either VK_NULL_HANDLE or valid
1689// handles.
1690// - Record/update the state of the swapchain, in case an error occurs
1691// (e.g. VK_ERROR_OUT_OF_DATE_KHR).
Ian Elliott0b4d6242015-09-22 10:51:24 -06001692 VkResult result = VK_SUCCESS;
1693 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001694 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001695
1696 // Validate that a valid VkDevice was used, and that the device
1697 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001698 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001699 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001700 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001701 device,
1702 "VkDevice");
Ian Elliott427058f2015-12-29 16:45:49 -07001703 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001704 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001705 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001706 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001707 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001708 }
1709 // Validate that a valid VkSwapchainKHR was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001710 SwpSwapchain *pSwapchain = &my_data->swapchainMap[swapchain];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001711 if (!pSwapchain) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001712 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Chia-I Wue2fc5522015-10-26 20:04:44 +08001713 swapchain,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001714 "VkSwapchainKHR");
1715 } else {
1716 // Look to see if the application is trying to own too many images at
1717 // the same time (i.e. not leave any to display):
Courtney Goeltzenleuchterdad30df2015-10-07 09:00:34 -06001718 uint32_t imagesOwnedByApp = 0;
1719 for (uint32_t i = 0 ; i < pSwapchain->imageCount ; i++) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001720 if (pSwapchain->images[i].ownedByApp) {
1721 imagesOwnedByApp++;
1722 }
1723 }
1724 if (imagesOwnedByApp >= (pSwapchain->imageCount - 1)) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001725 skipCall |= LOG_PERF_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott4a994452015-09-24 18:33:16 -06001726 swapchain,
1727 "VkSwapchainKHR",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001728 SWAPCHAIN_APP_OWNS_TOO_MANY_IMAGES,
Ian Elliott4a994452015-09-24 18:33:16 -06001729 "%s() called when the application "
1730 "already owns all presentable images "
1731 "in this swapchain except for the "
1732 "image currently being displayed. "
1733 "This call to %s() cannot succeed "
1734 "unless another thread calls the "
1735 "vkQueuePresentKHR() function in "
1736 "order to release ownership of one of "
1737 "the presentable images of this "
1738 "swapchain.",
1739 __FUNCTION__, __FUNCTION__);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001740 }
1741 }
Ian Elliottdd45e462015-12-29 17:52:10 -07001742 if (!pImageIndex) {
1743 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1744 device,
1745 "pImageIndex");
1746 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001747
1748 if (VK_FALSE == skipCall) {
1749 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001750 result = my_data->device_dispatch_table->AcquireNextImageKHR(
Ian Elliott27d39c72015-11-20 16:39:34 -07001751 device, swapchain, timeout, semaphore, fence, pImageIndex);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001752
1753 if (((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR)) &&
1754 pSwapchain) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001755 // Change the state of the image (now owned by the application):
1756 pSwapchain->images[*pImageIndex].ownedByApp = true;
1757 }
1758
1759 return result;
1760 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001761 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001762}
1763
Ian Elliott27d39c72015-11-20 16:39:34 -07001764VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(
1765 VkQueue queue,
1766 const VkPresentInfoKHR* pPresentInfo)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001767{
1768// TODOs:
1769//
1770// - Ensure that the queue is active, and is one of the queueFamilyIndex's
1771// that was returned by a previuos query.
1772// - Record/update the state of the swapchain, in case an error occurs
1773// (e.g. VK_ERROR_OUT_OF_DATE_KHR).
1774 VkResult result = VK_SUCCESS;
1775 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001776 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001777
Ian Elliott046ed2c2015-12-30 17:07:17 -07001778 if (!pPresentInfo) {
1779 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1780 device,
1781 "pPresentInfo");
1782 } else {
1783 if (pPresentInfo->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR) {
1784 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1785 device,
1786 "pPresentInfo",
1787 "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR");
1788 }
1789 if (pPresentInfo->pNext != NULL) {
1790 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1791 device,
1792 "pPresentInfo");
1793 }
1794 if (!pPresentInfo->waitSemaphoreCount) {
1795 skipCall |= LOG_ERROR_ZERO_VALUE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1796 device,
1797 "pPresentInfo->waitSemaphoreCount");
1798 }
1799 if (!pPresentInfo->pWaitSemaphores) {
1800 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1801 device,
1802 "pPresentInfo->pWaitSemaphores");
1803 }
1804 if (!pPresentInfo->swapchainCount) {
1805 skipCall |= LOG_ERROR_ZERO_VALUE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1806 device,
1807 "pPresentInfo->swapchainCount");
1808 }
1809 if (!pPresentInfo->pSwapchains) {
1810 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1811 device,
1812 "pPresentInfo->pSwapchains");
1813 }
1814 if (!pPresentInfo->pImageIndices) {
1815 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1816 device,
1817 "pPresentInfo->pImageIndices");
1818 }
1819 // Note: pPresentInfo->pResults is allowed to be NULL
1820 }
1821
1822 for (uint32_t i = 0;
1823 pPresentInfo && (i < pPresentInfo->swapchainCount);
1824 i++) {
1825 uint32_t swapchainCount = pPresentInfo->swapchainCount;
Ian Elliott27d39c72015-11-20 16:39:34 -07001826 uint32_t index = pPresentInfo->pImageIndices[i];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001827 SwpSwapchain *pSwapchain =
Ian Elliott27d39c72015-11-20 16:39:34 -07001828 &my_data->swapchainMap[pPresentInfo->pSwapchains[i]];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001829 if (pSwapchain) {
Ian Elliott427058f2015-12-29 16:45:49 -07001830 if (!pSwapchain->pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001831 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001832 pSwapchain->pDevice, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001833 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001834 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001835 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001836 }
1837 if (index >= pSwapchain->imageCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001838 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001839 pPresentInfo->pSwapchains[i],
Ian Elliott0b4d6242015-09-22 10:51:24 -06001840 "VkSwapchainKHR",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001841 SWAPCHAIN_INDEX_TOO_LARGE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001842 "%s() called for an index that is too "
1843 "large (i.e. %d). There are only %d "
1844 "images in this VkSwapchainKHR.\n",
1845 __FUNCTION__, index,
1846 pSwapchain->imageCount);
1847 } else {
1848 if (!pSwapchain->images[index].ownedByApp) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001849 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001850 pPresentInfo->pSwapchains[i],
Ian Elliott0b4d6242015-09-22 10:51:24 -06001851 "VkSwapchainKHR",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001852 SWAPCHAIN_INDEX_NOT_IN_USE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001853 "%s() returned an index (i.e. %d) "
1854 "for an image that is not owned by "
1855 "the application.",
1856 __FUNCTION__, index);
1857 }
1858 }
1859 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001860 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001861 pPresentInfo->pSwapchains[i],
Ian Elliott0b4d6242015-09-22 10:51:24 -06001862 "VkSwapchainKHR");
1863 }
1864 }
1865
1866 if (VK_FALSE == skipCall) {
1867 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001868 result = my_data->device_dispatch_table->QueuePresentKHR(queue,
Ian Elliott046ed2c2015-12-30 17:07:17 -07001869 pPresentInfo);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001870
Ian Elliott046ed2c2015-12-30 17:07:17 -07001871 if (pPresentInfo &&
1872 ((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) {
Courtney Goeltzenleuchterdad30df2015-10-07 09:00:34 -06001873 for (uint32_t i = 0; i < pPresentInfo->swapchainCount ; i++) {
Ian Elliott27d39c72015-11-20 16:39:34 -07001874 int index = pPresentInfo->pImageIndices[i];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001875 SwpSwapchain *pSwapchain =
Ian Elliott27d39c72015-11-20 16:39:34 -07001876 &my_data->swapchainMap[pPresentInfo->pSwapchains[i]];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001877 if (pSwapchain) {
1878 // Change the state of the image (no longer owned by the
1879 // application):
1880 pSwapchain->images[index].ownedByApp = false;
1881 }
1882 }
1883 }
1884
1885 return result;
1886 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001887 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001888}
1889
1890static inline PFN_vkVoidFunction layer_intercept_proc(const char *name)
1891{
1892 if (!name || name[0] != 'v' || name[1] != 'k')
1893 return NULL;
1894
1895 name += 2;
1896 if (!strcmp(name, "CreateInstance"))
1897 return (PFN_vkVoidFunction) vkCreateInstance;
1898 if (!strcmp(name, "DestroyInstance"))
1899 return (PFN_vkVoidFunction) vkDestroyInstance;
1900 if (!strcmp(name, "EnumeratePhysicalDevices"))
1901 return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
1902 if (!strcmp(name, "CreateDevice"))
1903 return (PFN_vkVoidFunction) vkCreateDevice;
1904 if (!strcmp(name, "DestroyDevice"))
1905 return (PFN_vkVoidFunction) vkDestroyDevice;
1906
1907 return NULL;
1908}
1909static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name)
1910{
1911 if (!name || name[0] != 'v' || name[1] != 'k')
1912 return NULL;
1913
1914 name += 2;
1915 if (!strcmp(name, "CreateInstance"))
1916 return (PFN_vkVoidFunction) vkCreateInstance;
1917 if (!strcmp(name, "DestroyInstance"))
1918 return (PFN_vkVoidFunction) vkDestroyInstance;
1919 if (!strcmp(name, "EnumeratePhysicalDevices"))
1920 return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
1921
1922 return NULL;
1923}
1924
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001925VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
1926 VkInstance instance,
1927 const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
1928 const VkAllocationCallbacks* pAllocator,
1929 VkDebugReportCallbackEXT* pMsgCallback)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001930{
Tobin Ehlis711ff312015-10-29 12:58:13 -06001931 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001932 VkResult result = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Ian Elliott68124ac2015-10-07 16:18:35 -06001933 if (VK_SUCCESS == result) {
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001934 result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Ian Elliott68124ac2015-10-07 16:18:35 -06001935 }
1936 return result;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001937}
1938
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001939VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001940{
Ian Elliott68124ac2015-10-07 16:18:35 -06001941 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001942 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001943 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001944}
1945
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001946VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07001947 VkInstance instance,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001948 VkDebugReportFlagsEXT flags,
1949 VkDebugReportObjectTypeEXT objType,
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07001950 uint64_t object,
1951 size_t location,
1952 int32_t msgCode,
1953 const char* pLayerPrefix,
1954 const char* pMsg)
1955{
1956 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001957 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07001958}
1959
Chia-I Wu9ab61502015-11-06 06:42:02 +08001960VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001961{
1962 PFN_vkVoidFunction addr;
1963 if (device == VK_NULL_HANDLE) {
1964 return NULL;
1965 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001966
Tobin Ehlis711ff312015-10-29 12:58:13 -06001967 layer_data *my_data;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001968 /* loader uses this to force layer initialization; device object is wrapped */
1969 if (!strcmp("vkGetDeviceProcAddr", funcName)) {
Tobin Ehlis711ff312015-10-29 12:58:13 -06001970 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
1971 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
1972 my_data->device_dispatch_table = new VkLayerDispatchTable;
1973 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001974 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
1975 }
1976
1977 addr = layer_intercept_proc(funcName);
1978 if (addr)
1979 return addr;
1980
Tobin Ehlis711ff312015-10-29 12:58:13 -06001981 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1982 VkLayerDispatchTable *pDisp = my_data->device_dispatch_table;
1983 if (my_data->deviceMap.size() != 0 &&
Ian Elliott427058f2015-12-29 16:45:49 -07001984 my_data->deviceMap[device].swapchainExtensionEnabled)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001985 {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001986 if (!strcmp("vkCreateSwapchainKHR", funcName))
1987 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateSwapchainKHR);
1988 if (!strcmp("vkDestroySwapchainKHR", funcName))
1989 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySwapchainKHR);
1990 if (!strcmp("vkGetSwapchainImagesKHR", funcName))
1991 return reinterpret_cast<PFN_vkVoidFunction>(vkGetSwapchainImagesKHR);
1992 if (!strcmp("vkAcquireNextImageKHR", funcName))
1993 return reinterpret_cast<PFN_vkVoidFunction>(vkAcquireNextImageKHR);
1994 if (!strcmp("vkQueuePresentKHR", funcName))
1995 return reinterpret_cast<PFN_vkVoidFunction>(vkQueuePresentKHR);
1996 }
1997 {
1998 if (pDisp->GetDeviceProcAddr == NULL)
1999 return NULL;
2000 return pDisp->GetDeviceProcAddr(device, funcName);
2001 }
2002}
2003
Chia-I Wu9ab61502015-11-06 06:42:02 +08002004VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Ian Elliott0b4d6242015-09-22 10:51:24 -06002005{
2006 PFN_vkVoidFunction addr;
2007 if (instance == VK_NULL_HANDLE) {
2008 return NULL;
2009 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06002010
Tobin Ehlis711ff312015-10-29 12:58:13 -06002011 layer_data *my_data;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002012 /* loader uses this to force layer initialization; instance object is wrapped */
2013 if (!strcmp("vkGetInstanceProcAddr", funcName)) {
Tobin Ehlis711ff312015-10-29 12:58:13 -06002014 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
2015 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
2016 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
2017 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002018 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
2019 }
2020
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -07002021 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
2022 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
2023 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
2024 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
2025
Ian Elliott0b4d6242015-09-22 10:51:24 -06002026 addr = layer_intercept_instance_proc(funcName);
2027 if (addr)
2028 return addr;
2029
Tobin Ehlis711ff312015-10-29 12:58:13 -06002030 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2031 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
Ian Elliott68124ac2015-10-07 16:18:35 -06002032 addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
2033 if (addr) {
2034 return addr;
2035 }
2036
Ian Elliotta983e9a2015-12-22 12:18:12 -07002037#ifdef VK_USE_PLATFORM_ANDROID_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002038 if (my_data->instanceMap.size() != 0 &&
2039 my_data->instanceMap[instance].androidSurfaceExtensionEnabled)
2040 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002041 if (!strcmp("vkCreateAndroidSurfaceKHR", funcName))
2042 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateAndroidSurfaceKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002043 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002044#endif // VK_USE_PLATFORM_ANDROID_KHR
2045#ifdef VK_USE_PLATFORM_MIR_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002046 if (my_data->instanceMap.size() != 0 &&
2047 my_data->instanceMap[instance].mirSurfaceExtensionEnabled)
2048 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002049 if (!strcmp("vkCreateMirSurfaceKHR", funcName))
2050 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateMirSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002051 if (!strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", funcName))
2052 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceMirPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002053 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002054#endif // VK_USE_PLATFORM_MIR_KHR
2055#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002056 if (my_data->instanceMap.size() != 0 &&
2057 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled)
2058 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002059 if (!strcmp("vkCreateWaylandSurfaceKHR", funcName))
2060 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateWaylandSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002061 if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", funcName))
2062 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002063 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002064#endif // VK_USE_PLATFORM_WAYLAND_KHR
2065#ifdef VK_USE_PLATFORM_WIN32_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002066 if (my_data->instanceMap.size() != 0 &&
2067 my_data->instanceMap[instance].win32SurfaceExtensionEnabled)
2068 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002069 if (!strcmp("vkCreateWin32SurfaceKHR", funcName))
2070 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateWin32SurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002071 if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", funcName))
2072 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceWin32PresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002073 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002074#endif // VK_USE_PLATFORM_WIN32_KHR
2075#ifdef VK_USE_PLATFORM_XCB_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002076 if (my_data->instanceMap.size() != 0 &&
2077 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled)
2078 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002079 if (!strcmp("vkCreateXcbSurfaceKHR", funcName))
2080 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateXcbSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002081 if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", funcName))
2082 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceXcbPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002083 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002084#endif // VK_USE_PLATFORM_XCB_KHR
2085#ifdef VK_USE_PLATFORM_XLIB_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002086 if (my_data->instanceMap.size() != 0 &&
2087 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled)
2088 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002089 if (!strcmp("vkCreateXlibSurfaceKHR", funcName))
2090 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateXlibSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002091 if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", funcName))
2092 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceXlibPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002093 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002094#endif // VK_USE_PLATFORM_XLIB_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002095 if (my_data->instanceMap.size() != 0 &&
2096 my_data->instanceMap[instance].surfaceExtensionEnabled)
2097 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002098 if (!strcmp("vkDestroySurfaceKHR", funcName))
2099 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySurfaceKHR);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002100 if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", funcName))
2101 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceSupportKHR);
Ian Elliott27d39c72015-11-20 16:39:34 -07002102 if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", funcName))
2103 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
2104 if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", funcName))
2105 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceFormatsKHR);
2106 if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", funcName))
2107 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfacePresentModesKHR);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002108 }
2109
2110 if (pTable->GetInstanceProcAddr == NULL)
2111 return NULL;
2112 return pTable->GetInstanceProcAddr(instance, funcName);
2113}
2114