blob: 4421c5056a303284165b8f982ddbf2db8f59678a [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 Lobodzinski1ed594e2016-02-03 09:57:14 -0700348 if (!pCreateInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700349 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700350 } else {
351 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700352 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700353 "VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR");
354 }
355 if (pCreateInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700356 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700357 }
358 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600359 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700360
Dustin Graves080069b2016-04-05 13:48:15 -0600361 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700362 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700363 result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600364 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700365
Ian Elliott32311832016-02-04 08:17:18 -0700366 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600367 {
368 auto it = my_data->instanceMap.find(instance);
369 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
370 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700371 if ((result == VK_SUCCESS) && pInstance && pSurface) {
372 // Record the VkSurfaceKHR returned by the ICD:
373 my_data->surfaceMap[*pSurface].surface = *pSurface;
374 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700375 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700376 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
377 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
378 // Point to the associated SwpInstance:
379 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
380 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600381 lock.unlock();
382
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700383 return result;
384 }
385 return VK_ERROR_VALIDATION_FAILED_EXT;
386}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700387#endif // VK_USE_PLATFORM_ANDROID_KHR
388
389#ifdef VK_USE_PLATFORM_MIR_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800390VKAPI_ATTR VkResult VKAPI_CALL
391CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
392 VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700393 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600394 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700395 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600396 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600397 SwpInstance *pInstance = NULL;
398 {
399 auto it = my_data->instanceMap.find(instance);
400 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
401 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700402
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700403 // Validate that the platform extension was enabled:
404 if (pInstance && !pInstance->mirSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600405 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
406 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
407 "vkCreateMirSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
408 VK_KHR_MIR_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700409 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700410
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700411 if (!pCreateInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700412 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700413 } else {
414 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700415 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700416 "VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR");
417 }
418 if (pCreateInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700419 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700420 }
421 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600422 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700423
Dustin Graves080069b2016-04-05 13:48:15 -0600424 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700425 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700426 result = my_data->instance_dispatch_table->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600427 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700428
Ian Elliott32311832016-02-04 08:17:18 -0700429 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600430 {
431 auto it = my_data->instanceMap.find(instance);
432 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
433 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700434 if ((result == VK_SUCCESS) && pInstance && pSurface) {
435 // Record the VkSurfaceKHR returned by the ICD:
436 my_data->surfaceMap[*pSurface].surface = *pSurface;
437 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700438 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700439 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
440 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
441 // Point to the associated SwpInstance:
442 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
443 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600444 lock.unlock();
445
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700446 return result;
447 }
448 return VK_ERROR_VALIDATION_FAILED_EXT;
449}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700450
Chia-I Wufccbfe42016-04-28 14:01:30 +0800451VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice,
452 uint32_t queueFamilyIndex,
453 MirConnection *connection) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700454 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600455 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700456 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600457 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600458 SwpPhysicalDevice *pPhysicalDevice = NULL;
459 {
460 auto it = my_data->physicalDeviceMap.find(physicalDevice);
461 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
462 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700463
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700464 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700465 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->mirSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600466 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
467 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
468 swapchain_layer_name, "vkGetPhysicalDeviceMirPresentationSupportKHR() called even though the %s "
469 "extension was not enabled for this VkInstance.",
470 VK_KHR_MIR_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700471 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700472 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
473 skipCall |=
474 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
475 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700476 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600477 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700478
Dustin Graves080069b2016-04-05 13:48:15 -0600479 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700480 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700481 result = my_data->instance_dispatch_table->GetPhysicalDeviceMirPresentationSupportKHR(physicalDevice, queueFamilyIndex,
482 connection);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700483 }
484 return result;
485}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700486#endif // VK_USE_PLATFORM_MIR_KHR
487
488#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800489VKAPI_ATTR VkResult VKAPI_CALL
490CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
491 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700492 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600493 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700494 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600495 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600496 SwpInstance *pInstance = NULL;
497 {
498 auto it = my_data->instanceMap.find(instance);
499 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
500 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700501
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700502 // Validate that the platform extension was enabled:
503 if (pInstance && !pInstance->waylandSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600504 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
505 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
506 "vkCreateWaylandSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
507 VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700508 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700509
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700510 if (!pCreateInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700511 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700512 } else {
513 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700514 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700515 "VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR");
516 }
517 if (pCreateInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700518 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700519 }
520 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600521 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700522
Dustin Graves080069b2016-04-05 13:48:15 -0600523 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700524 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700525 result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600526 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700527
Ian Elliott32311832016-02-04 08:17:18 -0700528 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600529 {
530 auto it = my_data->instanceMap.find(instance);
531 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
532 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700533 if ((result == VK_SUCCESS) && pInstance && pSurface) {
534 // Record the VkSurfaceKHR returned by the ICD:
535 my_data->surfaceMap[*pSurface].surface = *pSurface;
536 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700537 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700538 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
539 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
540 // Point to the associated SwpInstance:
541 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
542 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600543 lock.unlock();
544
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700545 return result;
546 }
547 return VK_ERROR_VALIDATION_FAILED_EXT;
548}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700549
Chia-I Wufccbfe42016-04-28 14:01:30 +0800550VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
551 uint32_t queueFamilyIndex,
552 struct wl_display *display) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700553 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600554 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700555 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600556 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600557 SwpPhysicalDevice *pPhysicalDevice = NULL;
558 {
559 auto it = my_data->physicalDeviceMap.find(physicalDevice);
560 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
561 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700562
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700563 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700564 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->waylandSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600565 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
566 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
567 swapchain_layer_name, "vkGetPhysicalDeviceWaylandPresentationSupportKHR() called even though the %s "
568 "extension was not enabled for this VkInstance.",
569 VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700570 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700571 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
572 skipCall |=
573 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
574 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700575 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600576 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700577
Dustin Graves080069b2016-04-05 13:48:15 -0600578 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700579 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700580 result = my_data->instance_dispatch_table->GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex,
581 display);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700582 }
583 return result;
584}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700585#endif // VK_USE_PLATFORM_WAYLAND_KHR
586
587#ifdef VK_USE_PLATFORM_WIN32_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800588VKAPI_ATTR VkResult VKAPI_CALL
589CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
590 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700591 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600592 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700593 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600594 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600595 SwpInstance *pInstance = NULL;
596 {
597 auto it = my_data->instanceMap.find(instance);
598 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
599 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700600
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700601 // Validate that the platform extension was enabled:
602 if (pInstance && !pInstance->win32SurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600603 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
604 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
605 "vkCreateWin32SurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
606 VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700607 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700608
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700609 if (!pCreateInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700610 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700611 } else {
612 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700613 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700614 "VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR");
615 }
616 if (pCreateInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700617 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700618 }
619 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600620 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700621
Dustin Graves080069b2016-04-05 13:48:15 -0600622 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700623 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700624 result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600625 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700626
Ian Elliott32311832016-02-04 08:17:18 -0700627 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600628 {
629 auto it = my_data->instanceMap.find(instance);
630 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
631 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700632 if ((result == VK_SUCCESS) && pInstance && pSurface) {
633 // Record the VkSurfaceKHR returned by the ICD:
634 my_data->surfaceMap[*pSurface].surface = *pSurface;
635 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700636 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700637 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
638 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
639 // Point to the associated SwpInstance:
640 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
641 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600642 lock.unlock();
643
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700644 return result;
645 }
646 return VK_ERROR_VALIDATION_FAILED_EXT;
647}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700648
Chia-I Wufccbfe42016-04-28 14:01:30 +0800649VKAPI_ATTR VkBool32 VKAPI_CALL
650GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700651 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600652 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700653 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600654 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600655 SwpPhysicalDevice *pPhysicalDevice = NULL;
656 {
657 auto it = my_data->physicalDeviceMap.find(physicalDevice);
658 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
659 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700660
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700661 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700662 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->win32SurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600663 skipCall |= log_msg(
664 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
665 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
666 "vkGetPhysicalDeviceWin32PresentationSupportKHR() called even though the %s extension was not enabled for this VkInstance.",
667 VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700668 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700669 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
670 skipCall |=
671 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
672 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700673 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600674 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700675
Dustin Graves080069b2016-04-05 13:48:15 -0600676 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700677 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700678 result = my_data->instance_dispatch_table->GetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700679 }
680 return result;
681}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700682#endif // VK_USE_PLATFORM_WIN32_KHR
683
684#ifdef VK_USE_PLATFORM_XCB_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800685VKAPI_ATTR VkResult VKAPI_CALL
686CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700687 VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700688 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600689 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700690 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600691 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600692 SwpInstance *pInstance = NULL;
693 {
694 auto it = my_data->instanceMap.find(instance);
695 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
696 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700697
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700698 // Validate that the platform extension was enabled:
699 if (pInstance && !pInstance->xcbSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600700 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
701 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
702 "vkCreateXcbSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
703 VK_KHR_XCB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700704 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700705
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700706 if (!pCreateInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700707 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700708 } else {
709 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700710 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700711 "VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR");
712 }
713 if (pCreateInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700714 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700715 }
716 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600717 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700718
Dustin Graves080069b2016-04-05 13:48:15 -0600719 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700720 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700721 result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600722 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700723
Ian Elliott32311832016-02-04 08:17:18 -0700724 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600725 {
726 auto it = my_data->instanceMap.find(instance);
727 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
728 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700729 if ((result == VK_SUCCESS) && pInstance && pSurface) {
730 // Record the VkSurfaceKHR returned by the ICD:
731 my_data->surfaceMap[*pSurface].surface = *pSurface;
732 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700733 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700734 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
735 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
736 // Point to the associated SwpInstance:
737 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
738 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600739 lock.unlock();
740
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700741 return result;
742 }
743 return VK_ERROR_VALIDATION_FAILED_EXT;
744}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700745
Chia-I Wufccbfe42016-04-28 14:01:30 +0800746VKAPI_ATTR VkBool32 VKAPI_CALL
747GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
748 xcb_connection_t *connection, xcb_visualid_t visual_id) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700749 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600750 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700751 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600752 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600753 SwpPhysicalDevice *pPhysicalDevice = NULL;
754 {
755 auto it = my_data->physicalDeviceMap.find(physicalDevice);
756 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
757 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700758
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700759 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700760 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->xcbSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600761 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
762 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
763 swapchain_layer_name, "vkGetPhysicalDeviceXcbPresentationSupportKHR() called even though the %s "
764 "extension was not enabled for this VkInstance.",
765 VK_KHR_XCB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700766 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700767 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
768 skipCall |=
769 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
770 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700771 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600772 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700773
Dustin Graves080069b2016-04-05 13:48:15 -0600774 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700775 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700776 result = my_data->instance_dispatch_table->GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex,
777 connection, visual_id);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700778 }
779 return result;
780}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700781#endif // VK_USE_PLATFORM_XCB_KHR
782
783#ifdef VK_USE_PLATFORM_XLIB_KHR
Chia-I Wufccbfe42016-04-28 14:01:30 +0800784VKAPI_ATTR VkResult VKAPI_CALL
785CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
786 VkSurfaceKHR *pSurface) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700787 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -0600788 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700789 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600790 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600791 SwpInstance *pInstance = NULL;
792 {
793 auto it = my_data->instanceMap.find(instance);
794 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
795 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700796
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700797 // Validate that the platform extension was enabled:
798 if (pInstance && !pInstance->xlibSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600799 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
800 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
801 "vkCreateXlibSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
802 VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700803 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700804
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700805 if (!pCreateInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700806 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700807 } else {
808 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700809 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700810 "VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR");
811 }
812 if (pCreateInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700813 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700814 }
815 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600816 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700817
Dustin Graves080069b2016-04-05 13:48:15 -0600818 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700819 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700820 result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600821 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700822
Ian Elliott32311832016-02-04 08:17:18 -0700823 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -0600824 {
825 auto it = my_data->instanceMap.find(instance);
826 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
827 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700828 if ((result == VK_SUCCESS) && pInstance && pSurface) {
829 // Record the VkSurfaceKHR returned by the ICD:
830 my_data->surfaceMap[*pSurface].surface = *pSurface;
831 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700832 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700833 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
834 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
835 // Point to the associated SwpInstance:
836 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
837 }
Ian Elliott970a2bd2016-06-21 11:08:43 -0600838 lock.unlock();
839
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700840 return result;
841 }
842 return VK_ERROR_VALIDATION_FAILED_EXT;
843}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700844
Chia-I Wufccbfe42016-04-28 14:01:30 +0800845VKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
846 uint32_t queueFamilyIndex,
847 Display *dpy, VisualID visualID) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700848 VkBool32 result = VK_FALSE;
Dustin Graves080069b2016-04-05 13:48:15 -0600849 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700850 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600851 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -0600852 SwpPhysicalDevice *pPhysicalDevice = NULL;
853 {
854 auto it = my_data->physicalDeviceMap.find(physicalDevice);
855 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
856 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700857
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700858 // Validate that the platform extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700859 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->xlibSurfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600860 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
861 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
862 swapchain_layer_name, "vkGetPhysicalDeviceXlibPresentationSupportKHR() called even though the %s "
863 "extension was not enabled for this VkInstance.",
864 VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700865 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700866 if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
867 skipCall |=
868 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
869 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700870 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -0600871 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700872
Dustin Graves080069b2016-04-05 13:48:15 -0600873 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700874 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -0700875 result = my_data->instance_dispatch_table->GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex,
876 dpy, visualID);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -0700877 }
878 return result;
879}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700880#endif // VK_USE_PLATFORM_XLIB_KHR
881
Petros Bantolas2b40be72016-04-15 11:02:59 +0100882VKAPI_ATTR VkResult VKAPI_CALL
883GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties) {
884 VkResult result = VK_SUCCESS;
885 bool skipCall = false;
886 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
887 std::unique_lock<std::mutex> lock(global_lock);
888 SwpPhysicalDevice *pPhysicalDevice = NULL;
889 {
890 auto it = my_data->physicalDeviceMap.find(physicalDevice);
891 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
892 }
893
894 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600895 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
896 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
897 swapchain_layer_name, "vkGetPhysicalDeviceDisplayPropertiesKHR() called even though the %s "
898 "extension was not enabled for this VkInstance.",
899 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100900 }
901
902 if (!pPropertyCount) {
903 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pPropertyCount");
904 }
Jon Ashburne699f442016-06-30 09:01:27 -0600905 // TODO add check for the count being consistent
Petros Bantolas2b40be72016-04-15 11:02:59 +0100906 lock.unlock();
907
908 if (!skipCall) {
909 result = my_data->instance_dispatch_table->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, pProperties);
910 return result;
911 }
912 return VK_ERROR_VALIDATION_FAILED_EXT;
913}
914
Petros Bantolas2b40be72016-04-15 11:02:59 +0100915VKAPI_ATTR VkResult VKAPI_CALL
916GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
917 VkResult result = VK_SUCCESS;
918 bool skipCall = false;
919 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
920 std::unique_lock<std::mutex> lock(global_lock);
921 SwpPhysicalDevice *pPhysicalDevice = NULL;
922 {
923 auto it = my_data->physicalDeviceMap.find(physicalDevice);
924 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
925 }
926
927 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600928 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
929 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
930 swapchain_layer_name, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR() called even though the %s "
931 "extension was not enabled for this VkInstance.",
932 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100933 }
934
935 if (!pPropertyCount) {
936 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pPropertyCount");
937 }
Jon Ashburne699f442016-06-30 09:01:27 -0600938 // TODO add check for the count being consistent
Petros Bantolas2b40be72016-04-15 11:02:59 +0100939 lock.unlock();
940
941 if (!skipCall) {
942 result = my_data->instance_dispatch_table->GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties);
943
944 lock.lock();
945 if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
946 {
947 pPhysicalDevice->displayPlanePropertyCount = *pPropertyCount;
948 pPhysicalDevice->gotDisplayPlanePropertyCount = true;
949 }
Jon Ashburne699f442016-06-30 09:01:27 -0600950 // TODO store the properties for later checks
Petros Bantolas2b40be72016-04-15 11:02:59 +0100951 lock.unlock();
952
953 return result;
954 }
955 return VK_ERROR_VALIDATION_FAILED_EXT;
956}
957
958VKAPI_ATTR VkResult VKAPI_CALL
959GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays) {
960 VkResult result = VK_SUCCESS;
961 bool skipCall = false;
962 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
963 std::unique_lock<std::mutex> lock(global_lock);
964 SwpPhysicalDevice *pPhysicalDevice = NULL;
965 {
966 auto it = my_data->physicalDeviceMap.find(physicalDevice);
967 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
968 }
969
970 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600971 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
972 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
973 swapchain_layer_name, "vkGetDisplayPlaneSupportedDisplaysKHR() called even though the %s "
974 "extension was not enabled for this VkInstance.",
975 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100976 }
977
978 if (!pDisplayCount) {
979 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pDisplayCount");
980 }
Jon Ashburne699f442016-06-30 09:01:27 -0600981 // TODO add check for the count being consistent
Petros Bantolas2b40be72016-04-15 11:02:59 +0100982
Jon Ashburn5e026df2016-06-15 08:19:07 -0600983 if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +0100984 {
985 LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
986 SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
987 "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.",
988 __FUNCTION__);
989 }
990
Jon Ashburn1e857902016-07-01 10:08:31 -0600991 if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->displayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +0100992 {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -0600993 skipCall |=
994 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
995 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_PLANE_INDEX_TOO_LARGE, swapchain_layer_name,
996 "vkGetDisplayPlaneSupportedDisplaysKHR(): planeIndex must be in the range [0, %d] that was returned by "
997 "vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
998 pPhysicalDevice->displayPlanePropertyCount - 1);
Petros Bantolas2b40be72016-04-15 11:02:59 +0100999 }
1000 lock.unlock();
1001
1002 if (!skipCall) {
1003 result = my_data->instance_dispatch_table->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
1004
1005 return result;
1006 }
Jon Ashburne699f442016-06-30 09:01:27 -06001007 // TODO validate the returned display objects
Petros Bantolas2b40be72016-04-15 11:02:59 +01001008 return VK_ERROR_VALIDATION_FAILED_EXT;
1009}
1010
1011VKAPI_ATTR VkResult VKAPI_CALL
1012GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties) {
1013 VkResult result = VK_SUCCESS;
1014 bool skipCall = false;
1015 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1016 std::unique_lock<std::mutex> lock(global_lock);
1017 SwpPhysicalDevice *pPhysicalDevice = NULL;
1018 {
1019 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1020 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1021 }
1022
1023 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001024 skipCall |= log_msg(
1025 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1026 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1027 "vkGetDisplayModePropertiesKHR() called even though the %s extension was not enabled for this VkInstance.",
1028 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001029 }
1030
1031 if (!pPropertyCount) {
1032 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pPropertyCount");
1033 }
Jon Ashburne699f442016-06-30 09:01:27 -06001034 // TODO add check for the count being consistent
Petros Bantolas2b40be72016-04-15 11:02:59 +01001035 lock.unlock();
1036
1037 if (!skipCall) {
1038 result = my_data->instance_dispatch_table->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, pProperties);
1039 return result;
1040 }
Jon Ashburne699f442016-06-30 09:01:27 -06001041 // TODO store the displayMode for later checking
Petros Bantolas2b40be72016-04-15 11:02:59 +01001042 return VK_ERROR_VALIDATION_FAILED_EXT;
1043}
1044
1045VKAPI_ATTR VkResult VKAPI_CALL
1046CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode) {
1047 VkResult result = VK_SUCCESS;
1048 bool skipCall = false;
1049 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1050 std::unique_lock<std::mutex> lock(global_lock);
1051 SwpPhysicalDevice *pPhysicalDevice = NULL;
1052 {
1053 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1054 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1055 }
1056
1057 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001058 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1059 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
1060 swapchain_layer_name,
1061 "vkCreateDisplayModeKHR() called even though the %s extension was not enabled for this VkInstance.",
1062 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001063 }
1064
1065 if (!pCreateInfo) {
1066 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pCreateInfo");
1067 }
1068 lock.unlock();
1069
Jon Ashburne699f442016-06-30 09:01:27 -06001070 // TODO more validation checks needed
Petros Bantolas2b40be72016-04-15 11:02:59 +01001071 if (!skipCall) {
1072 result = my_data->instance_dispatch_table->CreateDisplayModeKHR(physicalDevice, display, pCreateInfo, pAllocator, pMode);
1073 return result;
1074 }
1075
1076 return VK_ERROR_VALIDATION_FAILED_EXT;
1077}
1078
1079VKAPI_ATTR VkResult VKAPI_CALL
1080GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities) {
1081 VkResult result = VK_SUCCESS;
1082 bool skipCall = false;
1083 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1084 std::unique_lock<std::mutex> lock(global_lock);
1085 SwpPhysicalDevice *pPhysicalDevice = NULL;
1086 {
1087 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1088 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1089 }
1090
1091 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001092 skipCall |= log_msg(
1093 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1094 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1095 "vkGetDisplayPlaneCapabilitiesKHR) called even though the %s extension was not enabled for this VkInstance.",
1096 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001097 }
1098
Jon Ashburn5e026df2016-06-15 08:19:07 -06001099 if (!pPhysicalDevice->gotDisplayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +01001100 {
1101 LOG_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "planeIndex",
1102 SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,
1103 "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.",
1104 __FUNCTION__);
1105 }
1106
Jon Ashburn5e026df2016-06-15 08:19:07 -06001107 if (pPhysicalDevice->gotDisplayPlanePropertyCount && planeIndex >= pPhysicalDevice->displayPlanePropertyCount)
Petros Bantolas2b40be72016-04-15 11:02:59 +01001108 {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001109 skipCall |=
1110 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1111 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_PLANE_INDEX_TOO_LARGE, swapchain_layer_name,
1112 "vkGetDisplayPlaneCapabilitiesKHR(): planeIndex must be in the range [0, %d] that was returned by "
1113 "vkGetPhysicalDeviceDisplayPlanePropertiesKHR. Do you have the plane index hardcoded?",
1114 pPhysicalDevice->displayPlanePropertyCount - 1);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001115 }
1116
1117 if (!pCapabilities) {
1118 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "pCapabilities");
1119 }
1120 lock.unlock();
1121
1122 if (!skipCall) {
1123 result = my_data->instance_dispatch_table->GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities);
1124 return result;
1125 }
1126
1127 return VK_ERROR_VALIDATION_FAILED_EXT;
1128}
1129
1130VKAPI_ATTR VkResult VKAPI_CALL
1131CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator,
1132 VkSurfaceKHR *pSurface) {
1133 VkResult result = VK_SUCCESS;
1134 bool skipCall = false;
1135 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
1136 std::unique_lock<std::mutex> lock(global_lock);
1137 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
1138
1139 // Validate that the platform extension was enabled:
1140 if (pInstance && !pInstance->displayExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001141 skipCall |=
1142 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1143 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1144 "vkCreateDisplayPlaneSurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
1145 VK_KHR_DISPLAY_EXTENSION_NAME);
Petros Bantolas2b40be72016-04-15 11:02:59 +01001146 }
1147
1148 if (!pCreateInfo) {
1149 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
1150 } else {
1151 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR) {
1152 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
1153 "VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR");
1154 }
1155 if (pCreateInfo->pNext != NULL) {
1156 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
1157 }
1158 }
1159
Jon Ashburne699f442016-06-30 09:01:27 -06001160 // TODO more validation checks
Petros Bantolas2b40be72016-04-15 11:02:59 +01001161 if (!skipCall) {
1162 // Call down the call chain:
1163 lock.unlock();
1164 result = my_data->instance_dispatch_table->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
1165 lock.lock();
1166
1167 // Obtain this pointer again after locking:
1168 pInstance = &(my_data->instanceMap[instance]);
1169 if ((result == VK_SUCCESS) && pInstance && pSurface) {
1170 // Record the VkSurfaceKHR returned by the ICD:
1171 my_data->surfaceMap[*pSurface].surface = *pSurface;
1172 my_data->surfaceMap[*pSurface].pInstance = pInstance;
1173 my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
1174 my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
1175 my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
1176 // Point to the associated SwpInstance:
1177 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
1178 }
1179 lock.unlock();
1180 return result;
1181 }
1182 return VK_ERROR_VALIDATION_FAILED_EXT;
1183}
1184
Chia-I Wufccbfe42016-04-28 14:01:30 +08001185VKAPI_ATTR void VKAPI_CALL
1186DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) {
Dustin Graves080069b2016-04-05 13:48:15 -06001187 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001188 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001189 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001190 SwpSurface *pSurface = NULL;
1191 {
1192 auto it = my_data->surfaceMap.find(surface);
1193 pSurface = (it == my_data->surfaceMap.end()) ? NULL : &it->second;
1194 }
1195 SwpInstance *pInstance = NULL;
1196 {
1197 auto it = my_data->instanceMap.find(instance);
1198 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
1199 }
Ian Elliottf6b8c782016-04-29 13:03:17 -06001200
1201 // Validate that the platform extension was enabled:
1202 if (pInstance && !pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001203 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1204 (uint64_t)instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1205 "vkDestroySurfaceKHR() called even though the %s extension was not enabled for this VkInstance.",
1206 VK_KHR_DISPLAY_EXTENSION_NAME);
Ian Elliottf6b8c782016-04-29 13:03:17 -06001207 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001208
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001209 // Regardless of skipCall value, do some internal cleanup:
1210 if (pSurface) {
1211 // Delete the SwpSurface associated with this surface:
1212 if (pSurface->pInstance) {
1213 pSurface->pInstance->surfaces.erase(surface);
1214 }
1215 if (!pSurface->swapchains.empty()) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001216 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1217 (uint64_t)instance, __LINE__, SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, swapchain_layer_name,
1218 "vkDestroySurfaceKHR() called before all of its associated VkSwapchainKHRs were destroyed.");
1219
1220 // Empty and then delete all SwpSwapchains
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001221 for (auto it = pSurface->swapchains.begin(); it != pSurface->swapchains.end(); it++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001222 // Delete all SwpImage's
1223 it->second->images.clear();
1224 // In case the swapchain's device hasn't been destroyed yet
1225 // (which isn't likely, but is possible), delete its
1226 // association with this swapchain (i.e. so we can't point to
1227 // this swpchain from that device, later on):
1228 if (it->second->pDevice) {
1229 it->second->pDevice->swapchains.clear();
1230 }
1231 }
1232 pSurface->swapchains.clear();
1233 }
1234 if ((pAllocator != NULL) != pSurface->usedAllocatorToCreate) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001235 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1236 (uint64_t)instance, __LINE__, SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, swapchain_layer_name,
1237 "vkDestroySurfaceKHR() called with incompatible pAllocator from when the object was created.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001238 }
1239 my_data->surfaceMap.erase(surface);
1240 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001241 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001242
Dustin Graves080069b2016-04-05 13:48:15 -06001243 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001244 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001245 my_data->instance_dispatch_table->DestroySurfaceKHR(instance, surface, pAllocator);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001246 }
1247}
1248
Chia-I Wufccbfe42016-04-28 14:01:30 +08001249VKAPI_ATTR VkResult VKAPI_CALL
1250EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001251 VkResult result = VK_SUCCESS;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001252 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Ian Elliott32311832016-02-04 08:17:18 -07001253
1254 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001255 result = my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
Ian Elliott32311832016-02-04 08:17:18 -07001256
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001257 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001258 SwpInstance *pInstance = NULL;
1259 {
1260 auto it = my_data->instanceMap.find(instance);
1261 pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second;
1262 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001263 if ((result == VK_SUCCESS) && pInstance && pPhysicalDevices && (*pPhysicalDeviceCount > 0)) {
Ian Elliott32311832016-02-04 08:17:18 -07001264 // Record the VkPhysicalDevices returned by the ICD:
1265 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001266 my_data->physicalDeviceMap[pPhysicalDevices[i]].physicalDevice = pPhysicalDevices[i];
Ian Elliott32311832016-02-04 08:17:18 -07001267 my_data->physicalDeviceMap[pPhysicalDevices[i]].pInstance = pInstance;
1268 my_data->physicalDeviceMap[pPhysicalDevices[i]].pDevice = NULL;
1269 my_data->physicalDeviceMap[pPhysicalDevices[i]].gotQueueFamilyPropertyCount = false;
1270 my_data->physicalDeviceMap[pPhysicalDevices[i]].gotSurfaceCapabilities = false;
1271 my_data->physicalDeviceMap[pPhysicalDevices[i]].surfaceFormatCount = 0;
1272 my_data->physicalDeviceMap[pPhysicalDevices[i]].pSurfaceFormats = NULL;
1273 my_data->physicalDeviceMap[pPhysicalDevices[i]].presentModeCount = 0;
1274 my_data->physicalDeviceMap[pPhysicalDevices[i]].pPresentModes = NULL;
1275 // Point to the associated SwpInstance:
1276 if (pInstance) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001277 pInstance->physicalDevices[pPhysicalDevices[i]] = &my_data->physicalDeviceMap[pPhysicalDevices[i]];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001278 }
1279 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001280 }
Ian Elliotta3c69bc2016-02-04 15:34:59 -07001281 return result;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001282}
1283
Chia-I Wufccbfe42016-04-28 14:01:30 +08001284VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice,
1285 const VkDeviceCreateInfo *pCreateInfo,
1286 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
Chia-I Wua6737532016-04-28 16:04:15 +08001287 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001288 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
1289
1290 assert(chain_info->u.pLayerInfo);
1291 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1292 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
Chia-I Wua6737532016-04-28 16:04:15 +08001293 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001294 if (fpCreateDevice == NULL) {
1295 return VK_ERROR_INITIALIZATION_FAILED;
1296 }
1297
1298 // Advance the link info for the next element on the chain
1299 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
1300
1301 VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
1302 if (result != VK_SUCCESS) {
1303 return result;
1304 }
1305
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001306 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001307 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
1308
1309 // Setup device dispatch table
1310 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
1311 layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
1312
1313 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Mark Youngaa1aa3a2016-07-05 16:41:50 -06001314 checkDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001315
1316 return result;
1317}
1318
Chia-I Wufccbfe42016-04-28 14:01:30 +08001319VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001320 dispatch_key key = get_dispatch_key(device);
1321 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Ian Elliott32311832016-02-04 08:17:18 -07001322
1323 // Call down the call chain:
1324 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
1325
1326 // Do some internal cleanup:
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001327 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001328 SwpDevice *pDevice = NULL;
1329 {
1330 auto it = my_data->deviceMap.find(device);
1331 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1332 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001333 if (pDevice) {
1334 // Delete the SwpDevice associated with this device:
1335 if (pDevice->pPhysicalDevice) {
1336 pDevice->pPhysicalDevice->pDevice = NULL;
1337 }
1338 if (!pDevice->swapchains.empty()) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001339 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device,
1340 __LINE__, SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, swapchain_layer_name,
1341 "vkDestroyDevice() called before all of its associated VkSwapchainKHRs were destroyed.");
1342
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001343 // Empty and then delete all SwpSwapchain's
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001344 for (auto it = pDevice->swapchains.begin(); it != pDevice->swapchains.end(); it++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001345 // Delete all SwpImage's
1346 it->second->images.clear();
1347 // In case the swapchain's surface hasn't been destroyed yet
1348 // (which is likely) delete its association with this swapchain
1349 // (i.e. so we can't point to this swpchain from that surface,
1350 // later on):
1351 if (it->second->pSurface) {
1352 it->second->pSurface->swapchains.clear();
1353 }
1354 }
1355 pDevice->swapchains.clear();
1356 }
1357 my_data->deviceMap.erase(device);
1358 }
1359 delete my_data->device_dispatch_table;
1360 layer_data_map.erase(key);
1361}
1362
Chia-I Wufccbfe42016-04-28 14:01:30 +08001363VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
1364 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
1365 VkBool32 *pSupported) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001366 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001367 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001368 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001369 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001370 SwpPhysicalDevice *pPhysicalDevice = NULL;
1371 {
1372 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1373 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1374 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001375
1376 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001377 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001378 skipCall |= log_msg(
1379 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1380 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1381 "vkGetPhysicalDeviceSurfaceSupportKHR() called even though the %s extension was not enabled for this VkInstance.",
1382 VK_KHR_SURFACE_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001383 }
1384 if (!pPhysicalDevice->gotQueueFamilyPropertyCount) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001385 skipCall |= log_msg(
1386 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1387 (uint64_t)pPhysicalDevice->physicalDevice, __LINE__, SWAPCHAIN_DID_NOT_QUERY_QUEUE_FAMILIES, swapchain_layer_name,
1388 "vkGetPhysicalDeviceSurfaceSupportKHR() called before calling the vkGetPhysicalDeviceQueueFamilyProperties function.");
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001389 } else if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) {
1390 skipCall |=
1391 LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
1392 "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001393 }
1394 if (!pSupported) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001395 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSupported");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001396 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001397 lock.unlock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001398
Dustin Graves080069b2016-04-05 13:48:15 -06001399 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001400 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001401 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface,
1402 pSupported);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001403 lock.lock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001404
Ian Elliott32311832016-02-04 08:17:18 -07001405 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001406 {
1407 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1408 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1409 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001410 if ((result == VK_SUCCESS) && pSupported && pPhysicalDevice) {
1411 // Record the result of this query:
1412 SwpInstance *pInstance = pPhysicalDevice->pInstance;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001413 SwpSurface *pSurface = (pInstance) ? pInstance->surfaces[surface] : NULL;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001414 if (pSurface) {
1415 pPhysicalDevice->supportedSurfaces[surface] = pSurface;
1416 if (!pSurface->numQueueFamilyIndexSupport) {
1417 if (pPhysicalDevice->gotQueueFamilyPropertyCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001418 pSurface->pQueueFamilyIndexSupport =
1419 (VkBool32 *)malloc(pPhysicalDevice->numOfQueueFamilies * sizeof(VkBool32));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001420 if (pSurface->pQueueFamilyIndexSupport != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001421 pSurface->numQueueFamilyIndexSupport = pPhysicalDevice->numOfQueueFamilies;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001422 }
1423 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001424 }
1425 if (pSurface->numQueueFamilyIndexSupport) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001426 pSurface->pQueueFamilyIndexSupport[queueFamilyIndex] = *pSupported;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001427 }
1428 }
1429 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001430 lock.unlock();
1431
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001432 return result;
1433 }
1434 return VK_ERROR_VALIDATION_FAILED_EXT;
1435}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001436
Chia-I Wufccbfe42016-04-28 14:01:30 +08001437VKAPI_ATTR VkResult VKAPI_CALL
1438GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
1439 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001440 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001441 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001442 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001443 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001444 SwpPhysicalDevice *pPhysicalDevice = NULL;
1445 {
1446 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1447 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1448 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001449
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001450 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001451 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001452 skipCall |= log_msg(
1453 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1454 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1455 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR() called even though the %s extension was not enabled for this VkInstance.",
1456 VK_KHR_DISPLAY_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001457 }
1458 if (!pSurfaceCapabilities) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001459 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSurfaceCapabilities");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001460 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001461 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001462
Dustin Graves080069b2016-04-05 13:48:15 -06001463 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001464 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001465 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface,
1466 pSurfaceCapabilities);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001467 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001468
Ian Elliott32311832016-02-04 08:17:18 -07001469 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001470 {
1471 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1472 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1473 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001474 if ((result == VK_SUCCESS) && pPhysicalDevice) {
1475 // Record the result of this query:
1476 pPhysicalDevice->gotSurfaceCapabilities = true;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001477 // FIXME: NEED TO COPY THIS DATA, BECAUSE pSurfaceCapabilities POINTS TO APP-ALLOCATED DATA
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001478 pPhysicalDevice->surfaceCapabilities = *pSurfaceCapabilities;
1479 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001480 lock.unlock();
1481
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001482 return result;
1483 }
1484 return VK_ERROR_VALIDATION_FAILED_EXT;
1485}
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001486
Chia-I Wufccbfe42016-04-28 14:01:30 +08001487VKAPI_ATTR VkResult VKAPI_CALL
1488GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount,
1489 VkSurfaceFormatKHR *pSurfaceFormats) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001490 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001491 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001492 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001493 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001494 SwpPhysicalDevice *pPhysicalDevice = NULL;
1495 {
1496 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1497 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1498 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001499
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001500 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001501 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001502 skipCall |= log_msg(
1503 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1504 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1505 "vkGetPhysicalDeviceSurfaceFormatsKHR() called even though the %s extension was not enabled for this VkInstance.",
1506 VK_KHR_DISPLAY_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001507 }
1508 if (!pSurfaceFormatCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001509 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSurfaceFormatCount");
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001510 } else if (pPhysicalDevice && pSurfaceFormats) {
1511 // Compare the preliminary value of *pSurfaceFormatCount with the
1512 // value this time:
1513 if (pPhysicalDevice->surfaceFormatCount == 0) {
1514 // Since we haven't recorded a preliminary value of
1515 // *pSurfaceFormatCount, that likely means that the application
1516 // didn't previously call this function with a NULL value of
1517 // pSurfaceFormats:
1518 skipCall |= LOG_ERROR_ZERO_PRIOR_COUNT(
1519 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1520 physicalDevice, "pSurfaceFormatCount", "pSurfaceFormats");
1521 } else if (*pSurfaceFormatCount > pPhysicalDevice->surfaceFormatCount) {
1522 skipCall |= LOG_ERROR_INVALID_COUNT(
1523 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1524 physicalDevice, "pSurfaceFormatCount", "pSurfaceFormats",
1525 *pSurfaceFormatCount, pPhysicalDevice->surfaceFormatCount);
1526 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001527 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001528 lock.unlock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001529
Dustin Graves080069b2016-04-05 13:48:15 -06001530 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001531 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001532 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount,
1533 pSurfaceFormats);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001534 lock.lock();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001535
Ian Elliott32311832016-02-04 08:17:18 -07001536 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001537 {
1538 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1539 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1540 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001541 if ((result == VK_SUCCESS) && pPhysicalDevice && !pSurfaceFormats && pSurfaceFormatCount) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001542 // Record the result of this preliminary query:
1543 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001544 } else if ((result == VK_SUCCESS) && pPhysicalDevice &&
1545 pSurfaceFormats && pSurfaceFormatCount &&
1546 (*pSurfaceFormatCount > 0)) {
1547 // Record the result of this query:
1548 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
1549 pPhysicalDevice->pSurfaceFormats = (VkSurfaceFormatKHR *)malloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
1550 if (pPhysicalDevice->pSurfaceFormats) {
1551 for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) {
1552 pPhysicalDevice->pSurfaceFormats[i] = pSurfaceFormats[i];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001553 }
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001554 } else {
1555 pPhysicalDevice->surfaceFormatCount = 0;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001556 }
1557 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001558 lock.unlock();
1559
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001560 return result;
1561 }
1562 return VK_ERROR_VALIDATION_FAILED_EXT;
1563}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001564
Chia-I Wufccbfe42016-04-28 14:01:30 +08001565VKAPI_ATTR VkResult VKAPI_CALL
1566GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount,
1567 VkPresentModeKHR *pPresentModes) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001568 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06001569 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001570 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001571 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06001572 SwpPhysicalDevice *pPhysicalDevice = NULL;
1573 {
1574 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1575 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1576 }
Ian Elliott07adb112016-01-05 12:51:03 -07001577
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001578 // Validate that the surface extension was enabled:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001579 if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001580 skipCall |= log_msg(
1581 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
1582 (uint64_t)pPhysicalDevice->pInstance->instance, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1583 "vkGetPhysicalDeviceSurfacePresentModesKHR() called even though the %s extension was not enabled for this VkInstance.",
1584 VK_KHR_DISPLAY_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001585 }
1586 if (!pPresentModeCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001587 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pPresentModeCount");
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001588 } else if (pPhysicalDevice && pPresentModes) {
1589 // Compare the preliminary value of *pPresentModeCount with the
1590 // value this time:
1591 if (pPhysicalDevice->presentModeCount == 0) {
1592 // Since we haven't recorded a preliminary value of
1593 // *pPresentModeCount, that likely means that the application
1594 // didn't previously call this function with a NULL value of
1595 // pPresentModes:
1596 skipCall |= LOG_ERROR_ZERO_PRIOR_COUNT(
1597 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1598 physicalDevice, "pPresentModeCount", "pPresentModes");
1599 } else if (*pPresentModeCount > pPhysicalDevice->presentModeCount) {
1600 skipCall |= LOG_ERROR_INVALID_COUNT(
1601 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1602 physicalDevice, "pPresentModeCount", "pPresentModes",
1603 *pPresentModeCount, pPhysicalDevice->presentModeCount);
1604 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001605 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001606 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06001607
Dustin Graves080069b2016-04-05 13:48:15 -06001608 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001609 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001610 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface,
1611 pPresentModeCount, pPresentModes);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001612 lock.lock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001613
Ian Elliott32311832016-02-04 08:17:18 -07001614 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001615 {
1616 auto it = my_data->physicalDeviceMap.find(physicalDevice);
1617 pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second;
1618 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001619 if ((result == VK_SUCCESS) && pPhysicalDevice && !pPresentModes && pPresentModeCount) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001620 // Record the result of this preliminary query:
1621 pPhysicalDevice->presentModeCount = *pPresentModeCount;
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001622 } else if ((result == VK_SUCCESS) && pPhysicalDevice &&
1623 pPresentModes && pPresentModeCount &&
1624 (*pPresentModeCount > 0)) {
1625 // Record the result of this query:
1626 pPhysicalDevice->presentModeCount = *pPresentModeCount;
1627 pPhysicalDevice->pPresentModes = (VkPresentModeKHR *)malloc(*pPresentModeCount * sizeof(VkPresentModeKHR));
1628 if (pPhysicalDevice->pPresentModes) {
1629 for (uint32_t i = 0; i < *pPresentModeCount; i++) {
1630 pPhysicalDevice->pPresentModes[i] = pPresentModes[i];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001631 }
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06001632 } else {
1633 pPhysicalDevice->presentModeCount = 0;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001634 }
1635 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06001636 lock.unlock();
1637
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001638 return result;
1639 }
1640 return VK_ERROR_VALIDATION_FAILED_EXT;
1641}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001642
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001643// This function does the up-front validation work for vkCreateSwapchainKHR(),
Dustin Graves080069b2016-04-05 13:48:15 -06001644// and returns true if a logging callback indicates that the call down the
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001645// chain should be skipped:
Dustin Graves080069b2016-04-05 13:48:15 -06001646static bool validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, VkSwapchainKHR *pSwapchain) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001647 // TODO: Validate cases of re-creating a swapchain (the current code
1648 // assumes a new swapchain is being created).
Dustin Graves080069b2016-04-05 13:48:15 -06001649 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001650 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1651 char fn[] = "vkCreateSwapchainKHR";
Ian Elliott77f46ca2016-05-05 14:10:49 -06001652 SwpDevice *pDevice = NULL;
1653 {
1654 auto it = my_data->deviceMap.find(device);
1655 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1656 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001657
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001658 // Validate that the swapchain extension was enabled:
1659 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001660 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1661 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
1662 "vkCreateSwapchainKHR() called even though the %s extension was not enabled for this VkDevice.",
1663 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001664 }
1665 if (!pCreateInfo) {
Ian Elliott432a3172016-05-09 12:33:47 -06001666 return LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001667 } else {
1668 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001669 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001670 "VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR");
1671 }
1672 if (pCreateInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001673 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001674 }
1675 }
1676 if (!pSwapchain) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001677 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pSwapchain");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001678 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001679
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001680 // Keep around a useful pointer to pPhysicalDevice:
1681 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001682
Mark Lobodzinskid40b2db2016-02-25 13:56:57 -07001683 // Validate pCreateInfo values with result of
1684 // vkGetPhysicalDeviceQueueFamilyProperties
1685 if (pPhysicalDevice && pPhysicalDevice->gotQueueFamilyPropertyCount) {
Michael Mc Donnell75ecdb72016-04-03 14:47:51 -07001686 for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; i++) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001687 if (pCreateInfo->pQueueFamilyIndices[i] >= pPhysicalDevice->numOfQueueFamilies) {
1688 skipCall |= LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice,
1689 "VkPhysicalDevice", pCreateInfo->pQueueFamilyIndices[i],
1690 pPhysicalDevice->numOfQueueFamilies);
Mark Lobodzinskid40b2db2016-02-25 13:56:57 -07001691 }
1692 }
1693 }
1694
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001695 // Validate pCreateInfo values with the results of
1696 // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
1697 if (!pPhysicalDevice || !pPhysicalDevice->gotSurfaceCapabilities) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001698 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1699 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, swapchain_layer_name,
1700 "vkCreateSwapchainKHR() called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001701 } else if (pCreateInfo) {
1702 // Validate pCreateInfo->surface to make sure that
1703 // vkGetPhysicalDeviceSurfaceSupportKHR() reported this as a supported
1704 // surface:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001705 SwpSurface *pSurface = ((pPhysicalDevice) ? pPhysicalDevice->supportedSurfaces[pCreateInfo->surface] : NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001706 if (!pSurface) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001707 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1708 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_UNSUPPORTED_SURFACE, swapchain_layer_name,
1709 "The surface in pCreateInfo->surface, that was given to vkCreateSwapchainKHR(), must be a surface "
1710 "that is supported by the device as determined by vkGetPhysicalDeviceSurfaceSupportKHR(). "
1711 "However, vkGetPhysicalDeviceSurfaceSupportKHR() was never called with this surface.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001712 }
Ian Elliott4f147fc2016-01-20 08:52:08 -07001713
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001714 // Validate pCreateInfo->minImageCount against
1715 // VkSurfaceCapabilitiesKHR::{min|max}ImageCount:
1716 VkSurfaceCapabilitiesKHR *pCapabilities = &pPhysicalDevice->surfaceCapabilities;
1717 if ((pCreateInfo->minImageCount < pCapabilities->minImageCount) ||
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001718 ((pCapabilities->maxImageCount > 0) && (pCreateInfo->minImageCount > pCapabilities->maxImageCount))) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001719 skipCall |=
1720 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1721 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT, swapchain_layer_name,
1722 "vkCreateSwapchainKHR() called with pCreateInfo->minImageCount = %d, which is outside the bounds returned "
1723 "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. minImageCount = %d, maxImageCount = %d).",
1724 pCreateInfo->minImageCount, pCapabilities->minImageCount, pCapabilities->maxImageCount);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001725 }
1726 // Validate pCreateInfo->imageExtent against
1727 // VkSurfaceCapabilitiesKHR::{current|min|max}ImageExtent:
1728 if ((pCapabilities->currentExtent.width == -1) &&
1729 ((pCreateInfo->imageExtent.width < pCapabilities->minImageExtent.width) ||
1730 (pCreateInfo->imageExtent.width > pCapabilities->maxImageExtent.width) ||
1731 (pCreateInfo->imageExtent.height < pCapabilities->minImageExtent.height) ||
1732 (pCreateInfo->imageExtent.height > pCapabilities->maxImageExtent.height))) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001733 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1734 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS, swapchain_layer_name,
1735 "vkCreateSwapchainKHR() called with pCreateInfo->imageExtent = (%d,%d), which is outside the "
1736 "bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (%d,%d), "
1737 "minImageExtent = (%d,%d), maxImageExtent = (%d,%d).",
1738 pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, pCapabilities->currentExtent.width,
1739 pCapabilities->currentExtent.height, pCapabilities->minImageExtent.width,
1740 pCapabilities->minImageExtent.height, pCapabilities->maxImageExtent.width,
1741 pCapabilities->maxImageExtent.height);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001742 }
1743 if ((pCapabilities->currentExtent.width != -1) &&
1744 ((pCreateInfo->imageExtent.width != pCapabilities->currentExtent.width) ||
1745 (pCreateInfo->imageExtent.height != pCapabilities->currentExtent.height))) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001746 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1747 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN, swapchain_layer_name,
1748 "vkCreateSwapchainKHR() called with pCreateInfo->imageExtent = (%d,%d), which is not equal to the "
1749 "currentExtent = (%d,%d) returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR().",
1750 pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, pCapabilities->currentExtent.width,
1751 pCapabilities->currentExtent.height);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001752 }
1753 // Validate pCreateInfo->preTransform has one bit set (1st two
1754 // lines of if-statement), which bit is also set in
1755 // VkSurfaceCapabilitiesKHR::supportedTransforms (3rd line of if-statement):
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001756 if (!pCreateInfo->preTransform || (pCreateInfo->preTransform & (pCreateInfo->preTransform - 1)) ||
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001757 !(pCreateInfo->preTransform & pCapabilities->supportedTransforms)) {
1758 // This is an error situation; one for which we'd like to give
1759 // the developer a helpful, multi-line error message. Build it
1760 // up a little at a time, and then log it:
1761 std::string errorString = "";
1762 char str[1024];
1763 // Here's the first part of the message:
1764 sprintf(str, "%s() called with a non-supported "
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001765 "pCreateInfo->preTransform (i.e. %s). "
1766 "Supported values are:\n",
1767 fn, surfaceTransformStr(pCreateInfo->preTransform));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001768 errorString += str;
1769 for (int i = 0; i < 32; i++) {
1770 // Build up the rest of the message:
1771 if ((1 << i) & pCapabilities->supportedTransforms) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001772 const char *newStr = surfaceTransformStr((VkSurfaceTransformFlagBitsKHR)(1 << i));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001773 sprintf(str, " %s\n", newStr);
1774 errorString += str;
1775 }
1776 }
1777 // Log the message that we've built up:
Mark Lobodzinskia4cbbcd2016-05-24 15:44:50 -06001778 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1779 reinterpret_cast<uint64_t &>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM, LAYER_NAME,
1780 "%s", errorString.c_str());
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001781 }
1782 // Validate pCreateInfo->compositeAlpha has one bit set (1st two
1783 // lines of if-statement), which bit is also set in
1784 // VkSurfaceCapabilitiesKHR::supportedCompositeAlpha (3rd line of if-statement):
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001785 if (!pCreateInfo->compositeAlpha || (pCreateInfo->compositeAlpha & (pCreateInfo->compositeAlpha - 1)) ||
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001786 !((pCreateInfo->compositeAlpha) & pCapabilities->supportedCompositeAlpha)) {
1787 // This is an error situation; one for which we'd like to give
1788 // the developer a helpful, multi-line error message. Build it
1789 // up a little at a time, and then log it:
1790 std::string errorString = "";
1791 char str[1024];
1792 // Here's the first part of the message:
1793 sprintf(str, "%s() called with a non-supported "
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001794 "pCreateInfo->compositeAlpha (i.e. %s). "
1795 "Supported values are:\n",
1796 fn, surfaceCompositeAlphaStr(pCreateInfo->compositeAlpha));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001797 errorString += str;
1798 for (int i = 0; i < 32; i++) {
1799 // Build up the rest of the message:
1800 if ((1 << i) & pCapabilities->supportedCompositeAlpha) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001801 const char *newStr = surfaceCompositeAlphaStr((VkCompositeAlphaFlagBitsKHR)(1 << i));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001802 sprintf(str, " %s\n", newStr);
1803 errorString += str;
1804 }
1805 }
1806 // Log the message that we've built up:
Mark Lobodzinskia4cbbcd2016-05-24 15:44:50 -06001807 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1808 reinterpret_cast<uint64_t &>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA,
1809 LAYER_NAME, "%s", errorString.c_str());
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001810 }
David McFarlande22cfb02016-05-20 18:26:28 -03001811 // Validate pCreateInfo->imageArrayLayers against
1812 // VkSurfaceCapabilitiesKHR::maxImageArrayLayers:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001813 if ((pCreateInfo->imageArrayLayers < 1) || (pCreateInfo->imageArrayLayers > pCapabilities->maxImageArrayLayers)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001814 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1815 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_LAYERS, swapchain_layer_name,
1816 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageArrayLayers (i.e. %d). "
1817 "Minimum value is 1, maximum value is %d.",
1818 pCreateInfo->imageArrayLayers, pCapabilities->maxImageArrayLayers);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001819 }
1820 // Validate pCreateInfo->imageUsage against
1821 // VkSurfaceCapabilitiesKHR::supportedUsageFlags:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001822 if (pCreateInfo->imageUsage != (pCreateInfo->imageUsage & pCapabilities->supportedUsageFlags)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001823 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1824 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS, swapchain_layer_name,
1825 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageUsage (i.e. 0x%08x). "
1826 "Supported flag bits are 0x%08x.",
1827 pCreateInfo->imageUsage, pCapabilities->supportedUsageFlags);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001828 }
1829 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001830
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001831 // Validate pCreateInfo values with the results of
1832 // vkGetPhysicalDeviceSurfaceFormatsKHR():
1833 if (!pPhysicalDevice || !pPhysicalDevice->surfaceFormatCount) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001834 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1835 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, swapchain_layer_name,
1836 "vkCreateSwapchainKHR() called before calling vkGetPhysicalDeviceSurfaceFormatsKHR().");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001837 } else if (pCreateInfo) {
1838 // Validate pCreateInfo->imageFormat against
1839 // VkSurfaceFormatKHR::format:
1840 bool foundFormat = false;
1841 bool foundColorSpace = false;
1842 bool foundMatch = false;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001843 for (uint32_t i = 0; i < pPhysicalDevice->surfaceFormatCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001844 if (pCreateInfo->imageFormat == pPhysicalDevice->pSurfaceFormats[i].format) {
1845 // Validate pCreateInfo->imageColorSpace against
1846 // VkSurfaceFormatKHR::colorSpace:
1847 foundFormat = true;
1848 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
1849 foundMatch = true;
1850 break;
1851 }
1852 } else {
1853 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
1854 foundColorSpace = true;
1855 }
1856 }
1857 }
1858 if (!foundMatch) {
1859 if (!foundFormat) {
1860 if (!foundColorSpace) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001861 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1862 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP, swapchain_layer_name,
1863 "vkCreateSwapchainKHR() called with neither a supported pCreateInfo->imageFormat "
1864 "(i.e. %d) nor a supported "
1865 "pCreateInfo->imageColorSpace (i.e. %d).",
1866 pCreateInfo->imageFormat, pCreateInfo->imageColorSpace);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001867 } else {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001868 skipCall |=
1869 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1870 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT, swapchain_layer_name,
1871 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageFormat (i.e. %d)",
1872 pCreateInfo->imageFormat);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001873 }
1874 } else if (!foundColorSpace) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001875 skipCall |=
1876 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1877 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE, swapchain_layer_name,
1878 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageColorSpace (i.e. %d).",
1879 pCreateInfo->imageColorSpace);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001880 }
1881 }
1882 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001883
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001884 // Validate pCreateInfo values with the results of
1885 // vkGetPhysicalDeviceSurfacePresentModesKHR():
1886 if (!pPhysicalDevice || !pPhysicalDevice->presentModeCount) {
szdarkhackfb287d32016-03-12 18:41:19 +02001887 if (!pCreateInfo || (pCreateInfo->presentMode != VK_PRESENT_MODE_FIFO_KHR)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001888 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1889 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, swapchain_layer_name,
1890 "vkCreateSwapchainKHR() called before calling "
1891 "vkGetPhysicalDeviceSurfacePresentModesKHR().");
szdarkhackfb287d32016-03-12 18:41:19 +02001892 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001893 } else if (pCreateInfo) {
1894 // Validate pCreateInfo->presentMode against
1895 // vkGetPhysicalDeviceSurfacePresentModesKHR():
1896 bool foundMatch = false;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001897 for (uint32_t i = 0; i < pPhysicalDevice->presentModeCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001898 if (pPhysicalDevice->pPresentModes[i] == pCreateInfo->presentMode) {
1899 foundMatch = true;
1900 break;
1901 }
1902 }
1903 if (!foundMatch) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001904 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1905 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE, swapchain_layer_name,
1906 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->presentMode (i.e. %s).",
1907 presentModeStr(pCreateInfo->presentMode));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001908 }
1909 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001910
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001911 // Validate pCreateInfo->imageSharingMode and related values:
1912 if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001913 if ((pCreateInfo->queueFamilyIndexCount <= 1) || !pCreateInfo->pQueueFamilyIndices) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001914 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1915 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_SHARING_VALUES, swapchain_layer_name,
1916 "vkCreateSwapchainKHR() called with a supported pCreateInfo->sharingMode of (i.e. %s), but with a "
1917 "bad value(s) for pCreateInfo->queueFamilyIndexCount or pCreateInfo->pQueueFamilyIndices).",
1918 sharingModeStr(pCreateInfo->imageSharingMode));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001919 }
1920 } else if (pCreateInfo->imageSharingMode != VK_SHARING_MODE_EXCLUSIVE) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001921 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1922 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_SHARING_MODE, swapchain_layer_name,
1923 "vkCreateSwapchainKHR() called with a non-supported pCreateInfo->imageSharingMode (i.e. %s).",
1924 sharingModeStr(pCreateInfo->imageSharingMode));
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001925 }
Ian Elliotta2a89c52015-12-28 15:23:57 -07001926
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001927 // Validate pCreateInfo->clipped:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001928 if (pCreateInfo && (pCreateInfo->clipped != VK_FALSE) && (pCreateInfo->clipped != VK_TRUE)) {
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_BAD_BOOL, swapchain_layer_name,
1931 "vkCreateSwapchainKHR() called with a VkBool32 value that is neither VK_TRUE nor VK_FALSE, but "
1932 "has the numeric value of %d.",
1933 pCreateInfo->clipped);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001934 }
Ian Elliotta2a89c52015-12-28 15:23:57 -07001935
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001936 // Validate pCreateInfo->oldSwapchain:
1937 if (pCreateInfo && pCreateInfo->oldSwapchain) {
Ian Elliott77f46ca2016-05-05 14:10:49 -06001938 SwpSwapchain *pOldSwapchain = NULL;
1939 {
1940 auto it = my_data->swapchainMap.find(pCreateInfo->oldSwapchain);
1941 pOldSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
1942 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001943 if (pOldSwapchain) {
1944 if (device != pOldSwapchain->pDevice->device) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001945 skipCall |= log_msg(
1946 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device,
1947 __LINE__, SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, swapchain_layer_name,
1948 "vkCreateSwapchainKHR() called with a different VkDevice than the VkSwapchainKHR was created with.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001949 }
1950 if (pCreateInfo->surface != pOldSwapchain->pSurface->surface) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06001951 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1952 (uint64_t)device, __LINE__, SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE, swapchain_layer_name,
1953 "vkCreateSwapchainKHR() called with pCreateInfo->oldSwapchain pCreateInfo->surface.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001954 }
1955 } else {
1956 // TBD: Leave this in (not sure object_track will check this)?
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001957 skipCall |=
1958 LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pCreateInfo->oldSwapchain, "VkSwapchainKHR");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001959 }
1960 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001961
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001962 return skipCall;
1963}
Ian Elliott0b4d6242015-09-22 10:51:24 -06001964
Chia-I Wufccbfe42016-04-28 14:01:30 +08001965VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
1966 const VkAllocationCallbacks *pAllocator,
1967 VkSwapchainKHR *pSwapchain) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001968 VkResult result = VK_SUCCESS;
1969 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001970 std::unique_lock<std::mutex> lock(global_lock);
Dustin Graves080069b2016-04-05 13:48:15 -06001971 bool skipCall = validateCreateSwapchainKHR(device, pCreateInfo, pSwapchain);
Ian Elliott970a2bd2016-06-21 11:08:43 -06001972 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06001973
Dustin Graves080069b2016-04-05 13:48:15 -06001974 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001975 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001976 result = my_data->device_dispatch_table->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06001977 lock.lock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06001978
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001979 if (result == VK_SUCCESS) {
1980 // Remember the swapchain's handle, and link it to the device:
Ian Elliott77f46ca2016-05-05 14:10:49 -06001981 SwpDevice *pDevice = NULL;
1982 {
1983 auto it = my_data->deviceMap.find(device);
1984 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
1985 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001986
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001987 my_data->swapchainMap[*pSwapchain].swapchain = *pSwapchain;
1988 if (pDevice) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001989 pDevice->swapchains[*pSwapchain] = &my_data->swapchainMap[*pSwapchain];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001990 }
1991 my_data->swapchainMap[*pSwapchain].pDevice = pDevice;
1992 my_data->swapchainMap[*pSwapchain].imageCount = 0;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001993 my_data->swapchainMap[*pSwapchain].usedAllocatorToCreate = (pAllocator != NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001994 // Store a pointer to the surface
1995 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001996 SwpInstance *pInstance = (pPhysicalDevice) ? pPhysicalDevice->pInstance : NULL;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07001997 layer_data *my_instance_data =
Jon Ashburn5484e0c2016-03-08 17:48:44 -07001998 ((pInstance) ? get_my_data_ptr(get_dispatch_key(pInstance->instance), layer_data_map) : NULL);
1999 SwpSurface *pSurface = ((my_data && pCreateInfo) ? &my_instance_data->surfaceMap[pCreateInfo->surface] : NULL);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002000 my_data->swapchainMap[*pSwapchain].pSurface = pSurface;
2001 if (pSurface) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002002 pSurface->swapchains[*pSwapchain] = &my_data->swapchainMap[*pSwapchain];
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002003 }
2004 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002005 lock.unlock();
2006
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002007 return result;
2008 }
2009 return VK_ERROR_VALIDATION_FAILED_EXT;
2010}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002011
Chia-I Wufccbfe42016-04-28 14:01:30 +08002012VKAPI_ATTR void VKAPI_CALL
2013DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002014 // TODOs:
2015 //
2016 // - Implement a check for validity language that reads: All uses of
Ian Elliotta5d13a92016-04-07 09:05:45 -06002017 // presentable images acquired from pname:swapchain must: have completed
2018 // execution
Dustin Graves080069b2016-04-05 13:48:15 -06002019 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002020 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002021 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06002022 SwpDevice *pDevice = NULL;
2023 {
2024 auto it = my_data->deviceMap.find(device);
2025 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
2026 }
Ian Elliott8b9e2562016-01-05 13:00:50 -07002027
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002028 // Validate that the swapchain extension was enabled:
2029 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002030 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2031 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
2032 "vkDestroySwapchainKHR() called even though the %s extension was not enabled for this VkDevice.",
2033 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002034 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06002035
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002036 // Regardless of skipCall value, do some internal cleanup:
Ian Elliott77f46ca2016-05-05 14:10:49 -06002037 SwpSwapchain *pSwapchain = NULL;
2038 {
2039 auto it = my_data->swapchainMap.find(swapchain);
2040 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2041 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002042 if (pSwapchain) {
2043 // Delete the SwpSwapchain associated with this swapchain:
2044 if (pSwapchain->pDevice) {
2045 pSwapchain->pDevice->swapchains.erase(swapchain);
2046 if (device != pSwapchain->pDevice->device) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002047 skipCall |=
2048 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2049 (uint64_t)device, __LINE__, SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, swapchain_layer_name,
2050 "vkDestroySwapchainKHR() called with a different VkDevice than the VkSwapchainKHR was created with.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002051 }
2052 }
2053 if (pSwapchain->pSurface) {
2054 pSwapchain->pSurface->swapchains.erase(swapchain);
2055 }
2056 if (pSwapchain->imageCount) {
2057 pSwapchain->images.clear();
2058 }
2059 if ((pAllocator != NULL) != pSwapchain->usedAllocatorToCreate) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002060 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2061 (uint64_t)device, __LINE__, SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, swapchain_layer_name,
2062 "vkDestroySwapchainKHR() called with incompatible pAllocator from when the object was created.");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002063 }
2064 my_data->swapchainMap.erase(swapchain);
2065 }
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002066 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002067
Dustin Graves080069b2016-04-05 13:48:15 -06002068 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002069 // Call down the call chain:
2070 my_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator);
2071 }
2072}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002073
Chia-I Wufccbfe42016-04-28 14:01:30 +08002074VKAPI_ATTR VkResult VKAPI_CALL
2075GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002076 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06002077 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002078 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002079 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06002080 SwpDevice *pDevice = NULL;
2081 {
2082 auto it = my_data->deviceMap.find(device);
2083 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
2084 }
Ian Elliott8b9e2562016-01-05 13:00:50 -07002085
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002086 // Validate that the swapchain extension was enabled:
2087 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002088 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2089 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
2090 "vkGetSwapchainImagesKHR() called even though the %s extension was not enabled for this VkDevice.",
2091 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002092 }
Ian Elliott77f46ca2016-05-05 14:10:49 -06002093 SwpSwapchain *pSwapchain = NULL;
2094 {
2095 auto it = my_data->swapchainMap.find(swapchain);
2096 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2097 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002098 if (!pSwapchainImageCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002099 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pSwapchainImageCount");
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06002100 } else if (pSwapchain && pSwapchainImages) {
2101 // Compare the preliminary value of *pSwapchainImageCount with the
2102 // value this time:
2103 if (pSwapchain->imageCount == 0) {
2104 // Since we haven't recorded a preliminary value of
2105 // *pSwapchainImageCount, that likely means that the application
2106 // didn't previously call this function with a NULL value of
2107 // pSwapchainImages:
2108 skipCall |= LOG_ERROR_ZERO_PRIOR_COUNT(
2109 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2110 device, "pSwapchainImageCount", "pSwapchainImages");
2111 } else if (*pSwapchainImageCount > pSwapchain->imageCount) {
2112 skipCall |= LOG_ERROR_INVALID_COUNT(
2113 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2114 device, "pSwapchainImageCount", "pSwapchainImages",
2115 *pSwapchainImageCount, pSwapchain->imageCount);
2116 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002117 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002118 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002119
Dustin Graves080069b2016-04-05 13:48:15 -06002120 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002121 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002122 result = my_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002123 lock.lock();
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002124
Ian Elliott32311832016-02-04 08:17:18 -07002125 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06002126 {
2127 auto it = my_data->swapchainMap.find(swapchain);
2128 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2129 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002130 if ((result == VK_SUCCESS) && pSwapchain && !pSwapchainImages && pSwapchainImageCount) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002131 // Record the result of this preliminary query:
2132 pSwapchain->imageCount = *pSwapchainImageCount;
Ian Elliottfdf3ffa2016-05-05 14:06:53 -06002133 } else if ((result == VK_SUCCESS) && pSwapchain && pSwapchainImages &&
2134 pSwapchainImageCount && (*pSwapchainImageCount > 0)) {
2135 // Record the images and their state:
2136 pSwapchain->imageCount = *pSwapchainImageCount;
2137 for (uint32_t i = 0; i < *pSwapchainImageCount; i++) {
2138 pSwapchain->images[i].image = pSwapchainImages[i];
2139 pSwapchain->images[i].pSwapchain = pSwapchain;
2140 pSwapchain->images[i].acquiredByApp = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002141 }
2142 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002143 lock.unlock();
2144
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002145 return result;
2146 }
2147 return VK_ERROR_VALIDATION_FAILED_EXT;
2148}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002149
Chia-I Wufccbfe42016-04-28 14:01:30 +08002150VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
2151 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002152 // TODOs:
2153 //
2154 // - Address the timeout. Possibilities include looking at the state of the
2155 // swapchain's images, depending on the timeout value.
2156 // - Implement a check for validity language that reads: If pname:semaphore is
2157 // not sname:VK_NULL_HANDLE it must: be unsignalled
2158 // - Implement a check for validity language that reads: If pname:fence is not
2159 // sname:VK_NULL_HANDLE it must: be unsignalled and mustnot: be associated
2160 // with any other queue command that has not yet completed execution on that
2161 // queue
2162 // - Record/update the state of the swapchain, in case an error occurs
2163 // (e.g. VK_ERROR_OUT_OF_DATE_KHR).
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002164 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06002165 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002166 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002167 std::unique_lock<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06002168 SwpDevice *pDevice = NULL;
2169 {
2170 auto it = my_data->deviceMap.find(device);
2171 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
2172 }
Ian Elliott8b9e2562016-01-05 13:00:50 -07002173
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002174 // Validate that the swapchain extension was enabled:
2175 if (pDevice && !pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002176 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2177 (uint64_t)device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, swapchain_layer_name,
2178 "vkAcquireNextImageKHR() called even though the %s extension was not enabled for this VkDevice.",
2179 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002180 }
Ian Elliottfa8f0322016-03-23 08:28:54 -06002181 if ((semaphore == VK_NULL_HANDLE) && (fence == VK_NULL_HANDLE)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002182 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2183 (uint64_t)device, __LINE__, SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, swapchain_layer_name,
2184 "vkAcquireNextImageKHR() called with both the semaphore and fence parameters set to VK_NULL_HANDLE (at "
2185 "least one should be used).");
Ian Elliottfa8f0322016-03-23 08:28:54 -06002186 }
Ian Elliott77f46ca2016-05-05 14:10:49 -06002187 SwpSwapchain *pSwapchain = NULL;
2188 {
2189 auto it = my_data->swapchainMap.find(swapchain);
2190 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2191 }
Ian Elliott5c680282016-04-06 14:29:56 -06002192 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
2193 if (pSwapchain && pPhysicalDevice && pPhysicalDevice->gotSurfaceCapabilities) {
2194 // Look to see if the application has already acquired the maximum
2195 // number of images, and this will push it past the spec-defined
2196 // limits:
2197 uint32_t minImageCount = pPhysicalDevice->surfaceCapabilities.minImageCount;
2198 uint32_t imagesAcquiredByApp = 0;
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002199 for (uint32_t i = 0; i < pSwapchain->imageCount; i++) {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002200 if (pSwapchain->images[i].acquiredByApp) {
Ian Elliott5c680282016-04-06 14:29:56 -06002201 imagesAcquiredByApp++;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002202 }
2203 }
Ian Elliott5c680282016-04-06 14:29:56 -06002204 if (imagesAcquiredByApp > (pSwapchain->imageCount - minImageCount)) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002205 skipCall |= log_msg(
2206 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device,
2207 __LINE__, SWAPCHAIN_APP_ACQUIRES_TOO_MANY_IMAGES, swapchain_layer_name,
2208 "vkAcquireNextImageKHR() called when it cannot succeed. The application has acquired %d image(s) that have not yet "
2209 "been presented. The maximum number of images that the application can simultaneously acquire from this swapchain "
2210 "(including this call to vkCreateSwapchainKHR()) is %d. That value is derived by subtracting "
2211 "VkSurfaceCapabilitiesKHR::minImageCount (%d) from the number of images in the swapchain (%d) and adding 1.",
2212 imagesAcquiredByApp, (pSwapchain->imageCount - minImageCount + 1), minImageCount, pSwapchain->imageCount);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002213 }
2214 }
2215 if (!pImageIndex) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002216 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pImageIndex");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002217 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002218 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002219
Dustin Graves080069b2016-04-05 13:48:15 -06002220 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002221 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002222 result = my_data->device_dispatch_table->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002223 lock.lock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002224
Ian Elliott32311832016-02-04 08:17:18 -07002225 // Obtain this pointer again after locking:
Ian Elliott77f46ca2016-05-05 14:10:49 -06002226 {
2227 auto it = my_data->swapchainMap.find(swapchain);
2228 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2229 }
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002230 if (((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR)) && pSwapchain) {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002231 // Change the state of the image (now acquired by the application):
2232 pSwapchain->images[*pImageIndex].acquiredByApp = true;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002233 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002234 lock.unlock();
2235
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002236 return result;
2237 }
2238 return VK_ERROR_VALIDATION_FAILED_EXT;
2239}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002240
Chia-I Wufccbfe42016-04-28 14:01:30 +08002241VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002242 // TODOs:
2243 //
2244 // - Implement a check for validity language that reads: Any given element of
2245 // sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal
2246 // of that sname:VkSemaphore that won't be consumed by any other wait on that
2247 // semaphore
2248 // - Record/update the state of the swapchain, in case an error occurs
2249 // (e.g. VK_ERROR_OUT_OF_DATE_KHR).
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002250 VkResult result = VK_SUCCESS;
Dustin Graves080069b2016-04-05 13:48:15 -06002251 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002252 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002253
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002254 if (!pPresentInfo) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002255 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002256 } else {
2257 if (pPresentInfo->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002258 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo",
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002259 "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR");
2260 }
2261 if (pPresentInfo->pNext != NULL) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002262 skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002263 }
2264 if (!pPresentInfo->swapchainCount) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002265 skipCall |= LOG_ERROR_ZERO_VALUE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo->swapchainCount");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002266 }
2267 if (!pPresentInfo->pSwapchains) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002268 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo->pSwapchains");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002269 }
2270 if (!pPresentInfo->pImageIndices) {
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002271 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo->pImageIndices");
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002272 }
2273 // Note: pPresentInfo->pResults is allowed to be NULL
2274 }
Ian Elliott046ed2c2015-12-30 17:07:17 -07002275
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002276 std::unique_lock<std::mutex> lock(global_lock);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002277 for (uint32_t i = 0; pPresentInfo && (i < pPresentInfo->swapchainCount); i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002278 uint32_t index = pPresentInfo->pImageIndices[i];
Ian Elliott77f46ca2016-05-05 14:10:49 -06002279 SwpSwapchain *pSwapchain = NULL;
2280 {
2281 auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]);
2282 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2283 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002284 if (pSwapchain) {
2285 if (!pSwapchain->pDevice->swapchainExtensionEnabled) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002286 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
2287 (uint64_t)pSwapchain->pDevice->device, __LINE__, SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
2288 swapchain_layer_name,
2289 "vkQueuePresentKHR() called even though the %s extension was not enabled for this VkDevice.",
2290 VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002291 }
2292 if (index >= pSwapchain->imageCount) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002293 skipCall |=
2294 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
2295 (uint64_t)pPresentInfo->pSwapchains[i], __LINE__, SWAPCHAIN_INDEX_TOO_LARGE, swapchain_layer_name,
2296 "vkQueuePresentKHR() called for an index that is too large (i.e. %d). There are only %d images in "
2297 "this VkSwapchainKHR.\n",
2298 index, pSwapchain->imageCount);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002299 } else {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002300 if (!pSwapchain->images[index].acquiredByApp) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002301 skipCall |= log_msg(
2302 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
2303 (uint64_t)pPresentInfo->pSwapchains[i], __LINE__, SWAPCHAIN_INDEX_NOT_IN_USE, swapchain_layer_name,
2304 "vkQueuePresentKHR() returned an index (i.e. %d) for an image that is not acquired by the application.",
2305 index);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002306 }
2307 }
Ian Elliott77f46ca2016-05-05 14:10:49 -06002308 SwpQueue *pQueue = NULL;
2309 {
2310 auto it = my_data->queueMap.find(queue);
2311 pQueue = (it == my_data->queueMap.end()) ? NULL : &it->second;
2312 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002313 SwpSurface *pSurface = pSwapchain->pSurface;
2314 if (pQueue && pSurface && pSurface->numQueueFamilyIndexSupport) {
2315 uint32_t queueFamilyIndex = pQueue->queueFamilyIndex;
2316 // Note: the 1st test is to ensure queueFamilyIndex is in range,
2317 // and the 2nd test is the validation check:
2318 if ((pSurface->numQueueFamilyIndexSupport > queueFamilyIndex) &&
2319 (!pSurface->pQueueFamilyIndexSupport[queueFamilyIndex])) {
Mark Lobodzinski9b482fa2016-08-08 09:38:42 -06002320 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2321 VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, (uint64_t)pPresentInfo->pSwapchains[i],
2322 __LINE__, SWAPCHAIN_SURFACE_NOT_SUPPORTED_WITH_QUEUE, swapchain_layer_name,
2323 "vkQueuePresentKHR() called with a swapchain whose surface is not supported for presention "
2324 "on this device with the queueFamilyIndex (i.e. %d) of the given queue.",
2325 queueFamilyIndex);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002326 }
2327 }
2328 }
2329 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002330 lock.unlock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002331
Dustin Graves080069b2016-04-05 13:48:15 -06002332 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002333 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002334 result = my_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002335 lock.lock();
Ian Elliott0b4d6242015-09-22 10:51:24 -06002336
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002337 if (pPresentInfo && ((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) {
2338 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002339 int index = pPresentInfo->pImageIndices[i];
Ian Elliott77f46ca2016-05-05 14:10:49 -06002340 SwpSwapchain *pSwapchain = NULL;
2341 {
2342 auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]);
2343 pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
2344 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002345 if (pSwapchain) {
Ian Elliotta5d13a92016-04-07 09:05:45 -06002346 // Change the state of the image (no longer acquired by the
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002347 // application):
Ian Elliotta5d13a92016-04-07 09:05:45 -06002348 pSwapchain->images[index].acquiredByApp = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002349 }
2350 }
2351 }
Ian Elliott970a2bd2016-06-21 11:08:43 -06002352 lock.unlock();
2353
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002354 return result;
2355 }
2356 return VK_ERROR_VALIDATION_FAILED_EXT;
2357}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002358
Chia-I Wufccbfe42016-04-28 14:01:30 +08002359VKAPI_ATTR void VKAPI_CALL
2360GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
Dustin Graves080069b2016-04-05 13:48:15 -06002361 bool skipCall = false;
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002362 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliottc4db6952016-01-21 14:29:45 -07002363
Dustin Graves080069b2016-04-05 13:48:15 -06002364 if (!skipCall) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002365 // Call down the call chain:
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002366 my_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
Ian Elliottc4db6952016-01-21 14:29:45 -07002367
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002368 // Remember the queue's handle, and link it to the device:
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002369 std::lock_guard<std::mutex> lock(global_lock);
Ian Elliott77f46ca2016-05-05 14:10:49 -06002370 SwpDevice *pDevice = NULL;
2371 {
2372 auto it = my_data->deviceMap.find(device);
2373 pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second;
2374 }
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002375 my_data->queueMap[&pQueue].queue = *pQueue;
2376 if (pDevice) {
2377 pDevice->queues[*pQueue] = &my_data->queueMap[*pQueue];
2378 }
2379 my_data->queueMap[&pQueue].pDevice = pDevice;
2380 my_data->queueMap[&pQueue].queueFamilyIndex = queueFamilyIndex;
2381 }
2382}
Ian Elliottc4db6952016-01-21 14:29:45 -07002383
Chia-I Wufccbfe42016-04-28 14:01:30 +08002384VKAPI_ATTR VkResult VKAPI_CALL
2385CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
2386 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002387 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002388 VkResult result =
2389 my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002390 if (VK_SUCCESS == result) {
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002391 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski97c4d512016-05-19 15:27:18 -06002392 result = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002393 }
2394 return result;
2395}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002396
Chia-I Wufccbfe42016-04-28 14:01:30 +08002397VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance,
2398 VkDebugReportCallbackEXT msgCallback,
2399 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002400 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2401 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Jeremy Hayes9de0bd72016-04-13 11:57:20 -06002402 std::lock_guard<std::mutex> lock(global_lock);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002403 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
2404}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002405
Chia-I Wufccbfe42016-04-28 14:01:30 +08002406VKAPI_ATTR void VKAPI_CALL
2407DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
2408 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002409 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002410 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
2411 pMsg);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002412}
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07002413
Chia-I Wub02600c2016-05-20 07:11:22 +08002414VKAPI_ATTR VkResult VKAPI_CALL
2415EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
2416 return util_GetLayerProperties(1, &swapchain_layer, pCount, pProperties);
2417}
2418
2419VKAPI_ATTR VkResult VKAPI_CALL
2420EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
2421 return util_GetLayerProperties(1, &swapchain_layer, pCount, pProperties);
2422}
2423
2424VKAPI_ATTR VkResult VKAPI_CALL
2425EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
2426 if (pLayerName && !strcmp(pLayerName, swapchain_layer.layerName))
2427 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
2428
2429 return VK_ERROR_LAYER_NOT_PRESENT;
2430}
2431
Chia-I Wufccbfe42016-04-28 14:01:30 +08002432VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
2433 const char *pLayerName, uint32_t *pCount,
2434 VkExtensionProperties *pProperties) {
Chia-I Wu2b481252016-04-28 14:21:13 +08002435 if (pLayerName && !strcmp(pLayerName, swapchain_layer.layerName))
Chia-I Wu045209e2016-04-28 11:21:49 +08002436 return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
Chia-I Wu2b481252016-04-28 14:21:13 +08002437
2438 assert(physicalDevice);
2439
2440 dispatch_key key = get_dispatch_key(physicalDevice);
2441 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
2442 return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
Chia-I Wu045209e2016-04-28 11:21:49 +08002443}
2444
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002445static PFN_vkVoidFunction
Chia-I Wu22813c72016-04-28 14:38:57 +08002446intercept_core_instance_command(const char *name);
2447
2448static PFN_vkVoidFunction
2449intercept_khr_surface_command(const char *name, VkInstance instance);
2450
2451static PFN_vkVoidFunction
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002452intercept_core_device_command(const char *name);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07002453
Chia-I Wu83245952016-05-05 16:13:19 +08002454static PFN_vkVoidFunction
2455intercept_khr_swapchain_command(const char *name, VkDevice dev);
2456
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002457VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
2458 PFN_vkVoidFunction proc = intercept_core_device_command(funcName);
2459 if (proc)
2460 return proc;
2461
2462 assert(device);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002463
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002464 layer_data *my_data;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002465
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002466 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter1e9e6c82016-03-19 10:38:52 -06002467 VkLayerDispatchTable *pDisp = my_data->device_dispatch_table;
Chia-I Wu83245952016-05-05 16:13:19 +08002468
2469 proc = intercept_khr_swapchain_command(funcName, device);
2470 if (proc)
2471 return proc;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07002472
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002473 if (pDisp->GetDeviceProcAddr == NULL)
2474 return NULL;
2475 return pDisp->GetDeviceProcAddr(device, funcName);
2476}
Ian Elliott0b4d6242015-09-22 10:51:24 -06002477
Chia-I Wufccbfe42016-04-28 14:01:30 +08002478VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
Chia-I Wu22813c72016-04-28 14:38:57 +08002479 PFN_vkVoidFunction proc = intercept_core_instance_command(funcName);
Chia-I Wu5ae2f652016-04-28 15:16:59 +08002480 if (!proc)
2481 proc = intercept_core_device_command(funcName);
2482 if (!proc)
2483 proc = intercept_khr_swapchain_command(funcName, VK_NULL_HANDLE);
Chia-I Wu22813c72016-04-28 14:38:57 +08002484 if (proc)
2485 return proc;
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -07002486
Chia-I Wu5ae2f652016-04-28 15:16:59 +08002487 assert(instance);
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002488
2489 layer_data *my_data;
2490 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Jon Ashburn5484e0c2016-03-08 17:48:44 -07002491 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Ian Elliott68124ac2015-10-07 16:18:35 -06002492
Chia-I Wu5ae2f652016-04-28 15:16:59 +08002493 proc = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
2494 if (!proc)
2495 proc = intercept_khr_surface_command(funcName, instance);
Chia-I Wu22813c72016-04-28 14:38:57 +08002496 if (proc)
2497 return proc;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002498
Mark Lobodzinski1ed594e2016-02-03 09:57:14 -07002499 if (pTable->GetInstanceProcAddr == NULL)
2500 return NULL;
2501 return pTable->GetInstanceProcAddr(instance, funcName);
2502}
Chia-I Wu045209e2016-04-28 11:21:49 +08002503
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002504static PFN_vkVoidFunction
Chia-I Wu22813c72016-04-28 14:38:57 +08002505intercept_core_instance_command(const char *name) {
2506 static const struct {
2507 const char *name;
2508 PFN_vkVoidFunction proc;
2509 } core_instance_commands[] = {
2510 { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) },
2511 { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) },
2512 { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) },
2513 { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) },
2514 { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) },
Chia-I Wub02600c2016-05-20 07:11:22 +08002515 { "vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties) },
2516 { "vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties) },
2517 { "vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties) },
Chia-I Wu22813c72016-04-28 14:38:57 +08002518 { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) },
2519 { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) },
2520 };
2521
2522 for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
2523 if (!strcmp(core_instance_commands[i].name, name))
2524 return core_instance_commands[i].proc;
2525 }
2526
2527 return nullptr;
2528}
2529
2530static PFN_vkVoidFunction
2531intercept_khr_surface_command(const char *name, VkInstance instance) {
2532 static const struct {
2533 const char *name;
2534 PFN_vkVoidFunction proc;
2535 } khr_surface_commands[] = {
2536#ifdef VK_USE_PLATFORM_ANDROID_KHR
2537 { "vkCreateAndroidSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR) },
2538#endif // VK_USE_PLATFORM_ANDROID_KHR
2539#ifdef VK_USE_PLATFORM_MIR_KHR
2540 { "vkCreateMirSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateMirSurfaceKHR) },
2541 { "vkGetPhysicalDeviceMirPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMirPresentationSupportKHR) },
2542#endif // VK_USE_PLATFORM_MIR_KHR
2543#ifdef VK_USE_PLATFORM_WAYLAND_KHR
2544 { "vkCreateWaylandSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWaylandSurfaceKHR) },
2545 { "vkGetPhysicalDeviceWaylandPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWaylandPresentationSupportKHR) },
2546#endif // VK_USE_PLATFORM_WAYLAND_KHR
2547#ifdef VK_USE_PLATFORM_WIN32_KHR
2548 { "vkCreateWin32SurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWin32SurfaceKHR) },
2549 { "vkGetPhysicalDeviceWin32PresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWin32PresentationSupportKHR) },
2550#endif // VK_USE_PLATFORM_WIN32_KHR
2551#ifdef VK_USE_PLATFORM_XCB_KHR
2552 { "vkCreateXcbSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXcbSurfaceKHR) },
2553 { "vkGetPhysicalDeviceXcbPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXcbPresentationSupportKHR) },
2554#endif // VK_USE_PLATFORM_XCB_KHR
2555#ifdef VK_USE_PLATFORM_XLIB_KHR
2556 { "vkCreateXlibSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXlibSurfaceKHR) },
2557 { "vkGetPhysicalDeviceXlibPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXlibPresentationSupportKHR) },
2558#endif // VK_USE_PLATFORM_XLIB_KHR
2559 { "vkDestroySurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR) },
2560 { "vkGetPhysicalDeviceSurfaceSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR) },
2561 { "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR) },
2562 { "vkGetPhysicalDeviceSurfaceFormatsKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR) },
2563 { "vkGetPhysicalDeviceSurfacePresentModesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR) },
Petros Bantolas2b40be72016-04-15 11:02:59 +01002564 { "vkGetPhysicalDeviceDisplayPropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPropertiesKHR) },
2565 { "vkGetPhysicalDeviceDisplayPlanePropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceDisplayPlanePropertiesKHR) },
2566 { "vkGetDisplayPlaneSupportedDisplaysKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayPlaneSupportedDisplaysKHR) },
2567 { "vkGetDisplayModePropertiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayModePropertiesKHR) },
2568 { "vkCreateDisplayModeKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateDisplayModeKHR) },
2569 { "vkGetDisplayPlaneCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetDisplayPlaneCapabilitiesKHR) },
2570 { "vkCreateDisplayPlaneSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateDisplayPlaneSurfaceKHR) },
Chia-I Wu22813c72016-04-28 14:38:57 +08002571 };
2572
2573 // do not check if VK_KHR_*_surface is enabled (why?)
2574
2575 for (size_t i = 0; i < ARRAY_SIZE(khr_surface_commands); i++) {
2576 if (!strcmp(khr_surface_commands[i].name, name))
2577 return khr_surface_commands[i].proc;
2578 }
2579
2580 return nullptr;
2581}
2582
2583static PFN_vkVoidFunction
Chia-I Wu9bc0b582016-04-28 14:38:57 +08002584intercept_core_device_command(const char *name) {
2585 static const struct {
2586 const char *name;
2587 PFN_vkVoidFunction proc;
2588 } core_device_commands[] = {
2589 { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) },
2590 { "vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice) },
2591 { "vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue) },
2592 };
2593
2594 for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) {
2595 if (!strcmp(core_device_commands[i].name, name))
2596 return core_device_commands[i].proc;
2597 }
2598
2599 return nullptr;
2600}
2601
Chia-I Wu83245952016-05-05 16:13:19 +08002602static PFN_vkVoidFunction
2603intercept_khr_swapchain_command(const char *name, VkDevice dev) {
2604 static const struct {
2605 const char *name;
2606 PFN_vkVoidFunction proc;
2607 } khr_swapchain_commands[] = {
2608 { "vkCreateSwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR) },
2609 { "vkDestroySwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR) },
2610 { "vkGetSwapchainImagesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR) },
2611 { "vkAcquireNextImageKHR", reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR) },
2612 { "vkQueuePresentKHR", reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR) },
2613 };
2614
2615 // do not check if VK_KHR_swapchain is enabled (why?)
2616
2617 for (size_t i = 0; i < ARRAY_SIZE(khr_swapchain_commands); i++) {
2618 if (!strcmp(khr_swapchain_commands[i].name, name))
2619 return khr_swapchain_commands[i].proc;
2620 }
2621
2622 return nullptr;
2623}
2624
Chia-I Wu516b5082016-04-28 11:27:46 +08002625} // namespace swapchain
2626
2627// vk_layer_logging.h expects these to be defined
2628
Chia-I Wufccbfe42016-04-28 14:01:30 +08002629VKAPI_ATTR VkResult VKAPI_CALL
Chia-I Wu516b5082016-04-28 11:27:46 +08002630vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
2631 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002632 return swapchain::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Chia-I Wu516b5082016-04-28 11:27:46 +08002633}
2634
Chia-I Wufccbfe42016-04-28 14:01:30 +08002635VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,
Chia-I Wu516b5082016-04-28 11:27:46 +08002636 VkDebugReportCallbackEXT msgCallback,
2637 const VkAllocationCallbacks *pAllocator) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002638 swapchain::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Chia-I Wu516b5082016-04-28 11:27:46 +08002639}
2640
Chia-I Wufccbfe42016-04-28 14:01:30 +08002641VKAPI_ATTR void VKAPI_CALL
Chia-I Wu516b5082016-04-28 11:27:46 +08002642vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
2643 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002644 swapchain::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
Chia-I Wu516b5082016-04-28 11:27:46 +08002645}
2646
Chia-I Wub02600c2016-05-20 07:11:22 +08002647// loader-layer interface v0, just wrappers since there is only a layer
Chia-I Wu516b5082016-04-28 11:27:46 +08002648
Chia-I Wu045209e2016-04-28 11:21:49 +08002649VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2650vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002651 return swapchain::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
Chia-I Wu045209e2016-04-28 11:21:49 +08002652}
2653
2654VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2655vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002656 return swapchain::EnumerateInstanceLayerProperties(pCount, pProperties);
Chia-I Wu045209e2016-04-28 11:21:49 +08002657}
2658
2659VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2660vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002661 // the layer command handles VK_NULL_HANDLE just fine internally
2662 assert(physicalDevice == VK_NULL_HANDLE);
2663 return swapchain::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
Chia-I Wu516b5082016-04-28 11:27:46 +08002664}
2665
2666VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
2667 const char *pLayerName, uint32_t *pCount,
2668 VkExtensionProperties *pProperties) {
Chia-I Wub02600c2016-05-20 07:11:22 +08002669 // the layer command handles VK_NULL_HANDLE just fine internally
2670 assert(physicalDevice == VK_NULL_HANDLE);
Chia-I Wu2b481252016-04-28 14:21:13 +08002671 return swapchain::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
Chia-I Wu516b5082016-04-28 11:27:46 +08002672}
2673
2674VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002675 return swapchain::GetDeviceProcAddr(dev, funcName);
Chia-I Wu516b5082016-04-28 11:27:46 +08002676}
2677
2678VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Chia-I Wufccbfe42016-04-28 14:01:30 +08002679 return swapchain::GetInstanceProcAddr(instance, funcName);
Chia-I Wu045209e2016-04-28 11:21:49 +08002680}