blob: c4ae61162316e939e6f90e9e54436e4c0eec9d4b [file] [log] [blame]
Ian Elliott0b4d6242015-09-22 10:51:24 -06001/*
Ian Elliott0b4d6242015-09-22 10:51:24 -06002 *
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Ian Elliott0b4d6242015-09-22 10:51:24 -06004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060023 * Author: Ian Elliott <ian@lunarg.com>
24 *
Ian Elliott0b4d6242015-09-22 10:51:24 -060025 */
26
Ian Elliottd8c5db12015-10-07 11:32:31 -060027#include <stdio.h>
28#include <string.h>
Mark Lobodzinskib49b6e52015-11-26 10:59:58 -070029#include <vk_loader_platform.h>
Ian Elliotta983e9a2015-12-22 12:18:12 -070030#include <vk_icd.h>
Ian Elliott0b4d6242015-09-22 10:51:24 -060031#include "swapchain.h"
Tobin Ehlis711ff312015-10-29 12:58:13 -060032#include "vk_layer_extension_utils.h"
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070033#include "vk_enum_string_helper.h"
Ian Elliott68124ac2015-10-07 16:18:35 -060034
Ian Elliott0b4d6242015-09-22 10:51:24 -060035// FIXME/TODO: Make sure this layer is thread-safe!
36
Ian Elliott68124ac2015-10-07 16:18:35 -060037
Ian Elliott0b4d6242015-09-22 10:51:24 -060038// The following is for logging error messages:
Ian Elliott68124ac2015-10-07 16:18:35 -060039static std::unordered_map<void *, layer_data *> layer_data_map;
Ian Elliott0b4d6242015-09-22 10:51:24 -060040
Ian Elliott68124ac2015-10-07 16:18:35 -060041template layer_data *get_my_data_ptr<layer_data>(
42 void *data_key,
43 std::unordered_map<void *, layer_data *> &data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -060044
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070045static const VkExtensionProperties instance_extensions[] = {
46 {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -070047 VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
48 VK_EXT_DEBUG_REPORT_REVISION
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070049 }
50};
51
52VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
53 const char *pLayerName,
54 uint32_t *pCount,
55 VkExtensionProperties* pProperties)
56{
57 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
58}
59
60static const VkLayerProperties swapchain_global_layers[] = {
61 {
Mark Lobodzinski0d054fe2015-12-30 08:16:12 -070062 "swapchain",
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070063 VK_API_VERSION,
64 VK_MAKE_VERSION(0, 1, 0),
Mark Lobodzinski0d054fe2015-12-30 08:16:12 -070065 "Validation layer: swapchain",
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -070066 }
67};
68
69VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
70 uint32_t *pCount,
71 VkLayerProperties* pProperties)
72{
73 return util_GetLayerProperties(ARRAY_SIZE(swapchain_global_layers),
74 swapchain_global_layers,
75 pCount, pProperties);
76}
77
Ian Elliotta983e9a2015-12-22 12:18:12 -070078// This function validates a VkSurfaceKHR object:
79static VkBool32 validateSurface(layer_data *my_data, VkSurfaceKHR surface, char *fn)
80{
81 VkBool32 skipCall = VK_FALSE;
Ian Elliotta983e9a2015-12-22 12:18:12 -070082 SwpSurface *pSurface = &my_data->surfaceMap[surface];
Ian Elliott55646bd2016-01-05 11:24:56 -070083
Ian Elliotta983e9a2015-12-22 12:18:12 -070084 if ((pSurface == NULL) || (pSurface->surface != surface)) {
Ian Elliott1bf155f2015-12-29 17:35:46 -070085 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, surface, "VkSurfaceKHR",
Ian Elliotta983e9a2015-12-22 12:18:12 -070086 SWAPCHAIN_INVALID_HANDLE,
87 "%s() called with an invalid surface object.",
88 fn);
89 }
90 return skipCall;
91}
Ian Elliott0b4d6242015-09-22 10:51:24 -060092
Ian Elliott0b4d6242015-09-22 10:51:24 -060093static void createDeviceRegisterExtensions(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
94{
95 uint32_t i;
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070096 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
97 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -060098
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -070099 VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table;
100 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
101
102 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
103 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
104 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
105 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
106 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
107
108 SwpPhysicalDevice *pPhysicalDevice = &my_instance_data->physicalDeviceMap[physicalDevice];
Ian Elliott0b4d6242015-09-22 10:51:24 -0600109 if (pPhysicalDevice) {
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -0700110 my_device_data->deviceMap[device].pPhysicalDevice = pPhysicalDevice;
111 pPhysicalDevice->pDevice = &my_device_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -0600112 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700113 log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Mark Lobodzinski80e774f2016-01-04 15:54:59 -0700114 (uint64_t)physicalDevice , __LINE__, SWAPCHAIN_INVALID_HANDLE, "Swapchain",
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -0700115 "vkCreateDevice() called with a non-valid VkPhysicalDevice.");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600116 }
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -0700117 my_device_data->deviceMap[device].device = device;
Ian Elliott427058f2015-12-29 16:45:49 -0700118 my_device_data->deviceMap[device].swapchainExtensionEnabled = false;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600119
120 // Record whether the WSI device extension was enabled for this VkDevice.
121 // No need to check if the extension was advertised by
122 // vkEnumerateDeviceExtensionProperties(), since the loader handles that.
Chia-I Wud50a7d72015-10-26 20:48:51 +0800123 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700124 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600125
Ian Elliott427058f2015-12-29 16:45:49 -0700126 my_device_data->deviceMap[device].swapchainExtensionEnabled = true;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600127 }
128 }
129}
130
131static void createInstanceRegisterExtensions(const VkInstanceCreateInfo* pCreateInfo, VkInstance instance)
132{
133 uint32_t i;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600134 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
135 VkLayerInstanceDispatchTable *pDisp = my_data->instance_dispatch_table;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600136 PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700137#ifdef VK_USE_PLATFORM_ANDROID_KHR
138 pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) gpa(instance, "vkCreateAndroidSurfaceKHR");
139#endif // VK_USE_PLATFORM_ANDROID_KHR
140#ifdef VK_USE_PLATFORM_MIR_KHR
141 pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR) gpa(instance, "vkCreateMirSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700142 pDisp->GetPhysicalDeviceMirPresentationSupportKHR = (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700143#endif // VK_USE_PLATFORM_MIR_KHR
144#ifdef VK_USE_PLATFORM_WAYLAND_KHR
145 pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR) gpa(instance, "vkCreateWaylandSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700146 pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700147#endif // VK_USE_PLATFORM_WAYLAND_KHR
148#ifdef VK_USE_PLATFORM_WIN32_KHR
149 pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) gpa(instance, "vkCreateWin32SurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700150 pDisp->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700151#endif // VK_USE_PLATFORM_WIN32_KHR
152#ifdef VK_USE_PLATFORM_XCB_KHR
153 pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700154 pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700155#endif // VK_USE_PLATFORM_XCB_KHR
156#ifdef VK_USE_PLATFORM_XLIB_KHR
157 pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) gpa(instance, "vkCreateXlibSurfaceKHR");
Ian Elliott55ff7962015-12-30 10:18:47 -0700158 pDisp->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
Ian Elliotta983e9a2015-12-22 12:18:12 -0700159#endif // VK_USE_PLATFORM_XLIB_KHR
160 pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) gpa(instance, "vkDestroySurfaceKHR");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600161 pDisp->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
Ian Elliott27d39c72015-11-20 16:39:34 -0700162 pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
163 pDisp->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
164 pDisp->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600165
Ian Elliott1dcd1092015-11-17 17:29:40 -0700166 // Remember this instance, and whether the VK_KHR_surface extension
Ian Elliott0b4d6242015-09-22 10:51:24 -0600167 // was enabled for it:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600168 my_data->instanceMap[instance].instance = instance;
Ian Elliott1cb77a62015-12-29 16:44:39 -0700169 my_data->instanceMap[instance].surfaceExtensionEnabled = false;
Ian Elliott8dffaf32016-01-04 14:10:30 -0700170#ifdef VK_USE_PLATFORM_ANDROID_KHR
171 my_data->instanceMap[instance].androidSurfaceExtensionEnabled = false;
172#endif // VK_USE_PLATFORM_ANDROID_KHR
173#ifdef VK_USE_PLATFORM_MIR_KHR
174 my_data->instanceMap[instance].mirSurfaceExtensionEnabled = false;
175#endif // VK_USE_PLATFORM_MIR_KHR
176#ifdef VK_USE_PLATFORM_WAYLAND_KHR
177 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = false;
178#endif // VK_USE_PLATFORM_WAYLAND_KHR
179#ifdef VK_USE_PLATFORM_WIN32_KHR
180 my_data->instanceMap[instance].win32SurfaceExtensionEnabled = false;
181#endif // VK_USE_PLATFORM_WIN32_KHR
182#ifdef VK_USE_PLATFORM_XCB_KHR
183 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = false;
184#endif // VK_USE_PLATFORM_XCB_KHR
185#ifdef VK_USE_PLATFORM_XLIB_KHR
186 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = false;
187#endif // VK_USE_PLATFORM_XLIB_KHR
188
Ian Elliott0b4d6242015-09-22 10:51:24 -0600189
190 // Record whether the WSI instance extension was enabled for this
191 // VkInstance. No need to check if the extension was advertised by
192 // vkEnumerateInstanceExtensionProperties(), since the loader handles that.
Chia-I Wud50a7d72015-10-26 20:48:51 +0800193 for (i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott1dcd1092015-11-17 17:29:40 -0700194 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
Ian Elliott0b4d6242015-09-22 10:51:24 -0600195
Ian Elliott1cb77a62015-12-29 16:44:39 -0700196 my_data->instanceMap[instance].surfaceExtensionEnabled = true;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600197 }
Ian Elliott8dffaf32016-01-04 14:10:30 -0700198#ifdef VK_USE_PLATFORM_ANDROID_KHR
199 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
200
201 my_data->instanceMap[instance].androidSurfaceExtensionEnabled = true;
202#endif // VK_USE_PLATFORM_ANDROID_KHR
203#ifdef VK_USE_PLATFORM_MIR_KHR
204 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
205
206 my_data->instanceMap[instance].mirSurfaceExtensionEnabled = true;
207#endif // VK_USE_PLATFORM_MIR_KHR
208#ifdef VK_USE_PLATFORM_WAYLAND_KHR
209 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
210
211 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = true;
212#endif // VK_USE_PLATFORM_WAYLAND_KHR
213#ifdef VK_USE_PLATFORM_WIN32_KHR
214 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
215
216 my_data->instanceMap[instance].win32SurfaceExtensionEnabled = true;
217#endif // VK_USE_PLATFORM_WIN32_KHR
218#ifdef VK_USE_PLATFORM_XCB_KHR
219 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
220
221 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = true;
222#endif // VK_USE_PLATFORM_XCB_KHR
223#ifdef VK_USE_PLATFORM_XLIB_KHR
224 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
225
226 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = true;
227#endif // VK_USE_PLATFORM_XLIB_KHR
228 }
Ian Elliott0b4d6242015-09-22 10:51:24 -0600229 }
230}
231
232
233#include "vk_dispatch_table_helper.h"
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700234static void initSwapchain(layer_data *my_data, const VkAllocationCallbacks *pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600235{
236 uint32_t report_flags = 0;
237 uint32_t debug_action = 0;
238 FILE *log_output = NULL;
239 const char *option_str;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700240 VkDebugReportCallbackEXT callback;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600241
242 // Initialize Swapchain options:
243 report_flags = getLayerOptionFlags("SwapchainReportFlags", 0);
244 getLayerOptionEnum("SwapchainDebugAction", (uint32_t *) &debug_action);
245
246 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
247 {
248 // Turn on logging, since it was requested:
249 option_str = getLayerOption("SwapchainLogFilename");
250 log_output = getLayerLogOutput(option_str, "Swapchain");
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700251 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700252 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700253 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700254 dbgInfo.pfnCallback = log_callback;
255 dbgInfo.pUserData = log_output;
256 dbgInfo.flags = report_flags;
257 layer_create_msg_callback(my_data->report_data,
258 &dbgInfo,
259 pAllocator,
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600260 &callback);
261 my_data->logging_callback.push_back(callback);
262 }
263 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700264 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700265 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700266 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700267 dbgInfo.pfnCallback = win32_debug_output_msg;
268 dbgInfo.pUserData = log_output;
269 dbgInfo.flags = report_flags;
270 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600271 my_data->logging_callback.push_back(callback);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600272 }
273}
274
Ian Elliott27d39c72015-11-20 16:39:34 -0700275static const char *surfaceTransformStr(VkSurfaceTransformFlagBitsKHR value)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600276{
Ian Elliott0b4d6242015-09-22 10:51:24 -0600277 // Return a string corresponding to the value:
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -0700278 return string_VkSurfaceTransformFlagBitsKHR(value);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600279}
280
Ian Elliotta2a89c52015-12-28 15:23:57 -0700281static const char *surfaceCompositeAlphaStr(VkCompositeAlphaFlagBitsKHR value)
282{
283 // Return a string corresponding to the value:
284 return string_VkCompositeAlphaFlagBitsKHR(value);
285}
286
Ian Elliott0b4d6242015-09-22 10:51:24 -0600287static const char *presentModeStr(VkPresentModeKHR value)
288{
Ian Elliott0b4d6242015-09-22 10:51:24 -0600289 // Return a string corresponding to the value:
Ian Elliott24491af2015-12-28 15:04:49 -0700290 return string_VkPresentModeKHR(value);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600291}
292
Ian Elliotta2a89c52015-12-28 15:23:57 -0700293static const char *sharingModeStr(VkSharingMode value)
294{
295 // Return a string corresponding to the value:
296 return string_VkSharingMode(value);
297}
298
Ian Elliott0b4d6242015-09-22 10:51:24 -0600299
Chia-I Wu9ab61502015-11-06 06:42:02 +0800300VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600301{
Tobin Ehlis711ff312015-10-29 12:58:13 -0600302 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600303 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600304 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800305 VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600306 if (result == VK_SUCCESS) {
307 // Since it succeeded, do layer-specific work:
Ian Elliott68124ac2015-10-07 16:18:35 -0600308 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
309 my_data->report_data = debug_report_create_instance(
Tobin Ehlis711ff312015-10-29 12:58:13 -0600310 pTable,
Ian Elliott68124ac2015-10-07 16:18:35 -0600311 *pInstance,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800312 pCreateInfo->enabledExtensionNameCount,
Ian Elliott68124ac2015-10-07 16:18:35 -0600313 pCreateInfo->ppEnabledExtensionNames);
314 // Call the following function after my_data is initialized:
Ian Elliott0b4d6242015-09-22 10:51:24 -0600315 createInstanceRegisterExtensions(pCreateInfo, *pInstance);
Courtney Goeltzenleuchter6d8e8182015-11-25 14:31:49 -0700316 initSwapchain(my_data, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600317 }
318 return result;
319}
320
Chia-I Wu9ab61502015-11-06 06:42:02 +0800321VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600322{
323 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600324 dispatch_key key = get_dispatch_key(instance);
325 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600326 // Validate that a valid VkInstance was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600327 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600328 if (!pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700329 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -0600330 instance,
331 "VkInstance");
332 }
333
334 if (VK_FALSE == skipCall) {
335 // Call down the call chain:
Chia-I Wuf7458c52015-10-26 21:10:41 +0800336 my_data->instance_dispatch_table->DestroyInstance(instance, pAllocator);
Ian Elliott68124ac2015-10-07 16:18:35 -0600337
338 // Clean up logging callback, if any
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600339 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700340 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700341 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchtercf60e0a2015-10-08 17:07:25 -0600342 my_data->logging_callback.pop_back();
Ian Elliott68124ac2015-10-07 16:18:35 -0600343 }
344 layer_debug_report_destroy_instance(my_data->report_data);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600345 }
346
347 // Regardless of skipCall value, do some internal cleanup:
348 if (pInstance) {
349 // Delete all of the SwpPhysicalDevice's and the SwpInstance associated
350 // with this instance:
351 for (auto it = pInstance->physicalDevices.begin() ;
352 it != pInstance->physicalDevices.end() ; it++) {
Ian Elliott27d39c72015-11-20 16:39:34 -0700353
354 // Free memory that was allocated for/by this SwpPhysicalDevice:
355 SwpPhysicalDevice *pPhysicalDevice = it->second;
356 free(pPhysicalDevice->pSurfaceFormats);
357 free(pPhysicalDevice->pPresentModes);
358
Tobin Ehlis711ff312015-10-29 12:58:13 -0600359 // Erase the SwpPhysicalDevice's from the my_data->physicalDeviceMap (which
Ian Elliott0b4d6242015-09-22 10:51:24 -0600360 // are simply pointed to by the SwpInstance):
Tobin Ehlis711ff312015-10-29 12:58:13 -0600361 my_data->physicalDeviceMap.erase(it->second->physicalDevice);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600362 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600363 my_data->instanceMap.erase(instance);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600364 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600365 delete my_data->instance_dispatch_table;
366 layer_data_map.erase(key);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600367}
368
Ian Elliotta983e9a2015-12-22 12:18:12 -0700369#ifdef VK_USE_PLATFORM_ANDROID_KHR
370VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(
371 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700372 const VkAndroidSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700373 const VkAllocationCallbacks* pAllocator,
374 VkSurfaceKHR* pSurface)
375{
376 VkResult result = VK_SUCCESS;
377 VkBool32 skipCall = VK_FALSE;
378 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
379
380 // Validate that a valid VkInstance was used:
381 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
382 if (!pInstance) {
Ian Elliott1bf155f2015-12-29 17:35:46 -0700383 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700384 instance,
385 "VkInstance");
386 }
Ian Elliottf5758292015-12-30 17:39:02 -0700387 if (!pCreateInfo) {
388 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
389 device,
390 "pCreateInfo");
391 } else {
392 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR) {
393 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
394 device,
395 "pCreateInfo",
396 "VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR");
397 }
398 if (pCreateInfo->pNext != NULL) {
399 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
400 device,
401 "pCreateInfo");
402 }
403 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700404
405 if (VK_FALSE == skipCall) {
406 // Call down the call chain:
407 result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700408 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700409
410 if ((result == VK_SUCCESS) && pInstance && pSurface) {
411 // Record the VkSurfaceKHR returned by the ICD:
412 my_data->surfaceMap[*pSurface].surface = *pSurface;
413 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700414 // Point to the associated SwpInstance:
415 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
416 skipCall |= validateSurface(my_data, *pSurface, (char *) __FUNCTION__);
417 }
418 return result;
419 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700420 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700421}
422#endif // VK_USE_PLATFORM_ANDROID_KHR
423
424#ifdef VK_USE_PLATFORM_MIR_KHR
425VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
426 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700427 const VkMirSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700428 const VkAllocationCallbacks* pAllocator,
429 VkSurfaceKHR* pSurface)
430{
431 VkResult result = VK_SUCCESS;
432 VkBool32 skipCall = VK_FALSE;
433 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
434
435 // Validate that a valid VkInstance was used:
436 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
437 if (!pInstance) {
Ian Elliott1bf155f2015-12-29 17:35:46 -0700438 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700439 instance,
440 "VkInstance");
441 }
Ian Elliottf5758292015-12-30 17:39:02 -0700442 if (!pCreateInfo) {
443 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
444 device,
445 "pCreateInfo");
446 } else {
447 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR) {
448 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
449 device,
450 "pCreateInfo",
451 "VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR");
452 }
453 if (pCreateInfo->pNext != NULL) {
454 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
455 device,
456 "pCreateInfo");
457 }
458 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700459
460 if (VK_FALSE == skipCall) {
461 // Call down the call chain:
462 result = my_data->instance_dispatch_table->CreateMirSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700463 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700464
465 if ((result == VK_SUCCESS) && pInstance && pSurface) {
466 // Record the VkSurfaceKHR returned by the ICD:
467 my_data->surfaceMap[*pSurface].surface = *pSurface;
468 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700469 // Point to the associated SwpInstance:
470 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
471 skipCall |= validateSurface(my_data, *pSurface, (char *) __FUNCTION__);
472 }
473 return result;
474 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700475 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700476}
Ian Elliott55ff7962015-12-30 10:18:47 -0700477
478VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
479 VkPhysicalDevice physicalDevice,
480 uint32_t queueFamilyIndex,
481 MirConnection* connection)
482{
483 VkBool32 result = VK_FALSE;
484 VkBool32 skipCall = VK_FALSE;
485 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
486
Ian Elliott8dffaf32016-01-04 14:10:30 -0700487 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700488 // extension was enabled:
489 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
490 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
491 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
492 physicalDevice,
493 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700494 } else if (!pPhysicalDevice->pInstance->mirSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700495 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
496 pPhysicalDevice->pInstance,
497 "VkInstance",
498 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
499 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700500 __FUNCTION__, VK_KHR_MIR_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700501 }
502
503 if (VK_FALSE == skipCall) {
504 // Call down the call chain:
505 result = my_data->instance_dispatch_table->GetPhysicalDeviceMirPresentationSupportKHR(
506 physicalDevice, queueFamilyIndex, connection);
507
508 if (pPhysicalDevice) {
509 // Record the result of this query:
510 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
511 }
512 }
513 return result;
514}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700515#endif // VK_USE_PLATFORM_MIR_KHR
516
517#ifdef VK_USE_PLATFORM_WAYLAND_KHR
518VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
519 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700520 const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700521 const VkAllocationCallbacks* pAllocator,
522 VkSurfaceKHR* pSurface)
523{
524 VkResult result = VK_SUCCESS;
525 VkBool32 skipCall = VK_FALSE;
526 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
527
528 // Validate that a valid VkInstance was used:
529 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
530 if (!pInstance) {
Ian Elliott1bf155f2015-12-29 17:35:46 -0700531 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700532 instance,
533 "VkInstance");
534 }
Ian Elliottf5758292015-12-30 17:39:02 -0700535 if (!pCreateInfo) {
536 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
537 device,
538 "pCreateInfo");
539 } else {
540 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR) {
541 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
542 device,
543 "pCreateInfo",
544 "VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR");
545 }
546 if (pCreateInfo->pNext != NULL) {
547 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
548 device,
549 "pCreateInfo");
550 }
551 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700552
553 if (VK_FALSE == skipCall) {
554 // Call down the call chain:
555 result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700556 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700557
558 if ((result == VK_SUCCESS) && pInstance && pSurface) {
559 // Record the VkSurfaceKHR returned by the ICD:
560 my_data->surfaceMap[*pSurface].surface = *pSurface;
561 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700562 // Point to the associated SwpInstance:
563 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
564 skipCall |= validateSurface(my_data, *pSurface, (char *) __FUNCTION__);
565 }
566 return result;
567 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700568 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700569}
Ian Elliott55ff7962015-12-30 10:18:47 -0700570
571VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(
572 VkPhysicalDevice physicalDevice,
573 uint32_t queueFamilyIndex,
574 struct wl_display* display)
575{
576 VkBool32 result = VK_FALSE;
577 VkBool32 skipCall = VK_FALSE;
578 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
579
Ian Elliott8dffaf32016-01-04 14:10:30 -0700580 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700581 // extension was enabled:
582 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
583 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
584 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
585 physicalDevice,
586 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700587 } else if (!pPhysicalDevice->pInstance->waylandSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700588 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
589 pPhysicalDevice->pInstance,
590 "VkInstance",
591 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
592 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700593 __FUNCTION__, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700594 }
595
596 if (VK_FALSE == skipCall) {
597 // Call down the call chain:
598 result = my_data->instance_dispatch_table->GetPhysicalDeviceWaylandPresentationSupportKHR(
599 physicalDevice, queueFamilyIndex, display);
600
601 if (pPhysicalDevice) {
602 // Record the result of this query:
603 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
604 }
605 }
606 return result;
607}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700608#endif // VK_USE_PLATFORM_WAYLAND_KHR
609
610#ifdef VK_USE_PLATFORM_WIN32_KHR
611VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
612 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700613 const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700614 const VkAllocationCallbacks* pAllocator,
615 VkSurfaceKHR* pSurface)
616{
617 VkResult result = VK_SUCCESS;
618 VkBool32 skipCall = VK_FALSE;
619 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
620
621 // Validate that a valid VkInstance was used:
622 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
623 if (!pInstance) {
Ian Elliott1bf155f2015-12-29 17:35:46 -0700624 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700625 instance,
626 "VkInstance");
627 }
Ian Elliottf5758292015-12-30 17:39:02 -0700628 if (!pCreateInfo) {
629 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
630 device,
631 "pCreateInfo");
632 } else {
633 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR) {
634 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
635 device,
636 "pCreateInfo",
637 "VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR");
638 }
639 if (pCreateInfo->pNext != NULL) {
640 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
641 device,
642 "pCreateInfo");
643 }
644 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700645
646 if (VK_FALSE == skipCall) {
647 // Call down the call chain:
648 result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700649 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700650
651 if ((result == VK_SUCCESS) && pInstance && pSurface) {
652 // Record the VkSurfaceKHR returned by the ICD:
653 my_data->surfaceMap[*pSurface].surface = *pSurface;
654 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700655 // Point to the associated SwpInstance:
656 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
657 skipCall |= validateSurface(my_data, *pSurface, (char *) __FUNCTION__);
658 }
659 return result;
660 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700661 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700662}
Ian Elliott55ff7962015-12-30 10:18:47 -0700663
664VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
665 VkPhysicalDevice physicalDevice,
666 uint32_t queueFamilyIndex)
667{
668 VkBool32 result = VK_FALSE;
669 VkBool32 skipCall = VK_FALSE;
670 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
671
Ian Elliott8dffaf32016-01-04 14:10:30 -0700672 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700673 // extension was enabled:
674 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
675 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
676 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
677 physicalDevice,
678 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700679 } else if (!pPhysicalDevice->pInstance->win32SurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700680 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
681 pPhysicalDevice->pInstance,
682 "VkInstance",
683 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
684 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700685 __FUNCTION__, VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700686 }
687
688 if (VK_FALSE == skipCall) {
689 // Call down the call chain:
690 result = my_data->instance_dispatch_table->GetPhysicalDeviceWin32PresentationSupportKHR(
691 physicalDevice, queueFamilyIndex);
692
693 if (pPhysicalDevice) {
694 // Record the result of this query:
695 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
696 }
697 }
698 return result;
699}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700700#endif // VK_USE_PLATFORM_WIN32_KHR
701
702#ifdef VK_USE_PLATFORM_XCB_KHR
703VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(
704 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700705 const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700706 const VkAllocationCallbacks* pAllocator,
707 VkSurfaceKHR* pSurface)
708{
709 VkResult result = VK_SUCCESS;
710 VkBool32 skipCall = VK_FALSE;
711 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
712
713 // Validate that a valid VkInstance was used:
714 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
715 if (!pInstance) {
Ian Elliott1bf155f2015-12-29 17:35:46 -0700716 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700717 instance,
718 "VkInstance");
719 }
Ian Elliottf5758292015-12-30 17:39:02 -0700720 if (!pCreateInfo) {
721 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
722 device,
723 "pCreateInfo");
724 } else {
725 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) {
726 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
727 device,
728 "pCreateInfo",
729 "VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR");
730 }
731 if (pCreateInfo->pNext != NULL) {
732 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
733 device,
734 "pCreateInfo");
735 }
736 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700737
738 if (VK_FALSE == skipCall) {
739 // Call down the call chain:
740 result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700741 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700742
743 if ((result == VK_SUCCESS) && pInstance && pSurface) {
744 // Record the VkSurfaceKHR returned by the ICD:
745 my_data->surfaceMap[*pSurface].surface = *pSurface;
746 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700747 // Point to the associated SwpInstance:
748 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
749 skipCall |= validateSurface(my_data, *pSurface, (char *) __FUNCTION__);
750 }
751 return result;
752 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700753 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700754}
Ian Elliott55ff7962015-12-30 10:18:47 -0700755
756VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(
757 VkPhysicalDevice physicalDevice,
758 uint32_t queueFamilyIndex,
759 xcb_connection_t* connection,
760 xcb_visualid_t visual_id)
761{
762 VkBool32 result = VK_FALSE;
763 VkBool32 skipCall = VK_FALSE;
764 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
765
Ian Elliott8dffaf32016-01-04 14:10:30 -0700766 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700767 // extension was enabled:
768 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
769 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
770 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
771 physicalDevice,
772 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700773 } else if (!pPhysicalDevice->pInstance->xcbSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700774 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
775 pPhysicalDevice->pInstance,
776 "VkInstance",
777 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
778 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700779 __FUNCTION__, VK_KHR_XCB_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700780 }
781
782 if (VK_FALSE == skipCall) {
783 // Call down the call chain:
784 result = my_data->instance_dispatch_table->GetPhysicalDeviceXcbPresentationSupportKHR(
785 physicalDevice, queueFamilyIndex, connection, visual_id);
786
787 if (pPhysicalDevice) {
788 // Record the result of this query:
789 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
790 }
791 }
792 return result;
793}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700794#endif // VK_USE_PLATFORM_XCB_KHR
795
796#ifdef VK_USE_PLATFORM_XLIB_KHR
797VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(
798 VkInstance instance,
Ian Elliott1bf155f2015-12-29 17:35:46 -0700799 const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700800 const VkAllocationCallbacks* pAllocator,
801 VkSurfaceKHR* pSurface)
802{
803 VkResult result = VK_SUCCESS;
804 VkBool32 skipCall = VK_FALSE;
805 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
806
807 // Validate that a valid VkInstance was used:
808 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
809 if (!pInstance) {
Ian Elliott1bf155f2015-12-29 17:35:46 -0700810 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700811 instance,
812 "VkInstance");
813 }
Ian Elliottf5758292015-12-30 17:39:02 -0700814 if (!pCreateInfo) {
815 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
816 device,
817 "pCreateInfo");
818 } else {
819 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR) {
820 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
821 device,
822 "pCreateInfo",
823 "VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR");
824 }
825 if (pCreateInfo->pNext != NULL) {
826 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
827 device,
828 "pCreateInfo");
829 }
830 }
Ian Elliotta983e9a2015-12-22 12:18:12 -0700831
832 if (VK_FALSE == skipCall) {
833 // Call down the call chain:
834 result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR(
Ian Elliott1bf155f2015-12-29 17:35:46 -0700835 instance, pCreateInfo, pAllocator, pSurface);
Ian Elliotta983e9a2015-12-22 12:18:12 -0700836
837 if ((result == VK_SUCCESS) && pInstance && pSurface) {
838 // Record the VkSurfaceKHR returned by the ICD:
839 my_data->surfaceMap[*pSurface].surface = *pSurface;
840 my_data->surfaceMap[*pSurface].pInstance = pInstance;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700841 // Point to the associated SwpInstance:
842 pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface];
843 skipCall |= validateSurface(my_data, *pSurface, (char *) __FUNCTION__);
844 }
845 return result;
846 }
Ian Elliott1bf155f2015-12-29 17:35:46 -0700847 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliotta983e9a2015-12-22 12:18:12 -0700848}
Ian Elliott55ff7962015-12-30 10:18:47 -0700849
850VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(
851 VkPhysicalDevice physicalDevice,
852 uint32_t queueFamilyIndex,
853 Display* dpy,
854 VisualID visualID)
855{
856 VkBool32 result = VK_FALSE;
857 VkBool32 skipCall = VK_FALSE;
858 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
859
Ian Elliott8dffaf32016-01-04 14:10:30 -0700860 // Validate that a valid VkPhysicalDevice was used, and that the platform
Ian Elliott55ff7962015-12-30 10:18:47 -0700861 // extension was enabled:
862 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
863 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
864 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
865 physicalDevice,
866 "VkPhysicalDevice");
Ian Elliott8dffaf32016-01-04 14:10:30 -0700867 } else if (!pPhysicalDevice->pInstance->xlibSurfaceExtensionEnabled) {
Ian Elliott55ff7962015-12-30 10:18:47 -0700868 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
869 pPhysicalDevice->pInstance,
870 "VkInstance",
871 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
872 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott8dffaf32016-01-04 14:10:30 -0700873 __FUNCTION__, VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
Ian Elliott55ff7962015-12-30 10:18:47 -0700874 }
875
876 if (VK_FALSE == skipCall) {
877 // Call down the call chain:
878 result = my_data->instance_dispatch_table->GetPhysicalDeviceXlibPresentationSupportKHR(
879 physicalDevice, queueFamilyIndex, dpy, visualID);
880
881 if (pPhysicalDevice) {
882 // Record the result of this query:
883 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] = result;
884 }
885 }
886 return result;
887}
Ian Elliotta983e9a2015-12-22 12:18:12 -0700888#endif // VK_USE_PLATFORM_XLIB_KHR
889
890VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator)
891{
892 VkBool32 skipCall = VK_FALSE;
893 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
894
895 // Validate that a valid VkInstance was used:
896 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
897 if (!pInstance) {
Ian Elliott1bf155f2015-12-29 17:35:46 -0700898 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliotta983e9a2015-12-22 12:18:12 -0700899 instance,
900 "VkInstance");
901 }
902
903 if (VK_FALSE == skipCall) {
904 // Validate that a valid VkSurfaceKHR was used:
905 skipCall |= validateSurface(my_data, surface, (char *) __FUNCTION__);
906 }
907
908 if (VK_FALSE == skipCall) {
909 // Call down the call chain:
910 my_data->instance_dispatch_table->DestroySurfaceKHR(
911 instance, surface, pAllocator);
912 }
913
914 // Regardless of skipCall value, do some internal cleanup:
915 SwpSurface *pSurface = &my_data->surfaceMap[surface];
916 if (pSurface && pSurface->pInstance) {
917 pSurface->pInstance->surfaces.erase(surface);
918 }
919 my_data->surfaceMap.erase(surface);
920}
921
Chia-I Wu9ab61502015-11-06 06:42:02 +0800922VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600923{
924 VkResult result = VK_SUCCESS;
925 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600926 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600927
928 // Validate that a valid VkInstance was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600929 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600930 if (!pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700931 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -0600932 instance,
933 "VkInstance");
934 }
935
936 if (VK_FALSE == skipCall) {
937 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600938 result = my_data->instance_dispatch_table->EnumeratePhysicalDevices(
Ian Elliott0b4d6242015-09-22 10:51:24 -0600939 instance, pPhysicalDeviceCount, pPhysicalDevices);
940
941 if ((result == VK_SUCCESS) && pInstance && pPhysicalDevices &&
942 (*pPhysicalDeviceCount > 0)) {
943 // Record the VkPhysicalDevices returned by the ICD:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600944 SwpInstance *pInstance = &(my_data->instanceMap[instance]);
Courtney Goeltzenleuchterdad30df2015-10-07 09:00:34 -0600945 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
Tobin Ehlis711ff312015-10-29 12:58:13 -0600946 my_data->physicalDeviceMap[pPhysicalDevices[i]].physicalDevice =
Ian Elliott0b4d6242015-09-22 10:51:24 -0600947 pPhysicalDevices[i];
Tobin Ehlis711ff312015-10-29 12:58:13 -0600948 my_data->physicalDeviceMap[pPhysicalDevices[i]].pInstance = pInstance;
949 my_data->physicalDeviceMap[pPhysicalDevices[i]].pDevice = NULL;
Ian Elliott27d39c72015-11-20 16:39:34 -0700950 my_data->physicalDeviceMap[pPhysicalDevices[i]].gotSurfaceCapabilities = false;
951 my_data->physicalDeviceMap[pPhysicalDevices[i]].surfaceFormatCount = 0;
952 my_data->physicalDeviceMap[pPhysicalDevices[i]].pSurfaceFormats = NULL;
953 my_data->physicalDeviceMap[pPhysicalDevices[i]].presentModeCount = 0;
954 my_data->physicalDeviceMap[pPhysicalDevices[i]].pPresentModes = NULL;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600955 // Point to the associated SwpInstance:
956 pInstance->physicalDevices[pPhysicalDevices[i]] =
Tobin Ehlis711ff312015-10-29 12:58:13 -0600957 &my_data->physicalDeviceMap[pPhysicalDevices[i]];
Ian Elliott0b4d6242015-09-22 10:51:24 -0600958 }
959 }
960
961 return result;
962 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700963 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600964}
965
Chia-I Wu9ab61502015-11-06 06:42:02 +0800966VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600967{
968 VkResult result = VK_SUCCESS;
969 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -0600970 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600971
972 // Validate that a valid VkPhysicalDevice was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -0600973 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
Ian Elliott0b4d6242015-09-22 10:51:24 -0600974 if (!pPhysicalDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700975 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Mark Lobodzinski6c1cb5a2015-11-05 15:27:03 -0700976 physicalDevice, "VkPhysicalDevice");
Ian Elliott0b4d6242015-09-22 10:51:24 -0600977 }
978
Tobin Ehlis711ff312015-10-29 12:58:13 -0600979 if (VK_TRUE == skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -0700980 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600981
982 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
983 // Call down the call chain:
984 result = my_device_data->device_dispatch_table->CreateDevice(
Chia-I Wuf7458c52015-10-26 21:10:41 +0800985 physicalDevice, pCreateInfo, pAllocator, pDevice);
Tobin Ehlis711ff312015-10-29 12:58:13 -0600986 if (result == VK_SUCCESS) {
987 // Since it succeeded, do layer-specific work:
Mark Lobodzinski6c1cb5a2015-11-05 15:27:03 -0700988 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
989 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
990 createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice);
Ian Elliott0b4d6242015-09-22 10:51:24 -0600991 }
Tobin Ehlis711ff312015-10-29 12:58:13 -0600992 return result;
Ian Elliott0b4d6242015-09-22 10:51:24 -0600993}
994
Chia-I Wu9ab61502015-11-06 06:42:02 +0800995VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -0600996{
997 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis711ff312015-10-29 12:58:13 -0600998 dispatch_key key = get_dispatch_key(device);
999 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001000 // Validate that a valid VkDevice was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001001 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001002 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001003 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001004 device,
1005 "VkDevice");
1006 }
1007
1008 if (VK_FALSE == skipCall) {
1009 // Call down the call chain:
Chia-I Wuf7458c52015-10-26 21:10:41 +08001010 my_data->device_dispatch_table->DestroyDevice(device, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001011 }
1012
1013 // Regardless of skipCall value, do some internal cleanup:
1014 if (pDevice) {
1015 // Delete the SwpDevice associated with this device:
1016 if (pDevice->pPhysicalDevice) {
1017 pDevice->pPhysicalDevice->pDevice = NULL;
1018 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001019 if (!pDevice->swapchains.empty()) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001020 LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001021 SWAPCHAIN_DEL_DEVICE_BEFORE_SWAPCHAINS,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001022 "%s() called before all of its associated "
1023 "VkSwapchainKHRs were destroyed.",
1024 __FUNCTION__);
1025 // Empty and then delete all SwpSwapchain's
1026 for (auto it = pDevice->swapchains.begin() ;
1027 it != pDevice->swapchains.end() ; it++) {
1028 // Delete all SwpImage's
1029 it->second->images.clear();
1030 }
1031 pDevice->swapchains.clear();
1032 }
Tobin Ehlis711ff312015-10-29 12:58:13 -06001033 my_data->deviceMap.erase(device);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001034 }
Tobin Ehlis711ff312015-10-29 12:58:13 -06001035 delete my_data->device_dispatch_table;
1036 layer_data_map.erase(key);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001037}
1038
Ian Elliott27d39c72015-11-20 16:39:34 -07001039VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(
1040 VkPhysicalDevice physicalDevice,
1041 uint32_t queueFamilyIndex,
1042 VkSurfaceKHR surface,
1043 VkBool32* pSupported)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001044{
Ian Elliott320d0fc2015-12-30 12:04:43 -07001045// TODOs:
1046//
1047// - Ensure that queueFamilyIndex is a valid queue family index for
1048// physicalDevice. How? Probably need to record data from another function
1049// call(s).
Ian Elliott0b4d6242015-09-22 10:51:24 -06001050 VkResult result = VK_SUCCESS;
1051 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001052 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001053
1054 // Validate that a valid VkPhysicalDevice was used, and that the instance
1055 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001056 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001057 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001058 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001059 physicalDevice,
1060 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -07001061 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001062 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001063 pPhysicalDevice->pInstance,
1064 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001065 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001066 "%s() called even though the %s extension was not enabled for this VkInstance.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001067 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001068 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07001069 skipCall |= validateSurface(my_data, surface, (char *) __FUNCTION__);
Ian Elliottf955d682015-12-30 12:00:54 -07001070 if (!pSupported) {
1071 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1072 physicalDevice,
1073 "pSupported");
1074 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001075
1076 if (VK_FALSE == skipCall) {
1077 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001078 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceSupportKHR(
Ian Elliott27d39c72015-11-20 16:39:34 -07001079 physicalDevice, queueFamilyIndex, surface,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001080 pSupported);
1081
1082 if ((result == VK_SUCCESS) && pSupported && pPhysicalDevice) {
1083 // Record the result of this query:
1084 pPhysicalDevice->queueFamilyIndexSupport[queueFamilyIndex] =
1085 *pSupported;
1086 // TODO: We need to compare this with the actual queue used for
1087 // presentation, to ensure it was advertised to the application as
1088 // supported for presentation.
1089 }
1090
1091 return result;
1092 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001093 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001094}
1095
Ian Elliott27d39c72015-11-20 16:39:34 -07001096VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
1097 VkPhysicalDevice physicalDevice,
1098 VkSurfaceKHR surface,
1099 VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001100{
1101 VkResult result = VK_SUCCESS;
1102 VkBool32 skipCall = VK_FALSE;
Ian Elliott27d39c72015-11-20 16:39:34 -07001103 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001104
Ian Elliott27d39c72015-11-20 16:39:34 -07001105 // Validate that a valid VkPhysicalDevice was used, and that the instance
Ian Elliott0b4d6242015-09-22 10:51:24 -06001106 // extension was enabled:
Ian Elliott27d39c72015-11-20 16:39:34 -07001107 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
1108 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001109 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001110 physicalDevice,
1111 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -07001112 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001113 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001114 pPhysicalDevice->pInstance,
1115 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001116 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Ian Elliott27d39c72015-11-20 16:39:34 -07001117 "%s() called even though the %s extension was not enabled for this VkInstance.",
1118 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001119 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07001120 skipCall |= validateSurface(my_data, surface, (char *) __FUNCTION__);
Ian Elliottf955d682015-12-30 12:00:54 -07001121 if (!pSurfaceCapabilities) {
1122 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1123 physicalDevice,
1124 "pSurfaceCapabilities");
1125 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001126
1127 if (VK_FALSE == skipCall) {
1128 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -07001129 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceCapabilitiesKHR(
1130 physicalDevice, surface, pSurfaceCapabilities);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001131
Ian Elliott27d39c72015-11-20 16:39:34 -07001132 if ((result == VK_SUCCESS) && pPhysicalDevice) {
Ian Elliottf955d682015-12-30 12:00:54 -07001133 // Record the result of this query:
Ian Elliott27d39c72015-11-20 16:39:34 -07001134 pPhysicalDevice->gotSurfaceCapabilities = true;
1135// FIXME: NEED TO COPY THIS DATA, BECAUSE pSurfaceCapabilities POINTS TO APP-ALLOCATED DATA
1136 pPhysicalDevice->surfaceCapabilities = *pSurfaceCapabilities;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001137 }
1138
1139 return result;
1140 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001141 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001142}
1143
Ian Elliott27d39c72015-11-20 16:39:34 -07001144VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(
1145 VkPhysicalDevice physicalDevice,
1146 VkSurfaceKHR surface,
Ian Elliottf955d682015-12-30 12:00:54 -07001147 uint32_t* pSurfaceFormatCount,
Ian Elliott27d39c72015-11-20 16:39:34 -07001148 VkSurfaceFormatKHR* pSurfaceFormats)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001149{
1150 VkResult result = VK_SUCCESS;
1151 VkBool32 skipCall = VK_FALSE;
Ian Elliott27d39c72015-11-20 16:39:34 -07001152 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001153
Ian Elliott27d39c72015-11-20 16:39:34 -07001154 // Validate that a valid VkPhysicalDevice was used, and that the instance
Ian Elliott0b4d6242015-09-22 10:51:24 -06001155 // extension was enabled:
Ian Elliott27d39c72015-11-20 16:39:34 -07001156 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
1157 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001158 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001159 physicalDevice,
1160 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -07001161 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001162 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001163 pPhysicalDevice->pInstance,
1164 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001165 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Ian Elliott27d39c72015-11-20 16:39:34 -07001166 "%s() called even though the %s extension was not enabled for this VkInstance.",
1167 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001168 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07001169 skipCall |= validateSurface(my_data, surface, (char *) __FUNCTION__);
Ian Elliottf955d682015-12-30 12:00:54 -07001170 if (!pSurfaceFormatCount) {
1171 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1172 physicalDevice,
1173 "pSurfaceFormatCount");
1174 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001175
1176 if (VK_FALSE == skipCall) {
1177 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -07001178 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceFormatsKHR(
Ian Elliottf955d682015-12-30 12:00:54 -07001179 physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001180
Ian Elliottf955d682015-12-30 12:00:54 -07001181 if ((result == VK_SUCCESS) && pPhysicalDevice && !pSurfaceFormats &&
1182 pSurfaceFormatCount) {
1183 // Record the result of this preliminary query:
1184 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
1185 }
Ian Elliott9059b302015-12-30 13:14:36 -07001186 else if ((result == VK_SUCCESS) && pPhysicalDevice && pSurfaceFormats &&
1187 pSurfaceFormatCount) {
Ian Elliottf955d682015-12-30 12:00:54 -07001188 // Compare the preliminary value of *pSurfaceFormatCount with the
1189 // value this time:
1190 if (*pSurfaceFormatCount != pPhysicalDevice->surfaceFormatCount) {
1191 LOG_ERROR_INVALID_COUNT(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1192 physicalDevice,
1193 "pSurfaceFormatCount",
1194 "pSurfaceFormats",
1195 pPhysicalDevice->surfaceFormatCount);
1196 }
Ian Elliott9059b302015-12-30 13:14:36 -07001197 else if (*pSurfaceFormatCount > 0) {
1198 // Record the result of this query:
1199 pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount;
1200 pPhysicalDevice->pSurfaceFormats = (VkSurfaceFormatKHR *)
1201 malloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
1202 if (pPhysicalDevice->pSurfaceFormats) {
1203 for (uint32_t i = 0 ; i < *pSurfaceFormatCount ; i++) {
1204 pPhysicalDevice->pSurfaceFormats[i] = pSurfaceFormats[i];
1205 }
1206 } else {
1207 pPhysicalDevice->surfaceFormatCount = 0;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001208 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001209 }
1210 }
1211
1212 return result;
1213 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001214 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001215}
1216
Ian Elliott27d39c72015-11-20 16:39:34 -07001217VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(
1218 VkPhysicalDevice physicalDevice,
1219 VkSurfaceKHR surface,
Ian Elliottf955d682015-12-30 12:00:54 -07001220 uint32_t* pPresentModeCount,
Ian Elliott27d39c72015-11-20 16:39:34 -07001221 VkPresentModeKHR* pPresentModes)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001222{
1223 VkResult result = VK_SUCCESS;
1224 VkBool32 skipCall = VK_FALSE;
Ian Elliott27d39c72015-11-20 16:39:34 -07001225 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001226
Ian Elliott27d39c72015-11-20 16:39:34 -07001227 // Validate that a valid VkPhysicalDevice was used, and that the instance
Ian Elliott0b4d6242015-09-22 10:51:24 -06001228 // extension was enabled:
Ian Elliott27d39c72015-11-20 16:39:34 -07001229 SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice];
1230 if (!pPhysicalDevice || !pPhysicalDevice->pInstance) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001231 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001232 physicalDevice,
1233 "VkPhysicalDevice");
Ian Elliott1cb77a62015-12-29 16:44:39 -07001234 } else if (!pPhysicalDevice->pInstance->surfaceExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001235 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001236 pPhysicalDevice->pInstance,
1237 "VkInstance",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001238 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Ian Elliott27d39c72015-11-20 16:39:34 -07001239 "%s() called even though the %s extension was not enabled for this VkInstance.",
1240 __FUNCTION__, VK_KHR_SURFACE_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001241 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07001242 skipCall |= validateSurface(my_data, surface, (char *) __FUNCTION__);
Ian Elliottf955d682015-12-30 12:00:54 -07001243 if (!pPresentModeCount) {
1244 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1245 physicalDevice,
1246 "pPresentModeCount");
1247 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001248
1249 if (VK_FALSE == skipCall) {
1250 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -07001251 result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfacePresentModesKHR(
Ian Elliottf955d682015-12-30 12:00:54 -07001252 physicalDevice, surface, pPresentModeCount, pPresentModes);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001253
Ian Elliottf955d682015-12-30 12:00:54 -07001254 if ((result == VK_SUCCESS) && pPhysicalDevice && !pPresentModes &&
1255 pPresentModeCount) {
1256 // Record the result of this preliminary query:
1257 pPhysicalDevice->presentModeCount = *pPresentModeCount;
1258 }
Ian Elliott9059b302015-12-30 13:14:36 -07001259 else if ((result == VK_SUCCESS) && pPhysicalDevice && pPresentModes &&
1260 pPresentModeCount) {
Ian Elliottf955d682015-12-30 12:00:54 -07001261 // Compare the preliminary value of *pPresentModeCount with the
1262 // value this time:
1263 if (*pPresentModeCount != pPhysicalDevice->presentModeCount) {
1264 LOG_ERROR_INVALID_COUNT(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
1265 physicalDevice,
1266 "pPresentModeCount",
1267 "pPresentModes",
1268 pPhysicalDevice->presentModeCount);
1269 }
Ian Elliott9059b302015-12-30 13:14:36 -07001270 else if (*pPresentModeCount > 0) {
1271 // Record the result of this query:
1272 pPhysicalDevice->presentModeCount = *pPresentModeCount;
1273 pPhysicalDevice->pPresentModes = (VkPresentModeKHR *)
1274 malloc(*pPresentModeCount * sizeof(VkPresentModeKHR));
1275 if (pPhysicalDevice->pSurfaceFormats) {
1276 for (uint32_t i = 0 ; i < *pPresentModeCount ; i++) {
1277 pPhysicalDevice->pPresentModes[i] = pPresentModes[i];
1278 }
1279 } else {
1280 pPhysicalDevice->presentModeCount = 0;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001281 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001282 }
1283 }
1284
1285 return result;
1286 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001287 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001288}
1289
1290// This function does the up-front validation work for vkCreateSwapchainKHR(),
1291// and returns VK_TRUE if a logging callback indicates that the call down the
1292// chain should be skipped:
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001293static VkBool32 validateCreateSwapchainKHR(
1294 VkDevice device,
1295 const VkSwapchainCreateInfoKHR* pCreateInfo,
1296 VkSwapchainKHR* pSwapchain)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001297{
1298// TODO: Validate cases of re-creating a swapchain (the current code
1299// assumes a new swapchain is being created).
1300 VkResult result = VK_SUCCESS;
1301 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001302 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001303 char fn[] = "vkCreateSwapchainKHR";
1304
1305 // Validate that a valid VkDevice was used, and that the device
1306 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001307 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001308 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001309 return LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001310 SWAPCHAIN_INVALID_HANDLE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001311 "%s() called with a non-valid %s.",
1312 fn, "VkDevice");
1313
Ian Elliott427058f2015-12-29 16:45:49 -07001314 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001315 return LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001316 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001317 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001318 fn, VK_KHR_SWAPCHAIN_EXTENSION_NAME );
Ian Elliott0b4d6242015-09-22 10:51:24 -06001319 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001320 if (!pCreateInfo) {
1321 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1322 device,
1323 "pCreateInfo");
Ian Elliottf5758292015-12-30 17:39:02 -07001324 } else {
1325 if (pCreateInfo->sType != VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR) {
1326 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1327 device,
1328 "pCreateInfo",
1329 "VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR");
1330 }
1331 if (pCreateInfo->pNext != NULL) {
1332 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1333 device,
1334 "pCreateInfo");
1335 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001336 }
1337 if (!pSwapchain) {
1338 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1339 device,
1340 "pSwapchain");
1341 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001342
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001343 // Keep around a useful pointer to pPhysicalDevice:
1344 SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
1345
1346 // Validate pCreateInfo->surface:
1347 if (pPhysicalDevice) {
1348 // Note: in order to validate, we must lookup layer_data based on the
1349 // VkInstance associated with this VkDevice:
1350 SwpInstance *pInstance =
1351 (pPhysicalDevice) ? pPhysicalDevice->pInstance : NULL;
1352 layer_data *my_instance_data =
1353 (pInstance) ? get_my_data_ptr(get_dispatch_key(pInstance->instance), layer_data_map) : NULL;
1354 skipCall |= validateSurface(my_instance_data,
1355 pCreateInfo->surface,
1356 (char *) "vkCreateSwapchainKHR");
1357 }
1358
1359 // Validate pCreateInfo values with the results of
1360 // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
1361 if (!pPhysicalDevice || !pPhysicalDevice->gotSurfaceCapabilities) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001362 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001363 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001364 "%s() called before calling "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001365 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001366 fn);
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001367 } else if (pCreateInfo) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001368 // Validate pCreateInfo->minImageCount against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001369 // VkSurfaceCapabilitiesKHR::{min|max}ImageCount:
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001370 VkSurfaceCapabilitiesKHR *pCapabilities = &pPhysicalDevice->surfaceCapabilities;
Ian Elliott27d39c72015-11-20 16:39:34 -07001371 if ((pCreateInfo->minImageCount < pCapabilities->minImageCount) ||
1372 ((pCapabilities->maxImageCount > 0) &&
1373 (pCreateInfo->minImageCount > pCapabilities->maxImageCount))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001374 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001375 SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001376 "%s() called with pCreateInfo->minImageCount "
1377 "= %d, which is outside the bounds returned "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001378 "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. "
Ian Elliott0b4d6242015-09-22 10:51:24 -06001379 "minImageCount = %d, maxImageCount = %d).",
1380 fn,
1381 pCreateInfo->minImageCount,
Ian Elliott27d39c72015-11-20 16:39:34 -07001382 pCapabilities->minImageCount,
1383 pCapabilities->maxImageCount);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001384 }
1385 // Validate pCreateInfo->imageExtent against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001386 // VkSurfaceCapabilitiesKHR::{current|min|max}ImageExtent:
Ian Elliott27d39c72015-11-20 16:39:34 -07001387 if ((pCapabilities->currentExtent.width == -1) &&
1388 ((pCreateInfo->imageExtent.width < pCapabilities->minImageExtent.width) ||
1389 (pCreateInfo->imageExtent.width > pCapabilities->maxImageExtent.width) ||
1390 (pCreateInfo->imageExtent.height < pCapabilities->minImageExtent.height) ||
1391 (pCreateInfo->imageExtent.height > pCapabilities->maxImageExtent.height))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001392 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001393 SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001394 "%s() called with pCreateInfo->imageExtent = "
1395 "(%d,%d), which is outside the bounds "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001396 "returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): "
Ian Elliott0b4d6242015-09-22 10:51:24 -06001397 "currentExtent = (%d,%d), minImageExtent = "
1398 "(%d,%d), maxImageExtent = (%d,%d).",
1399 fn,
1400 pCreateInfo->imageExtent.width,
1401 pCreateInfo->imageExtent.height,
Ian Elliott27d39c72015-11-20 16:39:34 -07001402 pCapabilities->currentExtent.width,
1403 pCapabilities->currentExtent.height,
1404 pCapabilities->minImageExtent.width,
1405 pCapabilities->minImageExtent.height,
1406 pCapabilities->maxImageExtent.width,
1407 pCapabilities->maxImageExtent.height);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001408 }
Ian Elliott27d39c72015-11-20 16:39:34 -07001409 if ((pCapabilities->currentExtent.width != -1) &&
1410 ((pCreateInfo->imageExtent.width != pCapabilities->currentExtent.width) ||
1411 (pCreateInfo->imageExtent.height != pCapabilities->currentExtent.height))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001412 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001413 SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001414 "%s() called with pCreateInfo->imageExtent = "
1415 "(%d,%d), which is not equal to the "
1416 "currentExtent = (%d,%d) returned by "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001417 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001418 fn,
1419 pCreateInfo->imageExtent.width,
1420 pCreateInfo->imageExtent.height,
Ian Elliott27d39c72015-11-20 16:39:34 -07001421 pCapabilities->currentExtent.width,
1422 pCapabilities->currentExtent.height);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001423 }
1424 // Validate pCreateInfo->preTransform against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001425 // VkSurfaceCapabilitiesKHR::supportedTransforms:
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -07001426 if (!((pCreateInfo->preTransform) & pCapabilities->supportedTransforms)) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001427 // This is an error situation; one for which we'd like to give
1428 // the developer a helpful, multi-line error message. Build it
1429 // up a little at a time, and then log it:
1430 std::string errorString = "";
1431 char str[1024];
1432 // Here's the first part of the message:
1433 sprintf(str, "%s() called with a non-supported "
1434 "pCreateInfo->preTransform (i.e. %s). "
1435 "Supported values are:\n",
1436 fn,
1437 surfaceTransformStr(pCreateInfo->preTransform));
1438 errorString += str;
Mark Lobodzinski55cd49b2015-11-27 15:23:23 -07001439 for (int i = 0; i < 32; i++) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001440 // Build up the rest of the message:
Ian Elliott27d39c72015-11-20 16:39:34 -07001441 if ((1 << i) & pCapabilities->supportedTransforms) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001442 const char *newStr =
Ian Elliott27d39c72015-11-20 16:39:34 -07001443 surfaceTransformStr((VkSurfaceTransformFlagBitsKHR) (1 << i));
Ian Elliott0b4d6242015-09-22 10:51:24 -06001444 sprintf(str, " %s\n", newStr);
1445 errorString += str;
1446 }
1447 }
1448 // Log the message that we've built up:
Ian Elliott68124ac2015-10-07 16:18:35 -06001449 skipCall |= debug_report_log_msg(my_data->report_data,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001450 VK_DEBUG_REPORT_ERROR_BIT_EXT,
1451 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Mark Lobodzinski80e774f2016-01-04 15:54:59 -07001452 (uint64_t) device, __LINE__,
Ian Elliottb0f474c2015-09-25 15:50:55 -06001453 SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM,
1454 LAYER_NAME,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001455 errorString.c_str());
1456 }
Ian Elliotta2a89c52015-12-28 15:23:57 -07001457 // Validate pCreateInfo->compositeAlpha against
1458 // VkSurfaceCapabilitiesKHR::supportedCompositeAlpha:
1459 if (!((pCreateInfo->compositeAlpha) & pCapabilities->supportedCompositeAlpha)) {
1460 // This is an error situation; one for which we'd like to give
1461 // the developer a helpful, multi-line error message. Build it
1462 // up a little at a time, and then log it:
1463 std::string errorString = "";
1464 char str[1024];
1465 // Here's the first part of the message:
1466 sprintf(str, "%s() called with a non-supported "
1467 "pCreateInfo->compositeAlpha (i.e. %s). "
1468 "Supported values are:\n",
1469 fn,
1470 surfaceCompositeAlphaStr(pCreateInfo->compositeAlpha));
1471 errorString += str;
1472 for (int i = 0; i < 32; i++) {
1473 // Build up the rest of the message:
1474 if ((1 << i) & pCapabilities->supportedCompositeAlpha) {
1475 const char *newStr =
1476 surfaceCompositeAlphaStr((VkCompositeAlphaFlagBitsKHR) (1 << i));
1477 sprintf(str, " %s\n", newStr);
1478 errorString += str;
1479 }
1480 }
1481 // Log the message that we've built up:
1482 skipCall |= debug_report_log_msg(my_data->report_data,
Ian Elliott1bf155f2015-12-29 17:35:46 -07001483 VK_DEBUG_REPORT_ERROR_BIT_EXT,
1484 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliotta2a89c52015-12-28 15:23:57 -07001485 (uint64_t) device, 0,
1486 SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA,
1487 LAYER_NAME,
1488 errorString.c_str());
1489 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001490 // Validate pCreateInfo->imageArraySize against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001491 // VkSurfaceCapabilitiesKHR::maxImageArraySize:
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001492 if ((pCreateInfo->imageArrayLayers > 0) &&
1493 (pCreateInfo->imageArrayLayers > pCapabilities->maxImageArrayLayers)) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001494 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001495 SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001496 "%s() called with a non-supported "
1497 "pCreateInfo->imageArraySize (i.e. %d). "
1498 "Maximum value is %d.",
1499 fn,
Ian Elliott27d39c72015-11-20 16:39:34 -07001500 pCreateInfo->imageArrayLayers,
1501 pCapabilities->maxImageArrayLayers);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001502 }
Ian Elliott27d39c72015-11-20 16:39:34 -07001503 // Validate pCreateInfo->imageUsage against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001504 // VkSurfaceCapabilitiesKHR::supportedUsageFlags:
Ian Elliott27d39c72015-11-20 16:39:34 -07001505 if (pCreateInfo->imageUsage &&
1506 (pCreateInfo->imageUsage !=
1507 (pCreateInfo->imageUsage & pCapabilities->supportedUsageFlags))) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001508 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001509 SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001510 "%s() called with a non-supported "
Ian Elliott27d39c72015-11-20 16:39:34 -07001511 "pCreateInfo->imageUsage (i.e. 0x%08x)."
Ian Elliott0b4d6242015-09-22 10:51:24 -06001512 " Supported flag bits are 0x%08x.",
1513 fn,
Ian Elliott27d39c72015-11-20 16:39:34 -07001514 pCreateInfo->imageUsage,
1515 pCapabilities->supportedUsageFlags);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001516 }
1517 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001518
1519 // Validate pCreateInfo values with the results of
1520 // vkGetPhysicalDeviceSurfaceFormatsKHR():
1521 if (!pPhysicalDevice || !pPhysicalDevice->surfaceFormatCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001522 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001523 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001524 "%s() called before calling "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001525 "vkGetPhysicalDeviceSurfaceFormatsKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001526 fn);
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001527 } else if (pCreateInfo) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001528 // Validate pCreateInfo->imageFormat against
1529 // VkSurfaceFormatKHR::format:
1530 bool foundFormat = false;
1531 bool foundColorSpace = false;
1532 bool foundMatch = false;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001533 for (uint32_t i = 0 ; i < pPhysicalDevice->surfaceFormatCount ; i++) {
1534 if (pCreateInfo->imageFormat == pPhysicalDevice->pSurfaceFormats[i].format) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001535 // Validate pCreateInfo->imageColorSpace against
1536 // VkSurfaceFormatKHR::colorSpace:
1537 foundFormat = true;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001538 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001539 foundMatch = true;
1540 break;
1541 }
1542 } else {
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001543 if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001544 foundColorSpace = true;
1545 }
1546 }
1547 }
1548 if (!foundMatch) {
1549 if (!foundFormat) {
1550 if (!foundColorSpace) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001551 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001552 "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001553 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001554 "%s() called with neither a "
1555 "supported pCreateInfo->imageFormat "
1556 "(i.e. %d) nor a supported "
1557 "pCreateInfo->imageColorSpace "
1558 "(i.e. %d).",
1559 fn,
1560 pCreateInfo->imageFormat,
1561 pCreateInfo->imageColorSpace);
1562 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001563 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device,
Ian Elliottb0f474c2015-09-25 15:50:55 -06001564 "VkDevice",
1565 SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001566 "%s() called with a non-supported "
1567 "pCreateInfo->imageFormat (i.e. %d).",
1568 fn, pCreateInfo->imageFormat);
1569 }
1570 } else if (!foundColorSpace) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001571 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001572 SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001573 "%s() called with a non-supported "
1574 "pCreateInfo->imageColorSpace (i.e. %d).",
1575 fn, pCreateInfo->imageColorSpace);
1576 }
1577 }
1578 }
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001579
1580 // Validate pCreateInfo values with the results of
1581 // vkGetPhysicalDeviceSurfacePresentModesKHR():
1582 if (!pPhysicalDevice || !pPhysicalDevice->presentModeCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001583 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001584 SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001585 "%s() called before calling "
Ian Elliott1dcd1092015-11-17 17:29:40 -07001586 "vkGetPhysicalDeviceSurfacePresentModesKHR().",
Ian Elliott0b4d6242015-09-22 10:51:24 -06001587 fn);
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001588 } else if (pCreateInfo) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001589 // Validate pCreateInfo->presentMode against
Ian Elliott1dcd1092015-11-17 17:29:40 -07001590 // vkGetPhysicalDeviceSurfacePresentModesKHR():
Ian Elliott0b4d6242015-09-22 10:51:24 -06001591 bool foundMatch = false;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001592 for (uint32_t i = 0 ; i < pPhysicalDevice->presentModeCount ; i++) {
1593 if (pPhysicalDevice->pPresentModes[i] == pCreateInfo->presentMode) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001594 foundMatch = true;
1595 break;
1596 }
1597 }
1598 if (!foundMatch) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001599 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001600 SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001601 "%s() called with a non-supported "
1602 "pCreateInfo->presentMode (i.e. %s).",
1603 fn,
1604 presentModeStr(pCreateInfo->presentMode));
1605 }
1606 }
1607
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001608 // Validate pCreateInfo->imageSharingMode and related values:
Ian Elliotta2a89c52015-12-28 15:23:57 -07001609 if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
1610 if ((pCreateInfo->queueFamilyIndexCount <= 1) ||
1611 !pCreateInfo->pQueueFamilyIndices) {
Ian Elliott1bf155f2015-12-29 17:35:46 -07001612 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001613 SWAPCHAIN_CREATE_SWAP_BAD_SHARING_VALUES,
1614 "%s() called with a supported "
1615 "pCreateInfo->sharingMode of (i.e. %s),"
1616 "but with a bad value(s) for "
1617 "pCreateInfo->queueFamilyIndexCount or "
1618 "pCreateInfo->pQueueFamilyIndices).",
1619 fn,
1620 sharingModeStr(pCreateInfo->imageSharingMode));
1621 }
1622 } else if (pCreateInfo->imageSharingMode != VK_SHARING_MODE_EXCLUSIVE) {
Ian Elliott1bf155f2015-12-29 17:35:46 -07001623 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001624 SWAPCHAIN_CREATE_SWAP_BAD_SHARING_MODE,
1625 "%s() called with a non-supported "
1626 "pCreateInfo->imageSharingMode (i.e. %s).",
1627 fn,
1628 sharingModeStr(pCreateInfo->imageSharingMode));
1629 }
1630
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001631 // Validate pCreateInfo->clipped:
1632 if (pCreateInfo &&
1633 (pCreateInfo->clipped != VK_FALSE) &&
Ian Elliotta2a89c52015-12-28 15:23:57 -07001634 (pCreateInfo->clipped != VK_TRUE)) {
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001635 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1636 device, "VkDevice",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001637 SWAPCHAIN_BAD_BOOL,
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001638 "%s() called with a VkBool32 value that is "
1639 "neither VK_TRUE nor VK_FALSE, but has the "
1640 "numeric value of %d.",
Ian Elliotta2a89c52015-12-28 15:23:57 -07001641 fn,
1642 pCreateInfo->clipped);
1643 }
1644
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001645 // Validate pCreateInfo->oldSwapchain:
1646 if (pCreateInfo && pCreateInfo->oldSwapchain) {
1647 SwpSwapchain *pOldSwapchain = &my_data->swapchainMap[pCreateInfo->oldSwapchain];
1648 if (pOldSwapchain) {
1649 if (device != pOldSwapchain->pDevice->device) {
1650 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1651 device, "VkDevice",
1652 SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE,
1653 "%s() called with a different VkDevice "
1654 "than the VkSwapchainKHR was created with.",
1655 __FUNCTION__);
1656 }
1657 if (pCreateInfo->surface != pOldSwapchain->surface) {
1658 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1659 device, "VkDevice",
1660 SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE,
1661 "%s() called with pCreateInfo->oldSwapchain "
1662 "that has a different VkSurfaceKHR than "
1663 "pCreateInfo->surface.",
1664 fn);
Ian Elliotta2a89c52015-12-28 15:23:57 -07001665 }
1666 } else {
Ian Elliott1bf155f2015-12-29 17:35:46 -07001667 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliotta2a89c52015-12-28 15:23:57 -07001668 pCreateInfo->oldSwapchain,
1669 "VkSwapchainKHR");
1670 }
1671 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001672
1673 return skipCall;
1674}
1675
Ian Elliott27d39c72015-11-20 16:39:34 -07001676VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
1677 VkDevice device,
1678 const VkSwapchainCreateInfoKHR* pCreateInfo,
1679 const VkAllocationCallbacks* pAllocator,
1680 VkSwapchainKHR* pSwapchain)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001681{
1682 VkResult result = VK_SUCCESS;
Tobin Ehlis711ff312015-10-29 12:58:13 -06001683 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001684 VkBool32 skipCall = validateCreateSwapchainKHR(device, pCreateInfo,
1685 pSwapchain);
1686
1687 if (VK_FALSE == skipCall) {
1688 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001689 result = my_data->device_dispatch_table->CreateSwapchainKHR(
Ian Elliott27d39c72015-11-20 16:39:34 -07001690 device, pCreateInfo, pAllocator, pSwapchain);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001691
1692 if (result == VK_SUCCESS) {
1693 // Remember the swapchain's handle, and link it to the device:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001694 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001695
Tobin Ehlis711ff312015-10-29 12:58:13 -06001696 my_data->swapchainMap[*pSwapchain].swapchain = *pSwapchain;
Chia-I Wue2fc5522015-10-26 20:04:44 +08001697 pDevice->swapchains[*pSwapchain] =
Tobin Ehlis711ff312015-10-29 12:58:13 -06001698 &my_data->swapchainMap[*pSwapchain];
1699 my_data->swapchainMap[*pSwapchain].pDevice = pDevice;
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001700 my_data->swapchainMap[*pSwapchain].surface =
1701 (pCreateInfo) ? pCreateInfo->surface : 0;
Tobin Ehlis711ff312015-10-29 12:58:13 -06001702 my_data->swapchainMap[*pSwapchain].imageCount = 0;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001703 }
1704
1705 return result;
1706 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001707 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001708}
1709
Ian Elliott27d39c72015-11-20 16:39:34 -07001710VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(
1711 VkDevice device,
1712 VkSwapchainKHR swapchain,
1713 const VkAllocationCallbacks* pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001714{
1715 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001716 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001717
1718 // Validate that a valid VkDevice was used, and that the device
1719 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001720 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001721 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001722 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001723 device,
1724 "VkDevice");
Ian Elliott427058f2015-12-29 16:45:49 -07001725 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001726 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001727 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001728 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001729 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001730 }
1731
1732 // Regardless of skipCall value, do some internal cleanup:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001733 SwpSwapchain *pSwapchain = &my_data->swapchainMap[swapchain];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001734 if (pSwapchain) {
1735 // Delete the SwpSwapchain associated with this swapchain:
1736 if (pSwapchain->pDevice) {
Chia-I Wue2fc5522015-10-26 20:04:44 +08001737 pSwapchain->pDevice->swapchains.erase(swapchain);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001738 if (device != pSwapchain->pDevice->device) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001739 LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001740 SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001741 "%s() called with a different VkDevice than the "
1742 "VkSwapchainKHR was created with.",
1743 __FUNCTION__);
1744 }
1745 }
1746 if (pSwapchain->imageCount) {
1747 pSwapchain->images.clear();
1748 }
Tobin Ehlis711ff312015-10-29 12:58:13 -06001749 my_data->swapchainMap.erase(swapchain);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001750 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001751 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Chia-I Wue2fc5522015-10-26 20:04:44 +08001752 swapchain,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001753 "VkSwapchainKHR");
1754 }
1755
1756 if (VK_FALSE == skipCall) {
1757 // Call down the call chain:
Ian Elliott27d39c72015-11-20 16:39:34 -07001758 my_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001759 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001760}
1761
Ian Elliottf955d682015-12-30 12:00:54 -07001762VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
1763 VkDevice device,
1764 VkSwapchainKHR swapchain,
1765 uint32_t* pSwapchainImageCount,
1766 VkImage* pSwapchainImages)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001767{
1768 VkResult result = VK_SUCCESS;
1769 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001770 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001771
1772 // Validate that a valid VkDevice was used, and that the device
1773 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001774 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001775 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001776 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001777 device,
1778 "VkDevice");
Ian Elliott427058f2015-12-29 16:45:49 -07001779 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001780 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001781 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001782 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001783 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001784 }
Tobin Ehlis711ff312015-10-29 12:58:13 -06001785 SwpSwapchain *pSwapchain = &my_data->swapchainMap[swapchain];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001786 if (!pSwapchain) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001787 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001788 swapchain.handle,
1789 "VkSwapchainKHR");
1790 }
Ian Elliottf955d682015-12-30 12:00:54 -07001791 if (!pSwapchainImageCount) {
Ian Elliottf7f8ff02015-12-30 14:55:41 -07001792 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1793 device,
Ian Elliottf955d682015-12-30 12:00:54 -07001794 "pSwapchainImageCount");
1795 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001796
1797 if (VK_FALSE == skipCall) {
1798 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001799 result = my_data->device_dispatch_table->GetSwapchainImagesKHR(
Ian Elliottf955d682015-12-30 12:00:54 -07001800 device, swapchain, pSwapchainImageCount, pSwapchainImages);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001801
Ian Elliottf955d682015-12-30 12:00:54 -07001802 if ((result == VK_SUCCESS) && pSwapchain && !pSwapchainImages &&
1803 pSwapchainImageCount) {
1804 // Record the result of this preliminary query:
1805 pSwapchain->imageCount = *pSwapchainImageCount;
1806 }
Ian Elliott9059b302015-12-30 13:14:36 -07001807 else if ((result == VK_SUCCESS) && pSwapchain && pSwapchainImages &&
1808 pSwapchainImageCount) {
Ian Elliottf955d682015-12-30 12:00:54 -07001809 // Compare the preliminary value of *pSwapchainImageCount with the
1810 // value this time:
1811 if (*pSwapchainImageCount != pSwapchain->imageCount) {
1812 LOG_ERROR_INVALID_COUNT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1813 device,
1814 "pSwapchainImageCount",
1815 "pSwapchainImages",
1816 pSwapchain->imageCount);
1817 }
Ian Elliott9059b302015-12-30 13:14:36 -07001818 else if (*pSwapchainImageCount > 0) {
1819 // Record the images and their state:
1820 pSwapchain->imageCount = *pSwapchainImageCount;
1821 for (uint32_t i = 0 ; i < *pSwapchainImageCount ; i++) {
1822 pSwapchain->images[i].image = pSwapchainImages[i];
1823 pSwapchain->images[i].pSwapchain = pSwapchain;
1824 pSwapchain->images[i].ownedByApp = false;
1825 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001826 }
1827 }
1828
1829 return result;
1830 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001831 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001832}
1833
Ian Elliott27d39c72015-11-20 16:39:34 -07001834VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
1835 VkDevice device,
1836 VkSwapchainKHR swapchain,
1837 uint64_t timeout,
1838 VkSemaphore semaphore,
1839 VkFence fence,
1840 uint32_t* pImageIndex)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001841{
Ian Elliottdd45e462015-12-29 17:52:10 -07001842// TODOs:
1843//
1844// - Address the timeout. Possibilities include looking at the state of the
1845// swapchain's images, depending on the timeout value.
1846// - Validate that semaphore and fence are either VK_NULL_HANDLE or valid
1847// handles.
1848// - Record/update the state of the swapchain, in case an error occurs
1849// (e.g. VK_ERROR_OUT_OF_DATE_KHR).
Ian Elliott0b4d6242015-09-22 10:51:24 -06001850 VkResult result = VK_SUCCESS;
1851 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001852 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001853
1854 // Validate that a valid VkDevice was used, and that the device
1855 // extension was enabled:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001856 SwpDevice *pDevice = &my_data->deviceMap[device];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001857 if (!pDevice) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001858 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001859 device,
1860 "VkDevice");
Ian Elliott427058f2015-12-29 16:45:49 -07001861 } else if (!pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001862 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001863 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001864 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001865 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001866 }
1867 // Validate that a valid VkSwapchainKHR was used:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001868 SwpSwapchain *pSwapchain = &my_data->swapchainMap[swapchain];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001869 if (!pSwapchain) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001870 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Chia-I Wue2fc5522015-10-26 20:04:44 +08001871 swapchain,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001872 "VkSwapchainKHR");
1873 } else {
1874 // Look to see if the application is trying to own too many images at
1875 // the same time (i.e. not leave any to display):
Courtney Goeltzenleuchterdad30df2015-10-07 09:00:34 -06001876 uint32_t imagesOwnedByApp = 0;
1877 for (uint32_t i = 0 ; i < pSwapchain->imageCount ; i++) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001878 if (pSwapchain->images[i].ownedByApp) {
1879 imagesOwnedByApp++;
1880 }
1881 }
1882 if (imagesOwnedByApp >= (pSwapchain->imageCount - 1)) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001883 skipCall |= LOG_PERF_WARNING(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott4a994452015-09-24 18:33:16 -06001884 swapchain,
1885 "VkSwapchainKHR",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001886 SWAPCHAIN_APP_OWNS_TOO_MANY_IMAGES,
Ian Elliott4a994452015-09-24 18:33:16 -06001887 "%s() called when the application "
1888 "already owns all presentable images "
1889 "in this swapchain except for the "
1890 "image currently being displayed. "
1891 "This call to %s() cannot succeed "
1892 "unless another thread calls the "
1893 "vkQueuePresentKHR() function in "
1894 "order to release ownership of one of "
1895 "the presentable images of this "
1896 "swapchain.",
1897 __FUNCTION__, __FUNCTION__);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001898 }
1899 }
Ian Elliottdd45e462015-12-29 17:52:10 -07001900 if (!pImageIndex) {
1901 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1902 device,
1903 "pImageIndex");
1904 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06001905
1906 if (VK_FALSE == skipCall) {
1907 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06001908 result = my_data->device_dispatch_table->AcquireNextImageKHR(
Ian Elliott27d39c72015-11-20 16:39:34 -07001909 device, swapchain, timeout, semaphore, fence, pImageIndex);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001910
1911 if (((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR)) &&
1912 pSwapchain) {
Ian Elliott0b4d6242015-09-22 10:51:24 -06001913 // Change the state of the image (now owned by the application):
1914 pSwapchain->images[*pImageIndex].ownedByApp = true;
1915 }
1916
1917 return result;
1918 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001919 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06001920}
1921
Ian Elliott27d39c72015-11-20 16:39:34 -07001922VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(
1923 VkQueue queue,
1924 const VkPresentInfoKHR* pPresentInfo)
Ian Elliott0b4d6242015-09-22 10:51:24 -06001925{
1926// TODOs:
1927//
1928// - Ensure that the queue is active, and is one of the queueFamilyIndex's
1929// that was returned by a previuos query.
1930// - Record/update the state of the swapchain, in case an error occurs
1931// (e.g. VK_ERROR_OUT_OF_DATE_KHR).
1932 VkResult result = VK_SUCCESS;
1933 VkBool32 skipCall = VK_FALSE;
Ian Elliott68124ac2015-10-07 16:18:35 -06001934 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001935
Ian Elliott046ed2c2015-12-30 17:07:17 -07001936 if (!pPresentInfo) {
1937 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1938 device,
1939 "pPresentInfo");
1940 } else {
1941 if (pPresentInfo->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR) {
1942 skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1943 device,
1944 "pPresentInfo",
1945 "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR");
1946 }
1947 if (pPresentInfo->pNext != NULL) {
1948 skipCall |= LOG_ERROR_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1949 device,
1950 "pPresentInfo");
1951 }
1952 if (!pPresentInfo->waitSemaphoreCount) {
1953 skipCall |= LOG_ERROR_ZERO_VALUE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1954 device,
1955 "pPresentInfo->waitSemaphoreCount");
1956 }
1957 if (!pPresentInfo->pWaitSemaphores) {
1958 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1959 device,
1960 "pPresentInfo->pWaitSemaphores");
1961 }
1962 if (!pPresentInfo->swapchainCount) {
1963 skipCall |= LOG_ERROR_ZERO_VALUE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1964 device,
1965 "pPresentInfo->swapchainCount");
1966 }
1967 if (!pPresentInfo->pSwapchains) {
1968 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1969 device,
1970 "pPresentInfo->pSwapchains");
1971 }
1972 if (!pPresentInfo->pImageIndices) {
1973 skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
1974 device,
1975 "pPresentInfo->pImageIndices");
1976 }
1977 // Note: pPresentInfo->pResults is allowed to be NULL
1978 }
1979
1980 for (uint32_t i = 0;
1981 pPresentInfo && (i < pPresentInfo->swapchainCount);
1982 i++) {
1983 uint32_t swapchainCount = pPresentInfo->swapchainCount;
Ian Elliott27d39c72015-11-20 16:39:34 -07001984 uint32_t index = pPresentInfo->pImageIndices[i];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001985 SwpSwapchain *pSwapchain =
Ian Elliott27d39c72015-11-20 16:39:34 -07001986 &my_data->swapchainMap[pPresentInfo->pSwapchains[i]];
Ian Elliott0b4d6242015-09-22 10:51:24 -06001987 if (pSwapchain) {
Ian Elliott427058f2015-12-29 16:45:49 -07001988 if (!pSwapchain->pDevice->swapchainExtensionEnabled) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001989 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
Ian Elliott0b4d6242015-09-22 10:51:24 -06001990 pSwapchain->pDevice, "VkDevice",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001991 SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED,
Michael Lentine010f4692015-11-03 16:19:46 -08001992 "%s() called even though the %s extension was not enabled for this VkDevice.",
Ian Elliott1dcd1092015-11-17 17:29:40 -07001993 __FUNCTION__, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
Ian Elliott0b4d6242015-09-22 10:51:24 -06001994 }
1995 if (index >= pSwapchain->imageCount) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001996 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07001997 pPresentInfo->pSwapchains[i],
Ian Elliott0b4d6242015-09-22 10:51:24 -06001998 "VkSwapchainKHR",
Ian Elliottb0f474c2015-09-25 15:50:55 -06001999 SWAPCHAIN_INDEX_TOO_LARGE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06002000 "%s() called for an index that is too "
2001 "large (i.e. %d). There are only %d "
2002 "images in this VkSwapchainKHR.\n",
2003 __FUNCTION__, index,
2004 pSwapchain->imageCount);
2005 } else {
2006 if (!pSwapchain->images[index].ownedByApp) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002007 skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07002008 pPresentInfo->pSwapchains[i],
Ian Elliott0b4d6242015-09-22 10:51:24 -06002009 "VkSwapchainKHR",
Ian Elliottb0f474c2015-09-25 15:50:55 -06002010 SWAPCHAIN_INDEX_NOT_IN_USE,
Ian Elliott0b4d6242015-09-22 10:51:24 -06002011 "%s() returned an index (i.e. %d) "
2012 "for an image that is not owned by "
2013 "the application.",
2014 __FUNCTION__, index);
2015 }
2016 }
2017 } else {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002018 skipCall |= LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
Ian Elliott27d39c72015-11-20 16:39:34 -07002019 pPresentInfo->pSwapchains[i],
Ian Elliott0b4d6242015-09-22 10:51:24 -06002020 "VkSwapchainKHR");
2021 }
2022 }
2023
2024 if (VK_FALSE == skipCall) {
2025 // Call down the call chain:
Tobin Ehlis711ff312015-10-29 12:58:13 -06002026 result = my_data->device_dispatch_table->QueuePresentKHR(queue,
Ian Elliott046ed2c2015-12-30 17:07:17 -07002027 pPresentInfo);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002028
Ian Elliott046ed2c2015-12-30 17:07:17 -07002029 if (pPresentInfo &&
2030 ((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) {
Courtney Goeltzenleuchterdad30df2015-10-07 09:00:34 -06002031 for (uint32_t i = 0; i < pPresentInfo->swapchainCount ; i++) {
Ian Elliott27d39c72015-11-20 16:39:34 -07002032 int index = pPresentInfo->pImageIndices[i];
Ian Elliott0b4d6242015-09-22 10:51:24 -06002033 SwpSwapchain *pSwapchain =
Ian Elliott27d39c72015-11-20 16:39:34 -07002034 &my_data->swapchainMap[pPresentInfo->pSwapchains[i]];
Ian Elliott0b4d6242015-09-22 10:51:24 -06002035 if (pSwapchain) {
2036 // Change the state of the image (no longer owned by the
2037 // application):
2038 pSwapchain->images[index].ownedByApp = false;
2039 }
2040 }
2041 }
2042
2043 return result;
2044 }
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07002045 return VK_ERROR_VALIDATION_FAILED_EXT;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002046}
2047
2048static inline PFN_vkVoidFunction layer_intercept_proc(const char *name)
2049{
2050 if (!name || name[0] != 'v' || name[1] != 'k')
2051 return NULL;
2052
2053 name += 2;
2054 if (!strcmp(name, "CreateInstance"))
2055 return (PFN_vkVoidFunction) vkCreateInstance;
2056 if (!strcmp(name, "DestroyInstance"))
2057 return (PFN_vkVoidFunction) vkDestroyInstance;
2058 if (!strcmp(name, "EnumeratePhysicalDevices"))
2059 return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
2060 if (!strcmp(name, "CreateDevice"))
2061 return (PFN_vkVoidFunction) vkCreateDevice;
2062 if (!strcmp(name, "DestroyDevice"))
2063 return (PFN_vkVoidFunction) vkDestroyDevice;
2064
2065 return NULL;
2066}
2067static inline PFN_vkVoidFunction layer_intercept_instance_proc(const char *name)
2068{
2069 if (!name || name[0] != 'v' || name[1] != 'k')
2070 return NULL;
2071
2072 name += 2;
2073 if (!strcmp(name, "CreateInstance"))
2074 return (PFN_vkVoidFunction) vkCreateInstance;
2075 if (!strcmp(name, "DestroyInstance"))
2076 return (PFN_vkVoidFunction) vkDestroyInstance;
2077 if (!strcmp(name, "EnumeratePhysicalDevices"))
2078 return (PFN_vkVoidFunction) vkEnumeratePhysicalDevices;
2079
2080 return NULL;
2081}
2082
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002083VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
2084 VkInstance instance,
2085 const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
2086 const VkAllocationCallbacks* pAllocator,
2087 VkDebugReportCallbackEXT* pMsgCallback)
Ian Elliott0b4d6242015-09-22 10:51:24 -06002088{
Tobin Ehlis711ff312015-10-29 12:58:13 -06002089 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002090 VkResult result = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Ian Elliott68124ac2015-10-07 16:18:35 -06002091 if (VK_SUCCESS == result) {
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07002092 result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Ian Elliott68124ac2015-10-07 16:18:35 -06002093 }
2094 return result;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002095}
2096
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002097VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)
Ian Elliott0b4d6242015-09-22 10:51:24 -06002098{
Ian Elliott68124ac2015-10-07 16:18:35 -06002099 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002100 my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07002101 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002102}
2103
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002104VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07002105 VkInstance instance,
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002106 VkDebugReportFlagsEXT flags,
2107 VkDebugReportObjectTypeEXT objType,
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07002108 uint64_t object,
2109 size_t location,
2110 int32_t msgCode,
2111 const char* pLayerPrefix,
2112 const char* pMsg)
2113{
2114 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07002115 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07002116}
2117
Chia-I Wu9ab61502015-11-06 06:42:02 +08002118VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* funcName)
Ian Elliott0b4d6242015-09-22 10:51:24 -06002119{
2120 PFN_vkVoidFunction addr;
2121 if (device == VK_NULL_HANDLE) {
2122 return NULL;
2123 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06002124
Tobin Ehlis711ff312015-10-29 12:58:13 -06002125 layer_data *my_data;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002126 /* loader uses this to force layer initialization; device object is wrapped */
2127 if (!strcmp("vkGetDeviceProcAddr", funcName)) {
Tobin Ehlis711ff312015-10-29 12:58:13 -06002128 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) device;
2129 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
2130 my_data->device_dispatch_table = new VkLayerDispatchTable;
2131 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002132 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
2133 }
2134
2135 addr = layer_intercept_proc(funcName);
2136 if (addr)
2137 return addr;
2138
Tobin Ehlis711ff312015-10-29 12:58:13 -06002139 my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2140 VkLayerDispatchTable *pDisp = my_data->device_dispatch_table;
2141 if (my_data->deviceMap.size() != 0 &&
Ian Elliott427058f2015-12-29 16:45:49 -07002142 my_data->deviceMap[device].swapchainExtensionEnabled)
Ian Elliott0b4d6242015-09-22 10:51:24 -06002143 {
Ian Elliott0b4d6242015-09-22 10:51:24 -06002144 if (!strcmp("vkCreateSwapchainKHR", funcName))
2145 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateSwapchainKHR);
2146 if (!strcmp("vkDestroySwapchainKHR", funcName))
2147 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySwapchainKHR);
2148 if (!strcmp("vkGetSwapchainImagesKHR", funcName))
2149 return reinterpret_cast<PFN_vkVoidFunction>(vkGetSwapchainImagesKHR);
2150 if (!strcmp("vkAcquireNextImageKHR", funcName))
2151 return reinterpret_cast<PFN_vkVoidFunction>(vkAcquireNextImageKHR);
2152 if (!strcmp("vkQueuePresentKHR", funcName))
2153 return reinterpret_cast<PFN_vkVoidFunction>(vkQueuePresentKHR);
2154 }
2155 {
2156 if (pDisp->GetDeviceProcAddr == NULL)
2157 return NULL;
2158 return pDisp->GetDeviceProcAddr(device, funcName);
2159 }
2160}
2161
Chia-I Wu9ab61502015-11-06 06:42:02 +08002162VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Ian Elliott0b4d6242015-09-22 10:51:24 -06002163{
2164 PFN_vkVoidFunction addr;
2165 if (instance == VK_NULL_HANDLE) {
2166 return NULL;
2167 }
Ian Elliott0b4d6242015-09-22 10:51:24 -06002168
Tobin Ehlis711ff312015-10-29 12:58:13 -06002169 layer_data *my_data;
Ian Elliott0b4d6242015-09-22 10:51:24 -06002170 /* loader uses this to force layer initialization; instance object is wrapped */
2171 if (!strcmp("vkGetInstanceProcAddr", funcName)) {
Tobin Ehlis711ff312015-10-29 12:58:13 -06002172 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
2173 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
2174 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
2175 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002176 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
2177 }
2178
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -07002179 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
2180 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
2181 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
2182 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
2183
Ian Elliott0b4d6242015-09-22 10:51:24 -06002184 addr = layer_intercept_instance_proc(funcName);
2185 if (addr)
2186 return addr;
2187
Tobin Ehlis711ff312015-10-29 12:58:13 -06002188 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2189 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
Ian Elliott68124ac2015-10-07 16:18:35 -06002190 addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
2191 if (addr) {
2192 return addr;
2193 }
2194
Ian Elliotta983e9a2015-12-22 12:18:12 -07002195#ifdef VK_USE_PLATFORM_ANDROID_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002196 if (my_data->instanceMap.size() != 0 &&
2197 my_data->instanceMap[instance].androidSurfaceExtensionEnabled)
2198 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002199 if (!strcmp("vkCreateAndroidSurfaceKHR", funcName))
2200 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateAndroidSurfaceKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002201 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002202#endif // VK_USE_PLATFORM_ANDROID_KHR
2203#ifdef VK_USE_PLATFORM_MIR_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002204 if (my_data->instanceMap.size() != 0 &&
2205 my_data->instanceMap[instance].mirSurfaceExtensionEnabled)
2206 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002207 if (!strcmp("vkCreateMirSurfaceKHR", funcName))
2208 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateMirSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002209 if (!strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", funcName))
2210 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceMirPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002211 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002212#endif // VK_USE_PLATFORM_MIR_KHR
2213#ifdef VK_USE_PLATFORM_WAYLAND_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002214 if (my_data->instanceMap.size() != 0 &&
2215 my_data->instanceMap[instance].waylandSurfaceExtensionEnabled)
2216 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002217 if (!strcmp("vkCreateWaylandSurfaceKHR", funcName))
2218 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateWaylandSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002219 if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", funcName))
2220 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002221 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002222#endif // VK_USE_PLATFORM_WAYLAND_KHR
2223#ifdef VK_USE_PLATFORM_WIN32_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002224 if (my_data->instanceMap.size() != 0 &&
2225 my_data->instanceMap[instance].win32SurfaceExtensionEnabled)
2226 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002227 if (!strcmp("vkCreateWin32SurfaceKHR", funcName))
2228 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateWin32SurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002229 if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", funcName))
2230 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceWin32PresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002231 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002232#endif // VK_USE_PLATFORM_WIN32_KHR
2233#ifdef VK_USE_PLATFORM_XCB_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002234 if (my_data->instanceMap.size() != 0 &&
2235 my_data->instanceMap[instance].xcbSurfaceExtensionEnabled)
2236 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002237 if (!strcmp("vkCreateXcbSurfaceKHR", funcName))
2238 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateXcbSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002239 if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", funcName))
2240 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceXcbPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002241 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002242#endif // VK_USE_PLATFORM_XCB_KHR
2243#ifdef VK_USE_PLATFORM_XLIB_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002244 if (my_data->instanceMap.size() != 0 &&
2245 my_data->instanceMap[instance].xlibSurfaceExtensionEnabled)
2246 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002247 if (!strcmp("vkCreateXlibSurfaceKHR", funcName))
2248 return reinterpret_cast<PFN_vkVoidFunction>(vkCreateXlibSurfaceKHR);
Ian Elliott55ff7962015-12-30 10:18:47 -07002249 if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", funcName))
2250 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceXlibPresentationSupportKHR);
Ian Elliott8dffaf32016-01-04 14:10:30 -07002251 }
Ian Elliotta983e9a2015-12-22 12:18:12 -07002252#endif // VK_USE_PLATFORM_XLIB_KHR
Ian Elliott8dffaf32016-01-04 14:10:30 -07002253 if (my_data->instanceMap.size() != 0 &&
2254 my_data->instanceMap[instance].surfaceExtensionEnabled)
2255 {
Ian Elliotta983e9a2015-12-22 12:18:12 -07002256 if (!strcmp("vkDestroySurfaceKHR", funcName))
2257 return reinterpret_cast<PFN_vkVoidFunction>(vkDestroySurfaceKHR);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002258 if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", funcName))
2259 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceSupportKHR);
Ian Elliott27d39c72015-11-20 16:39:34 -07002260 if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", funcName))
2261 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
2262 if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", funcName))
2263 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfaceFormatsKHR);
2264 if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", funcName))
2265 return reinterpret_cast<PFN_vkVoidFunction>(vkGetPhysicalDeviceSurfacePresentModesKHR);
Ian Elliott0b4d6242015-09-22 10:51:24 -06002266 }
2267
2268 if (pTable->GetInstanceProcAddr == NULL)
2269 return NULL;
2270 return pTable->GetInstanceProcAddr(instance, funcName);
2271}
2272