blob: e44fbc588097790f2676de0e59588d01db588f7b [file] [log] [blame]
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
4 * Copyright (C) 2015-2016 Google Inc.
Ian Elliott0b4d6242015-09-22 10:51:24 -06005 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
Ian Elliott0b4d6242015-09-22 10:51:24 -06009 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060010 * http://www.apache.org/licenses/LICENSE-2.0
Ian Elliott0b4d6242015-09-22 10:51:24 -060011 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060012 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
Ian Elliott0b4d6242015-09-22 10:51:24 -060017 *
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060018 * Author: Ian Elliott <ian@lunarg.com>
Ian Elliott578e7e22016-01-05 14:03:16 -070019 * Author: Ian Elliott <ianelliott@google.com>
Ian Elliott0b4d6242015-09-22 10:51:24 -060020 */
21
Jeremy Hayes9de0bd72016-04-13 11:57:20 -060022#include <mutex>
Ian Elliottd8c5db12015-10-07 11:32:31 -060023#include <stdio.h>
24#include <string.h>
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -070025#include <vk_loader_platform.h>
Cody Northropd08141b2016-02-01 09:52:07 -070026#include <vulkan/vk_icd.h>
Ian Elliott0b4d6242015-09-22 10:51:24 -060027#include "swapchain.h"
Tobin Ehlis711ff312015-10-29 12:58:13 -060028#include "vk_layer_extension_utils.h"
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070029#include "vk_enum_string_helper.h"
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -060030#include "vk_layer_utils.h"
Ian Elliott68124ac2015-10-07 16:18:35 -060031
Chia-I Wu516b5082016-04-28 11:27:46 +080032namespace swapchain {
33
Jeremy Hayes9de0bd72016-04-13 11:57:20 -060034static std::mutex global_lock;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070035
Ian Elliott0b4d6242015-09-22 10:51:24 -060036// The following is for logging error messages:
Ian Elliott68124ac2015-10-07 16:18:35 -060037static std::unordered_map<void *, layer_data *> layer_data_map;
Ian Elliott0b4d6242015-09-22 10:51:24 -060038
Jon Ashburn5484e0c2016-03-08 17:48:44 -070039static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070040
Chia-I Wu40e25e72016-04-28 14:12:27 +080041static const VkLayerProperties swapchain_layer = {
Jon Ashburndc9111c2016-03-22 12:57:13 -060042 "VK_LAYER_LUNARG_swapchain", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
Chia-I Wu40e25e72016-04-28 14:12:27 +080043};
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070044
Mark Youngaa1aa3a2016-07-05 16:41:50 -060045static void checkDeviceRegisterExtensions(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
46 VkDevice device) {
Ian Elliott0b4d6242015-09-22 10:51:24 -060047 uint32_t i;
Jon Ashburn5484e0c2016-03-08 17:48:44 -070048 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070049 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -060050
Ian Elliott77f46ca2016-05-05 14:10:49 -060051 SwpPhysicalDevice *pPhysicalDevice = NULL;
52 {
53 auto it = my_instance_data->physicalDeviceMap.find(physicalDevice);
54 pPhysicalDevice = (it == my_instance_data->physicalDeviceMap.end()) ? NULL : &it->second;
55 }
Ian Elliott0b4d6242015-09-22 10:51:24 -060056 if (pPhysicalDevice) {
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070057 my_device_data->deviceMap[device].pPhysicalDevice = pPhysicalDevice;
58 pPhysicalDevice->pDevice = &my_device_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -060059 } else {
Ian Elliott07adb112016-01-05 12:51:03 -070060 // TBD: Should we leave error in (since Swapchain really needs this
61 // link)?
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070062 log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Jon Ashburn5484e0c2016-03-08 17:48:44 -070063 (uint64_t)physicalDevice, __LINE__, SWAPCHAIN_INVALID_HANDLE, "Swapchain",
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070064 "vkCreateDevice() called with a non-valid VkPhysicalDevice.");
Ian Elliott0b4d6242015-09-22 10:51:24 -060065 }
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070066 my_device_data->deviceMap[device].device = device;
Ian Elliott427058f2015-12-29 16:45:49 -070067 my_device_data->deviceMap[device].swapchainExtensionEnabled = false;
Ian Elliott0b4d6242015-09-22 10:51:24 -060068
69 // Record whether the WSI device extension was enabled for this VkDevice.
70 // No need to check if the extension was advertised by
71 // vkEnumerateDeviceExtensionProperties(), since the loader handles that.
Jon Ashburnf19916e2016-01-11 13:12:43 -070072 for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070073 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
Ian Elliott0b4d6242015-09-22 10:51:24 -060074
Ian Elliott427058f2015-12-29 16:45:49 -070075 my_device_data->deviceMap[device].swapchainExtensionEnabled = true;
Ian Elliott0b4d6242015-09-22 10:51:24 -060076 }
77 }
78}
79
Mark Youngaa1aa3a2016-07-05 16:41:50 -060080static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
Ian Elliott0b4d6242015-09-22 10:51:24 -060081 uint32_t i;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -070082 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -060083
Ian Elliott1dcd1092015-11-17 17:29:40 -070084 // Remember this instance, and whether the VK_KHR_surface extension
Ian Elliott0b4d6242015-09-22 10:51:24 -060085 // was enabled for it:
Tobin Ehlis711ff312015-10-29 12:58:13 -060086 my_data->instanceMap[instance].instance = instance;
Ian Elliott1cb77a62015-12-29 16:44:39 -070087 my_data->instanceMap[instance].surfaceExtensionEnabled = false;
Petros Bantolas2b40be72016-04-15 11:02:59 +010088 my_data->instanceMap[instance].displayExtensionEnabled = false;
Ian Elliott8dffaf32016-01-04 14:10:30 -070089#ifdef VK_USE_PLATFORM_ANDROID_KHR
90 my_data->instanceMap[instance].androidSurfaceExtensionEnabled = false;
91#endif // VK_USE_PLATFORM_ANDROID_KHR
92#ifdef VK_USE_PLATFORM_MIR_KHR
93 my_data->instanceMap[instance].mirSurfaceExtensionEnabled = false;
94#endif // VK_USE_PLATFORM_MIR_KHR
95#ifdef VK_USE_PLATFORM_WAYLAND_KHR
96 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = false;
97#endif // VK_USE_PLATFORM_WAYLAND_KHR
98#ifdef VK_USE_PLATFORM_WIN32_KHR
99 my_data->instanceMap[instance].win32SurfaceExtensionEnabled = false;
100#endif // VK_USE_PLATFORM_WIN32_KHR
101#ifdef VK_USE_PLATFORM_XCB_KHR
102 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = false;
103#endif // VK_USE_PLATFORM_XCB_KHR
104#ifdef VK_USE_PLATFORM_XLIB_KHR
105 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = false;
106#endif // VK_USE_PLATFORM_XLIB_KHR
107
Ian Elliotted6b5ac2016-04-28 09:08:13 -0600108 // Look for one or more debug report create info structures, and copy the
109 // callback(s) for each one found (for use by vkDestroyInstance)
110 layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_data->num_tmp_callbacks, &my_data->tmp_dbg_create_infos,
111 &my_data->tmp_callbacks);
112
Ian Elliott0b4d6242015-09-22 10:51:24 -0600113 // Record whether the WSI instance extension was enabled for this
114 // VkInstance. No need to check if the extension was advertised by
115 // vkEnumerateInstanceExtensionProperties(), since the loader handles that.
Jon Ashburnf19916e2016-01-11 13:12:43 -0700116 for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700117 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600118
Ian Elliott1cb77a62015-12-29 16:44:39 -0700119 my_data->instanceMap[instance].surfaceExtensionEnabled = true;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600120 }
Petros Bantolas2b40be72016-04-15 11:02:59 +0100121 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
122
123 my_data->instanceMap[instance].displayExtensionEnabled = true;
124 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700125#ifdef VK_USE_PLATFORM_ANDROID_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700126 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott8dffaf32016-01-04 14:10:30 -0700127
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700128 my_data->instanceMap[instance].androidSurfaceExtensionEnabled = true;
Jason Ekstranda5ebe8a2016-02-12 17:25:03 -0800129 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700130#endif // VK_USE_PLATFORM_ANDROID_KHR
131#ifdef VK_USE_PLATFORM_MIR_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700132 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott8dffaf32016-01-04 14:10:30 -0700133
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700134 my_data->instanceMap[instance].mirSurfaceExtensionEnabled = true;
Jason Ekstranda5ebe8a2016-02-12 17:25:03 -0800135 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700136#endif // VK_USE_PLATFORM_MIR_KHR
137#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700138 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott8dffaf32016-01-04 14:10:30 -0700139
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700140 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = true;
Jason Ekstranda5ebe8a2016-02-12 17:25:03 -0800141 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700142#endif // VK_USE_PLATFORM_WAYLAND_KHR
143#ifdef VK_USE_PLATFORM_WIN32_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700144 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott8dffaf32016-01-04 14:10:30 -0700145
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700146 my_data->instanceMap[instance].win32SurfaceExtensionEnabled = true;
Jason Ekstranda5ebe8a2016-02-12 17:25:03 -0800147 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700148#endif // VK_USE_PLATFORM_WIN32_KHR
149#ifdef VK_USE_PLATFORM_XCB_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700150 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott8dffaf32016-01-04 14:10:30 -0700151
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700152 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = true;
Jason Ekstranda5ebe8a2016-02-12 17:25:03 -0800153 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700154#endif // VK_USE_PLATFORM_XCB_KHR
155#ifdef VK_USE_PLATFORM_XLIB_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700156 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott8dffaf32016-01-04 14:10:30 -0700157
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700158 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = true;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700159 }
Jason Ekstranda5ebe8a2016-02-12 17:25:03 -0800160#endif // VK_USE_PLATFORM_XLIB_KHR
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700161 }
162}
163
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700164#include "vk_dispatch_table_helper.h"
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -0600165static void init_swapchain(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600166
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -0600167 layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_swapchain");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700168}
Ian Elliott0b4d6242015-09-22 10:51:24 -0600169
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700170static const char *surfaceTransformStr(VkSurfaceTransformFlagBitsKHR value) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700171 // Return a string corresponding to the value:
172 return string_VkSurfaceTransformFlagBitsKHR(value);
173}
Ian Elliott0b4d6242015-09-22 10:51:24 -0600174
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700175static const char *surfaceCompositeAlphaStr(VkCompositeAlphaFlagBitsKHR value) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700176 // Return a string corresponding to the value:
177 return string_VkCompositeAlphaFlagBitsKHR(value);
178}
Ian Elliott0b4d6242015-09-22 10:51:24 -0600179
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700180static const char *presentModeStr(VkPresentModeKHR value) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700181 // Return a string corresponding to the value:
182 return string_VkPresentModeKHR(value);
183}
Ian Elliott0b4d6242015-09-22 10:51:24 -0600184
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700185static const char *sharingModeStr(VkSharingMode value) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700186 // Return a string corresponding to the value:
187 return string_VkSharingMode(value);
188}
Ian Elliott07adb112016-01-05 12:51:03 -0700189
Chia-I Wufccbfe42016-04-28 14:01:30 +0800190VKAPI_ATTR VkResult VKAPI_CALL
191CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700192 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600193
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700194 assert(chain_info->u.pLayerInfo);
195 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700196 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700197 if (fpCreateInstance == NULL) {
198 return VK_ERROR_INITIALIZATION_FAILED;
199 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700200
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700201 // Advance the link info for the next element on the chain
202 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700203
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700204 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
205 if (result != VK_SUCCESS) {
206 return result;
207 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700208
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700209 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Chia-I Wua6737532016-04-28 16:04:15 +0800210 my_data->instance = *pInstance;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700211 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
212 layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700213
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700214 my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance,
215 pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700216
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700217 // Call the following function after my_data is initialized:
Mark Youngaa1aa3a2016-07-05 16:41:50 -0600218 checkInstanceRegisterExtensions(pCreateInfo, *pInstance);
Mark Lobodzinski1079e1b2016-03-15 14:21:59 -0600219 init_swapchain(my_data, pAllocator);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700220
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700221 return result;
222}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700223
Chia-I Wufccbfe42016-04-28 14:01:30 +0800224VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700225 dispatch_key key = get_dispatch_key(instance);
226 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600227 SwpInstance *pInstance = NULL;
228 {
229 auto it = my_data->instanceMap.find(instance);
230 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
231 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700232
Ian Elliott32311832016-02-04 08:17:18 -0700233 // Call down the call chain:
234 my_data->instance_dispatch_table->DestroyInstance(instance, pAllocator);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700235
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600236 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott32311832016-02-04 08:17:18 -0700237
Ian Elliotted6b5ac2016-04-28 09:08:13 -0600238 // Enable the temporary callback(s) here to catch cleanup issues:
239 bool callback_setup = false;
240 if (my_data->num_tmp_callbacks > 0) {
241 if (!layer_enable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_dbg_create_infos,
242 my_data->tmp_callbacks)) {
243 callback_setup = true;
244 }
245 }
246
Ian Elliott32311832016-02-04 08:17:18 -0700247 // Do additional internal cleanup:
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700248 if (pInstance) {
249 // Delete all of the SwpPhysicalDevice's, SwpSurface's, and the
250 // SwpInstance associated with this instance:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700251 for (auto it = pInstance->physicalDevices.begin(); it != pInstance->physicalDevices.end(); it++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700252
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700253 // Free memory that was allocated for/by this SwpPhysicalDevice:
254 SwpPhysicalDevice *pPhysicalDevice = it->second;
255 if (pPhysicalDevice) {
Ian Elliott458696a2016-02-04 06:11:17 -0700256 if (pPhysicalDevice->pDevice) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600257 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
258 (uint64_t)pPhysicalDevice->pDevice->device, __LINE__, SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN,
259 swapchain_layer_name,
260 "VkDestroyInstance() called before all of its associated VkDevices were destroyed.");
Ian Elliott458696a2016-02-04 06:11:17 -0700261 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700262 free(pPhysicalDevice->pSurfaceFormats);
263 free(pPhysicalDevice->pPresentModes);
264 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700265
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700266 // Erase the SwpPhysicalDevice's from the my_data->physicalDeviceMap (which
267 // are simply pointed to by the SwpInstance):
268 my_data->physicalDeviceMap.erase(it->second->physicalDevice);
269 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700270 for (auto it = pInstance->surfaces.begin(); it != pInstance->surfaces.end(); it++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700271
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700272 // Free memory that was allocated for/by this SwpPhysicalDevice:
273 SwpSurface *pSurface = it->second;
274 if (pSurface) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600275 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
276 (uint64_t)pInstance->instance, __LINE__, SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, swapchain_layer_name,
277 "VkDestroyInstance() called before all of its associated VkSurfaceKHRs were destroyed.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700278 }
279 }
280 my_data->instanceMap.erase(instance);
281 }
Mark Lobodzinski3c99d552016-02-04 13:50:23 -0700282
Ian Elliotted6b5ac2016-04-28 09:08:13 -0600283 // Disable and cleanup the temporary callback(s):
284 if (callback_setup) {
285 layer_disable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_callbacks);
286 }
287 if (my_data->num_tmp_callbacks > 0) {
288 layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos, my_data->tmp_callbacks);
289 my_data->num_tmp_callbacks = 0;
290 }
291
Mark Lobodzinski3c99d552016-02-04 13:50:23 -0700292 // Clean up logging callback, if any
293 while (my_data->logging_callback.size() > 0) {
294 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
295 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
296 my_data->logging_callback.pop_back();
297 }
298 layer_debug_report_destroy_instance(my_data->report_data);
299
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700300 delete my_data->instance_dispatch_table;
301 layer_data_map.erase(key);
302}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700303
Chia-I Wufccbfe42016-04-28 14:01:30 +0800304VKAPI_ATTR void VKAPI_CALL
305GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount,
306 VkQueueFamilyProperties *pQueueFamilyProperties) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700307 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott32311832016-02-04 08:17:18 -0700308
309 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700310 my_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount,
311 pQueueFamilyProperties);
Ian Elliott32311832016-02-04 08:17:18 -0700312
313 // Record the result of this query:
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600314 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600315 SwpPhysicalDevice *pPhysicalDevice = NULL;
316 {
317 auto it = my_data->physicalDeviceMap.find(physicalDevice);
318 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
319 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700320 if (pPhysicalDevice && pQueueFamilyPropertyCount && !pQueueFamilyProperties) {
Ian Elliott32311832016-02-04 08:17:18 -0700321 pPhysicalDevice->gotQueueFamilyPropertyCount = true;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700322 pPhysicalDevice->numOfQueueFamilies = *pQueueFamilyPropertyCount;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700323 }
324}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700325
326#ifdef VK_USE_PLATFORM_ANDROID_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800327VKAPI_ATTR VkResult VKAPI_CALL
328CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
329 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700330 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600331 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700332 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600333 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600334 SwpInstance *pInstance = NULL;
335 {
336 auto it = my_data->instanceMap.find(instance);
337 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
338 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700339
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700340 // Validate that the platform extension was enabled:
Cody Northropd08141b2016-02-01 09:52:07 -0700341 if (pInstance && !pInstance->androidSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600342 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
343 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
344 "vkCreateAndroidSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
345 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700346 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700347
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -0600348 if (pCreateInfo->pNext != NULL) {
349 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700350 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600351 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700352
Dustin Graves080069b2016-04-05 13:48:15 -0600353 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700354 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700355 result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600356 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700357
Ian Elliott32311832016-02-04 08:17:18 -0700358 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600359 {
360 auto it = my_data->instanceMap.find(instance);
361 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
362 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700363 if ((result == VK_SUCCESS) && pInstance && pSurface) {
364 // Record the VkSurfaceKHR returned by the ICD:
365 my_data->surfaceMap[*pSurface].surface = *pSurface;
366 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700367 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700368 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
369 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
370 // Point to the associated SwpInstance:
371 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
372 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600373 lock.unlock();
374
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700375 return result;
376 }
377 return VK_ERROR_VALIDATION_FAILED_EXT;
378}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700379#endif // VK_USE_PLATFORM_ANDROID_KHR
380
381#ifdef VK_USE_PLATFORM_MIR_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800382VKAPI_ATTR VkResult VKAPI_CALL
383CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
384 VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700385 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600386 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700387 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600388 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600389 SwpInstance *pInstance = NULL;
390 {
391 auto it = my_data->instanceMap.find(instance);
392 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
393 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700394
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700395 // Validate that the platform extension was enabled:
396 if (pInstance && !pInstance->mirSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600397 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
398 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
399 "vkCreateMirSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
400 VK_KHR_MIR_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700401 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700402
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -0600403 if (pCreateInfo->pNext != NULL) {
404 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700405 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600406 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700407
Dustin Graves080069b2016-04-05 13:48:15 -0600408 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700409 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700410 result = my_data->instance_dispatch_table->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600411 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700412
Ian Elliott32311832016-02-04 08:17:18 -0700413 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600414 {
415 auto it = my_data->instanceMap.find(instance);
416 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
417 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700418 if ((result == VK_SUCCESS) && pInstance && pSurface) {
419 // Record the VkSurfaceKHR returned by the ICD:
420 my_data->surfaceMap[*pSurface].surface = *pSurface;
421 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700422 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700423 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
424 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
425 // Point to the associated SwpInstance:
426 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
427 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600428 lock.unlock();
429
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700430 return result;
431 }
432 return VK_ERROR_VALIDATION_FAILED_EXT;
433}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700434
Chia-I Wufccbfe42016-04-28 14:01:30 +0800435VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice,
436 uint32_t queueFamilyIndex,
437 MirConnection *connection) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700438 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600439 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700440 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600441 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600442 SwpPhysicalDevice *pPhysicalDevice = NULL;
443 {
444 auto it = my_data->physicalDeviceMap.find(physicalDevice);
445 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
446 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700447
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700448 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700449 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->mirSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600450 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
451 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
452 swapchain_layer_name, "vkGetPhysicalDeviceMirPresentationSupportKHR() called even though the %s "
453 "extension was not enabled for this VkInstance.",
454 VK_KHR_MIR_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700455 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700456 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
457 skipCall |=
458 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
459 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700460 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600461 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700462
Dustin Graves080069b2016-04-05 13:48:15 -0600463 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700464 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700465 result = my_data->instance_dispatch_table->GetPhysicalDeviceMirPresentationSupportKHR(physicalDevice, queueFamilyIndex,
466 connection);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700467 }
468 return result;
469}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700470#endif // VK_USE_PLATFORM_MIR_KHR
471
472#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800473VKAPI_ATTR VkResult VKAPI_CALL
474CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
475 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700476 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600477 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700478 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600479 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600480 SwpInstance *pInstance = NULL;
481 {
482 auto it = my_data->instanceMap.find(instance);
483 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
484 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700485
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700486 // Validate that the platform extension was enabled:
487 if (pInstance && !pInstance->waylandSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600488 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
489 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
490 "vkCreateWaylandSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
491 VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700492 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700493
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -0600494 if (pCreateInfo->pNext != NULL) {
495 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700496 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600497 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700498
Dustin Graves080069b2016-04-05 13:48:15 -0600499 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700500 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700501 result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600502 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700503
Ian Elliott32311832016-02-04 08:17:18 -0700504 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600505 {
506 auto it = my_data->instanceMap.find(instance);
507 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
508 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700509 if ((result == VK_SUCCESS) && pInstance && pSurface) {
510 // Record the VkSurfaceKHR returned by the ICD:
511 my_data->surfaceMap[*pSurface].surface = *pSurface;
512 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700513 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700514 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
515 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
516 // Point to the associated SwpInstance:
517 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
518 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600519 lock.unlock();
520
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700521 return result;
522 }
523 return VK_ERROR_VALIDATION_FAILED_EXT;
524}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700525
Chia-I Wufccbfe42016-04-28 14:01:30 +0800526VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
527 uint32_t queueFamilyIndex,
528 struct wl_display *display) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700529 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600530 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700531 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600532 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600533 SwpPhysicalDevice *pPhysicalDevice = NULL;
534 {
535 auto it = my_data->physicalDeviceMap.find(physicalDevice);
536 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
537 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700538
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700539 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700540 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->waylandSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600541 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
542 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
543 swapchain_layer_name, "vkGetPhysicalDeviceWaylandPresentationSupportKHR() called even though the %s "
544 "extension was not enabled for this VkInstance.",
545 VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700546 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700547 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
548 skipCall |=
549 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
550 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700551 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600552 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700553
Dustin Graves080069b2016-04-05 13:48:15 -0600554 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700555 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700556 result = my_data->instance_dispatch_table->GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex,
557 display);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700558 }
559 return result;
560}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700561#endif // VK_USE_PLATFORM_WAYLAND_KHR
562
563#ifdef VK_USE_PLATFORM_WIN32_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800564VKAPI_ATTR VkResult VKAPI_CALL
565CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
566 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700567 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600568 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700569 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600570 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600571 SwpInstance *pInstance = NULL;
572 {
573 auto it = my_data->instanceMap.find(instance);
574 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
575 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700576
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700577 // Validate that the platform extension was enabled:
578 if (pInstance && !pInstance->win32SurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600579 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
580 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
581 "vkCreateWin32SurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
582 VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700583 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700584
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -0600585 if (pCreateInfo->pNext != NULL) {
586 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700587 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600588 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700589
Dustin Graves080069b2016-04-05 13:48:15 -0600590 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700591 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700592 result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600593 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700594
Ian Elliott32311832016-02-04 08:17:18 -0700595 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600596 {
597 auto it = my_data->instanceMap.find(instance);
598 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
599 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700600 if ((result == VK_SUCCESS) && pInstance && pSurface) {
601 // Record the VkSurfaceKHR returned by the ICD:
602 my_data->surfaceMap[*pSurface].surface = *pSurface;
603 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700604 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700605 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
606 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
607 // Point to the associated SwpInstance:
608 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
609 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600610 lock.unlock();
611
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700612 return result;
613 }
614 return VK_ERROR_VALIDATION_FAILED_EXT;
615}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700616
Chia-I Wufccbfe42016-04-28 14:01:30 +0800617VKAPI_ATTR VkBool32 VKAPI_CALL
618GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700619 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600620 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700621 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600622 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600623 SwpPhysicalDevice *pPhysicalDevice = NULL;
624 {
625 auto it = my_data->physicalDeviceMap.find(physicalDevice);
626 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
627 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700628
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700629 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700630 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->win32SurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600631 skipCall |= log_msg(
632 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
633 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
634 "vkGetPhysicalDeviceWin32PresentationSupportKHR() called even though the %s extension was not enabled for this VkInstance.",
635 VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700636 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700637 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
638 skipCall |=
639 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
640 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700641 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600642 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700643
Dustin Graves080069b2016-04-05 13:48:15 -0600644 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700645 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700646 result = my_data->instance_dispatch_table->GetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700647 }
648 return result;
649}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700650#endif // VK_USE_PLATFORM_WIN32_KHR
651
652#ifdef VK_USE_PLATFORM_XCB_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800653VKAPI_ATTR VkResult VKAPI_CALL
654CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700655 VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700656 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600657 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700658 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600659 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600660 SwpInstance *pInstance = NULL;
661 {
662 auto it = my_data->instanceMap.find(instance);
663 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
664 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700665
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700666 // Validate that the platform extension was enabled:
667 if (pInstance && !pInstance->xcbSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600668 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
669 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
670 "vkCreateXcbSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
671 VK_KHR_XCB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700672 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700673
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -0600674 if (pCreateInfo->pNext != NULL) {
675 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700676 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600677 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700678
Dustin Graves080069b2016-04-05 13:48:15 -0600679 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700680 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700681 result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600682 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700683
Ian Elliott32311832016-02-04 08:17:18 -0700684 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600685 {
686 auto it = my_data->instanceMap.find(instance);
687 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
688 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700689 if ((result == VK_SUCCESS) && pInstance && pSurface) {
690 // Record the VkSurfaceKHR returned by the ICD:
691 my_data->surfaceMap[*pSurface].surface = *pSurface;
692 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700693 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700694 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
695 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
696 // Point to the associated SwpInstance:
697 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
698 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600699 lock.unlock();
700
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700701 return result;
702 }
703 return VK_ERROR_VALIDATION_FAILED_EXT;
704}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700705
Chia-I Wufccbfe42016-04-28 14:01:30 +0800706VKAPI_ATTR VkBool32 VKAPI_CALL
707GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
708 xcb_connection_t *connection, xcb_visualid_t visual_id) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700709 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600710 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700711 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600712 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600713 SwpPhysicalDevice *pPhysicalDevice = NULL;
714 {
715 auto it = my_data->physicalDeviceMap.find(physicalDevice);
716 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
717 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700718
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700719 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700720 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->xcbSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600721 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
722 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
723 swapchain_layer_name, "vkGetPhysicalDeviceXcbPresentationSupportKHR() called even though the %s "
724 "extension was not enabled for this VkInstance.",
725 VK_KHR_XCB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700726 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700727 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
728 skipCall |=
729 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
730 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700731 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600732 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700733
Dustin Graves080069b2016-04-05 13:48:15 -0600734 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700735 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700736 result = my_data->instance_dispatch_table->GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex,
737 connection, visual_id);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700738 }
739 return result;
740}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700741#endif // VK_USE_PLATFORM_XCB_KHR
742
743#ifdef VK_USE_PLATFORM_XLIB_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800744VKAPI_ATTR VkResult VKAPI_CALL
745CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
746 VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700747 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600748 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700749 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600750 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600751 SwpInstance *pInstance = NULL;
752 {
753 auto it = my_data->instanceMap.find(instance);
754 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
755 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700756
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700757 // Validate that the platform extension was enabled:
758 if (pInstance && !pInstance->xlibSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600759 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
760 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
761 "vkCreateXlibSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
762 VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700763 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700764
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -0600765 if (pCreateInfo->pNext != NULL) {
766 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700767 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600768 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700769
Dustin Graves080069b2016-04-05 13:48:15 -0600770 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700771 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700772 result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600773 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700774
Ian Elliott32311832016-02-04 08:17:18 -0700775 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600776 {
777 auto it = my_data->instanceMap.find(instance);
778 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
779 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700780 if ((result == VK_SUCCESS) && pInstance && pSurface) {
781 // Record the VkSurfaceKHR returned by the ICD:
782 my_data->surfaceMap[*pSurface].surface = *pSurface;
783 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700784 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700785 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
786 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
787 // Point to the associated SwpInstance:
788 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
789 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600790 lock.unlock();
791
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700792 return result;
793 }
794 return VK_ERROR_VALIDATION_FAILED_EXT;
795}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700796
Chia-I Wufccbfe42016-04-28 14:01:30 +0800797VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
798 uint32_t queueFamilyIndex,
799 Display *dpy, VisualID visualID) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700800 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600801 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700802 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600803 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600804 SwpPhysicalDevice *pPhysicalDevice = NULL;
805 {
806 auto it = my_data->physicalDeviceMap.find(physicalDevice);
807 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
808 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700809
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700810 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700811 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->xlibSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600812 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
813 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
814 swapchain_layer_name, "vkGetPhysicalDeviceXlibPresentationSupportKHR() called even though the %s "
815 "extension was not enabled for this VkInstance.",
816 VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700817 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700818 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
819 skipCall |=
820 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
821 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700822 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600823 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700824
Dustin Graves080069b2016-04-05 13:48:15 -0600825 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700826 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700827 result = my_data->instance_dispatch_table->GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex,
828 dpy, visualID);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700829 }
830 return result;
831}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700832#endif // VK_USE_PLATFORM_XLIB_KHR
833
Petros Bantolas2b40be72016-04-15 11:02:59 +0100834VKAPI_ATTR VkResult VKAPI_CALL
835GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties) {
836 VkResult result = VK_SUCCESS;
837 bool skipCall = false;
838 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
839 std::unique_lock<std::mutex> lock(global_lock);
840 SwpPhysicalDevice *pPhysicalDevice = NULL;
841 {
842 auto it = my_data->physicalDeviceMap.find(physicalDevice);
843 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
844 }
845
846 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600847 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
848 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
849 swapchain_layer_name, "vkGetPhysicalDeviceDisplayPropertiesKHR() called even though the %s "
850 "extension was not enabled for this VkInstance.",
851 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100852 }
Petros Bantolas2b40be72016-04-15 11:02:59 +0100853 lock.unlock();
854
855 if (!skipCall) {
856 result = my_data->instance_dispatch_table->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
857 return result;
858 }
859 return VK_ERROR_VALIDATION_FAILED_EXT;
860}
861
Petros Bantolas2b40be72016-04-15 11:02:59 +0100862VKAPI_ATTR VkResult VKAPI_CALL
863GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
864 VkResult result = VK_SUCCESS;
865 bool skipCall = false;
866 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
867 std::unique_lock<std::mutex> lock(global_lock);
868 SwpPhysicalDevice *pPhysicalDevice = NULL;
869 {
870 auto it = my_data->physicalDeviceMap.find(physicalDevice);
871 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
872 }
873
874 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600875 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
876 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
877 swapchain_layer_name, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR() called even though the %s "
878 "extension was not enabled for this VkInstance.",
879 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100880 }
Petros Bantolas2b40be72016-04-15 11:02:59 +0100881 lock.unlock();
882
883 if (!skipCall) {
884 result = my_data->instance_dispatch_table->GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
885
886 lock.lock();
887 if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
888 {
889 pPhysicalDevice->displayPlanePropertyCount = *pPropertyCount;
890 pPhysicalDevice->gotDisplayPlanePropertyCount = true;
891 }
Jon Ashburne699f442016-06-30 09:01:27 -0600892 // TODO store the properties for later checks
Petros Bantolas2b40be72016-04-15 11:02:59 +0100893 lock.unlock();
894
895 return result;
896 }
897 return VK_ERROR_VALIDATION_FAILED_EXT;
898}
899
900VKAPI_ATTR VkResult VKAPI_CALL
901GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
902 VkResult result = VK_SUCCESS;
903 bool skipCall = false;
904 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
905 std::unique_lock<std::mutex> lock(global_lock);
906 SwpPhysicalDevice *pPhysicalDevice = NULL;
907 {
908 auto it = my_data->physicalDeviceMap.find(physicalDevice);
909 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
910 }
911
912 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600913 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
914 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
915 swapchain_layer_name, "vkGetDisplayPlaneSupportedDisplaysKHR() called even though the %s "
916 "extension was not enabled for this VkInstance.",
917 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100918 }
919
Jon Ashburn5e026df2016-06-15 08:19:07 -0600920 if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +0100921 {
922 LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
923 SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
924 "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.",
925 __FUNCTION__);
926 }
927
Jon Ashburn1e857902016-07-01 10:08:31 -0600928 if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->displayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +0100929 {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600930 skipCall |=
931 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
932 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_PLANE_INDEX_TOO_LARGE, swapchain_layer_name,
933 "vkGetDisplayPlaneSupportedDisplaysKHR(): planeIndex must be in the range [0, %d] that was returned by "
934 "vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
935 pPhysicalDevice->displayPlanePropertyCount - 1);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100936 }
937 lock.unlock();
938
939 if (!skipCall) {
940 result = my_data->instance_dispatch_table->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
941
942 return result;
943 }
Jon Ashburne699f442016-06-30 09:01:27 -0600944 // TODO validate the returned display objects
Petros Bantolas2b40be72016-04-15 11:02:59 +0100945 return VK_ERROR_VALIDATION_FAILED_EXT;
946}
947
948VKAPI_ATTR VkResult VKAPI_CALL
949GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties) {
950 VkResult result = VK_SUCCESS;
951 bool skipCall = false;
952 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
953 std::unique_lock<std::mutex> lock(global_lock);
954 SwpPhysicalDevice *pPhysicalDevice = NULL;
955 {
956 auto it = my_data->physicalDeviceMap.find(physicalDevice);
957 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
958 }
959
960 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600961 skipCall |= log_msg(
962 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
963 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
964 "vkGetDisplayModePropertiesKHR() called even though the %s extension was not enabled for this VkInstance.",
965 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100966 }
967
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -0600968
Petros Bantolas2b40be72016-04-15 11:02:59 +0100969 lock.unlock();
970
971 if (!skipCall) {
972 result = my_data->instance_dispatch_table->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
973 return result;
974 }
Jon Ashburne699f442016-06-30 09:01:27 -0600975 // TODO store the displayMode for later checking
Petros Bantolas2b40be72016-04-15 11:02:59 +0100976 return VK_ERROR_VALIDATION_FAILED_EXT;
977}
978
979VKAPI_ATTR VkResult VKAPI_CALL
980CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode) {
981 VkResult result = VK_SUCCESS;
982 bool skipCall = false;
983 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
984 std::unique_lock<std::mutex> lock(global_lock);
985 SwpPhysicalDevice *pPhysicalDevice = NULL;
986 {
987 auto it = my_data->physicalDeviceMap.find(physicalDevice);
988 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
989 }
990
991 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600992 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
993 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
994 swapchain_layer_name,
995 "vkCreateDisplayModeKHR() called even though the %s extension was not enabled for this VkInstance.",
996 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100997 }
998
Petros Bantolas2b40be72016-04-15 11:02:59 +0100999 lock.unlock();
1000
Jon Ashburne699f442016-06-30 09:01:27 -06001001 // TODO more validation checks needed
Petros Bantolas2b40be72016-04-15 11:02:59 +01001002 if (!skipCall) {
1003 result = my_data->instance_dispatch_table->CreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode);
1004 return result;
1005 }
1006
1007 return VK_ERROR_VALIDATION_FAILED_EXT;
1008}
1009
1010VKAPI_ATTR VkResult VKAPI_CALL
1011GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
1012 VkResult result = VK_SUCCESS;
1013 bool skipCall = false;
1014 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1015 std::unique_lock<std::mutex> lock(global_lock);
1016 SwpPhysicalDevice *pPhysicalDevice = NULL;
1017 {
1018 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1019 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1020 }
1021
1022 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001023 skipCall |= log_msg(
1024 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1025 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1026 "vkGetDisplayPlaneCapabilitiesKHR) called even though the %s extension was not enabled for this VkInstance.",
1027 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001028 }
1029
Jon Ashburn5e026df2016-06-15 08:19:07 -06001030 if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +01001031 {
1032 LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
1033 SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
1034 "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.",
1035 __FUNCTION__);
1036 }
1037
Jon Ashburn5e026df2016-06-15 08:19:07 -06001038 if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->displayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +01001039 {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001040 skipCall |=
1041 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1042 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_PLANE_INDEX_TOO_LARGE, swapchain_layer_name,
1043 "vkGetDisplayPlaneCapabilitiesKHR(): planeIndex must be in the range [0, %d] that was returned by "
1044 "vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
1045 pPhysicalDevice->displayPlanePropertyCount - 1);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001046 }
1047
Petros Bantolas2b40be72016-04-15 11:02:59 +01001048 lock.unlock();
1049
1050 if (!skipCall) {
1051 result = my_data->instance_dispatch_table->GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities);
1052 return result;
1053 }
1054
1055 return VK_ERROR_VALIDATION_FAILED_EXT;
1056}
1057
1058VKAPI_ATTR VkResult VKAPI_CALL
1059CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
1060 VkSurfaceKHR *pSurface) {
1061 VkResult result = VK_SUCCESS;
1062 bool skipCall = false;
1063 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
1064 std::unique_lock<std::mutex> lock(global_lock);
1065 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
1066
1067 // Validate that the platform extension was enabled:
1068 if (pInstance && !pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001069 skipCall |=
1070 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1071 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1072 "vkCreateDisplayPlaneSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
1073 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001074 }
1075
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001076 if (pCreateInfo->pNext != NULL) {
1077 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Petros Bantolas2b40be72016-04-15 11:02:59 +01001078 }
1079
Jon Ashburne699f442016-06-30 09:01:27 -06001080 // TODO more validation checks
Petros Bantolas2b40be72016-04-15 11:02:59 +01001081 if (!skipCall) {
1082 // Call down the call chain:
1083 lock.unlock();
1084 result = my_data->instance_dispatch_table->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
1085 lock.lock();
1086
1087 // Obtain this pointer again after locking:
1088 pInstance = &(my_data->instanceMap[instance]);
1089 if ((result == VK_SUCCESS) && pInstance && pSurface) {
1090 // Record the VkSurfaceKHR returned by the ICD:
1091 my_data->surfaceMap[*pSurface].surface = *pSurface;
1092 my_data->surfaceMap[*pSurface].pInstance = pInstance;
1093 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
1094 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
1095 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
1096 // Point to the associated SwpInstance:
1097 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
1098 }
1099 lock.unlock();
1100 return result;
1101 }
1102 return VK_ERROR_VALIDATION_FAILED_EXT;
1103}
1104
Chia-I Wufccbfe42016-04-28 14:01:30 +08001105VKAPI_ATTR void VKAPI_CALL
1106DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) {
Dustin Graves080069b2016-04-05 13:48:15 -06001107 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001108 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001109 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001110 SwpSurface *pSurface = NULL;
1111 {
1112 auto it = my_data->surfaceMap.find(surface);
1113 pSurface = (it == my_data->surfaceMap.end()) ? NULL : &it->second;
1114 }
1115 SwpInstance *pInstance = NULL;
1116 {
1117 auto it = my_data->instanceMap.find(instance);
1118 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
1119 }
Ian Elliottf6b8c782016-04-29 13:03:17 -06001120
1121 // Validate that the platform extension was enabled:
1122 if (pInstance && !pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001123 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1124 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1125 "vkDestroySurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
1126 VK_KHR_DISPLAY_EXTENSION_NAME);
Ian Elliottf6b8c782016-04-29 13:03:17 -06001127 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001128
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001129 // Regardless of skipCall value, do some internal cleanup:
1130 if (pSurface) {
1131 // Delete the SwpSurface associated with this surface:
1132 if (pSurface->pInstance) {
1133 pSurface->pInstance->surfaces.erase(surface);
1134 }
1135 if (!pSurface->swapchains.empty()) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001136 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1137 (uint64_t)instance, __LINE__, SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, swapchain_layer_name,
1138 "vkDestroySurfaceKHR() called before all of its associated VkSwapchainKHRs were destroyed.");
1139
1140 // Empty and then delete all SwpSwapchains
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001141 for (auto it = pSurface->swapchains.begin(); it != pSurface->swapchains.end(); it++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001142 // Delete all SwpImage's
1143 it->second->images.clear();
1144 // In case the swapchain's device hasn't been destroyed yet
1145 // (which isn't likely, but is possible), delete its
1146 // association with this swapchain (i.e. so we can't point to
1147 // this swpchain from that device, later on):
1148 if (it->second->pDevice) {
1149 it->second->pDevice->swapchains.clear();
1150 }
1151 }
1152 pSurface->swapchains.clear();
1153 }
1154 if ((pAllocator != NULL) != pSurface->usedAllocatorToCreate) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001155 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1156 (uint64_t)instance, __LINE__, SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, swapchain_layer_name,
1157 "vkDestroySurfaceKHR() called with incompatible pAllocator from when the object was created.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001158 }
1159 my_data->surfaceMap.erase(surface);
1160 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001161 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001162
Dustin Graves080069b2016-04-05 13:48:15 -06001163 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001164 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001165 my_data->instance_dispatch_table->DestroySurfaceKHR(instance, surface, pAllocator);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001166 }
1167}
1168
Chia-I Wufccbfe42016-04-28 14:01:30 +08001169VKAPI_ATTR VkResult VKAPI_CALL
1170EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001171 VkResult result = VK_SUCCESS;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001172 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Ian Elliott32311832016-02-04 08:17:18 -07001173
1174 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001175 result = my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Ian Elliott32311832016-02-04 08:17:18 -07001176
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001177 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001178 SwpInstance *pInstance = NULL;
1179 {
1180 auto it = my_data->instanceMap.find(instance);
1181 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
1182 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001183 if ((result == VK_SUCCESS) && pInstance && pPhysicalDevices && (*pPhysicalDeviceCount > 0)) {
Ian Elliott32311832016-02-04 08:17:18 -07001184 // Record the VkPhysicalDevices returned by the ICD:
1185 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001186 my_data->physicalDeviceMap[pPhysicalDevices[i]].physicalDevice = pPhysicalDevices[i];
Ian Elliott32311832016-02-04 08:17:18 -07001187 my_data->physicalDeviceMap[pPhysicalDevices[i]].pInstance = pInstance;
1188 my_data->physicalDeviceMap[pPhysicalDevices[i]].pDevice = NULL;
1189 my_data->physicalDeviceMap[pPhysicalDevices[i]].gotQueueFamilyPropertyCount = false;
1190 my_data->physicalDeviceMap[pPhysicalDevices[i]].gotSurfaceCapabilities = false;
1191 my_data->physicalDeviceMap[pPhysicalDevices[i]].surfaceFormatCount = 0;
1192 my_data->physicalDeviceMap[pPhysicalDevices[i]].pSurfaceFormats = NULL;
1193 my_data->physicalDeviceMap[pPhysicalDevices[i]].presentModeCount = 0;
1194 my_data->physicalDeviceMap[pPhysicalDevices[i]].pPresentModes = NULL;
1195 // Point to the associated SwpInstance:
1196 if (pInstance) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001197 pInstance->physicalDevices[pPhysicalDevices[i]] = &my_data->physicalDeviceMap[pPhysicalDevices[i]];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001198 }
1199 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001200 }
Ian Elliotta3c69bc2016-02-04 15:34:59 -07001201 return result;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001202}
1203
Chia-I Wufccbfe42016-04-28 14:01:30 +08001204VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice,
1205 const VkDeviceCreateInfo *pCreateInfo,
1206 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Chia-I Wua6737532016-04-28 16:04:15 +08001207 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001208 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
1209
1210 assert(chain_info->u.pLayerInfo);
1211 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1212 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Chia-I Wua6737532016-04-28 16:04:15 +08001213 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001214 if (fpCreateDevice == NULL) {
1215 return VK_ERROR_INITIALIZATION_FAILED;
1216 }
1217
1218 // Advance the link info for the next element on the chain
1219 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
1220
1221 VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
1222 if (result != VK_SUCCESS) {
1223 return result;
1224 }
1225
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001226 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001227 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
1228
1229 // Setup device dispatch table
1230 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
1231 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
1232
1233 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Mark Youngaa1aa3a2016-07-05 16:41:50 -06001234 checkDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001235
1236 return result;
1237}
1238
Chia-I Wufccbfe42016-04-28 14:01:30 +08001239VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001240 dispatch_key key = get_dispatch_key(device);
1241 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Ian Elliott32311832016-02-04 08:17:18 -07001242
1243 // Call down the call chain:
1244 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
1245
1246 // Do some internal cleanup:
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001247 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001248 SwpDevice *pDevice = NULL;
1249 {
1250 auto it = my_data->deviceMap.find(device);
1251 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1252 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001253 if (pDevice) {
1254 // Delete the SwpDevice associated with this device:
1255 if (pDevice->pPhysicalDevice) {
1256 pDevice->pPhysicalDevice->pDevice = NULL;
1257 }
1258 if (!pDevice->swapchains.empty()) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001259 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device,
1260 __LINE__, SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, swapchain_layer_name,
1261 "vkDestroyDevice() called before all of its associated VkSwapchainKHRs were destroyed.");
1262
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001263 // Empty and then delete all SwpSwapchain's
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001264 for (auto it = pDevice->swapchains.begin(); it != pDevice->swapchains.end(); it++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001265 // Delete all SwpImage's
1266 it->second->images.clear();
1267 // In case the swapchain's surface hasn't been destroyed yet
1268 // (which is likely) delete its association with this swapchain
1269 // (i.e. so we can't point to this swpchain from that surface,
1270 // later on):
1271 if (it->second->pSurface) {
1272 it->second->pSurface->swapchains.clear();
1273 }
1274 }
1275 pDevice->swapchains.clear();
1276 }
1277 my_data->deviceMap.erase(device);
1278 }
1279 delete my_data->device_dispatch_table;
1280 layer_data_map.erase(key);
1281}
1282
Chia-I Wufccbfe42016-04-28 14:01:30 +08001283VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
1284 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
1285 VkBool32 *pSupported) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001286 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001287 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001288 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001289 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001290 SwpPhysicalDevice *pPhysicalDevice = NULL;
1291 {
1292 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1293 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1294 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001295
1296 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001297 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001298 skipCall |= log_msg(
1299 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1300 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1301 "vkGetPhysicalDeviceSurfaceSupportKHR() called even though the %s extension was not enabled for this VkInstance.",
1302 VK_KHR_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001303 }
1304 if (!pPhysicalDevice->gotQueueFamilyPropertyCount) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001305 skipCall |= log_msg(
1306 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1307 (uint64_t)pPhysicalDevice->physicalDevice, __LINE__, SWAPCHAIN_DID_NOT_QUERY_QUEUE_FAMILIES, swapchain_layer_name,
1308 "vkGetPhysicalDeviceSurfaceSupportKHR() called before calling the vkGetPhysicalDeviceQueueFamilyProperties function.");
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001309 } else if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
1310 skipCall |=
1311 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
1312 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001313 }
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001314
Ian Elliott970a2bd2016-06-21 11:08:43 -06001315 lock.unlock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001316
Dustin Graves080069b2016-04-05 13:48:15 -06001317 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001318 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001319 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface,
1320 pSupported);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001321 lock.lock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001322
Ian Elliott32311832016-02-04 08:17:18 -07001323 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001324 {
1325 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1326 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1327 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001328 if ((result == VK_SUCCESS) && pSupported && pPhysicalDevice) {
1329 // Record the result of this query:
1330 SwpInstance *pInstance = pPhysicalDevice->pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001331 SwpSurface *pSurface = (pInstance) ? pInstance->surfaces[surface] : NULL;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001332 if (pSurface) {
1333 pPhysicalDevice->supportedSurfaces[surface] = pSurface;
1334 if (!pSurface->numQueueFamilyIndexSupport) {
1335 if (pPhysicalDevice->gotQueueFamilyPropertyCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001336 pSurface->pQueueFamilyIndexSupport =
1337 (VkBool32 *)malloc(pPhysicalDevice->numOfQueueFamilies * sizeof(VkBool32));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001338 if (pSurface->pQueueFamilyIndexSupport != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001339 pSurface->numQueueFamilyIndexSupport = pPhysicalDevice->numOfQueueFamilies;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001340 }
1341 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001342 }
1343 if (pSurface->numQueueFamilyIndexSupport) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001344 pSurface->pQueueFamilyIndexSupport[queueFamilyIndex] = *pSupported;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001345 }
1346 }
1347 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001348 lock.unlock();
1349
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001350 return result;
1351 }
1352 return VK_ERROR_VALIDATION_FAILED_EXT;
1353}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001354
Chia-I Wufccbfe42016-04-28 14:01:30 +08001355VKAPI_ATTR VkResult VKAPI_CALL
1356GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
1357 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001358 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001359 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001360 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001361 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001362 SwpPhysicalDevice *pPhysicalDevice = NULL;
1363 {
1364 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1365 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1366 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001367
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001368 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001369 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001370 skipCall |= log_msg(
1371 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1372 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1373 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR() called even though the %s extension was not enabled for this VkInstance.",
1374 VK_KHR_DISPLAY_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001375 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001376 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001377
Dustin Graves080069b2016-04-05 13:48:15 -06001378 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001379 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001380 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface,
1381 pSurfaceCapabilities);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001382 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001383
Ian Elliott32311832016-02-04 08:17:18 -07001384 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001385 {
1386 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1387 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1388 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001389 if ((result == VK_SUCCESS) && pPhysicalDevice) {
1390 // Record the result of this query:
1391 pPhysicalDevice->gotSurfaceCapabilities = true;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001392 // FIXME: NEED TO COPY THIS DATA, BECAUSE pSurfaceCapabilities POINTS TO APP-ALLOCATED DATA
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001393 pPhysicalDevice->surfaceCapabilities = *pSurfaceCapabilities;
1394 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001395 lock.unlock();
1396
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001397 return result;
1398 }
1399 return VK_ERROR_VALIDATION_FAILED_EXT;
1400}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001401
Chia-I Wufccbfe42016-04-28 14:01:30 +08001402VKAPI_ATTR VkResult VKAPI_CALL
1403GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount,
1404 VkSurfaceFormatKHR *pSurfaceFormats) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001405 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001406 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001407 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001408 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001409 SwpPhysicalDevice *pPhysicalDevice = NULL;
1410 {
1411 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1412 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1413 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001414
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001415 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001416 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001417 skipCall |= log_msg(
1418 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1419 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1420 "vkGetPhysicalDeviceSurfaceFormatsKHR() called even though the %s extension was not enabled for this VkInstance.",
1421 VK_KHR_DISPLAY_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001422 }
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001423 if (pPhysicalDevice && pSurfaceFormats) {
1424 // Compare the preliminary value of *pSurfaceFormatCount with the value this time:
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001425 if (pPhysicalDevice->surfaceFormatCount == 0) {
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001426 // Since we haven't recorded a preliminary value of *pSurfaceFormatCount, that likely means that the application didn't
1427 // previously call this function with a NULL value of pSurfaceFormats:
Mark Lobodzinskica708d92016-08-08 10:29:34 -06001428 skipCall |=
1429 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1430 (uint64_t)pPhysicalDevice->physicalDevice, __LINE__, SWAPCHAIN_PRIOR_COUNT, swapchain_layer_name,
1431 "vkGetPhysicalDeviceSurfaceFormatsKHR() called with non-NULL pSurfaceFormatCount; but no prior positive "
1432 "value has been seen for pSurfaceFormats.");
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001433 } else if (*pSurfaceFormatCount > pPhysicalDevice->surfaceFormatCount) {
Mark Lobodzinski2511de12016-08-08 10:18:49 -06001434 skipCall |= log_msg(
1435 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1436 (uint64_t)pPhysicalDevice->physicalDevice, __LINE__, SWAPCHAIN_INVALID_COUNT, swapchain_layer_name,
1437 "vkGetPhysicalDeviceSurfaceFormatsKHR() called with non-NULL pSurfaceFormatCount, and with pSurfaceFormats set to "
1438 "a value (%d) that is greater than the value (%d) that was returned when pSurfaceFormatCount was NULL.",
1439 *pSurfaceFormatCount, pPhysicalDevice->surfaceFormatCount);
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001440 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001441 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001442 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001443
Dustin Graves080069b2016-04-05 13:48:15 -06001444 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001445 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001446 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount,
1447 pSurfaceFormats);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001448 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001449
Ian Elliott32311832016-02-04 08:17:18 -07001450 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001451 {
1452 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1453 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1454 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001455 if ((result == VK_SUCCESS) && pPhysicalDevice && !pSurfaceFormats && pSurfaceFormatCount) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001456 // Record the result of this preliminary query:
1457 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001458 } else if ((result == VK_SUCCESS) && pPhysicalDevice &&
1459 pSurfaceFormats && pSurfaceFormatCount &&
1460 (*pSurfaceFormatCount > 0)) {
1461 // Record the result of this query:
1462 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
1463 pPhysicalDevice->pSurfaceFormats = (VkSurfaceFormatKHR *)malloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
1464 if (pPhysicalDevice->pSurfaceFormats) {
1465 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
1466 pPhysicalDevice->pSurfaceFormats[i] = pSurfaceFormats[i];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001467 }
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001468 } else {
1469 pPhysicalDevice->surfaceFormatCount = 0;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001470 }
1471 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001472 lock.unlock();
1473
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001474 return result;
1475 }
1476 return VK_ERROR_VALIDATION_FAILED_EXT;
1477}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001478
Chia-I Wufccbfe42016-04-28 14:01:30 +08001479VKAPI_ATTR VkResult VKAPI_CALL
1480GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount,
1481 VkPresentModeKHR *pPresentModes) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001482 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001483 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001484 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001485 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001486 SwpPhysicalDevice *pPhysicalDevice = NULL;
1487 {
1488 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1489 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1490 }
Ian Elliott07adb112016-01-05 12:51:03 -07001491
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001492 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001493 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001494 skipCall |= log_msg(
1495 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1496 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1497 "vkGetPhysicalDeviceSurfacePresentModesKHR() called even though the %s extension was not enabled for this VkInstance.",
1498 VK_KHR_DISPLAY_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001499 }
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001500 if (pPhysicalDevice && pPresentModes) {
1501 // Compare the preliminary value of *pPresentModeCount with the value this time:
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001502 if (pPhysicalDevice->presentModeCount == 0) {
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001503 // Since we haven't recorded a preliminary value of *pPresentModeCount, that likely means that the application didn't
1504 // previously call this function with a NULL value of pPresentModes:
Mark Lobodzinskica708d92016-08-08 10:29:34 -06001505 skipCall |=
1506 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1507 (uint64_t)pPhysicalDevice->physicalDevice, __LINE__, SWAPCHAIN_PRIOR_COUNT, swapchain_layer_name,
1508 "vkGetPhysicalDeviceSurfacePresentModesKHR() called with non-NULL pPresentModeCount; but no prior positive "
1509 "value has been seen for pPresentModes.");
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001510 } else if (*pPresentModeCount > pPhysicalDevice->presentModeCount) {
Mark Lobodzinski2511de12016-08-08 10:18:49 -06001511 skipCall |= log_msg(
1512 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1513 (uint64_t)pPhysicalDevice->physicalDevice, __LINE__, SWAPCHAIN_INVALID_COUNT, swapchain_layer_name,
1514 "vkGetPhysicalDeviceSurfacePresentModesKHR() called with non-NULL pPresentModeCount, and with pPresentModes set to "
1515 "a value (%d) that is greater than the value (%d) that was returned when pPresentModeCount was NULL.",
1516 *pPresentModeCount, pPhysicalDevice->presentModeCount);
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001517 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001518 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001519 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06001520
Dustin Graves080069b2016-04-05 13:48:15 -06001521 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001522 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001523 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface,
1524 pPresentModeCount, pPresentModes);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001525 lock.lock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001526
Ian Elliott32311832016-02-04 08:17:18 -07001527 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001528 {
1529 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1530 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1531 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001532 if ((result == VK_SUCCESS) && pPhysicalDevice && !pPresentModes && pPresentModeCount) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001533 // Record the result of this preliminary query:
1534 pPhysicalDevice->presentModeCount = *pPresentModeCount;
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001535 } else if ((result == VK_SUCCESS) && pPhysicalDevice &&
1536 pPresentModes && pPresentModeCount &&
1537 (*pPresentModeCount > 0)) {
1538 // Record the result of this query:
1539 pPhysicalDevice->presentModeCount = *pPresentModeCount;
1540 pPhysicalDevice->pPresentModes = (VkPresentModeKHR *)malloc(*pPresentModeCount * sizeof(VkPresentModeKHR));
1541 if (pPhysicalDevice->pPresentModes) {
1542 for (uint32_t i = 0; i < *pPresentModeCount; i++) {
1543 pPhysicalDevice->pPresentModes[i] = pPresentModes[i];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001544 }
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001545 } else {
1546 pPhysicalDevice->presentModeCount = 0;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001547 }
1548 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001549 lock.unlock();
1550
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001551 return result;
1552 }
1553 return VK_ERROR_VALIDATION_FAILED_EXT;
1554}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001555
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001556// This function does the up-front validation work for vkCreateSwapchainKHR(),
Dustin Graves080069b2016-04-05 13:48:15 -06001557// and returns true if a logging callback indicates that the call down the
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001558// chain should be skipped:
Dustin Graves080069b2016-04-05 13:48:15 -06001559static bool validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, VkSwapchainKHR *pSwapchain) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001560 // TODO: Validate cases of re-creating a swapchain (the current code
1561 // assumes a new swapchain is being created).
Dustin Graves080069b2016-04-05 13:48:15 -06001562 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001563 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1564 char fn[] = "vkCreateSwapchainKHR";
Ian Elliott77f46ca2016-05-05 14:10:49 -06001565 SwpDevice *pDevice = NULL;
1566 {
1567 auto it = my_data->deviceMap.find(device);
1568 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1569 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001570
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001571 // Validate that the swapchain extension was enabled:
1572 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001573 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1574 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1575 "vkCreateSwapchainKHR() called even though the %s extension was not enabled for this VkDevice.",
1576 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001577 }
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001578
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001579 if (pCreateInfo->pNext != NULL) {
1580 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001581 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001582
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001583 // Keep around a useful pointer to pPhysicalDevice:
1584 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001585
Mark Lobodzinskid40b2db2016-02-25 13:56:57 -07001586 // Validate pCreateInfo values with result of
1587 // vkGetPhysicalDeviceQueueFamilyProperties
1588 if (pPhysicalDevice && pPhysicalDevice->gotQueueFamilyPropertyCount) {
Michael Mc Donnell75ecdb72016-04-03 14:47:51 -07001589 for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001590 if (pCreateInfo->pQueueFamilyIndices[i] >= pPhysicalDevice->numOfQueueFamilies) {
1591 skipCall |= LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
1592 "VkPhysicalDevice", pCreateInfo->pQueueFamilyIndices[i],
1593 pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinskid40b2db2016-02-25 13:56:57 -07001594 }
1595 }
1596 }
1597
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001598 // Validate pCreateInfo values with the results of
1599 // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
1600 if (!pPhysicalDevice || !pPhysicalDevice->gotSurfaceCapabilities) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001601 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1602 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, swapchain_layer_name,
1603 "vkCreateSwapchainKHR() called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001604 } else if (pCreateInfo) {
1605 // Validate pCreateInfo->surface to make sure that
1606 // vkGetPhysicalDeviceSurfaceSupportKHR() reported this as a supported
1607 // surface:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001608 SwpSurface *pSurface = ((pPhysicalDevice) ? pPhysicalDevice->supportedSurfaces[pCreateInfo->surface] : NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001609 if (!pSurface) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001610 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1611 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_UNSUPPORTED_SURFACE, swapchain_layer_name,
1612 "The surface in pCreateInfo->surface, that was given to vkCreateSwapchainKHR(), must be a surface "
1613 "that is supported by the device as determined by vkGetPhysicalDeviceSurfaceSupportKHR(). "
1614 "However, vkGetPhysicalDeviceSurfaceSupportKHR() was never called with this surface.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001615 }
Ian Elliott4f147fc2016-01-20 08:52:08 -07001616
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001617 // Validate pCreateInfo->minImageCount against
1618 // VkSurfaceCapabilitiesKHR::{min|max}ImageCount:
1619 VkSurfaceCapabilitiesKHR *pCapabilities = &pPhysicalDevice->surfaceCapabilities;
1620 if ((pCreateInfo->minImageCount < pCapabilities->minImageCount) ||
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001621 ((pCapabilities->maxImageCount > 0) && (pCreateInfo->minImageCount > pCapabilities->maxImageCount))) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001622 skipCall |=
1623 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1624 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT, swapchain_layer_name,
1625 "vkCreateSwapchainKHR() called with pCreateInfo->minImageCount = %d, which is outside the bounds returned "
1626 "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. minImageCount = %d, maxImageCount = %d).",
1627 pCreateInfo->minImageCount, pCapabilities->minImageCount, pCapabilities->maxImageCount);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001628 }
1629 // Validate pCreateInfo->imageExtent against
1630 // VkSurfaceCapabilitiesKHR::{current|min|max}ImageExtent:
1631 if ((pCapabilities->currentExtent.width == -1) &&
1632 ((pCreateInfo->imageExtent.width < pCapabilities->minImageExtent.width) ||
1633 (pCreateInfo->imageExtent.width > pCapabilities->maxImageExtent.width) ||
1634 (pCreateInfo->imageExtent.height < pCapabilities->minImageExtent.height) ||
1635 (pCreateInfo->imageExtent.height > pCapabilities->maxImageExtent.height))) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001636 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1637 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS, swapchain_layer_name,
1638 "vkCreateSwapchainKHR() called with pCreateInfo->imageExtent = (%d,%d), which is outside the "
1639 "bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (%d,%d), "
1640 "minImageExtent = (%d,%d), maxImageExtent = (%d,%d).",
1641 pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, pCapabilities->currentExtent.width,
1642 pCapabilities->currentExtent.height, pCapabilities->minImageExtent.width,
1643 pCapabilities->minImageExtent.height, pCapabilities->maxImageExtent.width,
1644 pCapabilities->maxImageExtent.height);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001645 }
1646 if ((pCapabilities->currentExtent.width != -1) &&
1647 ((pCreateInfo->imageExtent.width != pCapabilities->currentExtent.width) ||
1648 (pCreateInfo->imageExtent.height != pCapabilities->currentExtent.height))) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001649 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1650 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN, swapchain_layer_name,
1651 "vkCreateSwapchainKHR() called with pCreateInfo->imageExtent = (%d,%d), which is not equal to the "
1652 "currentExtent = (%d,%d) returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR().",
1653 pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, pCapabilities->currentExtent.width,
1654 pCapabilities->currentExtent.height);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001655 }
1656 // Validate pCreateInfo->preTransform has one bit set (1st two
1657 // lines of if-statement), which bit is also set in
1658 // VkSurfaceCapabilitiesKHR::supportedTransforms (3rd line of if-statement):
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001659 if (!pCreateInfo->preTransform || (pCreateInfo->preTransform & (pCreateInfo->preTransform - 1)) ||
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001660 !(pCreateInfo->preTransform & pCapabilities->supportedTransforms)) {
1661 // This is an error situation; one for which we'd like to give
1662 // the developer a helpful, multi-line error message. Build it
1663 // up a little at a time, and then log it:
1664 std::string errorString = "";
1665 char str[1024];
1666 // Here's the first part of the message:
1667 sprintf(str, "%s() called with a non-supported "
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001668 "pCreateInfo->preTransform (i.e. %s). "
1669 "Supported values are:\n",
1670 fn, surfaceTransformStr(pCreateInfo->preTransform));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001671 errorString += str;
1672 for (int i = 0; i < 32; i++) {
1673 // Build up the rest of the message:
1674 if ((1 << i) & pCapabilities->supportedTransforms) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001675 const char *newStr = surfaceTransformStr((VkSurfaceTransformFlagBitsKHR)(1 << i));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001676 sprintf(str, " %s\n", newStr);
1677 errorString += str;
1678 }
1679 }
1680 // Log the message that we've built up:
Mark Lobodzinskia4cbbcd2016-05-24 15:44:50 -06001681 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1682 reinterpret_cast<uint64_t &>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM, LAYER_NAME,
1683 "%s", errorString.c_str());
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001684 }
1685 // Validate pCreateInfo->compositeAlpha has one bit set (1st two
1686 // lines of if-statement), which bit is also set in
1687 // VkSurfaceCapabilitiesKHR::supportedCompositeAlpha (3rd line of if-statement):
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001688 if (!pCreateInfo->compositeAlpha || (pCreateInfo->compositeAlpha & (pCreateInfo->compositeAlpha - 1)) ||
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001689 !((pCreateInfo->compositeAlpha) & pCapabilities->supportedCompositeAlpha)) {
1690 // This is an error situation; one for which we'd like to give
1691 // the developer a helpful, multi-line error message. Build it
1692 // up a little at a time, and then log it:
1693 std::string errorString = "";
1694 char str[1024];
1695 // Here's the first part of the message:
1696 sprintf(str, "%s() called with a non-supported "
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001697 "pCreateInfo->compositeAlpha (i.e. %s). "
1698 "Supported values are:\n",
1699 fn, surfaceCompositeAlphaStr(pCreateInfo->compositeAlpha));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001700 errorString += str;
1701 for (int i = 0; i < 32; i++) {
1702 // Build up the rest of the message:
1703 if ((1 << i) & pCapabilities->supportedCompositeAlpha) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001704 const char *newStr = surfaceCompositeAlphaStr((VkCompositeAlphaFlagBitsKHR)(1 << i));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001705 sprintf(str, " %s\n", newStr);
1706 errorString += str;
1707 }
1708 }
1709 // Log the message that we've built up:
Mark Lobodzinskia4cbbcd2016-05-24 15:44:50 -06001710 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1711 reinterpret_cast<uint64_t &>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA,
1712 LAYER_NAME, "%s", errorString.c_str());
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001713 }
David McFarlande22cfb02016-05-20 18:26:28 -03001714 // Validate pCreateInfo->imageArrayLayers against
1715 // VkSurfaceCapabilitiesKHR::maxImageArrayLayers:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001716 if ((pCreateInfo->imageArrayLayers < 1) || (pCreateInfo->imageArrayLayers > pCapabilities->maxImageArrayLayers)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001717 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1718 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_LAYERS, swapchain_layer_name,
1719 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageArrayLayers (i.e. %d). "
1720 "Minimum value is 1, maximum value is %d.",
1721 pCreateInfo->imageArrayLayers, pCapabilities->maxImageArrayLayers);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001722 }
1723 // Validate pCreateInfo->imageUsage against
1724 // VkSurfaceCapabilitiesKHR::supportedUsageFlags:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001725 if (pCreateInfo->imageUsage != (pCreateInfo->imageUsage & pCapabilities->supportedUsageFlags)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001726 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1727 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS, swapchain_layer_name,
1728 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageUsage (i.e. 0x%08x). "
1729 "Supported flag bits are 0x%08x.",
1730 pCreateInfo->imageUsage, pCapabilities->supportedUsageFlags);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001731 }
1732 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001733
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001734 // Validate pCreateInfo values with the results of
1735 // vkGetPhysicalDeviceSurfaceFormatsKHR():
1736 if (!pPhysicalDevice || !pPhysicalDevice->surfaceFormatCount) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001737 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1738 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, swapchain_layer_name,
1739 "vkCreateSwapchainKHR() called before calling vkGetPhysicalDeviceSurfaceFormatsKHR().");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001740 } else if (pCreateInfo) {
1741 // Validate pCreateInfo->imageFormat against
1742 // VkSurfaceFormatKHR::format:
1743 bool foundFormat = false;
1744 bool foundColorSpace = false;
1745 bool foundMatch = false;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001746 for (uint32_t i = 0; i < pPhysicalDevice->surfaceFormatCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001747 if (pCreateInfo->imageFormat == pPhysicalDevice->pSurfaceFormats[i].format) {
1748 // Validate pCreateInfo->imageColorSpace against
1749 // VkSurfaceFormatKHR::colorSpace:
1750 foundFormat = true;
1751 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
1752 foundMatch = true;
1753 break;
1754 }
1755 } else {
1756 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
1757 foundColorSpace = true;
1758 }
1759 }
1760 }
1761 if (!foundMatch) {
1762 if (!foundFormat) {
1763 if (!foundColorSpace) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001764 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1765 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP, swapchain_layer_name,
1766 "vkCreateSwapchainKHR() called with neither a supported pCreateInfo->imageFormat "
1767 "(i.e. %d) nor a supported "
1768 "pCreateInfo->imageColorSpace (i.e. %d).",
1769 pCreateInfo->imageFormat, pCreateInfo->imageColorSpace);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001770 } else {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001771 skipCall |=
1772 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1773 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT, swapchain_layer_name,
1774 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageFormat (i.e. %d)",
1775 pCreateInfo->imageFormat);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001776 }
1777 } else if (!foundColorSpace) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001778 skipCall |=
1779 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1780 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE, swapchain_layer_name,
1781 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageColorSpace (i.e. %d).",
1782 pCreateInfo->imageColorSpace);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001783 }
1784 }
1785 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001786
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001787 // Validate pCreateInfo values with the results of
1788 // vkGetPhysicalDeviceSurfacePresentModesKHR():
1789 if (!pPhysicalDevice || !pPhysicalDevice->presentModeCount) {
szdarkhackfb287d32016-03-12 18:41:19 +02001790 if (!pCreateInfo || (pCreateInfo->presentMode != VK_PRESENT_MODE_FIFO_KHR)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001791 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1792 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, swapchain_layer_name,
1793 "vkCreateSwapchainKHR() called before calling "
1794 "vkGetPhysicalDeviceSurfacePresentModesKHR().");
szdarkhackfb287d32016-03-12 18:41:19 +02001795 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001796 } else if (pCreateInfo) {
1797 // Validate pCreateInfo->presentMode against
1798 // vkGetPhysicalDeviceSurfacePresentModesKHR():
1799 bool foundMatch = false;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001800 for (uint32_t i = 0; i < pPhysicalDevice->presentModeCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001801 if (pPhysicalDevice->pPresentModes[i] == pCreateInfo->presentMode) {
1802 foundMatch = true;
1803 break;
1804 }
1805 }
1806 if (!foundMatch) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001807 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1808 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE, swapchain_layer_name,
1809 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->presentMode (i.e. %s).",
1810 presentModeStr(pCreateInfo->presentMode));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001811 }
1812 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001813
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001814 // Validate pCreateInfo->imageSharingMode and related values:
1815 if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001816 if ((pCreateInfo->queueFamilyIndexCount <= 1) || !pCreateInfo->pQueueFamilyIndices) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001817 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1818 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_SHARING_VALUES, swapchain_layer_name,
1819 "vkCreateSwapchainKHR() called with a supported pCreateInfo->sharingMode of (i.e. %s), but with a "
1820 "bad value(s) for pCreateInfo->queueFamilyIndexCount or pCreateInfo->pQueueFamilyIndices).",
1821 sharingModeStr(pCreateInfo->imageSharingMode));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001822 }
1823 } else if (pCreateInfo->imageSharingMode != VK_SHARING_MODE_EXCLUSIVE) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001824 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1825 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_SHARING_MODE, swapchain_layer_name,
1826 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageSharingMode (i.e. %s).",
1827 sharingModeStr(pCreateInfo->imageSharingMode));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001828 }
Ian Elliotta2a89c52015-12-28 15:23:57 -07001829
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001830 // Validate pCreateInfo->clipped:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001831 if (pCreateInfo && (pCreateInfo->clipped != VK_FALSE) && (pCreateInfo->clipped != VK_TRUE)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001832 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1833 (uint64_t)device, __LINE__, SWAPCHAIN_BAD_BOOL, swapchain_layer_name,
1834 "vkCreateSwapchainKHR() called with a VkBool32 value that is neither VK_TRUE nor VK_FALSE, but "
1835 "has the numeric value of %d.",
1836 pCreateInfo->clipped);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001837 }
Ian Elliotta2a89c52015-12-28 15:23:57 -07001838
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001839 // Validate pCreateInfo->oldSwapchain:
1840 if (pCreateInfo && pCreateInfo->oldSwapchain) {
Ian Elliott77f46ca2016-05-05 14:10:49 -06001841 SwpSwapchain *pOldSwapchain = NULL;
1842 {
1843 auto it = my_data->swapchainMap.find(pCreateInfo->oldSwapchain);
1844 pOldSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
1845 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001846 if (pOldSwapchain) {
1847 if (device != pOldSwapchain->pDevice->device) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001848 skipCall |= log_msg(
1849 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device,
1850 __LINE__, SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, swapchain_layer_name,
1851 "vkCreateSwapchainKHR() called with a different VkDevice than the VkSwapchainKHR was created with.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001852 }
1853 if (pCreateInfo->surface != pOldSwapchain->pSurface->surface) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001854 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1855 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE, swapchain_layer_name,
1856 "vkCreateSwapchainKHR() called with pCreateInfo->oldSwapchain pCreateInfo->surface.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001857 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001858 }
1859 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001860
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001861 return skipCall;
1862}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001863
Chia-I Wufccbfe42016-04-28 14:01:30 +08001864VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
1865 const VkAllocationCallbacks *pAllocator,
1866 VkSwapchainKHR *pSwapchain) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001867 VkResult result = VK_SUCCESS;
1868 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001869 std::unique_lock<std::mutex> lock(global_lock);
Dustin Graves080069b2016-04-05 13:48:15 -06001870 bool skipCall = validateCreateSwapchainKHR(device, pCreateInfo, pSwapchain);
Ian Elliott970a2bd2016-06-21 11:08:43 -06001871 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06001872
Dustin Graves080069b2016-04-05 13:48:15 -06001873 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001874 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001875 result = my_data->device_dispatch_table->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001876 lock.lock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06001877
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001878 if (result == VK_SUCCESS) {
1879 // Remember the swapchain's handle, and link it to the device:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001880 SwpDevice *pDevice = NULL;
1881 {
1882 auto it = my_data->deviceMap.find(device);
1883 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1884 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001885
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001886 my_data->swapchainMap[*pSwapchain].swapchain = *pSwapchain;
1887 if (pDevice) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001888 pDevice->swapchains[*pSwapchain] = &my_data->swapchainMap[*pSwapchain];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001889 }
1890 my_data->swapchainMap[*pSwapchain].pDevice = pDevice;
1891 my_data->swapchainMap[*pSwapchain].imageCount = 0;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001892 my_data->swapchainMap[*pSwapchain].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001893 // Store a pointer to the surface
1894 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001895 SwpInstance *pInstance = (pPhysicalDevice) ? pPhysicalDevice->pInstance : NULL;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001896 layer_data *my_instance_data =
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001897 ((pInstance) ? get_my_data_ptr(get_dispatch_key(pInstance->instance), layer_data_map) : NULL);
1898 SwpSurface *pSurface = ((my_data && pCreateInfo) ? &my_instance_data->surfaceMap[pCreateInfo->surface] : NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001899 my_data->swapchainMap[*pSwapchain].pSurface = pSurface;
1900 if (pSurface) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001901 pSurface->swapchains[*pSwapchain] = &my_data->swapchainMap[*pSwapchain];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001902 }
1903 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001904 lock.unlock();
1905
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001906 return result;
1907 }
1908 return VK_ERROR_VALIDATION_FAILED_EXT;
1909}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001910
Chia-I Wufccbfe42016-04-28 14:01:30 +08001911VKAPI_ATTR void VKAPI_CALL
1912DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001913 // TODOs:
1914 //
1915 // - Implement a check for validity language that reads: All uses of
Ian Elliotta5d13a92016-04-07 09:05:45 -06001916 // presentable images acquired from pname:swapchain must: have completed
1917 // execution
Dustin Graves080069b2016-04-05 13:48:15 -06001918 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001919 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001920 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001921 SwpDevice *pDevice = NULL;
1922 {
1923 auto it = my_data->deviceMap.find(device);
1924 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1925 }
Ian Elliott8b9e2562016-01-05 13:00:50 -07001926
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001927 // Validate that the swapchain extension was enabled:
1928 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001929 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1930 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1931 "vkDestroySwapchainKHR() called even though the %s extension was not enabled for this VkDevice.",
1932 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001933 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001934
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001935 // Regardless of skipCall value, do some internal cleanup:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001936 SwpSwapchain *pSwapchain = NULL;
1937 {
1938 auto it = my_data->swapchainMap.find(swapchain);
1939 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
1940 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001941 if (pSwapchain) {
1942 // Delete the SwpSwapchain associated with this swapchain:
1943 if (pSwapchain->pDevice) {
1944 pSwapchain->pDevice->swapchains.erase(swapchain);
1945 if (device != pSwapchain->pDevice->device) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001946 skipCall |=
1947 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1948 (uint64_t)device, __LINE__, SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, swapchain_layer_name,
1949 "vkDestroySwapchainKHR() called with a different VkDevice than the VkSwapchainKHR was created with.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001950 }
1951 }
1952 if (pSwapchain->pSurface) {
1953 pSwapchain->pSurface->swapchains.erase(swapchain);
1954 }
1955 if (pSwapchain->imageCount) {
1956 pSwapchain->images.clear();
1957 }
1958 if ((pAllocator != NULL) != pSwapchain->usedAllocatorToCreate) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001959 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1960 (uint64_t)device, __LINE__, SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, swapchain_layer_name,
1961 "vkDestroySwapchainKHR() called with incompatible pAllocator from when the object was created.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001962 }
1963 my_data->swapchainMap.erase(swapchain);
1964 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001965 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06001966
Dustin Graves080069b2016-04-05 13:48:15 -06001967 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001968 // Call down the call chain:
1969 my_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator);
1970 }
1971}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001972
Chia-I Wufccbfe42016-04-28 14:01:30 +08001973VKAPI_ATTR VkResult VKAPI_CALL
1974GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001975 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001976 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001977 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001978 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001979 SwpDevice *pDevice = NULL;
1980 {
1981 auto it = my_data->deviceMap.find(device);
1982 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1983 }
Ian Elliott8b9e2562016-01-05 13:00:50 -07001984
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001985 // Validate that the swapchain extension was enabled:
1986 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001987 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1988 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1989 "vkGetSwapchainImagesKHR() called even though the %s extension was not enabled for this VkDevice.",
1990 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001991 }
Ian Elliott77f46ca2016-05-05 14:10:49 -06001992 SwpSwapchain *pSwapchain = NULL;
1993 {
1994 auto it = my_data->swapchainMap.find(swapchain);
1995 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
1996 }
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06001997 if (pSwapchain && pSwapchainImages) {
1998 // Compare the preliminary value of *pSwapchainImageCount with the value this time:
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001999 if (pSwapchain->imageCount == 0) {
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06002000 // Since we haven't recorded a preliminary value of *pSwapchainImageCount, that likely means that the application didn't
2001 // previously call this function with a NULL value of pSwapchainImages:
Mark Lobodzinskica708d92016-08-08 10:29:34 -06002002 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2003 (uint64_t)device, __LINE__, SWAPCHAIN_PRIOR_COUNT, swapchain_layer_name,
2004 "vkGetSwapchainImagesKHR() called with non-NULL pSwapchainImageCount; but no prior positive "
2005 "value has been seen for pSwapchainImages.");
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06002006 } else if (*pSwapchainImageCount > pSwapchain->imageCount) {
Mark Lobodzinski2511de12016-08-08 10:18:49 -06002007 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2008 (uint64_t)device, __LINE__, SWAPCHAIN_INVALID_COUNT, swapchain_layer_name,
2009 "vkGetSwapchainImagesKHR() called with non-NULL pSwapchainImageCount, and with "
2010 "pSwapchainImages set to a value (%d) that is greater than the value (%d) that was returned when "
2011 "pSwapchainImageCount was NULL.",
2012 *pSwapchainImageCount, pSwapchain->imageCount);
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06002013 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002014 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002015 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002016
Dustin Graves080069b2016-04-05 13:48:15 -06002017 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002018 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002019 result = my_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002020 lock.lock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002021
Ian Elliott32311832016-02-04 08:17:18 -07002022 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06002023 {
2024 auto it = my_data->swapchainMap.find(swapchain);
2025 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2026 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002027 if ((result == VK_SUCCESS) && pSwapchain && !pSwapchainImages && pSwapchainImageCount) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002028 // Record the result of this preliminary query:
2029 pSwapchain->imageCount = *pSwapchainImageCount;
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06002030 } else if ((result == VK_SUCCESS) && pSwapchain && pSwapchainImages &&
2031 pSwapchainImageCount && (*pSwapchainImageCount > 0)) {
2032 // Record the images and their state:
2033 pSwapchain->imageCount = *pSwapchainImageCount;
2034 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
2035 pSwapchain->images[i].image = pSwapchainImages[i];
2036 pSwapchain->images[i].pSwapchain = pSwapchain;
2037 pSwapchain->images[i].acquiredByApp = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002038 }
2039 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002040 lock.unlock();
2041
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002042 return result;
2043 }
2044 return VK_ERROR_VALIDATION_FAILED_EXT;
2045}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002046
Chia-I Wufccbfe42016-04-28 14:01:30 +08002047VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
2048 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002049 // TODOs:
2050 //
2051 // - Address the timeout. Possibilities include looking at the state of the
2052 // swapchain's images, depending on the timeout value.
2053 // - Implement a check for validity language that reads: If pname:semaphore is
2054 // not sname:VK_NULL_HANDLE it must: be unsignalled
2055 // - Implement a check for validity language that reads: If pname:fence is not
2056 // sname:VK_NULL_HANDLE it must: be unsignalled and mustnot: be associated
2057 // with any other queue command that has not yet completed execution on that
2058 // queue
2059 // - Record/update the state of the swapchain, in case an error occurs
2060 // (e.g. VK_ERROR_OUT_OF_DATE_KHR).
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002061 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06002062 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002063 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002064 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06002065 SwpDevice *pDevice = NULL;
2066 {
2067 auto it = my_data->deviceMap.find(device);
2068 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
2069 }
Ian Elliott8b9e2562016-01-05 13:00:50 -07002070
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002071 // Validate that the swapchain extension was enabled:
2072 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002073 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2074 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
2075 "vkAcquireNextImageKHR() called even though the %s extension was not enabled for this VkDevice.",
2076 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002077 }
Ian Elliottfa8f0322016-03-23 08:28:54 -06002078 if ((semaphore == VK_NULL_HANDLE) && (fence == VK_NULL_HANDLE)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002079 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2080 (uint64_t)device, __LINE__, SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, swapchain_layer_name,
2081 "vkAcquireNextImageKHR() called with both the semaphore and fence parameters set to VK_NULL_HANDLE (at "
2082 "least one should be used).");
Ian Elliottfa8f0322016-03-23 08:28:54 -06002083 }
Ian Elliott77f46ca2016-05-05 14:10:49 -06002084 SwpSwapchain *pSwapchain = NULL;
2085 {
2086 auto it = my_data->swapchainMap.find(swapchain);
2087 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2088 }
Ian Elliott5c680282016-04-06 14:29:56 -06002089 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
2090 if (pSwapchain && pPhysicalDevice && pPhysicalDevice->gotSurfaceCapabilities) {
2091 // Look to see if the application has already acquired the maximum
2092 // number of images, and this will push it past the spec-defined
2093 // limits:
2094 uint32_t minImageCount = pPhysicalDevice->surfaceCapabilities.minImageCount;
2095 uint32_t imagesAcquiredByApp = 0;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002096 for (uint32_t i = 0; i < pSwapchain->imageCount; i++) {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002097 if (pSwapchain->images[i].acquiredByApp) {
Ian Elliott5c680282016-04-06 14:29:56 -06002098 imagesAcquiredByApp++;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002099 }
2100 }
Ian Elliott5c680282016-04-06 14:29:56 -06002101 if (imagesAcquiredByApp > (pSwapchain->imageCount - minImageCount)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002102 skipCall |= log_msg(
2103 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device,
2104 __LINE__, SWAPCHAIN_APP_ACQUIRES_TOO_MANY_IMAGES, swapchain_layer_name,
2105 "vkAcquireNextImageKHR() called when it cannot succeed. The application has acquired %d image(s) that have not yet "
2106 "been presented. The maximum number of images that the application can simultaneously acquire from this swapchain "
2107 "(including this call to vkCreateSwapchainKHR()) is %d. That value is derived by subtracting "
2108 "VkSurfaceCapabilitiesKHR::minImageCount (%d) from the number of images in the swapchain (%d) and adding 1.",
2109 imagesAcquiredByApp, (pSwapchain->imageCount - minImageCount + 1), minImageCount, pSwapchain->imageCount);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002110 }
2111 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002112 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002113
Dustin Graves080069b2016-04-05 13:48:15 -06002114 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002115 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002116 result = my_data->device_dispatch_table->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002117 lock.lock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002118
Ian Elliott32311832016-02-04 08:17:18 -07002119 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06002120 {
2121 auto it = my_data->swapchainMap.find(swapchain);
2122 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2123 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002124 if (((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR)) && pSwapchain) {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002125 // Change the state of the image (now acquired by the application):
2126 pSwapchain->images[*pImageIndex].acquiredByApp = true;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002127 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002128 lock.unlock();
2129
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002130 return result;
2131 }
2132 return VK_ERROR_VALIDATION_FAILED_EXT;
2133}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002134
Chia-I Wufccbfe42016-04-28 14:01:30 +08002135VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002136 // TODOs:
2137 //
2138 // - Implement a check for validity language that reads: Any given element of
2139 // sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal
2140 // of that sname:VkSemaphore that won't be consumed by any other wait on that
2141 // semaphore
2142 // - Record/update the state of the swapchain, in case an error occurs
2143 // (e.g. VK_ERROR_OUT_OF_DATE_KHR).
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002144 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06002145 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002146 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002147
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06002148 if (pPresentInfo->pNext != NULL) {
2149 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo");
2150 }
Mark Lobodzinski0f73c0b2016-08-08 09:57:09 -06002151 // Note: pPresentInfo->pResults is allowed to be NULL
Ian Elliott046ed2c2015-12-30 17:07:17 -07002152
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002153 std::unique_lock<std::mutex> lock(global_lock);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002154 for (uint32_t i = 0; pPresentInfo && (i < pPresentInfo->swapchainCount); i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002155 uint32_t index = pPresentInfo->pImageIndices[i];
Ian Elliott77f46ca2016-05-05 14:10:49 -06002156 SwpSwapchain *pSwapchain = NULL;
2157 {
2158 auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]);
2159 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2160 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002161 if (pSwapchain) {
2162 if (!pSwapchain->pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002163 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2164 (uint64_t)pSwapchain->pDevice->device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
2165 swapchain_layer_name,
2166 "vkQueuePresentKHR() called even though the %s extension was not enabled for this VkDevice.",
2167 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002168 }
2169 if (index >= pSwapchain->imageCount) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002170 skipCall |=
2171 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
2172 (uint64_t)pPresentInfo->pSwapchains[i], __LINE__, SWAPCHAIN_INDEX_TOO_LARGE, swapchain_layer_name,
2173 "vkQueuePresentKHR() called for an index that is too large (i.e. %d). There are only %d images in "
2174 "this VkSwapchainKHR.\n",
2175 index, pSwapchain->imageCount);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002176 } else {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002177 if (!pSwapchain->images[index].acquiredByApp) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002178 skipCall |= log_msg(
2179 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
2180 (uint64_t)pPresentInfo->pSwapchains[i], __LINE__, SWAPCHAIN_INDEX_NOT_IN_USE, swapchain_layer_name,
2181 "vkQueuePresentKHR() returned an index (i.e. %d) for an image that is not acquired by the application.",
2182 index);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002183 }
2184 }
Ian Elliott77f46ca2016-05-05 14:10:49 -06002185 SwpQueue *pQueue = NULL;
2186 {
2187 auto it = my_data->queueMap.find(queue);
2188 pQueue = (it == my_data->queueMap.end()) ? NULL : &it->second;
2189 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002190 SwpSurface *pSurface = pSwapchain->pSurface;
2191 if (pQueue && pSurface && pSurface->numQueueFamilyIndexSupport) {
2192 uint32_t queueFamilyIndex = pQueue->queueFamilyIndex;
2193 // Note: the 1st test is to ensure queueFamilyIndex is in range,
2194 // and the 2nd test is the validation check:
2195 if ((pSurface->numQueueFamilyIndexSupport > queueFamilyIndex) &&
2196 (!pSurface->pQueueFamilyIndexSupport[queueFamilyIndex])) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002197 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2198 VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, (uint64_t)pPresentInfo->pSwapchains[i],
2199 __LINE__, SWAPCHAIN_SURFACE_NOT_SUPPORTED_WITH_QUEUE, swapchain_layer_name,
2200 "vkQueuePresentKHR() called with a swapchain whose surface is not supported for presention "
2201 "on this device with the queueFamilyIndex (i.e. %d) of the given queue.",
2202 queueFamilyIndex);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002203 }
2204 }
2205 }
2206 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002207 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002208
Dustin Graves080069b2016-04-05 13:48:15 -06002209 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002210 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002211 result = my_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002212 lock.lock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002213
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002214 if (pPresentInfo && ((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) {
2215 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002216 int index = pPresentInfo->pImageIndices[i];
Ian Elliott77f46ca2016-05-05 14:10:49 -06002217 SwpSwapchain *pSwapchain = NULL;
2218 {
2219 auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]);
2220 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2221 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002222 if (pSwapchain) {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002223 // Change the state of the image (no longer acquired by the
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002224 // application):
Ian Elliotta5d13a92016-04-07 09:05:45 -06002225 pSwapchain->images[index].acquiredByApp = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002226 }
2227 }
2228 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002229 lock.unlock();
2230
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002231 return result;
2232 }
2233 return VK_ERROR_VALIDATION_FAILED_EXT;
2234}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002235
Chia-I Wufccbfe42016-04-28 14:01:30 +08002236VKAPI_ATTR void VKAPI_CALL
2237GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
Dustin Graves080069b2016-04-05 13:48:15 -06002238 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002239 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliottc4db6952016-01-21 14:29:45 -07002240
Dustin Graves080069b2016-04-05 13:48:15 -06002241 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002242 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002243 my_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
Ian Elliottc4db6952016-01-21 14:29:45 -07002244
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002245 // Remember the queue's handle, and link it to the device:
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002246 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06002247 SwpDevice *pDevice = NULL;
2248 {
2249 auto it = my_data->deviceMap.find(device);
2250 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
2251 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002252 my_data->queueMap[&pQueue].queue = *pQueue;
2253 if (pDevice) {
2254 pDevice->queues[*pQueue] = &my_data->queueMap[*pQueue];
2255 }
2256 my_data->queueMap[&pQueue].pDevice = pDevice;
2257 my_data->queueMap[&pQueue].queueFamilyIndex = queueFamilyIndex;
2258 }
2259}
Ian Elliottc4db6952016-01-21 14:29:45 -07002260
Chia-I Wufccbfe42016-04-28 14:01:30 +08002261VKAPI_ATTR VkResult VKAPI_CALL
2262CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
2263 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002264 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002265 VkResult result =
2266 my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002267 if (VK_SUCCESS == result) {
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002268 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski97c4d512016-05-19 15:27:18 -06002269 result = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002270 }
2271 return result;
2272}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002273
Chia-I Wufccbfe42016-04-28 14:01:30 +08002274VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance,
2275 VkDebugReportCallbackEXT msgCallback,
2276 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002277 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2278 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002279 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002280 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
2281}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002282
Chia-I Wufccbfe42016-04-28 14:01:30 +08002283VKAPI_ATTR void VKAPI_CALL
2284DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
2285 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002286 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002287 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
2288 pMsg);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002289}
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07002290
Chia-I Wub02600c2016-05-20 07:11:22 +08002291VKAPI_ATTR VkResult VKAPI_CALL
2292EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
2293 return util_GetLayerProperties(1, &swapchain_layer, pCount, pProperties);
2294}
2295
2296VKAPI_ATTR VkResult VKAPI_CALL
2297EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
2298 return util_GetLayerProperties(1, &swapchain_layer, pCount, pProperties);
2299}
2300
2301VKAPI_ATTR VkResult VKAPI_CALL
2302EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
2303 if (pLayerName && !strcmp(pLayerName, swapchain_layer.layerName))
2304 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
2305
2306 return VK_ERROR_LAYER_NOT_PRESENT;
2307}
2308
Chia-I Wufccbfe42016-04-28 14:01:30 +08002309VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
2310 const char *pLayerName, uint32_t *pCount,
2311 VkExtensionProperties *pProperties) {
Chia-I Wu2b481252016-04-28 14:21:13 +08002312 if (pLayerName && !strcmp(pLayerName, swapchain_layer.layerName))
Chia-I Wu045209e2016-04-28 11:21:49 +08002313 return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
Chia-I Wu2b481252016-04-28 14:21:13 +08002314
2315 assert(physicalDevice);
2316
2317 dispatch_key key = get_dispatch_key(physicalDevice);
2318 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
2319 return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
Chia-I Wu045209e2016-04-28 11:21:49 +08002320}
2321
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002322static PFN_vkVoidFunction
Chia-I Wu22813c72016-04-28 14:38:57 +08002323intercept_core_instance_command(const char *name);
2324
2325static PFN_vkVoidFunction
2326intercept_khr_surface_command(const char *name, VkInstance instance);
2327
2328static PFN_vkVoidFunction
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002329intercept_core_device_command(const char *name);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07002330
Chia-I Wu83245952016-05-05 16:13:19 +08002331static PFN_vkVoidFunction
2332intercept_khr_swapchain_command(const char *name, VkDevice dev);
2333
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002334VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
2335 PFN_vkVoidFunction proc = intercept_core_device_command(funcName);
2336 if (proc)
2337 return proc;
2338
2339 assert(device);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002340
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002341 layer_data *my_data;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002342
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002343 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter1e9e6c82016-03-19 10:38:52 -06002344 VkLayerDispatchTable *pDisp = my_data->device_dispatch_table;
Chia-I Wu83245952016-05-05 16:13:19 +08002345
2346 proc = intercept_khr_swapchain_command(funcName, device);
2347 if (proc)
2348 return proc;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07002349
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002350 if (pDisp->GetDeviceProcAddr == NULL)
2351 return NULL;
2352 return pDisp->GetDeviceProcAddr(device, funcName);
2353}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002354
Chia-I Wufccbfe42016-04-28 14:01:30 +08002355VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
Chia-I Wu22813c72016-04-28 14:38:57 +08002356 PFN_vkVoidFunction proc = intercept_core_instance_command(funcName);
Chia-I Wu5ae2f652016-04-28 15:16:59 +08002357 if (!proc)
2358 proc = intercept_core_device_command(funcName);
2359 if (!proc)
2360 proc = intercept_khr_swapchain_command(funcName, VK_NULL_HANDLE);
Chia-I Wu22813c72016-04-28 14:38:57 +08002361 if (proc)
2362 return proc;
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -07002363
Chia-I Wu5ae2f652016-04-28 15:16:59 +08002364 assert(instance);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002365
2366 layer_data *my_data;
2367 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002368 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Ian Elliott68124ac2015-10-07 16:18:35 -06002369
Chia-I Wu5ae2f652016-04-28 15:16:59 +08002370 proc = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
2371 if (!proc)
2372 proc = intercept_khr_surface_command(funcName, instance);
Chia-I Wu22813c72016-04-28 14:38:57 +08002373 if (proc)
2374 return proc;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002375
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002376 if (pTable->GetInstanceProcAddr == NULL)
2377 return NULL;
2378 return pTable->GetInstanceProcAddr(instance, funcName);
2379}
Chia-I Wu045209e2016-04-28 11:21:49 +08002380
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002381static PFN_vkVoidFunction
Chia-I Wu22813c72016-04-28 14:38:57 +08002382intercept_core_instance_command(const char *name) {
2383 static const struct {
2384 const char *name;
2385 PFN_vkVoidFunction proc;
2386 } core_instance_commands[] = {
2387 { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) },
2388 { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) },
2389 { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) },
2390 { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) },
2391 { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) },
Chia-I Wub02600c2016-05-20 07:11:22 +08002392 { "vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties) },
2393 { "vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties) },
2394 { "vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties) },
Chia-I Wu22813c72016-04-28 14:38:57 +08002395 { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) },
2396 { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) },
2397 };
2398
2399 for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
2400 if (!strcmp(core_instance_commands[i].name, name))
2401 return core_instance_commands[i].proc;
2402 }
2403
2404 return nullptr;
2405}
2406
2407static PFN_vkVoidFunction
2408intercept_khr_surface_command(const char *name, VkInstance instance) {
2409 static const struct {
2410 const char *name;
2411 PFN_vkVoidFunction proc;
2412 } khr_surface_commands[] = {
2413#ifdef VK_USE_PLATFORM_ANDROID_KHR
2414 { "vkCreateAndroidSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR) },
2415#endif // VK_USE_PLATFORM_ANDROID_KHR
2416#ifdef VK_USE_PLATFORM_MIR_KHR
2417 { "vkCreateMirSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateMirSurfaceKHR) },
2418 { "vkGetPhysicalDeviceMirPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMirPresentationSupportKHR) },
2419#endif // VK_USE_PLATFORM_MIR_KHR
2420#ifdef VK_USE_PLATFORM_WAYLAND_KHR
2421 { "vkCreateWaylandSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWaylandSurfaceKHR) },
2422 { "vkGetPhysicalDeviceWaylandPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWaylandPresentationSupportKHR) },
2423#endif // VK_USE_PLATFORM_WAYLAND_KHR
2424#ifdef VK_USE_PLATFORM_WIN32_KHR
2425 { "vkCreateWin32SurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWin32SurfaceKHR) },
2426 { "vkGetPhysicalDeviceWin32PresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWin32PresentationSupportKHR) },
2427#endif // VK_USE_PLATFORM_WIN32_KHR
2428#ifdef VK_USE_PLATFORM_XCB_KHR
2429 { "vkCreateXcbSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXcbSurfaceKHR) },
2430 { "vkGetPhysicalDeviceXcbPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXcbPresentationSupportKHR) },
2431#endif // VK_USE_PLATFORM_XCB_KHR
2432#ifdef VK_USE_PLATFORM_XLIB_KHR
2433 { "vkCreateXlibSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXlibSurfaceKHR) },
2434 { "vkGetPhysicalDeviceXlibPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXlibPresentationSupportKHR) },
2435#endif // VK_USE_PLATFORM_XLIB_KHR
2436 { "vkDestroySurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR) },
2437 { "vkGetPhysicalDeviceSurfaceSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR) },
2438 { "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR) },
2439 { "vkGetPhysicalDeviceSurfaceFormatsKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR) },
2440 { "vkGetPhysicalDeviceSurfacePresentModesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR) },
Petros Bantolas2b40be72016-04-15 11:02:59 +01002441 { "vkGetPhysicalDeviceDisplayPropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPropertiesKHR) },
2442 { "vkGetPhysicalDeviceDisplayPlanePropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPlanePropertiesKHR) },
2443 { "vkGetDisplayPlaneSupportedDisplaysKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayPlaneSupportedDisplaysKHR) },
2444 { "vkGetDisplayModePropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayModePropertiesKHR) },
2445 { "vkCreateDisplayModeKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateDisplayModeKHR) },
2446 { "vkGetDisplayPlaneCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayPlaneCapabilitiesKHR) },
2447 { "vkCreateDisplayPlaneSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateDisplayPlaneSurfaceKHR) },
Chia-I Wu22813c72016-04-28 14:38:57 +08002448 };
2449
2450 // do not check if VK_KHR_*_surface is enabled (why?)
2451
2452 for (size_t i = 0; i < ARRAY_SIZE(khr_surface_commands); i++) {
2453 if (!strcmp(khr_surface_commands[i].name, name))
2454 return khr_surface_commands[i].proc;
2455 }
2456
2457 return nullptr;
2458}
2459
2460static PFN_vkVoidFunction
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002461intercept_core_device_command(const char *name) {
2462 static const struct {
2463 const char *name;
2464 PFN_vkVoidFunction proc;
2465 } core_device_commands[] = {
2466 { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) },
2467 { "vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice) },
2468 { "vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue) },
2469 };
2470
2471 for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) {
2472 if (!strcmp(core_device_commands[i].name, name))
2473 return core_device_commands[i].proc;
2474 }
2475
2476 return nullptr;
2477}
2478
Chia-I Wu83245952016-05-05 16:13:19 +08002479static PFN_vkVoidFunction
2480intercept_khr_swapchain_command(const char *name, VkDevice dev) {
2481 static const struct {
2482 const char *name;
2483 PFN_vkVoidFunction proc;
2484 } khr_swapchain_commands[] = {
2485 { "vkCreateSwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR) },
2486 { "vkDestroySwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR) },
2487 { "vkGetSwapchainImagesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR) },
2488 { "vkAcquireNextImageKHR", reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR) },
2489 { "vkQueuePresentKHR", reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR) },
2490 };
2491
2492 // do not check if VK_KHR_swapchain is enabled (why?)
2493
2494 for (size_t i = 0; i < ARRAY_SIZE(khr_swapchain_commands); i++) {
2495 if (!strcmp(khr_swapchain_commands[i].name, name))
2496 return khr_swapchain_commands[i].proc;
2497 }
2498
2499 return nullptr;
2500}
2501
Chia-I Wu516b5082016-04-28 11:27:46 +08002502} // namespace swapchain
2503
2504// vk_layer_logging.h expects these to be defined
2505
Chia-I Wufccbfe42016-04-28 14:01:30 +08002506VKAPI_ATTR VkResult VKAPI_CALL
Chia-I Wu516b5082016-04-28 11:27:46 +08002507vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
2508 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002509 return swapchain::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Chia-I Wu516b5082016-04-28 11:27:46 +08002510}
2511
Chia-I Wufccbfe42016-04-28 14:01:30 +08002512VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,
Chia-I Wu516b5082016-04-28 11:27:46 +08002513 VkDebugReportCallbackEXT msgCallback,
2514 const VkAllocationCallbacks *pAllocator) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002515 swapchain::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Chia-I Wu516b5082016-04-28 11:27:46 +08002516}
2517
Chia-I Wufccbfe42016-04-28 14:01:30 +08002518VKAPI_ATTR void VKAPI_CALL
Chia-I Wu516b5082016-04-28 11:27:46 +08002519vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
2520 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002521 swapchain::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
Chia-I Wu516b5082016-04-28 11:27:46 +08002522}
2523
Chia-I Wub02600c2016-05-20 07:11:22 +08002524// loader-layer interface v0, just wrappers since there is only a layer
Chia-I Wu516b5082016-04-28 11:27:46 +08002525
Chia-I Wu045209e2016-04-28 11:21:49 +08002526VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2527vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002528 return swapchain::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
Chia-I Wu045209e2016-04-28 11:21:49 +08002529}
2530
2531VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2532vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002533 return swapchain::EnumerateInstanceLayerProperties(pCount, pProperties);
Chia-I Wu045209e2016-04-28 11:21:49 +08002534}
2535
2536VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2537vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002538 // the layer command handles VK_NULL_HANDLE just fine internally
2539 assert(physicalDevice == VK_NULL_HANDLE);
2540 return swapchain::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
Chia-I Wu516b5082016-04-28 11:27:46 +08002541}
2542
2543VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
2544 const char *pLayerName, uint32_t *pCount,
2545 VkExtensionProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002546 // the layer command handles VK_NULL_HANDLE just fine internally
2547 assert(physicalDevice == VK_NULL_HANDLE);
Chia-I Wu2b481252016-04-28 14:21:13 +08002548 return swapchain::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
Chia-I Wu516b5082016-04-28 11:27:46 +08002549}
2550
2551VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002552 return swapchain::GetDeviceProcAddr(dev, funcName);
Chia-I Wu516b5082016-04-28 11:27:46 +08002553}
2554
2555VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002556 return swapchain::GetInstanceProcAddr(instance, funcName);
Chia-I Wu045209e2016-04-28 11:21:49 +08002557}