From 64d58c5aac5b1a161ab0ab7fb7d2234edcedaa32 Mon Sep 17 00:00:00 2001 From: Ian Elliott Date: Thu, 4 Feb 2016 08:17:18 -0700 Subject: [PATCH] layers: MR212 Add locking to the swapchain layer. --- layers/swapchain.cpp | 265 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 188 insertions(+), 77 deletions(-) diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp index 69e3d96..912d06a 100644 --- a/layers/swapchain.cpp +++ b/layers/swapchain.cpp @@ -38,8 +38,8 @@ #include "vk_layer_extension_utils.h" #include "vk_enum_string_helper.h" -// FIXME/TODO: Make sure this layer is thread-safe! - +static int globalLockInitialized = 0; +static loader_platform_thread_mutex globalLock; // The following is for logging error messages: static std::unordered_map layer_data_map; @@ -264,6 +264,11 @@ static void initSwapchain(layer_data *my_data, const VkAllocationCallbacks *pAll layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback); my_data->logging_callback.push_back(callback); } + if (!globalLockInitialized) + { + loader_platform_thread_create_mutex(&globalLock); + globalLockInitialized = 1; + } } static const char *surfaceTransformStr(VkSurfaceTransformFlagBitsKHR value) @@ -329,25 +334,24 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstance VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) { - VkBool32 skipCall = VK_FALSE; dispatch_key key = get_dispatch_key(instance); layer_data *my_data = get_my_data_ptr(key, layer_data_map); SwpInstance *pInstance = &(my_data->instanceMap[instance]); - if (VK_FALSE == skipCall) { - // Call down the call chain: - my_data->instance_dispatch_table->DestroyInstance(instance, pAllocator); + // Call down the call chain: + my_data->instance_dispatch_table->DestroyInstance(instance, pAllocator); - // Clean up logging callback, if any - while (my_data->logging_callback.size() > 0) { - VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); - layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); - my_data->logging_callback.pop_back(); - } - layer_debug_report_destroy_instance(my_data->report_data); + loader_platform_thread_lock_mutex(&globalLock); + + // Clean up logging callback, if any + while (my_data->logging_callback.size() > 0) { + VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); + layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); + my_data->logging_callback.pop_back(); } + layer_debug_report_destroy_instance(my_data->report_data); - // Regardless of skipCall value, do some internal cleanup: + // Do additional internal cleanup: if (pInstance) { // Delete all of the SwpPhysicalDevice's, SwpSurface's, and the // SwpInstance associated with this instance: @@ -389,6 +393,14 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance } delete my_data->instance_dispatch_table; layer_data_map.erase(key); + if (layer_data_map.empty()) { + // Release mutex when destroying last instance + loader_platform_thread_unlock_mutex(&globalLock); + loader_platform_thread_delete_mutex(&globalLock); + globalLockInitialized = 0; + } else { + loader_platform_thread_unlock_mutex(&globalLock); + } } VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties( @@ -396,25 +408,24 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyPropert uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties) { - VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); - SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; - if (VK_FALSE == skipCall) { - // Call down the call chain: - my_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties( - physicalDevice, - pQueueFamilyPropertyCount, - pQueueFamilyProperties); + // Call down the call chain: + my_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties( + physicalDevice, + pQueueFamilyPropertyCount, + pQueueFamilyProperties); - // Record the result of this query: - if (pPhysicalDevice && - pQueueFamilyPropertyCount && !pQueueFamilyProperties) { - pPhysicalDevice->gotQueueFamilyPropertyCount = true; - pPhysicalDevice->numOfQueueFamilies = - *pQueueFamilyPropertyCount; - } + // Record the result of this query: + loader_platform_thread_lock_mutex(&globalLock); + SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; + if (pPhysicalDevice && + pQueueFamilyPropertyCount && !pQueueFamilyProperties) { + pPhysicalDevice->gotQueueFamilyPropertyCount = true; + pPhysicalDevice->numOfQueueFamilies = + *pQueueFamilyPropertyCount; } + loader_platform_thread_unlock_mutex(&globalLock); } #ifdef VK_USE_PLATFORM_ANDROID_KHR @@ -427,6 +438,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpInstance *pInstance = &(my_data->instanceMap[instance]); // Validate that the platform extension was enabled: @@ -459,9 +471,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->CreateAndroidSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pInstance = &(my_data->instanceMap[instance]); if ((result == VK_SUCCESS) && pInstance && pSurface) { // Record the VkSurfaceKHR returned by the ICD: my_data->surfaceMap[*pSurface].surface = *pSurface; @@ -473,9 +489,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( // Point to the associated SwpInstance: pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } #endif // VK_USE_PLATFORM_ANDROID_KHR @@ -490,6 +507,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpInstance *pInstance = &(my_data->instanceMap[instance]); // Validate that the platform extension was enabled: @@ -522,9 +540,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->CreateMirSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pInstance = &(my_data->instanceMap[instance]); if ((result == VK_SUCCESS) && pInstance && pSurface) { // Record the VkSurfaceKHR returned by the ICD: my_data->surfaceMap[*pSurface].surface = *pSurface; @@ -536,9 +558,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR( // Point to the associated SwpInstance: pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -550,6 +573,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentatio VkBool32 result = VK_FALSE; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the platform extension was enabled: @@ -570,6 +594,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentatio queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); } + loader_platform_thread_unlock_mutex(&globalLock); if (VK_FALSE == skipCall) { // Call down the call chain: @@ -590,6 +615,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpInstance *pInstance = &(my_data->instanceMap[instance]); // Validate that the platform extension was enabled: @@ -622,9 +648,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->CreateWaylandSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pInstance = &(my_data->instanceMap[instance]); if ((result == VK_SUCCESS) && pInstance && pSurface) { // Record the VkSurfaceKHR returned by the ICD: my_data->surfaceMap[*pSurface].surface = *pSurface; @@ -636,9 +666,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( // Point to the associated SwpInstance: pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -650,6 +681,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresent VkBool32 result = VK_FALSE; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the platform extension was enabled: @@ -670,6 +702,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresent queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); } + loader_platform_thread_unlock_mutex(&globalLock); if (VK_FALSE == skipCall) { // Call down the call chain: @@ -690,6 +723,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpInstance *pInstance = &(my_data->instanceMap[instance]); // Validate that the platform extension was enabled: @@ -722,9 +756,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->CreateWin32SurfaceKHR( instance, pCreateInfo, pAllocator, pSurface); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pInstance = &(my_data->instanceMap[instance]); if ((result == VK_SUCCESS) && pInstance && pSurface) { // Record the VkSurfaceKHR returned by the ICD: my_data->surfaceMap[*pSurface].surface = *pSurface; @@ -736,9 +774,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( // Point to the associated SwpInstance: pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -749,6 +788,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32Presentat VkBool32 result = VK_FALSE; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the platform extension was enabled: @@ -769,6 +809,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32Presentat queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); } + loader_platform_thread_unlock_mutex(&globalLock); if (VK_FALSE == skipCall) { // Call down the call chain: @@ -789,6 +830,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpInstance *pInstance = &(my_data->instanceMap[instance]); // Validate that the platform extension was enabled: @@ -821,9 +863,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->CreateXcbSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pInstance = &(my_data->instanceMap[instance]); if ((result == VK_SUCCESS) && pInstance && pSurface) { // Record the VkSurfaceKHR returned by the ICD: my_data->surfaceMap[*pSurface].surface = *pSurface; @@ -835,9 +881,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( // Point to the associated SwpInstance: pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -850,6 +897,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentatio VkBool32 result = VK_FALSE; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the platform extension was enabled: @@ -870,6 +918,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentatio queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); } + loader_platform_thread_unlock_mutex(&globalLock); if (VK_FALSE == skipCall) { // Call down the call chain: @@ -890,6 +939,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpInstance *pInstance = &(my_data->instanceMap[instance]); // Validate that the platform extension was enabled: @@ -922,9 +972,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->CreateXlibSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pInstance = &(my_data->instanceMap[instance]); if ((result == VK_SUCCESS) && pInstance && pSurface) { // Record the VkSurfaceKHR returned by the ICD: my_data->surfaceMap[*pSurface].surface = *pSurface; @@ -936,9 +990,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( // Point to the associated SwpInstance: pInstance->surfaces[*pSurface] = &my_data->surfaceMap[*pSurface]; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -951,6 +1006,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentati VkBool32 result = VK_FALSE; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the platform extension was enabled: @@ -971,6 +1027,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentati queueFamilyIndex, pPhysicalDevice->numOfQueueFamilies); } + loader_platform_thread_unlock_mutex(&globalLock); if (VK_FALSE == skipCall) { // Call down the call chain: @@ -985,6 +1042,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance insta { VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpInstance *pInstance = &(my_data->instanceMap[instance]); SwpSurface *pSurface = &my_data->surfaceMap[surface]; @@ -1024,6 +1082,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance insta } my_data->surfaceMap.erase(surface); } + loader_platform_thread_unlock_mutex(&globalLock); if (VK_FALSE == skipCall) { // Call down the call chain: @@ -1035,39 +1094,38 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance insta VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices) { VkResult result = VK_SUCCESS; - VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); - SwpInstance *pInstance = &(my_data->instanceMap[instance]); - if (VK_FALSE == skipCall) { - // Call down the call chain: - result = my_data->instance_dispatch_table->EnumeratePhysicalDevices( - instance, pPhysicalDeviceCount, pPhysicalDevices); - - if ((result == VK_SUCCESS) && pInstance && pPhysicalDevices && - (*pPhysicalDeviceCount > 0)) { - // Record the VkPhysicalDevices returned by the ICD: - for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { - my_data->physicalDeviceMap[pPhysicalDevices[i]].physicalDevice = - pPhysicalDevices[i]; - my_data->physicalDeviceMap[pPhysicalDevices[i]].pInstance = pInstance; - my_data->physicalDeviceMap[pPhysicalDevices[i]].pDevice = NULL; - my_data->physicalDeviceMap[pPhysicalDevices[i]].gotQueueFamilyPropertyCount = false; - my_data->physicalDeviceMap[pPhysicalDevices[i]].gotSurfaceCapabilities = false; - my_data->physicalDeviceMap[pPhysicalDevices[i]].surfaceFormatCount = 0; - my_data->physicalDeviceMap[pPhysicalDevices[i]].pSurfaceFormats = NULL; - my_data->physicalDeviceMap[pPhysicalDevices[i]].presentModeCount = 0; - my_data->physicalDeviceMap[pPhysicalDevices[i]].pPresentModes = NULL; - // Point to the associated SwpInstance: - if (pInstance) { - pInstance->physicalDevices[pPhysicalDevices[i]] = - &my_data->physicalDeviceMap[pPhysicalDevices[i]]; - } + // Call down the call chain: + result = my_data->instance_dispatch_table->EnumeratePhysicalDevices( + instance, pPhysicalDeviceCount, pPhysicalDevices); + + loader_platform_thread_lock_mutex(&globalLock); + SwpInstance *pInstance = &(my_data->instanceMap[instance]); + if ((result == VK_SUCCESS) && pInstance && pPhysicalDevices && + (*pPhysicalDeviceCount > 0)) { + // Record the VkPhysicalDevices returned by the ICD: + for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { + my_data->physicalDeviceMap[pPhysicalDevices[i]].physicalDevice = + pPhysicalDevices[i]; + my_data->physicalDeviceMap[pPhysicalDevices[i]].pInstance = pInstance; + my_data->physicalDeviceMap[pPhysicalDevices[i]].pDevice = NULL; + my_data->physicalDeviceMap[pPhysicalDevices[i]].gotQueueFamilyPropertyCount = false; + my_data->physicalDeviceMap[pPhysicalDevices[i]].gotSurfaceCapabilities = false; + my_data->physicalDeviceMap[pPhysicalDevices[i]].surfaceFormatCount = 0; + my_data->physicalDeviceMap[pPhysicalDevices[i]].pSurfaceFormats = NULL; + my_data->physicalDeviceMap[pPhysicalDevices[i]].presentModeCount = 0; + my_data->physicalDeviceMap[pPhysicalDevices[i]].pPresentModes = NULL; + // Point to the associated SwpInstance: + if (pInstance) { + pInstance->physicalDevices[pPhysicalDevices[i]] = + &my_data->physicalDeviceMap[pPhysicalDevices[i]]; } } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1091,6 +1149,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice p return result; } + loader_platform_thread_lock_mutex(&globalLock); layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); @@ -1100,23 +1159,22 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice p my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); createDeviceRegisterExtensions(physicalDevice, pCreateInfo, *pDevice); + loader_platform_thread_unlock_mutex(&globalLock); return result; } VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { - VkBool32 skipCall = VK_FALSE; dispatch_key key = get_dispatch_key(device); layer_data *my_data = get_my_data_ptr(key, layer_data_map); - SwpDevice *pDevice = &my_data->deviceMap[device]; - if (VK_FALSE == skipCall) { - // Call down the call chain: - my_data->device_dispatch_table->DestroyDevice(device, pAllocator); - } + // Call down the call chain: + my_data->device_dispatch_table->DestroyDevice(device, pAllocator); - // Regardless of skipCall value, do some internal cleanup: + // Do some internal cleanup: + loader_platform_thread_lock_mutex(&globalLock); + SwpDevice *pDevice = &my_data->deviceMap[device]; if (pDevice) { // Delete the SwpDevice associated with this device: if (pDevice->pPhysicalDevice) { @@ -1147,6 +1205,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, cons } delete my_data->device_dispatch_table; layer_data_map.erase(key); + loader_platform_thread_unlock_mutex(&globalLock); } VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( @@ -1158,6 +1217,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupport VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the surface extension was enabled: @@ -1195,10 +1255,14 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupport if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceSupportKHR( physicalDevice, queueFamilyIndex, surface, pSupported); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; if ((result == VK_SUCCESS) && pSupported && pPhysicalDevice) { // Record the result of this query: SwpInstance *pInstance = pPhysicalDevice->pInstance; @@ -1223,9 +1287,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupport } } } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1237,6 +1302,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabil VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the surface extension was enabled: @@ -1257,18 +1323,23 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabil if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceCapabilitiesKHR( physicalDevice, surface, pSurfaceCapabilities); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; if ((result == VK_SUCCESS) && pPhysicalDevice) { // Record the result of this query: pPhysicalDevice->gotSurfaceCapabilities = true; // FIXME: NEED TO COPY THIS DATA, BECAUSE pSurfaceCapabilities POINTS TO APP-ALLOCATED DATA pPhysicalDevice->surfaceCapabilities = *pSurfaceCapabilities; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1281,6 +1352,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the surface extension was enabled: @@ -1301,9 +1373,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfaceFormatsKHR( physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; if ((result == VK_SUCCESS) && pPhysicalDevice && !pSurfaceFormats && pSurfaceFormatCount) { // Record the result of this preliminary query: @@ -1335,9 +1411,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats } } } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1350,6 +1427,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresent VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpPhysicalDevice *pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; // Validate that the surface extension was enabled: @@ -1370,9 +1448,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresent if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->instance_dispatch_table->GetPhysicalDeviceSurfacePresentModesKHR( physicalDevice, surface, pPresentModeCount, pPresentModes); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pPhysicalDevice = &my_data->physicalDeviceMap[physicalDevice]; if ((result == VK_SUCCESS) && pPhysicalDevice && !pPresentModes && pPresentModeCount) { // Record the result of this preliminary query: @@ -1404,9 +1486,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresent } } } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1806,13 +1889,16 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( { VkResult result = VK_SUCCESS; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); VkBool32 skipCall = validateCreateSwapchainKHR(device, pCreateInfo, pSwapchain); if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->device_dispatch_table->CreateSwapchainKHR( device, pCreateInfo, pAllocator, pSwapchain); + loader_platform_thread_lock_mutex(&globalLock); if (result == VK_SUCCESS) { // Remember the swapchain's handle, and link it to the device: @@ -1844,9 +1930,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( &my_data->swapchainMap[*pSwapchain]; } } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1862,6 +1949,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( // application must: have completed execution VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpDevice *pDevice = &my_data->deviceMap[device]; // Validate that the swapchain extension was enabled: @@ -1901,6 +1989,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( } my_data->swapchainMap.erase(swapchain); } + loader_platform_thread_unlock_mutex(&globalLock); if (VK_FALSE == skipCall) { // Call down the call chain: @@ -1917,6 +2006,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpDevice *pDevice = &my_data->deviceMap[device]; // Validate that the swapchain extension was enabled: @@ -1935,9 +2025,13 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->device_dispatch_table->GetSwapchainImagesKHR( device, swapchain, pSwapchainImageCount, pSwapchainImages); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pSwapchain = &my_data->swapchainMap[swapchain]; if ((result == VK_SUCCESS) && pSwapchain && !pSwapchainImages && pSwapchainImageCount) { // Record the result of this preliminary query: @@ -1965,9 +2059,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( } } } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -1994,6 +2089,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( VkResult result = VK_SUCCESS; VkBool32 skipCall = VK_FALSE; layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); + loader_platform_thread_lock_mutex(&globalLock); SwpDevice *pDevice = &my_data->deviceMap[device]; // Validate that the swapchain extension was enabled: @@ -2039,17 +2135,22 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->device_dispatch_table->AcquireNextImageKHR( device, swapchain, timeout, semaphore, fence, pImageIndex); + loader_platform_thread_lock_mutex(&globalLock); + // Obtain this pointer again after locking: + pSwapchain = &my_data->swapchainMap[swapchain]; if (((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR)) && pSwapchain) { // Change the state of the image (now owned by the application): pSwapchain->images[*pImageIndex].ownedByApp = true; } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -2103,6 +2204,7 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( // Note: pPresentInfo->pResults is allowed to be NULL } + loader_platform_thread_lock_mutex(&globalLock); for (uint32_t i = 0; pPresentInfo && (i < pPresentInfo->swapchainCount); i++) { @@ -2165,8 +2267,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( if (VK_FALSE == skipCall) { // Call down the call chain: + loader_platform_thread_unlock_mutex(&globalLock); result = my_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo); + loader_platform_thread_lock_mutex(&globalLock); if (pPresentInfo && ((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) { @@ -2181,9 +2285,10 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( } } } - + loader_platform_thread_unlock_mutex(&globalLock); return result; } + loader_platform_thread_unlock_mutex(&globalLock); return VK_ERROR_VALIDATION_FAILED_EXT; } @@ -2202,6 +2307,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( device, queueFamilyIndex, queueIndex, pQueue); // Remember the queue's handle, and link it to the device: + loader_platform_thread_lock_mutex(&globalLock); SwpDevice *pDevice = &my_data->deviceMap[device]; my_data->queueMap[&pQueue].queue = *pQueue; if (pDevice) { @@ -2209,6 +2315,7 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( } my_data->queueMap[&pQueue].pDevice = pDevice; my_data->queueMap[&pQueue].queueFamilyIndex = queueFamilyIndex; + loader_platform_thread_unlock_mutex(&globalLock); } } @@ -2222,7 +2329,9 @@ VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); VkResult result = my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); if (VK_SUCCESS == result) { + loader_platform_thread_lock_mutex(&globalLock); result = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback); + loader_platform_thread_unlock_mutex(&globalLock); } return result; } @@ -2231,7 +2340,9 @@ VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkIns { layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); + loader_platform_thread_lock_mutex(&globalLock); layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator); + loader_platform_thread_unlock_mutex(&globalLock); } VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( -- 2.7.4