111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Copyright (c) 2015-2016 The Khronos Group Inc. 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 Valve Corporation 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 LunarG, Inc. 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (C) 2015-2016 Google Inc. 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Licensed under the Apache License, Version 2.0 (the "License"); 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * you may not use this file except in compliance with the License. 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * You may obtain a copy of the License at 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * http://www.apache.org/licenses/LICENSE-2.0 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Unless required by applicable law or agreed to in writing, software 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * distributed under the License is distributed on an "AS IS" BASIS, 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * See the License for the specific language governing permissions and 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * limitations under the License. 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Ian Elliott <ian@lunarg.com> 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Ian Elliott <ianelliott@google.com> 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <mutex> 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <stdio.h> 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <string.h> 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <vk_loader_platform.h> 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <vulkan/vk_icd.h> 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "swapchain.h" 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_extension_utils.h" 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_enum_string_helper.h" 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_utils.h" 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace swapchain { 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic std::mutex global_lock; 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The following is for logging error messages: 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic std::unordered_map<void *, layer_data *> layer_data_map; 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const VkLayerProperties swapchain_layer = { 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_LAYER_LUNARG_swapchain", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic void createDeviceRegisterExtensions(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDevice device) { 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t i; 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table; 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr; 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR"); 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR"); 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR"); 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR"); 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR"); 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetDeviceQueue = (PFN_vkGetDeviceQueue)gpa(device, "vkGetDeviceQueue"); 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_instance_data->physicalDeviceMap.find(physicalDevice); 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_instance_data->physicalDeviceMap.end()) ? NULL : &it->second; 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice) { 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->deviceMap[device].pPhysicalDevice = pPhysicalDevice; 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->pDevice = &my_device_data->deviceMap[device]; 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TBD: Should we leave error in (since Swapchain really needs this 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // link)? 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert log_msg(my_instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (uint64_t)physicalDevice, __LINE__, SWAPCHAIN_INVALID_HANDLE, "Swapchain", 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkCreateDevice() called with a non-valid VkPhysicalDevice."); 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->deviceMap[device].device = device; 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->deviceMap[device].swapchainExtensionEnabled = false; 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record whether the WSI device extension was enabled for this VkDevice. 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // No need to check if the extension was advertised by 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkEnumerateDeviceExtensionProperties(), since the loader handles that. 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) { 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->deviceMap[device].swapchainExtensionEnabled = true; 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic void createInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) { 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t i; 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerInstanceDispatchTable *pDisp = my_data->instance_dispatch_table; 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetInstanceProcAddr gpa = pDisp->GetInstanceProcAddr; 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_ANDROID_KHR 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(instance, "vkCreateAndroidSurfaceKHR"); 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_ANDROID_KHR 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_MIR_KHR 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->CreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)gpa(instance, "vkCreateMirSurfaceKHR"); 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceMirPresentationSupportKHR = 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR"); 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_MIR_KHR 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WAYLAND_KHR 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(instance, "vkCreateWaylandSurfaceKHR"); 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceWaylandPresentationSupportKHR = 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR"); 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WAYLAND_KHR 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WIN32_KHR 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(instance, "vkCreateWin32SurfaceKHR"); 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceWin32PresentationSupportKHR = 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR"); 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WIN32_KHR 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XCB_KHR 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(instance, "vkCreateXcbSurfaceKHR"); 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceXcbPresentationSupportKHR = 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR"); 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XCB_KHR 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XLIB_KHR 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(instance, "vkCreateXlibSurfaceKHR"); 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceXlibPresentationSupportKHR = 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR"); 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XLIB_KHR 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(instance, "vkDestroySurfaceKHR"); 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceSurfaceSupportKHR = 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR"); 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceSurfaceCapabilitiesKHR = 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceSurfaceFormatsKHR = 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR"); 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDisp->GetPhysicalDeviceSurfacePresentModesKHR = 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR"); 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Remember this instance, and whether the VK_KHR_surface extension 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // was enabled for it: 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].instance = instance; 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].surfaceExtensionEnabled = false; 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_ANDROID_KHR 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].androidSurfaceExtensionEnabled = false; 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_ANDROID_KHR 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_MIR_KHR 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].mirSurfaceExtensionEnabled = false; 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_MIR_KHR 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WAYLAND_KHR 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = false; 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WAYLAND_KHR 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WIN32_KHR 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].win32SurfaceExtensionEnabled = false; 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WIN32_KHR 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XCB_KHR 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = false; 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XCB_KHR 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XLIB_KHR 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = false; 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XLIB_KHR 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Look for one or more debug report create info structures, and copy the 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // callback(s) for each one found (for use by vkDestroyInstance) 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_data->num_tmp_callbacks, &my_data->tmp_dbg_create_infos, 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert &my_data->tmp_callbacks); 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record whether the WSI instance extension was enabled for this 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkInstance. No need to check if the extension was advertised by 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkEnumerateInstanceExtensionProperties(), since the loader handles that. 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) { 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].surfaceExtensionEnabled = true; 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_ANDROID_KHR 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].androidSurfaceExtensionEnabled = true; 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_ANDROID_KHR 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_MIR_KHR 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) { 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].mirSurfaceExtensionEnabled = true; 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_MIR_KHR 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WAYLAND_KHR 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].waylandSurfaceExtensionEnabled = true; 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WAYLAND_KHR 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WIN32_KHR 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].win32SurfaceExtensionEnabled = true; 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WIN32_KHR 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XCB_KHR 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].xcbSurfaceExtensionEnabled = true; 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XCB_KHR 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XLIB_KHR 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap[instance].xlibSurfaceExtensionEnabled = true; 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XLIB_KHR 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_dispatch_table_helper.h" 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic void init_swapchain(layer_data *my_data, const VkAllocationCallbacks *pAllocator) { 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_swapchain"); 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const char *surfaceTransformStr(VkSurfaceTransformFlagBitsKHR value) { 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Return a string corresponding to the value: 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return string_VkSurfaceTransformFlagBitsKHR(value); 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const char *surfaceCompositeAlphaStr(VkCompositeAlphaFlagBitsKHR value) { 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Return a string corresponding to the value: 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return string_VkCompositeAlphaFlagBitsKHR(value); 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const char *presentModeStr(VkPresentModeKHR value) { 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Return a string corresponding to the value: 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return string_VkPresentModeKHR(value); 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const char *sharingModeStr(VkSharingMode value) { 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Return a string corresponding to the value: 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return string_VkSharingMode(value); 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 23511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(chain_info->u.pLayerInfo); 23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (fpCreateInstance == NULL) { 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_INITIALIZATION_FAILED; 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Advance the link info for the next element on the chain 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (result != VK_SUCCESS) { 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance = *pInstance; 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance, 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call the following function after my_data is initialized: 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert createInstanceRegisterExtensions(pCreateInfo, *pInstance); 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert init_swapchain(my_data, pAllocator); 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 26811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_key key = get_dispatch_key(instance); 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(key, layer_data_map); 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->DestroyInstance(instance, pAllocator); 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Enable the temporary callback(s) here to catch cleanup issues: 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool callback_setup = false; 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (my_data->num_tmp_callbacks > 0) { 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!layer_enable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_dbg_create_infos, 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->tmp_callbacks)) { 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert callback_setup = true; 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Do additional internal cleanup: 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance) { 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Delete all of the SwpPhysicalDevice's, SwpSurface's, and the 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // SwpInstance associated with this instance: 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (auto it = pInstance->physicalDevices.begin(); it != pInstance->physicalDevices.end(); it++) { 29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Free memory that was allocated for/by this SwpPhysicalDevice: 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = it->second; 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice) { 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->pDevice) { 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, instance, "VkInstance", SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called before all of its associated " 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkDevices were destroyed.", 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert free(pPhysicalDevice->pSurfaceFormats); 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert free(pPhysicalDevice->pPresentModes); 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Erase the SwpPhysicalDevice's from the my_data->physicalDeviceMap (which 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // are simply pointed to by the SwpInstance): 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap.erase(it->second->physicalDevice); 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (auto it = pInstance->surfaces.begin(); it != pInstance->surfaces.end(); it++) { 31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Free memory that was allocated for/by this SwpPhysicalDevice: 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSurface *pSurface = it->second; 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSurface) { 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, instance, "VkInstance", SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called before all of its associated " 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkSurfaceKHRs were destroyed.", 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instanceMap.erase(instance); 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Disable and cleanup the temporary callback(s): 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (callback_setup) { 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_disable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_callbacks); 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (my_data->num_tmp_callbacks > 0) { 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos, my_data->tmp_callbacks); 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->num_tmp_callbacks = 0; 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Clean up logging callback, if any 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (my_data->logging_callback.size() > 0) { 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->logging_callback.pop_back(); 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_debug_report_destroy_instance(my_data->report_data); 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert delete my_data->instance_dispatch_table; 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data_map.erase(key); 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 35011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkQueueFamilyProperties *pQueueFamilyProperties) { 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pQueueFamilyProperties); 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this query: 35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pQueueFamilyPropertyCount && !pQueueFamilyProperties) { 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->gotQueueFamilyPropertyCount = true; 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->numOfQueueFamilies = *pQueueFamilyPropertyCount; 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_ANDROID_KHR 37211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 37311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance && !pInstance->androidSurfaceExtensionEnabled) { 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo) { 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->sType != VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR) { 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo", 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR"); 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pNext != NULL) { 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pInstance && pSurface) { 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the VkSurfaceKHR returned by the ICD: 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].surface = *pSurface; 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pInstance = pInstance; 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL); 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0; 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL; 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Point to the associated SwpInstance: 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_ANDROID_KHR 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_MIR_KHR 43211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 43311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, 43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSurfaceKHR *pSurface) { 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance && !pInstance->mirSurfaceExtensionEnabled) { 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_MIR_SURFACE_EXTENSION_NAME); 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo) { 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->sType != VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR) { 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo", 45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR"); 45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pNext != NULL) { 46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pInstance && pSurface) { 47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the VkSurfaceKHR returned by the ICD: 47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].surface = *pSurface; 47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pInstance = pInstance; 47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL); 48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0; 48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL; 48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Point to the associated SwpInstance: 48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; 48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 49011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice, 49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t queueFamilyIndex, 49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert MirConnection *connection) { 49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 result = VK_FALSE; 49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->mirSurfaceExtensionEnabled) { 50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_MIR_SURFACE_EXTENSION_NAME); 50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) { 51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, 51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); 51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceMirPresentationSupportKHR(physicalDevice, queueFamilyIndex, 52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert connection); 52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_MIR_KHR 52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WAYLAND_KHR 52711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 52811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, 52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance && !pInstance->waylandSurfaceExtensionEnabled) { 54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); 54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo) { 54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR) { 55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo", 55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR"); 55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pNext != NULL) { 55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pInstance && pSurface) { 57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the VkSurfaceKHR returned by the ICD: 57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].surface = *pSurface; 57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pInstance = pInstance; 57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL); 57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0; 57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL; 57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Point to the associated SwpInstance: 57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; 57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, 58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t queueFamilyIndex, 58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct wl_display *display) { 58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 result = VK_FALSE; 58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->waylandSurfaceExtensionEnabled) { 60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); 60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) { 60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, 60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); 60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, 61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert display); 61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WAYLAND_KHR 62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WIN32_KHR 62211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 62311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance && !pInstance->win32SurfaceExtensionEnabled) { 63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo) { 64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->sType != VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR) { 64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo", 64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR"); 64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pNext != NULL) { 65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pInstance && pSurface) { 66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the VkSurfaceKHR returned by the ICD: 66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].surface = *pSurface; 66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pInstance = pInstance; 66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL); 67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0; 67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL; 67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Point to the associated SwpInstance: 67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; 67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkBool32 VKAPI_CALL 68111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) { 68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 result = VK_FALSE; 68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->win32SurfaceExtensionEnabled) { 69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) { 70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, 70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); 70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex); 70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WIN32_KHR 71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XCB_KHR 71511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 71611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, 71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSurfaceKHR *pSurface) { 71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance && !pInstance->xcbSurfaceExtensionEnabled) { 73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_XCB_SURFACE_EXTENSION_NAME); 73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 73411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo) { 73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) { 73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo", 74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR"); 74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pNext != NULL) { 74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pInstance && pSurface) { 75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the VkSurfaceKHR returned by the ICD: 76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].surface = *pSurface; 76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pInstance = pInstance; 76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL); 76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0; 76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL; 76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Point to the associated SwpInstance: 76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; 76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 77311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkBool32 VKAPI_CALL 77411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, 77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert xcb_connection_t *connection, xcb_visualid_t visual_id) { 77611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 result = VK_FALSE; 77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 78411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->xcbSurfaceExtensionEnabled) { 78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_XCB_SURFACE_EXTENSION_NAME); 79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) { 79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, 79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); 79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, 80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert connection, visual_id); 80411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 80511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 80611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 80711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XCB_KHR 80811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 80911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XLIB_KHR 81011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 81111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, 81211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSurfaceKHR *pSurface) { 81311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 81411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 81511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 81611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 81711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 81811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 81911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 82011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 82111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 82211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 82311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 82411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance && !pInstance->xlibSurfaceExtensionEnabled) { 82511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 82611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 82711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_XLIB_SURFACE_EXTENSION_NAME); 82811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 82911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 83011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo) { 83111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 83211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 83311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->sType != VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR) { 83411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo", 83511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR"); 83611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 83711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pNext != NULL) { 83811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 83911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 84011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 84111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 84211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 84311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 84411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 84511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 84611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 84711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 84811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 84911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 85011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 85111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 85211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 85311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pInstance && pSurface) { 85411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the VkSurfaceKHR returned by the ICD: 85511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].surface = *pSurface; 85611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pInstance = pInstance; 85711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL); 85811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0; 85911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL; 86011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Point to the associated SwpInstance: 86111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; 86211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 86311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 86411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 86511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 86611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 86711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 86811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, 86911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t queueFamilyIndex, 87011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert Display *dpy, VisualID visualID) { 87111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 result = VK_FALSE; 87211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 87311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 87411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 87511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 87611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 87711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 87811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 87911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 88011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 88111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 88211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->xlibSurfaceExtensionEnabled) { 88311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 88411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 88511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 88611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_XLIB_SURFACE_EXTENSION_NAME); 88711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 88811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) { 88911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 89011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, 89111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); 89211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 89311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 89411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 89511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 89611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 89711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, 89811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dpy, visualID); 89911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 90011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 90111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 90211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XLIB_KHR 90311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 90411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 90511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) { 90611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 90711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 90811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 90911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSurface *pSurface = NULL; 91011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 91111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->surfaceMap.find(surface); 91211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurface = (it == my_data->surfaceMap.end()) ? NULL : &it->second; 91311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 91411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 91511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 91611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 91711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 91811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 91911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 92011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the platform extension was enabled: 92111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance && !pInstance->surfaceExtensionEnabled) { 92211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pInstance, "VkInstance", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 92311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 92411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SURFACE_EXTENSION_NAME); 92511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 92611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 92711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Regardless of skipCall value, do some internal cleanup: 92811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSurface) { 92911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Delete the SwpSurface associated with this surface: 93011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSurface->pInstance) { 93111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurface->pInstance->surfaces.erase(surface); 93211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 93311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSurface->swapchains.empty()) { 93411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, instance, "VkInstance", SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, 93511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called before all of its associated " 93611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkSwapchainKHRs were destroyed.", 93711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 93811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Empty and then delete all SwpSwapchain's 93911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (auto it = pSurface->swapchains.begin(); it != pSurface->swapchains.end(); it++) { 94011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Delete all SwpImage's 94111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert it->second->images.clear(); 94211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // In case the swapchain's device hasn't been destroyed yet 94311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // (which isn't likely, but is possible), delete its 94411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // association with this swapchain (i.e. so we can't point to 94511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // this swpchain from that device, later on): 94611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (it->second->pDevice) { 94711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert it->second->pDevice->swapchains.clear(); 94811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 94911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 95011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurface->swapchains.clear(); 95111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 95211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pAllocator != NULL) != pSurface->usedAllocatorToCreate) { 95311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, instance, "VkInstance", SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, 95411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with incompatible pAllocator from when " 95511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "the object was created.", 95611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 95711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 95811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->surfaceMap.erase(surface); 95911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 96011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 96111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 96211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 96311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 96411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->DestroySurfaceKHR(instance, surface, pAllocator); 96511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 96611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 96711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 96811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 96911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) { 97011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 97111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 97211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 97311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 97411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); 97511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 97611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 97711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = NULL; 97811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 97911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->instanceMap.find(instance); 98011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance = (it == my_data->instanceMap.end()) ? NULL : &it->second; 98111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 98211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pInstance && pPhysicalDevices && (*pPhysicalDeviceCount > 0)) { 98311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the VkPhysicalDevices returned by the ICD: 98411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { 98511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].physicalDevice = pPhysicalDevices[i]; 98611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].pInstance = pInstance; 98711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].pDevice = NULL; 98811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].gotQueueFamilyPropertyCount = false; 98911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].gotSurfaceCapabilities = false; 99011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].surfaceFormatCount = 0; 99111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].pSurfaceFormats = NULL; 99211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].presentModeCount = 0; 99311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->physicalDeviceMap[pPhysicalDevices[i]].pPresentModes = NULL; 99411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Point to the associated SwpInstance: 99511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pInstance) { 99611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pInstance->physicalDevices[pPhysicalDevices[i]] = &my_data->physicalDeviceMap[pPhysicalDevices[i]]; 99711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 99811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 99911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 100011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 100111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 100211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 100311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, 100411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkDeviceCreateInfo *pCreateInfo, 100511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 100611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 100711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 100811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 100911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(chain_info->u.pLayerInfo); 101011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 101111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 101211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice"); 101311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (fpCreateDevice == NULL) { 101411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_INITIALIZATION_FAILED; 101511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 101611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 101711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Advance the link info for the next element on the chain 101811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 101911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 102011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); 102111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (result != VK_SUCCESS) { 102211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 102311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 102411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 102511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 102611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); 102711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 102811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Setup device dispatch table 102911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->device_dispatch_table = new VkLayerDispatchTable; 103011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); 103111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 103211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); 103311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice); 103411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 103511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 103611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 103711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 103811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 103911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_key key = get_dispatch_key(device); 104011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(key, layer_data_map); 104111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 104211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 104311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->device_dispatch_table->DestroyDevice(device, pAllocator); 104411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 104511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Do some internal cleanup: 104611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 104711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpDevice *pDevice = NULL; 104811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 104911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->deviceMap.find(device); 105011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second; 105111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 105211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice) { 105311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Delete the SwpDevice associated with this device: 105411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice->pPhysicalDevice) { 105511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice->pPhysicalDevice->pDevice = NULL; 105611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 105711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pDevice->swapchains.empty()) { 105811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_DEL_OBJECT_BEFORE_CHILDREN, 105911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called before all of its associated " 106011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkSwapchainKHRs were destroyed.", 106111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 106211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Empty and then delete all SwpSwapchain's 106311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (auto it = pDevice->swapchains.begin(); it != pDevice->swapchains.end(); it++) { 106411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Delete all SwpImage's 106511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert it->second->images.clear(); 106611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // In case the swapchain's surface hasn't been destroyed yet 106711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // (which is likely) delete its association with this swapchain 106811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // (i.e. so we can't point to this swpchain from that surface, 106911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // later on): 107011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (it->second->pSurface) { 107111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert it->second->pSurface->swapchains.clear(); 107211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 107311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 107411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice->swapchains.clear(); 107511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 107611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->deviceMap.erase(device); 107711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 107811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert delete my_data->device_dispatch_table; 107911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data_map.erase(key); 108011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 108111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 108211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, 108311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t queueFamilyIndex, VkSurfaceKHR surface, 108411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkBool32 *pSupported) { 108511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 108611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 108711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 108811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 108911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 109011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 109111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 109211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 109311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 109411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 109511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the surface extension was enabled: 109611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) { 109711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 109811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 109911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 110011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SURFACE_EXTENSION_NAME); 110111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 110211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPhysicalDevice->gotQueueFamilyPropertyCount) { 110311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, "VkPhysicalDevice", 110411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_DID_NOT_QUERY_QUEUE_FAMILIES, "%s() called before calling the " 110511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkGetPhysicalDeviceQueueFamilyProperties " 110611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "function.", 110711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 110811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pPhysicalDevice->gotQueueFamilyPropertyCount && (queueFamilyIndex >= pPhysicalDevice->numOfQueueFamilies)) { 110911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 111011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, 111111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkPhysicalDevice", queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); 111211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 111311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSupported) { 111411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSupported"); 111511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 111611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 111711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 111811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 111911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 112011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, 112111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSupported); 112211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 112311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 112411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 112511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 112611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 112711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 112811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 112911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pSupported && pPhysicalDevice) { 113011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this query: 113111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = pPhysicalDevice->pInstance; 113211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSurface *pSurface = (pInstance) ? pInstance->surfaces[surface] : NULL; 113311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSurface) { 113411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->supportedSurfaces[surface] = pSurface; 113511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSurface->numQueueFamilyIndexSupport) { 113611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->gotQueueFamilyPropertyCount) { 113711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurface->pQueueFamilyIndexSupport = 113811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (VkBool32 *)malloc(pPhysicalDevice->numOfQueueFamilies * sizeof(VkBool32)); 113911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSurface->pQueueFamilyIndexSupport != NULL) { 114011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurface->numQueueFamilyIndexSupport = pPhysicalDevice->numOfQueueFamilies; 114111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 114211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 114311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 114411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSurface->numQueueFamilyIndexSupport) { 114511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurface->pQueueFamilyIndexSupport[queueFamilyIndex] = *pSupported; 114611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 114711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 114811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 114911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 115011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 115111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 115211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 115311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 115411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 115511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 115611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { 115711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 115811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 115911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 116011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 116111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 116211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 116311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 116411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 116511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 116611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 116711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the surface extension was enabled: 116811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) { 116911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 117011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 117111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 117211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SURFACE_EXTENSION_NAME); 117311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 117411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSurfaceCapabilities) { 117511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSurfaceCapabilities"); 117611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 117711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 117811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 117911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 118011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 118111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, 118211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurfaceCapabilities); 118311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 118411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 118511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 118611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 118711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 118811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 118911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 119011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pPhysicalDevice) { 119111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this query: 119211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->gotSurfaceCapabilities = true; 119311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // FIXME: NEED TO COPY THIS DATA, BECAUSE pSurfaceCapabilities POINTS TO APP-ALLOCATED DATA 119411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->surfaceCapabilities = *pSurfaceCapabilities; 119511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 119611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 119711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 119811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 119911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 120011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 120111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 120211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, 120311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSurfaceFormatKHR *pSurfaceFormats) { 120411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 120511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 120611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 120711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 120811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 120911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 121011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 121111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 121211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 121311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 121411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the surface extension was enabled: 121511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) { 121611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 121711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 121811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 121911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SURFACE_EXTENSION_NAME); 122011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 122111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSurfaceFormatCount) { 122211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pSurfaceFormatCount"); 122311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pPhysicalDevice && pSurfaceFormats) { 122411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Compare the preliminary value of *pSurfaceFormatCount with the 122511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // value this time: 122611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->surfaceFormatCount == 0) { 122711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Since we haven't recorded a preliminary value of 122811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // *pSurfaceFormatCount, that likely means that the application 122911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // didn't previously call this function with a NULL value of 123011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // pSurfaceFormats: 123111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_ZERO_PRIOR_COUNT( 123211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 123311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert physicalDevice, "pSurfaceFormatCount", "pSurfaceFormats"); 123411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (*pSurfaceFormatCount > pPhysicalDevice->surfaceFormatCount) { 123511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_INVALID_COUNT( 123611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 123711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert physicalDevice, "pSurfaceFormatCount", "pSurfaceFormats", 123811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *pSurfaceFormatCount, pPhysicalDevice->surfaceFormatCount); 123911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 124011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 124111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 124211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 124311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 124411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 124511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, 124611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurfaceFormats); 124711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 124811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 124911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 125011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 125111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 125211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 125311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 125411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pPhysicalDevice && !pSurfaceFormats && pSurfaceFormatCount) { 125511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this preliminary query: 125611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount; 125711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if ((result == VK_SUCCESS) && pPhysicalDevice && 125811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurfaceFormats && pSurfaceFormatCount && 125911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (*pSurfaceFormatCount > 0)) { 126011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this query: 126111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->surfaceFormatCount = *pSurfaceFormatCount; 126211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->pSurfaceFormats = (VkSurfaceFormatKHR *)malloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR)); 126311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->pSurfaceFormats) { 126411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) { 126511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->pSurfaceFormats[i] = pSurfaceFormats[i]; 126611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 126711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 126811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->surfaceFormatCount = 0; 126911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 127011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 127111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 127211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 127311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 127411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 127511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 127611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 127711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, 127811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkPresentModeKHR *pPresentModes) { 127911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 128011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 128111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 128211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 128311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = NULL; 128411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 128511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 128611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 128711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 128811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 128911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the surface extension was enabled: 129011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->pInstance && !pPhysicalDevice->pInstance->surfaceExtensionEnabled) { 129111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pPhysicalDevice->pInstance, "VkInstance", 129211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 129311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkInstance.", __FUNCTION__, 129411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SURFACE_EXTENSION_NAME); 129511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 129611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPresentModeCount) { 129711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, physicalDevice, "pPresentModeCount"); 129811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pPhysicalDevice && pPresentModes) { 129911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Compare the preliminary value of *pPresentModeCount with the 130011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // value this time: 130111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->presentModeCount == 0) { 130211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Since we haven't recorded a preliminary value of 130311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // *pPresentModeCount, that likely means that the application 130411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // didn't previously call this function with a NULL value of 130511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // pPresentModes: 130611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_ZERO_PRIOR_COUNT( 130711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 130811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert physicalDevice, "pPresentModeCount", "pPresentModes"); 130911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (*pPresentModeCount > pPhysicalDevice->presentModeCount) { 131011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_INVALID_COUNT( 131111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 131211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert physicalDevice, "pPresentModeCount", "pPresentModes", 131311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *pPresentModeCount, pPhysicalDevice->presentModeCount); 131411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 131511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 131611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 131711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 131811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 131911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 132011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, 132111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPresentModeCount, pPresentModes); 132211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 132311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 132411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 132511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 132611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->physicalDeviceMap.find(physicalDevice); 132711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice = (it == my_data->physicalDeviceMap.end()) ? NULL : &it->second; 132811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 132911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pPhysicalDevice && !pPresentModes && pPresentModeCount) { 133011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this preliminary query: 133111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->presentModeCount = *pPresentModeCount; 133211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if ((result == VK_SUCCESS) && pPhysicalDevice && 133311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPresentModes && pPresentModeCount && 133411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (*pPresentModeCount > 0)) { 133511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this query: 133611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->presentModeCount = *pPresentModeCount; 133711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->pPresentModes = (VkPresentModeKHR *)malloc(*pPresentModeCount * sizeof(VkPresentModeKHR)); 133811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->pPresentModes) { 133911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < *pPresentModeCount; i++) { 134011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->pPresentModes[i] = pPresentModes[i]; 134111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 134211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 134311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->presentModeCount = 0; 134411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 134511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 134611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 134711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 134811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 134911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 135011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 135111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This function does the up-front validation work for vkCreateSwapchainKHR(), 135211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// and returns true if a logging callback indicates that the call down the 135311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// chain should be skipped: 135411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic bool validateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, VkSwapchainKHR *pSwapchain) { 135511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO: Validate cases of re-creating a swapchain (the current code 135611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // assumes a new swapchain is being created). 135711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 135811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 135911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert char fn[] = "vkCreateSwapchainKHR"; 136011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpDevice *pDevice = NULL; 136111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 136211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->deviceMap.find(device); 136311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second; 136411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 136511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 136611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the swapchain extension was enabled: 136711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice && !pDevice->swapchainExtensionEnabled) { 136811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 136911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkDevice.", fn, 137011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SWAPCHAIN_EXTENSION_NAME); 137111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 137211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo) { 137311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 137411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 137511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->sType != VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR) { 137611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo", 137711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR"); 137811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 137911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pNext != NULL) { 138011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pCreateInfo"); 138111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 138211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 138311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSwapchain) { 138411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pSwapchain"); 138511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 138611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 138711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Keep around a useful pointer to pPhysicalDevice: 138811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice; 138911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 139011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo values with result of 139111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkGetPhysicalDeviceQueueFamilyProperties 139211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice && pPhysicalDevice->gotQueueFamilyPropertyCount) { 139311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; i++) { 139411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->pQueueFamilyIndices[i] >= pPhysicalDevice->numOfQueueFamilies) { 139511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_QUEUE_FAMILY_INDEX_TOO_LARGE(VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, pPhysicalDevice, 139611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkPhysicalDevice", pCreateInfo->pQueueFamilyIndices[i], 139711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pPhysicalDevice->numOfQueueFamilies); 139811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 139911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 140011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 140111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 140211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo values with the results of 140311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): 140411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPhysicalDevice || !pPhysicalDevice->gotSurfaceCapabilities) { 140511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, 140611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called before calling " 140711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkGetPhysicalDeviceSurfaceCapabilitiesKHR().", 140811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn); 140911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pCreateInfo) { 141011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->surface to make sure that 141111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkGetPhysicalDeviceSurfaceSupportKHR() reported this as a supported 141211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // surface: 141311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSurface *pSurface = ((pPhysicalDevice) ? pPhysicalDevice->supportedSurfaces[pCreateInfo->surface] : NULL); 141411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSurface) { 141511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_CREATE_UNSUPPORTED_SURFACE, 141611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with pCreateInfo->surface that " 141711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "was not returned by " 141811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkGetPhysicalDeviceSurfaceSupportKHR() " 141911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "for the device.", 142011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn); 142111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 142211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 142311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->minImageCount against 142411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceCapabilitiesKHR::{min|max}ImageCount: 142511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSurfaceCapabilitiesKHR *pCapabilities = &pPhysicalDevice->surfaceCapabilities; 142611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pCreateInfo->minImageCount < pCapabilities->minImageCount) || 142711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ((pCapabilities->maxImageCount > 0) && (pCreateInfo->minImageCount > pCapabilities->maxImageCount))) { 142811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 142911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_MIN_IMG_COUNT, "%s() called with pCreateInfo->minImageCount " 143011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "= %d, which is outside the bounds returned " 143111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. " 143211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "minImageCount = %d, maxImageCount = %d).", 143311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->minImageCount, pCapabilities->minImageCount, pCapabilities->maxImageCount); 143411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 143511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->imageExtent against 143611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceCapabilitiesKHR::{current|min|max}ImageExtent: 143711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pCapabilities->currentExtent.width == -1) && 143811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ((pCreateInfo->imageExtent.width < pCapabilities->minImageExtent.width) || 143911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pCreateInfo->imageExtent.width > pCapabilities->maxImageExtent.width) || 144011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pCreateInfo->imageExtent.height < pCapabilities->minImageExtent.height) || 144111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pCreateInfo->imageExtent.height > pCapabilities->maxImageExtent.height))) { 144211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR( 144311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_CREATE_SWAP_OUT_OF_BOUNDS_EXTENTS, 144411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with pCreateInfo->imageExtent = " 144511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "(%d,%d), which is outside the bounds " 144611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): " 144711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "currentExtent = (%d,%d), minImageExtent = " 144811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "(%d,%d), maxImageExtent = (%d,%d).", 144911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, pCapabilities->currentExtent.width, 145011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pCapabilities->currentExtent.height, pCapabilities->minImageExtent.width, pCapabilities->minImageExtent.height, 145111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pCapabilities->maxImageExtent.width, pCapabilities->maxImageExtent.height); 145211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 145311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pCapabilities->currentExtent.width != -1) && 145411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ((pCreateInfo->imageExtent.width != pCapabilities->currentExtent.width) || 145511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pCreateInfo->imageExtent.height != pCapabilities->currentExtent.height))) { 145611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 145711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_EXTENTS_NO_MATCH_WIN, "%s() called with pCreateInfo->imageExtent = " 145811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "(%d,%d), which is not equal to the " 145911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "currentExtent = (%d,%d) returned by " 146011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkGetPhysicalDeviceSurfaceCapabilitiesKHR().", 146111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, 146211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pCapabilities->currentExtent.width, pCapabilities->currentExtent.height); 146311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 146411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->preTransform has one bit set (1st two 146511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // lines of if-statement), which bit is also set in 146611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceCapabilitiesKHR::supportedTransforms (3rd line of if-statement): 146711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo->preTransform || (pCreateInfo->preTransform & (pCreateInfo->preTransform - 1)) || 146811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert !(pCreateInfo->preTransform & pCapabilities->supportedTransforms)) { 146911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // This is an error situation; one for which we'd like to give 147011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // the developer a helpful, multi-line error message. Build it 147111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // up a little at a time, and then log it: 147211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::string errorString = ""; 147311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert char str[1024]; 147411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Here's the first part of the message: 147511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert sprintf(str, "%s() called with a non-supported " 147611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->preTransform (i.e. %s). " 147711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Supported values are:\n", 147811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, surfaceTransformStr(pCreateInfo->preTransform)); 147911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert errorString += str; 148011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (int i = 0; i < 32; i++) { 148111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Build up the rest of the message: 148211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((1 << i) & pCapabilities->supportedTransforms) { 148311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *newStr = surfaceTransformStr((VkSurfaceTransformFlagBitsKHR)(1 << i)); 148411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert sprintf(str, " %s\n", newStr); 148511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert errorString += str; 148611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 148711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 148811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Log the message that we've built up: 148911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 149011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reinterpret_cast<uint64_t &>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_PRE_TRANSFORM, LAYER_NAME, 149111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s", errorString.c_str()); 149211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 149311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->compositeAlpha has one bit set (1st two 149411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // lines of if-statement), which bit is also set in 149511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceCapabilitiesKHR::supportedCompositeAlpha (3rd line of if-statement): 149611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo->compositeAlpha || (pCreateInfo->compositeAlpha & (pCreateInfo->compositeAlpha - 1)) || 149711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert !((pCreateInfo->compositeAlpha) & pCapabilities->supportedCompositeAlpha)) { 149811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // This is an error situation; one for which we'd like to give 149911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // the developer a helpful, multi-line error message. Build it 150011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // up a little at a time, and then log it: 150111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::string errorString = ""; 150211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert char str[1024]; 150311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Here's the first part of the message: 150411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert sprintf(str, "%s() called with a non-supported " 150511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->compositeAlpha (i.e. %s). " 150611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Supported values are:\n", 150711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, surfaceCompositeAlphaStr(pCreateInfo->compositeAlpha)); 150811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert errorString += str; 150911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (int i = 0; i < 32; i++) { 151011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Build up the rest of the message: 151111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((1 << i) & pCapabilities->supportedCompositeAlpha) { 151211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *newStr = surfaceCompositeAlphaStr((VkCompositeAlphaFlagBitsKHR)(1 << i)); 151311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert sprintf(str, " %s\n", newStr); 151411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert errorString += str; 151511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 151611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 151711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Log the message that we've built up: 151811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 151911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reinterpret_cast<uint64_t &>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_BAD_COMPOSITE_ALPHA, 152011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LAYER_NAME, "%s", errorString.c_str()); 152111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 152211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->imageArraySize against 152311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceCapabilitiesKHR::maxImageArraySize: 152411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pCreateInfo->imageArrayLayers < 1) || (pCreateInfo->imageArrayLayers > pCapabilities->maxImageArrayLayers)) { 152511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 152611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_IMG_ARRAY_SIZE, "%s() called with a non-supported " 152711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->imageArraySize (i.e. %d). " 152811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "Minimum value is 1, maximum value is %d.", 152911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->imageArrayLayers, pCapabilities->maxImageArrayLayers); 153011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 153111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->imageUsage against 153211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceCapabilitiesKHR::supportedUsageFlags: 153311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->imageUsage != (pCreateInfo->imageUsage & pCapabilities->supportedUsageFlags)) { 153411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 153511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_IMG_USAGE_FLAGS, "%s() called with a non-supported " 153611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->imageUsage (i.e. 0x%08x)." 153711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert " Supported flag bits are 0x%08x.", 153811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->imageUsage, pCapabilities->supportedUsageFlags); 153911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 154011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 154111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 154211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo values with the results of 154311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkGetPhysicalDeviceSurfaceFormatsKHR(): 154411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPhysicalDevice || !pPhysicalDevice->surfaceFormatCount) { 154511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, 154611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called before calling " 154711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkGetPhysicalDeviceSurfaceFormatsKHR().", 154811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn); 154911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pCreateInfo) { 155011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->imageFormat against 155111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceFormatKHR::format: 155211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool foundFormat = false; 155311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool foundColorSpace = false; 155411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool foundMatch = false; 155511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < pPhysicalDevice->surfaceFormatCount; i++) { 155611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->imageFormat == pPhysicalDevice->pSurfaceFormats[i].format) { 155711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->imageColorSpace against 155811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // VkSurfaceFormatKHR::colorSpace: 155911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert foundFormat = true; 156011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) { 156111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert foundMatch = true; 156211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert break; 156311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 156411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 156511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->imageColorSpace == pPhysicalDevice->pSurfaceFormats[i].colorSpace) { 156611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert foundColorSpace = true; 156711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 156811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 156911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 157011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!foundMatch) { 157111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!foundFormat) { 157211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!foundColorSpace) { 157311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 157411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_IMG_FMT_CLR_SP, "%s() called with neither a " 157511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "supported pCreateInfo->imageFormat " 157611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "(i.e. %d) nor a supported " 157711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->imageColorSpace " 157811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "(i.e. %d).", 157911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->imageFormat, pCreateInfo->imageColorSpace); 158011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 158111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 158211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_IMG_FORMAT, "%s() called with a non-supported " 158311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->imageFormat (i.e. %d).", 158411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->imageFormat); 158511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 158611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (!foundColorSpace) { 158711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 158811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_IMG_COLOR_SPACE, "%s() called with a non-supported " 158911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->imageColorSpace (i.e. %d).", 159011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->imageColorSpace); 159111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 159211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 159311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 159411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 159511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo values with the results of 159611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkGetPhysicalDeviceSurfacePresentModesKHR(): 159711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPhysicalDevice || !pPhysicalDevice->presentModeCount) { 159811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pCreateInfo || (pCreateInfo->presentMode != VK_PRESENT_MODE_FIFO_KHR)) { 159911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_CREATE_SWAP_WITHOUT_QUERY, 160011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called before calling " 160111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "vkGetPhysicalDeviceSurfacePresentModesKHR().", 160211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn); 160311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 160411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pCreateInfo) { 160511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->presentMode against 160611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // vkGetPhysicalDeviceSurfacePresentModesKHR(): 160711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool foundMatch = false; 160811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < pPhysicalDevice->presentModeCount; i++) { 160911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPhysicalDevice->pPresentModes[i] == pCreateInfo->presentMode) { 161011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert foundMatch = true; 161111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert break; 161211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 161311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 161411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!foundMatch) { 161511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 161611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_PRESENT_MODE, "%s() called with a non-supported " 161711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->presentMode (i.e. %s).", 161811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, presentModeStr(pCreateInfo->presentMode)); 161911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 162011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 162111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 162211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->imageSharingMode and related values: 162311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) { 162411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pCreateInfo->queueFamilyIndexCount <= 1) || !pCreateInfo->pQueueFamilyIndices) { 162511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 162611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_BAD_SHARING_VALUES, "%s() called with a supported " 162711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->sharingMode of (i.e. %s), " 162811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "but with a bad value(s) for " 162911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->queueFamilyIndexCount or " 163011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->pQueueFamilyIndices).", 163111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, sharingModeStr(pCreateInfo->imageSharingMode)); 163211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 163311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pCreateInfo->imageSharingMode != VK_SHARING_MODE_EXCLUSIVE) { 163411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_CREATE_SWAP_BAD_SHARING_MODE, 163511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with a non-supported " 163611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->imageSharingMode (i.e. %s).", 163711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, sharingModeStr(pCreateInfo->imageSharingMode)); 163811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 163911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 164011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->clipped: 164111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo && (pCreateInfo->clipped != VK_FALSE) && (pCreateInfo->clipped != VK_TRUE)) { 164211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_BAD_BOOL, 164311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with a VkBool32 value that is " 164411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "neither VK_TRUE nor VK_FALSE, but has the " 164511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "numeric value of %d.", 164611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn, pCreateInfo->clipped); 164711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 164811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 164911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate pCreateInfo->oldSwapchain: 165011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo && pCreateInfo->oldSwapchain) { 165111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSwapchain *pOldSwapchain = NULL; 165211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 165311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(pCreateInfo->oldSwapchain); 165411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pOldSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 165511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 165611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pOldSwapchain) { 165711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (device != pOldSwapchain->pDevice->device) { 165811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 165911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, "%s() called with a different VkDevice " 166011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "than the VkSwapchainKHR was created with.", 166111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 166211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 166311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pCreateInfo->surface != pOldSwapchain->pSurface->surface) { 166411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", 166511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE, "%s() called with pCreateInfo->oldSwapchain " 166611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "that has a different VkSurfaceKHR than " 166711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "pCreateInfo->surface.", 166811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert fn); 166911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 167011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 167111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TBD: Leave this in (not sure object_track will check this)? 167211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 167311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR_NON_VALID_OBJ(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pCreateInfo->oldSwapchain, "VkSwapchainKHR"); 167411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 167511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 167611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 167711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return skipCall; 167811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 167911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 168011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, 168111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, 168211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSwapchainKHR *pSwapchain) { 168311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 168411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 168511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 168611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = validateCreateSwapchainKHR(device, pCreateInfo, pSwapchain); 168711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 168811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 168911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 169011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 169111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->device_dispatch_table->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); 169211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 169311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 169411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (result == VK_SUCCESS) { 169511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Remember the swapchain's handle, and link it to the device: 169611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpDevice *pDevice = NULL; 169711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 169811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->deviceMap.find(device); 169911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second; 170011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 170111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 170211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->swapchainMap[*pSwapchain].swapchain = *pSwapchain; 170311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice) { 170411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice->swapchains[*pSwapchain] = &my_data->swapchainMap[*pSwapchain]; 170511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 170611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->swapchainMap[*pSwapchain].pDevice = pDevice; 170711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->swapchainMap[*pSwapchain].imageCount = 0; 170811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->swapchainMap[*pSwapchain].usedAllocatorToCreate = (pAllocator != NULL); 170911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Store a pointer to the surface 171011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice; 171111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpInstance *pInstance = (pPhysicalDevice) ? pPhysicalDevice->pInstance : NULL; 171211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_instance_data = 171311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ((pInstance) ? get_my_data_ptr(get_dispatch_key(pInstance->instance), layer_data_map) : NULL); 171411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSurface *pSurface = ((my_data && pCreateInfo) ? &my_instance_data->surfaceMap[pCreateInfo->surface] : NULL); 171511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->swapchainMap[*pSwapchain].pSurface = pSurface; 171611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSurface) { 171711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSurface->swapchains[*pSwapchain] = &my_data->swapchainMap[*pSwapchain]; 171811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 171911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 172011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 172111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 172211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 172311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 172411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 172511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 172611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) { 172711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODOs: 172811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 172911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - Implement a check for validity language that reads: All uses of 173011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // presentable images acquired from pname:swapchain must: have completed 173111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // execution 173211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 173311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 173411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 173511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpDevice *pDevice = NULL; 173611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 173711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->deviceMap.find(device); 173811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second; 173911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 174011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 174111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the swapchain extension was enabled: 174211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice && !pDevice->swapchainExtensionEnabled) { 174311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 174411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkDevice.", __FUNCTION__, 174511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SWAPCHAIN_EXTENSION_NAME); 174611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 174711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 174811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Regardless of skipCall value, do some internal cleanup: 174911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSwapchain *pSwapchain = NULL; 175011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 175111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(swapchain); 175211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 175311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 175411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain) { 175511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Delete the SwpSwapchain associated with this swapchain: 175611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain->pDevice) { 175711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->pDevice->swapchains.erase(swapchain); 175811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (device != pSwapchain->pDevice->device) { 175911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, 176011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with a different VkDevice than the " 176111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkSwapchainKHR was created with.", 176211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 176311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 176411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 176511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain->pSurface) { 176611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->pSurface->swapchains.erase(swapchain); 176711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 176811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain->imageCount) { 176911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->images.clear(); 177011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 177111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pAllocator != NULL) != pSwapchain->usedAllocatorToCreate) { 177211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, instance, "VkInstance", SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, 177311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with incompatible pAllocator from when " 177411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "the object was created.", 177511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__); 177611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 177711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->swapchainMap.erase(swapchain); 177811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 177911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 178011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 178111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 178211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 178311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator); 178411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 178511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 178611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 178711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 178811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { 178911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 179011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 179111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 179211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 179311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpDevice *pDevice = NULL; 179411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 179511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->deviceMap.find(device); 179611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second; 179711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 179811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 179911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the swapchain extension was enabled: 180011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice && !pDevice->swapchainExtensionEnabled) { 180111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 180211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkDevice.", __FUNCTION__, 180311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SWAPCHAIN_EXTENSION_NAME); 180411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 180511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSwapchain *pSwapchain = NULL; 180611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 180711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(swapchain); 180811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 180911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 181011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSwapchainImageCount) { 181111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pSwapchainImageCount"); 181211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (pSwapchain && pSwapchainImages) { 181311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Compare the preliminary value of *pSwapchainImageCount with the 181411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // value this time: 181511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain->imageCount == 0) { 181611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Since we haven't recorded a preliminary value of 181711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // *pSwapchainImageCount, that likely means that the application 181811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // didn't previously call this function with a NULL value of 181911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // pSwapchainImages: 182011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_ZERO_PRIOR_COUNT( 182111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 182211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert device, "pSwapchainImageCount", "pSwapchainImages"); 182311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if (*pSwapchainImageCount > pSwapchain->imageCount) { 182411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_INVALID_COUNT( 182511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 182611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert device, "pSwapchainImageCount", "pSwapchainImages", 182711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *pSwapchainImageCount, pSwapchain->imageCount); 182811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 182911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 183011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 183111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 183211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 183311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 183411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages); 183511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 183611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 183711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 183811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 183911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(swapchain); 184011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 184111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 184211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((result == VK_SUCCESS) && pSwapchain && !pSwapchainImages && pSwapchainImageCount) { 184311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the result of this preliminary query: 184411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->imageCount = *pSwapchainImageCount; 184511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else if ((result == VK_SUCCESS) && pSwapchain && pSwapchainImages && 184611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchainImageCount && (*pSwapchainImageCount > 0)) { 184711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Record the images and their state: 184811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->imageCount = *pSwapchainImageCount; 184911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < *pSwapchainImageCount; i++) { 185011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->images[i].image = pSwapchainImages[i]; 185111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->images[i].pSwapchain = pSwapchain; 185211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->images[i].acquiredByApp = false; 185311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 185411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 185511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 185611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 185711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 185811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 185911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 186011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 186111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) { 186211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODOs: 186311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 186411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - Address the timeout. Possibilities include looking at the state of the 186511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // swapchain's images, depending on the timeout value. 186611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - Implement a check for validity language that reads: If pname:semaphore is 186711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // not sname:VK_NULL_HANDLE it must: be unsignalled 186811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - Implement a check for validity language that reads: If pname:fence is not 186911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // sname:VK_NULL_HANDLE it must: be unsignalled and mustnot: be associated 187011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // with any other queue command that has not yet completed execution on that 187111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // queue 187211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - Record/update the state of the swapchain, in case an error occurs 187311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // (e.g. VK_ERROR_OUT_OF_DATE_KHR). 187411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 187511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 187611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 187711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 187811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpDevice *pDevice = NULL; 187911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 188011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->deviceMap.find(device); 188111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second; 188211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 188311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 188411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Validate that the swapchain extension was enabled: 188511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice && !pDevice->swapchainExtensionEnabled) { 188611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 188711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkDevice.", __FUNCTION__, 188811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SWAPCHAIN_EXTENSION_NAME); 188911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 189011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((semaphore == VK_NULL_HANDLE) && (fence == VK_NULL_HANDLE)) { 189111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "VkDevice", SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, 189211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called with both the semaphore and fence parameters set to " 189311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_NULL_HANDLE (at least one should be used).", __FUNCTION__); 189411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 189511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSwapchain *pSwapchain = NULL; 189611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 189711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(swapchain); 189811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 189911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 190011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice; 190111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain && pPhysicalDevice && pPhysicalDevice->gotSurfaceCapabilities) { 190211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Look to see if the application has already acquired the maximum 190311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // number of images, and this will push it past the spec-defined 190411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // limits: 190511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t minImageCount = pPhysicalDevice->surfaceCapabilities.minImageCount; 190611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t imagesAcquiredByApp = 0; 190711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < pSwapchain->imageCount; i++) { 190811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain->images[i].acquiredByApp) { 190911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert imagesAcquiredByApp++; 191011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 191111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 191211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (imagesAcquiredByApp > (pSwapchain->imageCount - minImageCount)) { 191311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR( 191411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 191511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert swapchain, "VkSwapchainKHR", 191611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_APP_ACQUIRES_TOO_MANY_IMAGES, 191711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called when it cannot succeed. The application has " 191811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "acquired %d image(s) that have not yet been presented. The " 191911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "maximum number of images that the application can " 192011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "simultaneously acquire from this swapchain (including this " 192111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "call to %s()) is %d. That value is derived by subtracting " 192211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkSurfaceCapabilitiesKHR::minImageCount (%d) from the number " 192311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "of images in the swapchain (%d) and adding 1.\n", 192411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__, imagesAcquiredByApp, __FUNCTION__, 192511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (pSwapchain->imageCount - minImageCount + 1), 192611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert minImageCount, pSwapchain->imageCount); 192711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 192811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 192911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pImageIndex) { 193011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pImageIndex"); 193111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 193211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 193311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 193411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 193511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 193611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->device_dispatch_table->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); 193711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 193811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 193911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Obtain this pointer again after locking: 194011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 194111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(swapchain); 194211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 194311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 194411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR)) && pSwapchain) { 194511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Change the state of the image (now acquired by the application): 194611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->images[*pImageIndex].acquiredByApp = true; 194711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 194811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 194911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 195011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 195111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 195211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 195311cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) { 195411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODOs: 195511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 195611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - Implement a check for validity language that reads: Any given element of 195711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal 195811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // of that sname:VkSemaphore that won't be consumed by any other wait on that 195911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // semaphore 196011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - Record/update the state of the swapchain, in case an error occurs 196111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // (e.g. VK_ERROR_OUT_OF_DATE_KHR). 196211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = VK_SUCCESS; 196311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 196411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map); 196511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 196611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPresentInfo) { 196711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo"); 196811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 196911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPresentInfo->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR) { 197011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_WRONG_STYPE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo", 197111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR"); 197211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 197311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPresentInfo->pNext != NULL) { 197411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_INFO_WRONG_NEXT(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo"); 197511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 197611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPresentInfo->swapchainCount) { 197711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_ZERO_VALUE(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo->swapchainCount"); 197811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 197911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPresentInfo->pSwapchains) { 198011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo->pSwapchains"); 198111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 198211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pPresentInfo->pImageIndices) { 198311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR_NULL_POINTER(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, device, "pPresentInfo->pImageIndices"); 198411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 198511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Note: pPresentInfo->pResults is allowed to be NULL 198611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 198711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 198811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::unique_lock<std::mutex> lock(global_lock); 198911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; pPresentInfo && (i < pPresentInfo->swapchainCount); i++) { 199011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t index = pPresentInfo->pImageIndices[i]; 199111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSwapchain *pSwapchain = NULL; 199211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 199311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]); 199411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 199511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 199611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain) { 199711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSwapchain->pDevice->swapchainExtensionEnabled) { 199811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, pSwapchain->pDevice, "VkDevice", 199911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_EXT_NOT_ENABLED_BUT_USED, 200011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "%s() called even though the %s extension was not enabled for this VkDevice.", __FUNCTION__, 200111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VK_KHR_SWAPCHAIN_EXTENSION_NAME); 200211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 200311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (index >= pSwapchain->imageCount) { 200411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pPresentInfo->pSwapchains[i], "VkSwapchainKHR", 200511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_INDEX_TOO_LARGE, "%s() called for an index that is too " 200611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "large (i.e. %d). There are only %d " 200711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "images in this VkSwapchainKHR.\n", 200811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__, index, pSwapchain->imageCount); 200911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } else { 201011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!pSwapchain->images[index].acquiredByApp) { 201111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pPresentInfo->pSwapchains[i], 201211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "VkSwapchainKHR", SWAPCHAIN_INDEX_NOT_IN_USE, "%s() returned an index (i.e. %d) " 201311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "for an image that is not acquired by " 201411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "the application.", 201511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__, index); 201611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 201711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 201811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpQueue *pQueue = NULL; 201911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 202011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->queueMap.find(queue); 202111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pQueue = (it == my_data->queueMap.end()) ? NULL : &it->second; 202211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 202311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSurface *pSurface = pSwapchain->pSurface; 202411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pQueue && pSurface && pSurface->numQueueFamilyIndexSupport) { 202511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert uint32_t queueFamilyIndex = pQueue->queueFamilyIndex; 202611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Note: the 1st test is to ensure queueFamilyIndex is in range, 202711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // and the 2nd test is the validation check: 202811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((pSurface->numQueueFamilyIndexSupport > queueFamilyIndex) && 202911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (!pSurface->pQueueFamilyIndexSupport[queueFamilyIndex])) { 203011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert skipCall |= 203111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert LOG_ERROR(VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pPresentInfo->pSwapchains[i], "VkSwapchainKHR", 203211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SWAPCHAIN_SURFACE_NOT_SUPPORTED_WITH_QUEUE, "%s() called with a swapchain whose " 203311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "surface is not supported for " 203411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "presention on this device with the " 203511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "queueFamilyIndex (i.e. %d) of the " 203611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "given queue.", 203711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __FUNCTION__, queueFamilyIndex); 203811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 203911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 204011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 204111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 204211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 204311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 204411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 204511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.unlock(); 204611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = my_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo); 204711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock.lock(); 204811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 204911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pPresentInfo && ((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) { 205011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) { 205111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert int index = pPresentInfo->pImageIndices[i]; 205211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpSwapchain *pSwapchain = NULL; 205311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 205411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]); 205511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second; 205611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 205711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pSwapchain) { 205811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Change the state of the image (no longer acquired by the 205911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // application): 206011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pSwapchain->images[index].acquiredByApp = false; 206111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 206211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 206311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 206411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 206511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 206611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return VK_ERROR_VALIDATION_FAILED_EXT; 206711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 206811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 206911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 207011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { 207111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool skipCall = false; 207211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 207311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 207411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!skipCall) { 207511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Call down the call chain: 207611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); 207711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 207811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Remember the queue's handle, and link it to the device: 207911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 208011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert SwpDevice *pDevice = NULL; 208111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 208211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto it = my_data->deviceMap.find(device); 208311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice = (it == my_data->deviceMap.end()) ? NULL : &it->second; 208411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 208511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->queueMap[&pQueue].queue = *pQueue; 208611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDevice) { 208711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pDevice->queues[*pQueue] = &my_data->queueMap[*pQueue]; 208811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 208911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->queueMap[&pQueue].pDevice = pDevice; 209011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->queueMap[&pQueue].queueFamilyIndex = queueFamilyIndex; 209111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 209211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 209311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 209411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 209511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 209611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { 209711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 209811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkResult result = 209911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 210011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (VK_SUCCESS == result) { 210111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 210211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback); 210311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 210411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return result; 210511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 210611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 210711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, 210811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDebugReportCallbackEXT msgCallback, 210911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator) { 211011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 211111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 211211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::lock_guard<std::mutex> lock(global_lock); 211311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator); 211411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 211511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 211611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 211711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, 211811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 211911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 212011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, 212111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert pMsg); 212211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 212311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 212411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 212511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *pLayerName, uint32_t *pCount, 212611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkExtensionProperties *pProperties) { 212711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pLayerName && !strcmp(pLayerName, swapchain_layer.layerName)) 212811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetExtensionProperties(0, nullptr, pCount, pProperties); 212911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 213011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(physicalDevice); 213111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 213211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dispatch_key key = get_dispatch_key(physicalDevice); 213311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data = get_my_data_ptr(key, layer_data_map); 213411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties); 213511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 213611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 213711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 213811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_instance_command(const char *name); 213911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 214011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 214111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_khr_surface_command(const char *name, VkInstance instance); 214211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 214311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 214411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_device_command(const char *name); 214511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 214611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 214711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_khr_swapchain_command(const char *name, VkDevice dev); 214811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 214911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) { 215011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc = intercept_core_device_command(funcName); 215111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (proc) 215211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return proc; 215311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 215411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(device); 215511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 215611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data; 215711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 215811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 215911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerDispatchTable *pDisp = my_data->device_dispatch_table; 216011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 216111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert proc = intercept_khr_swapchain_command(funcName, device); 216211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (proc) 216311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return proc; 216411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 216511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pDisp->GetDeviceProcAddr == NULL) 216611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return NULL; 216711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pDisp->GetDeviceProcAddr(device, funcName); 216811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 216911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 217011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) { 217111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc = intercept_core_instance_command(funcName); 217211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!proc) 217311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert proc = intercept_core_device_command(funcName); 217411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!proc) 217511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert proc = intercept_khr_swapchain_command(funcName, VK_NULL_HANDLE); 217611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (proc) 217711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return proc; 217811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 217911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(instance); 218011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 218111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert layer_data *my_data; 218211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 218311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; 218411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 218511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert proc = debug_report_get_instance_proc_addr(my_data->report_data, funcName); 218611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!proc) 218711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert proc = intercept_khr_surface_command(funcName, instance); 218811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (proc) 218911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return proc; 219011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 219111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (pTable->GetInstanceProcAddr == NULL) 219211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return NULL; 219311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pTable->GetInstanceProcAddr(instance, funcName); 219411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 219511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 219611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 219711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_instance_command(const char *name) { 219811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static const struct { 219911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *name; 220011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc; 220111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } core_instance_commands[] = { 220211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) }, 220311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) }, 220411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) }, 220511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) }, 220611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) }, 220711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) }, 220811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) }, 220911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 221011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 221111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // we should never be queried for these commands 221211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert assert(strcmp(name, "vkEnumerateInstanceLayerProperties") && 221311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert strcmp(name, "vkEnumerateInstanceExtensionProperties") && 221411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert strcmp(name, "vkEnumerateDeviceLayerProperties")); 221511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 221611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) { 221711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(core_instance_commands[i].name, name)) 221811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return core_instance_commands[i].proc; 221911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 222011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 222111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 222211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 222311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 222411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 222511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_khr_surface_command(const char *name, VkInstance instance) { 222611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static const struct { 222711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *name; 222811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc; 222911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } khr_surface_commands[] = { 223011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_ANDROID_KHR 223111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateAndroidSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR) }, 223211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_ANDROID_KHR 223311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_MIR_KHR 223411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateMirSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateMirSurfaceKHR) }, 223511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceMirPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMirPresentationSupportKHR) }, 223611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_MIR_KHR 223711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WAYLAND_KHR 223811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateWaylandSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWaylandSurfaceKHR) }, 223911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceWaylandPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWaylandPresentationSupportKHR) }, 224011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WAYLAND_KHR 224111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_WIN32_KHR 224211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateWin32SurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWin32SurfaceKHR) }, 224311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceWin32PresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceWin32PresentationSupportKHR) }, 224411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_WIN32_KHR 224511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XCB_KHR 224611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateXcbSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXcbSurfaceKHR) }, 224711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceXcbPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXcbPresentationSupportKHR) }, 224811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XCB_KHR 224911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef VK_USE_PLATFORM_XLIB_KHR 225011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateXlibSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXlibSurfaceKHR) }, 225111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceXlibPresentationSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceXlibPresentationSupportKHR) }, 225211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // VK_USE_PLATFORM_XLIB_KHR 225311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkDestroySurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR) }, 225411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceSurfaceSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR) }, 225511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR) }, 225611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceSurfaceFormatsKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR) }, 225711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetPhysicalDeviceSurfacePresentModesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR) }, 225811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 225911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 226011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // do not check if VK_KHR_*_surface is enabled (why?) 226111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 226211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (size_t i = 0; i < ARRAY_SIZE(khr_surface_commands); i++) { 226311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(khr_surface_commands[i].name, name)) 226411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return khr_surface_commands[i].proc; 226511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 226611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 226711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 226811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 226911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 227011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 227111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_core_device_command(const char *name) { 227211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static const struct { 227311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *name; 227411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc; 227511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } core_device_commands[] = { 227611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) }, 227711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice) }, 227811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue) }, 227911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 228011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 228111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) { 228211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(core_device_commands[i].name, name)) 228311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return core_device_commands[i].proc; 228411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 228511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 228611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 228711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 228811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 228911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic PFN_vkVoidFunction 229011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertintercept_khr_swapchain_command(const char *name, VkDevice dev) { 229111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static const struct { 229211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *name; 229311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert PFN_vkVoidFunction proc; 229411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } khr_swapchain_commands[] = { 229511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkCreateSwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR) }, 229611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkDestroySwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR) }, 229711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkGetSwapchainImagesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR) }, 229811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkAcquireNextImageKHR", reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR) }, 229911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { "vkQueuePresentKHR", reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR) }, 230011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 230111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 230211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // do not check if VK_KHR_swapchain is enabled (why?) 230311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 230411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (size_t i = 0; i < ARRAY_SIZE(khr_swapchain_commands); i++) { 230511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(khr_swapchain_commands[i].name, name)) 230611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return khr_swapchain_commands[i].proc; 230711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 230811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 230911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 231011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 231111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 231211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace swapchain 231311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 231411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// vk_layer_logging.h expects these to be defined 231511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 231611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR VkResult VKAPI_CALL 231711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 231811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { 231911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return swapchain::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 232011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 232111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 232211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, 232311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkDebugReportCallbackEXT msgCallback, 232411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const VkAllocationCallbacks *pAllocator) { 232511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert swapchain::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 232611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 232711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 232811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVKAPI_ATTR void VKAPI_CALL 232911cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, 233011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 233111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert swapchain::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg); 233211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 233311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 233411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// loader-layer interface v0 233511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 233611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 233711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) { 233811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetExtensionProperties(ARRAY_SIZE(swapchain::instance_extensions), swapchain::instance_extensions, pCount, pProperties); 233911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 234011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 234111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 234211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 234311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetLayerProperties(1, &swapchain::swapchain_layer, pCount, pProperties); 234411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 234511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 234611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 234711cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertvkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) { 234811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return util_GetLayerProperties(1, &swapchain::swapchain_layer, pCount, pProperties); 234911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 235011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 235111cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 235211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char *pLayerName, uint32_t *pCount, 235311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert VkExtensionProperties *pProperties) { 235411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // the layer command handles VK_NULL_HANDLE just fine 235511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return swapchain::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); 235611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 235711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 235811cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) { 235911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return swapchain::GetDeviceProcAddr(dev, funcName); 236011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 236111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 236211cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 236311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) 236411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceLayerProperties); 236511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties")) 236611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateDeviceLayerProperties); 236711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) 236811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkEnumerateInstanceExtensionProperties); 236911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!strcmp(funcName, "vkGetInstanceProcAddr")) 237011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return reinterpret_cast<PFN_vkVoidFunction>(vkGetInstanceProcAddr); 237111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 237211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return swapchain::GetInstanceProcAddr(instance, funcName); 237311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 2374