From: Charles Giessen Date: Tue, 26 Mar 2024 22:23:13 +0000 (-0500) Subject: Refactor instance level objects to not use icd_index X-Git-Tag: upstream/1.3.296~71 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a2daf4d465438d7043b892f728eb16020a829b88;p=platform%2Fupstream%2FVulkan-Loader.git Refactor instance level objects to not use icd_index The previous way per-ICD instance level objects were accessed was using the ICD's index into an array that was allocated with the object. This solution worked while the indexes were static, but with the recent change to remove unused ICD's that is no longer the case. This commit replaces an array per object with object arrays, one for each type (surface, debug messenger, & debug report) and per ICD. That flips where the index comes from, with the instance storing an array indication which indices are used and which are free. Whenever an instance level object is created, the loader checks if there is a free index available, reusing it if available. Otherwise it resizes its own store as well as each ICD's array for that object. --- diff --git a/loader/debug_utils.c b/loader/debug_utils.c index 6656eb77..8a12d4a0 100644 --- a/loader/debug_utils.c +++ b/loader/debug_utils.c @@ -92,7 +92,6 @@ VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkD if (0 < pCallbackData->objectCount) { debug_utils_AnnotObjectToDebugReportObject(pCallbackData->pObjects, &object_type, &object_handle); } - while (pTrav) { if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & messageSeverity) && (pTrav->messenger.messageType & messageTypes)) { @@ -106,7 +105,6 @@ VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkD bail = true; } } - pTrav = pTrav->pNext; } } @@ -175,33 +173,44 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstanc const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger) { - VkDebugUtilsMessengerEXT *icd_info = NULL; - const struct loader_icd_term *icd_term; struct loader_instance *inst = (struct loader_instance *)instance; VkResult res = VK_SUCCESS; - uint32_t storage_idx; VkLayerDbgFunctionNode *new_dbg_func_node = NULL; + uint32_t next_index = 0; - icd_info = (VkDebugUtilsMessengerEXT *)loader_calloc_with_instance_fallback( - pAllocator, inst, inst->icd_terms_count * sizeof(VkDebugUtilsMessengerEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - - if (!icd_info) { + uint32_t *pNextIndex = loader_instance_heap_alloc(inst, sizeof(uint32_t), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (NULL == pNextIndex) { res = VK_ERROR_OUT_OF_HOST_MEMORY; goto out; } - storage_idx = 0; - for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { - if (!icd_term->dispatch.CreateDebugUtilsMessengerEXT) { - continue; + res = loader_get_next_available_entry(inst, &inst->debug_utils_messengers_list, &next_index); + if (res != VK_SUCCESS) { + goto out; + } + + for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { + if (icd_term->debug_utils_messenger_list.list == NULL) { + res = loader_init_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_utils_messenger_list, + sizeof(VkDebugUtilsMessengerEXT)); + if (res != VK_SUCCESS) { + goto out; + } + } else if (icd_term->debug_utils_messenger_list.capacity <= next_index * sizeof(VkDebugUtilsMessengerEXT)) { + res = loader_resize_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_utils_messenger_list); + if (res != VK_SUCCESS) { + goto out; + } } - res = icd_term->dispatch.CreateDebugUtilsMessengerEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]); + if (icd_term->dispatch.CreateDebugUtilsMessengerEXT) { + res = icd_term->dispatch.CreateDebugUtilsMessengerEXT(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->debug_utils_messenger_list.list[next_index]); - if (res != VK_SUCCESS) { - goto out; + if (res != VK_SUCCESS) { + goto out; + } } - storage_idx++; } // Setup the debug report callback in the terminator since a layer may want @@ -221,27 +230,29 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstanc new_dbg_func_node->pUserData = pCreateInfo->pUserData; new_dbg_func_node->pNext = inst->current_dbg_function_head; inst->current_dbg_function_head = new_dbg_func_node; - - *pMessenger = (VkDebugUtilsMessengerEXT)(uintptr_t)icd_info; + *pNextIndex = next_index; + *pMessenger = (VkDebugUtilsMessengerEXT)(uintptr_t)pNextIndex; new_dbg_func_node->messenger.messenger = *pMessenger; out: // Roll back on errors if (VK_SUCCESS != res) { - storage_idx = 0; - for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { - if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) { - continue; - } - - if (icd_info && icd_info[storage_idx]) { - icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator); + if (pNextIndex) { + for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { + if (icd_term->debug_utils_messenger_list.list && icd_term->debug_utils_messenger_list.list[next_index] && + NULL != icd_term->dispatch.DestroyDebugUtilsMessengerEXT) { + icd_term->dispatch.DestroyDebugUtilsMessengerEXT( + icd_term->instance, icd_term->debug_utils_messenger_list.list[next_index], pAllocator); + } } - storage_idx++; + } + if (inst->debug_utils_messengers_list.list && + inst->debug_utils_messengers_list.capacity > (*pNextIndex) * sizeof(VkBool32)) { + inst->debug_utils_messengers_list.list[*pNextIndex] = VK_FALSE; } loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node); - loader_free_with_instance_fallback(pAllocator, inst, icd_info); + loader_free_with_instance_fallback(pAllocator, inst, pNextIndex); } return res; @@ -250,27 +261,28 @@ out: // This is the instance chain terminator function for DestroyDebugUtilsMessenger VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks *pAllocator) { - uint32_t storage_idx; - VkDebugUtilsMessengerEXT *icd_info; - const struct loader_icd_term *icd_term; - struct loader_instance *inst = (struct loader_instance *)instance; - icd_info = (VkDebugUtilsMessengerEXT *)(uintptr_t)messenger; - storage_idx = 0; - for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { - if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) { - continue; - } + uint32_t *debug_messenger_index = (uint32_t *)(uintptr_t)messenger; + // Make sure that messenger actually points to anything + if (NULL == debug_messenger_index) { + return; + } - if (icd_info && icd_info[storage_idx]) { - icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator); + for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { + if (icd_term->debug_utils_messenger_list.list && icd_term->debug_utils_messenger_list.list[*debug_messenger_index] && + NULL != icd_term->dispatch.DestroyDebugUtilsMessengerEXT) { + icd_term->dispatch.DestroyDebugUtilsMessengerEXT( + icd_term->instance, icd_term->debug_utils_messenger_list.list[*debug_messenger_index], pAllocator); } - storage_idx++; } util_DestroyDebugUtilsMessenger(inst, messenger, pAllocator); + if (inst->debug_utils_messengers_list.list && + inst->debug_utils_messengers_list.capacity > (*debug_messenger_index) * sizeof(VkBool32)) { + inst->debug_utils_messengers_list.list[*debug_messenger_index] = VK_FALSE; + } - loader_free_with_instance_fallback(pAllocator, inst, icd_info); + loader_free_with_instance_fallback(pAllocator, inst, debug_messenger_index); } // This is the instance chain terminator function for SubmitDebugUtilsMessageEXT @@ -431,32 +443,44 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstanc const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) { - VkDebugReportCallbackEXT *icd_info = NULL; - const struct loader_icd_term *icd_term; struct loader_instance *inst = (struct loader_instance *)instance; VkResult res = VK_SUCCESS; - uint32_t storage_idx; VkLayerDbgFunctionNode *new_dbg_func_node = NULL; + uint32_t next_index = 0; - icd_info = ((VkDebugReportCallbackEXT *)loader_calloc_with_instance_fallback( - pAllocator, inst, inst->icd_terms_count * sizeof(VkDebugReportCallbackEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)); - if (!icd_info) { + uint32_t *pNextIndex = loader_instance_heap_alloc(inst, sizeof(uint32_t), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (NULL == pNextIndex) { res = VK_ERROR_OUT_OF_HOST_MEMORY; goto out; } - storage_idx = 0; - for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { - if (!icd_term->dispatch.CreateDebugReportCallbackEXT) { - continue; + res = loader_get_next_available_entry(inst, &inst->debug_report_callbacks_list, &next_index); + if (res != VK_SUCCESS) { + goto out; + } + + for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { + if (icd_term->debug_report_callback_list.list == NULL) { + res = loader_init_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_report_callback_list, + sizeof(VkDebugUtilsMessengerEXT)); + if (res != VK_SUCCESS) { + goto out; + } + } else if (icd_term->debug_report_callback_list.capacity <= next_index * sizeof(VkDebugReportCallbackEXT)) { + res = loader_resize_generic_list(inst, (struct loader_generic_list *)&icd_term->debug_report_callback_list); + if (res != VK_SUCCESS) { + goto out; + } } - res = icd_term->dispatch.CreateDebugReportCallbackEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]); + if (icd_term->dispatch.CreateDebugReportCallbackEXT) { + res = icd_term->dispatch.CreateDebugReportCallbackEXT(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->debug_report_callback_list.list[next_index]); - if (res != VK_SUCCESS) { - goto out; + if (res != VK_SUCCESS) { + goto out; + } } - storage_idx++; } // Setup the debug report callback in the terminator since a layer may want @@ -476,27 +500,29 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstanc new_dbg_func_node->pUserData = pCreateInfo->pUserData; new_dbg_func_node->pNext = inst->current_dbg_function_head; inst->current_dbg_function_head = new_dbg_func_node; - - *pCallback = (VkDebugReportCallbackEXT)(uintptr_t)icd_info; + *pNextIndex = next_index; + *pCallback = (VkDebugReportCallbackEXT)(uintptr_t)pNextIndex; new_dbg_func_node->report.msgCallback = *pCallback; out: // Roll back on errors if (VK_SUCCESS != res) { - storage_idx = 0; - for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { - if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) { - continue; - } - - if (icd_info && icd_info[storage_idx]) { - icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator); + if (pNextIndex) { + for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { + if (icd_term->debug_report_callback_list.list && icd_term->debug_report_callback_list.list[next_index] && + NULL != icd_term->dispatch.DestroyDebugReportCallbackEXT) { + icd_term->dispatch.DestroyDebugReportCallbackEXT( + icd_term->instance, icd_term->debug_report_callback_list.list[next_index], pAllocator); + } } - storage_idx++; + } + if (inst->debug_report_callbacks_list.list && + inst->debug_report_callbacks_list.capacity > (*pNextIndex) * sizeof(VkBool32)) { + inst->debug_report_callbacks_list.list[*pNextIndex] = VK_FALSE; } loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node); - loader_free_with_instance_fallback(pAllocator, inst, icd_info); + loader_free_with_instance_fallback(pAllocator, inst, pNextIndex); } return res; @@ -505,27 +531,26 @@ out: // This is the instance chain terminator function for DestroyDebugReportCallback VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *pAllocator) { - uint32_t storage_idx; - VkDebugReportCallbackEXT *icd_info; - const struct loader_icd_term *icd_term; - struct loader_instance *inst = (struct loader_instance *)instance; - icd_info = (VkDebugReportCallbackEXT *)(uintptr_t)callback; - storage_idx = 0; - for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { - if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) { - continue; - } - - if (icd_info[storage_idx]) { - icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator); + uint32_t *debug_report_index = (uint32_t *)(uintptr_t)callback; + // Make sure that callback actually points to anything + if (NULL == debug_report_index) { + return; + } + for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { + if (icd_term->debug_report_callback_list.list && icd_term->debug_report_callback_list.list[*debug_report_index] && + NULL != icd_term->dispatch.DestroyDebugReportCallbackEXT) { + icd_term->dispatch.DestroyDebugReportCallbackEXT( + icd_term->instance, icd_term->debug_report_callback_list.list[*debug_report_index], pAllocator); } - storage_idx++; } util_DestroyDebugReportCallback(inst, callback, pAllocator); - - loader_free_with_instance_fallback(pAllocator, inst, icd_info); + if (inst->debug_report_callbacks_list.list && + inst->debug_report_callbacks_list.capacity > (*debug_report_index) * sizeof(VkBool32)) { + inst->debug_report_callbacks_list.list[*debug_report_index] = VK_FALSE; + } + loader_free_with_instance_fallback(pAllocator, inst, debug_report_index); } // This is the instance chain terminator function for DebugReportMessage diff --git a/loader/extension_manual.c b/loader/extension_manual.c index b8ed8a33..ad5fe0c1 100644 --- a/loader/extension_manual.c +++ b/loader/extension_manual.c @@ -107,12 +107,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2E struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface); - uint8_t icd_index = phys_dev_term->icd_index; // Unwrap the surface if needed VkSurfaceKHR unwrapped_surface = surface; - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) { - unwrapped_surface = icd_surface->real_icd_surfaces[icd_index]; + if (NULL != phys_dev_term->this_icd_term->surface_list.list && + phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) { + unwrapped_surface = phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]; } if (NULL != icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT) { @@ -275,12 +276,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2E abort(); } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface); - uint8_t icd_index = phys_dev_term->icd_index; - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy; surface_info_copy.sType = pSurfaceInfo->sType; surface_info_copy.pNext = pSurfaceInfo->pNext; - surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; + surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index]; return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy, pPresentModeCount, pPresentModes); } @@ -304,9 +306,8 @@ VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(VkDevice de VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR *pModes) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev || NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, @@ -321,12 +322,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT( "[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-pSurfaceInfo-parameter]"); abort(); /* Intentionally fail so user can correct issue. */ } - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface; - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) { + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface); + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy; surface_info_copy.sType = pSurfaceInfo->sType; surface_info_copy.pNext = pSurfaceInfo->pNext; - surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; + surface_info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index]; return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy, pModes); } diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c index b74369c8..3fa7593b 100644 --- a/loader/generated/vk_loader_extensions.c +++ b/loader/generated/vk_loader_extensions.c @@ -40,7 +40,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev) { struct loader_device *found_dev; // The device going in is a trampoline device - struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev, NULL); + struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev); if (icd_term) loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0, @@ -5075,9 +5075,8 @@ VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT( VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectTagEXT( VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "DebugMarkerSetObjectTagEXT: Invalid device handle"); abort(); /* Intentionally fail so user can correct issue. */ @@ -5092,8 +5091,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectTagEXT( } else if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->object; - if (NULL != icd_surface->real_icd_surfaces) { - local_tag_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; + if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) + && icd_term->surface_list.list[icd_surface->surface_index]) { + local_tag_info.object = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index]; } } // If this is an instance we have to replace it with the proper one for the next call. @@ -5134,9 +5134,8 @@ VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT( VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectNameEXT( VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "DebugMarkerSetObjectNameEXT: Invalid device handle"); abort(); /* Intentionally fail so user can correct issue. */ @@ -5151,8 +5150,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectNameEXT( } else if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) { if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->object; - if (NULL != icd_surface->real_icd_surfaces) { - local_name_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; + if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) + && icd_term->surface_list.list[icd_surface->surface_index]) { + local_name_info.object = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index]; } } // If this is an instance we have to replace it with the proper one for the next call. @@ -5725,9 +5725,8 @@ VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT( VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectNameEXT( VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "SetDebugUtilsObjectNameEXT: Invalid device handle"); abort(); /* Intentionally fail so user can correct issue. */ @@ -5742,8 +5741,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectNameEXT( } else if (pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->objectHandle; - if (NULL != icd_surface->real_icd_surfaces) { - local_name_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; + if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) + && icd_term->surface_list.list[icd_surface->surface_index]) { + local_name_info.objectHandle = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index]; } } // If this is an instance we have to replace it with the proper one for the next call. @@ -5788,9 +5788,8 @@ VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT( VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectTagEXT( VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "SetDebugUtilsObjectTagEXT: Invalid device handle"); abort(); /* Intentionally fail so user can correct issue. */ @@ -5805,8 +5804,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectTagEXT( } else if (pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) { if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) { VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->objectHandle; - if (NULL != icd_surface->real_icd_surfaces) { - local_tag_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index]; + if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) + && icd_term->surface_list.list[icd_surface->surface_index]) { + local_tag_info.objectHandle = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index]; } } // If this is an instance we have to replace it with the proper one for the next call. diff --git a/loader/loader.c b/loader/loader.c index e455b48c..a2cef49f 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -209,7 +209,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkSetInstanceDispatch(VkInstance instance, void * VKAPI_ATTR VkResult VKAPI_CALL vkSetDeviceDispatch(VkDevice device, void *object) { struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, NULL); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { return VK_ERROR_INITIALIZATION_FAILED; @@ -714,11 +714,58 @@ VkResult loader_init_generic_list(const struct loader_instance *inst, struct loa return VK_SUCCESS; } +VkResult loader_resize_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info) { + list_info->list = loader_instance_heap_realloc(inst, list_info->list, list_info->capacity, list_info->capacity * 2, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + if (list_info->list == NULL) { + loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, "loader_resize_generic_list: Failed to allocate space for generic list"); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + list_info->capacity = list_info->capacity * 2; + return VK_SUCCESS; +} + void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list) { loader_instance_heap_free(inst, list->list); memset(list, 0, sizeof(struct loader_generic_list)); } +VkResult loader_get_next_available_entry(const struct loader_instance *inst, struct loader_used_object_list *list_info, + uint32_t *free_index) { + if (NULL == list_info->list) { + VkResult res = loader_init_generic_list(inst, (struct loader_generic_list *)list_info, sizeof(VkBool32)); + if (VK_SUCCESS != res) { + return res; + } + } + for (uint32_t i = 0; i < list_info->capacity / sizeof(VkBool32); i++) { + if (list_info->list[i] == VK_FALSE) { + list_info->list[i] = VK_TRUE; + *free_index = i; + return VK_SUCCESS; + } + } + // No free space, must resize + + size_t old_capacity = list_info->capacity; + VkResult res = loader_resize_generic_list(inst, (struct loader_generic_list *)list_info); + if (VK_SUCCESS != res) { + return res; + } + uint32_t new_index = (uint32_t)(old_capacity / sizeof(VkBool32)); + // Zero out the newly allocated back half of list. + memset(&list_info->list[new_index], 0, old_capacity); + list_info->list[new_index] = VK_TRUE; + *free_index = new_index; + return VK_SUCCESS; +} + +void loader_release_object_from_list(struct loader_used_object_list *list_info, uint32_t index_to_free) { + if (list_info->list && list_info->capacity > index_to_free * sizeof(VkBool32)) { + list_info->list[index_to_free] = VK_FALSE; + } +} + // Append non-duplicate extension properties defined in props to the given ext_list. // Return - Vk_SUCCESS on success VkResult loader_add_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list, @@ -1228,7 +1275,7 @@ out: return res; } -struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev, uint32_t *icd_index) { +struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev) { VkLayerDispatchTable *dispatch_table_device = loader_get_dispatch(device); if (NULL == dispatch_table_device) { *found_dev = NULL; @@ -1238,21 +1285,16 @@ struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loa *found_dev = NULL; for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) { - uint32_t index = 0; for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) { for (struct loader_device *dev = icd_term->logical_device_list; dev; dev = dev->next) { // Value comparison of device prevents object wrapping by layers if (loader_get_dispatch(dev->icd_device) == dispatch_table_device || (dev->chain_device != VK_NULL_HANDLE && loader_get_dispatch(dev->chain_device) == dispatch_table_device)) { *found_dev = dev; - if (NULL != icd_index) { - *icd_index = index; - } loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock); return icd_term; } } - index++; } } loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock); @@ -1318,6 +1360,37 @@ void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term dev = next_dev; } + for (uint32_t i = 0; i < icd_term->surface_list.capacity / sizeof(VkSurfaceKHR); i++) { + if (ptr_inst->surfaces_list.capacity > i * sizeof(VkBool32) && ptr_inst->surfaces_list.list[i] == VK_TRUE && + NULL != icd_term->surface_list.list && icd_term->surface_list.list[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) { + icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[i], pAllocator); + icd_term->surface_list.list[i] = (VkSurfaceKHR)(uintptr_t)NULL; + } + } + loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->surface_list); + + for (uint32_t i = 0; i < icd_term->debug_utils_messenger_list.capacity / sizeof(VkDebugUtilsMessengerEXT); i++) { + if (ptr_inst->debug_utils_messengers_list.capacity > i * sizeof(VkBool32) && + ptr_inst->debug_utils_messengers_list.list[i] == VK_TRUE && NULL != icd_term->debug_utils_messenger_list.list && + icd_term->debug_utils_messenger_list.list[i] && NULL != icd_term->dispatch.DestroyDebugUtilsMessengerEXT) { + icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_term->debug_utils_messenger_list.list[i], + pAllocator); + icd_term->debug_utils_messenger_list.list[i] = (VkDebugUtilsMessengerEXT)(uintptr_t)NULL; + } + } + loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->debug_utils_messenger_list); + + for (uint32_t i = 0; i < icd_term->debug_report_callback_list.capacity / sizeof(VkDebugReportCallbackEXT); i++) { + if (ptr_inst->debug_report_callbacks_list.capacity > i * sizeof(VkBool32) && + ptr_inst->debug_report_callbacks_list.list[i] == VK_TRUE && NULL != icd_term->debug_report_callback_list.list && + icd_term->debug_report_callback_list.list[i] && NULL != icd_term->dispatch.DestroyDebugReportCallbackEXT) { + icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_term->debug_report_callback_list.list[i], + pAllocator); + icd_term->debug_report_callback_list.list[i] = (VkDebugReportCallbackEXT)(uintptr_t)NULL; + } + } + loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->debug_report_callback_list); + loader_instance_heap_free(ptr_inst, icd_term); } @@ -4065,7 +4138,7 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_terminator(VkInstan VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_device_terminator(VkDevice device, const char *pName) { struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, NULL); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); // Return this function if a layer above here is asking for the vkGetDeviceProcAddr. // This is so we can properly intercept any device commands needing a terminator. @@ -4394,7 +4467,7 @@ VKAPI_ATTR void VKAPI_CALL loader_layer_destroy_device(VkDevice device, const Vk return; } - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, NULL); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); destroyFunction(device, pAllocator); if (NULL != dev) { @@ -6113,7 +6186,6 @@ VkResult check_and_add_to_new_phys_devs(struct loader_instance *inst, VkPhysical loader_set_dispatch((void *)new_phys_devs[idx], inst->disp); new_phys_devs[idx]->this_icd_term = dev_array->icd_term; - new_phys_devs[idx]->icd_index = (uint8_t)(dev_array->icd_index); new_phys_devs[idx]->phys_dev = physical_device; // Increment the count of new physical devices @@ -6214,7 +6286,6 @@ VkResult setup_loader_term_phys_devs(struct loader_instance *inst) { icd_phys_dev_array[icd_idx].physical_devices = 0; } icd_phys_dev_array[icd_idx].icd_term = icd_term; - icd_phys_dev_array[icd_idx].icd_index = icd_idx; icd_term->physical_device_count = icd_phys_dev_array[icd_idx].device_count; icd_term = icd_term->next; ++icd_idx; @@ -6959,7 +7030,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups( cur_icd_group_count = 0; icd_term = inst->icd_terms; - for (uint8_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) { + while (NULL != icd_term) { uint32_t count_this_time = total_count - cur_icd_group_count; // Get the function pointer to use to call into the ICD. This could be the core or KHR version @@ -6995,7 +7066,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups( for (uint32_t indiv_gpu = 0; indiv_gpu < count_this_time; indiv_gpu++) { uint32_t cur_index = indiv_gpu + cur_icd_group_count; local_phys_dev_groups[cur_index].this_icd_term = icd_term; - local_phys_dev_groups[cur_index].icd_index = icd_idx; local_phys_dev_groups[cur_index].group_props.physicalDeviceCount = 1; local_phys_dev_groups[cur_index].group_props.physicalDevices[0] = phys_dev_array[indiv_gpu]; } @@ -7026,7 +7096,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups( uint32_t cur_index = group + cur_icd_group_count; local_phys_dev_groups[cur_index].group_props = pPhysicalDeviceGroupProperties[cur_index]; local_phys_dev_groups[cur_index].this_icd_term = icd_term; - local_phys_dev_groups[cur_index].icd_index = icd_idx; } } else { // There's not enough space in the callee's allocated pPhysicalDeviceGroupProperties structs, @@ -7057,7 +7126,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups( uint32_t cur_index = group + cur_icd_group_count; local_phys_dev_groups[cur_index].group_props = tmp_group_props[group]; local_phys_dev_groups[cur_index].this_icd_term = icd_term; - local_phys_dev_groups[cur_index].icd_index = icd_idx; } } if (VK_SUCCESS != res) { @@ -7070,6 +7138,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups( } cur_icd_group_count += count_this_time; + icd_term = icd_term->next; } #if defined(LOADER_ENABLE_LINUX_SORT) diff --git a/loader/loader.h b/loader/loader.h index 6bd7115f..7be68f97 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -119,6 +119,10 @@ VkResult copy_str_to_string_list(const struct loader_instance *inst, struct load void free_string_list(const struct loader_instance *inst, struct loader_string_list *string_list); VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size); +VkResult loader_resize_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info); +VkResult loader_get_next_available_entry(const struct loader_instance *inst, struct loader_used_object_list *list_info, + uint32_t *free_index); +void loader_release_object_from_list(struct loader_used_object_list *list_info, uint32_t index_to_free); bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count, const VkExtensionProperties *ext_array); bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop, const struct loader_extension_list *ext_list); @@ -161,7 +165,7 @@ VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct lo const struct loader_envvar_all_filters *layer_filters); VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list, struct loader_extension_list *inst_exts); -struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev, uint32_t *icd_index); +struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev); struct loader_instance *loader_get_instance(const VkInstance instance); struct loader_device *loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator); void loader_add_logical_device(struct loader_icd_term *icd_term, struct loader_device *found_dev); diff --git a/loader/loader_common.h b/loader/loader_common.h index 53ee0f0d..0b76387e 100644 --- a/loader/loader_common.h +++ b/loader/loader_common.h @@ -90,6 +90,30 @@ struct loader_device_extension_list { struct loader_dev_ext_props *list; }; +struct loader_used_object_list { + size_t capacity; + uint32_t padding; // count variable isn't used + VkBool32 *list; +}; + +struct loader_surface_list { + size_t capacity; + uint32_t padding; // count variable isn't used + VkSurfaceKHR *list; +}; + +struct loader_debug_utils_messenger_list { + size_t capacity; + uint32_t padding; // count variable isn't used + VkDebugUtilsMessengerEXT *list; +}; + +struct loader_debug_report_callback_list { + size_t capacity; + uint32_t padding; // count variable isn't used + VkDebugReportCallbackEXT *list; +}; + struct loader_name_value { char *name; char *value; @@ -231,6 +255,10 @@ struct loader_icd_term { bool supports_get_dev_prop_2; uint32_t physical_device_count; + + struct loader_surface_list surface_list; + struct loader_debug_utils_messenger_list debug_utils_messenger_list; + struct loader_debug_report_callback_list debug_report_callback_list; }; // Per ICD library structure @@ -309,6 +337,11 @@ struct loader_instance { struct loader_extension_list ext_list; // icds and loaders extensions struct loader_instance_extension_enables enabled_known_extensions; + // Indicates which indices in the array are in-use and which are free to be reused + struct loader_used_object_list surfaces_list; + struct loader_used_object_list debug_utils_messengers_list; + struct loader_used_object_list debug_report_callbacks_list; + // Stores debug callbacks - used in the log. VkLayerDbgFunctionNode *current_dbg_function_head; // Current head VkLayerDbgFunctionNode *instance_only_dbg_function_head; // Only used for instance create/destroy @@ -399,7 +432,6 @@ struct loader_physical_device_tramp { struct loader_physical_device_term { struct loader_instance_dispatch_table *disp; // must be first entry in structure struct loader_icd_term *this_icd_term; - uint8_t icd_index; VkPhysicalDevice phys_dev; // object from ICD }; @@ -413,7 +445,6 @@ struct LinuxSortedDeviceInfo { bool default_device; // Loader specific items about the driver providing support for this physical device - uint32_t icd_index; struct loader_icd_term *icd_term; // Some generic device properties @@ -434,7 +465,6 @@ struct LinuxSortedDeviceInfo { // Per enumerated PhysicalDeviceGroup structure, used to wrap in terminator code struct loader_physical_device_group_term { struct loader_icd_term *this_icd_term; - uint8_t icd_index; VkPhysicalDeviceGroupProperties group_props; #if defined(LOADER_ENABLE_LINUX_SORT) struct LinuxSortedDeviceInfo internal_device_info[VK_MAX_DEVICE_GROUP_SIZE]; @@ -469,7 +499,6 @@ enum loader_data_files_type { struct loader_icd_physical_devices { uint32_t device_count; VkPhysicalDevice *physical_devices; - uint32_t icd_index; struct loader_icd_term *icd_term; #if defined(WIN32) LUID windows_adapter_luid; diff --git a/loader/loader_linux.c b/loader/loader_linux.c index e0b3db81..4c12be60 100644 --- a/loader/loader_linux.c +++ b/loader/loader_linux.c @@ -256,7 +256,6 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32 VkPhysicalDeviceProperties dev_props = {}; sorted_device_info[index].physical_device = icd_devices[icd_idx].physical_devices[phys_dev]; - sorted_device_info[index].icd_index = icd_idx; sorted_device_info[index].icd_term = icd_term; sorted_device_info[index].has_pci_bus_info = false; @@ -330,7 +329,6 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32 // Add all others after (they've already been sorted) for (uint32_t dev = 0; dev < phys_dev_count; ++dev) { sorted_device_term[dev]->this_icd_term = sorted_device_info[dev].icd_term; - sorted_device_term[dev]->icd_index = sorted_device_info[dev].icd_index; sorted_device_term[dev]->phys_dev = sorted_device_info[dev].physical_device; loader_set_dispatch((void *)sorted_device_term[dev], inst->disp); loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s %s", dev, diff --git a/loader/loader_windows.c b/loader/loader_windows.c index fa245cc0..43ecf667 100644 --- a/loader/loader_windows.c +++ b/loader/loader_windows.c @@ -795,8 +795,8 @@ out: return vk_result; } -VkResult enumerate_adapter_physical_devices(struct loader_instance *inst, struct loader_icd_term *icd_term, uint32_t icd_idx, - LUID luid, uint32_t *icd_phys_devs_array_count, +VkResult enumerate_adapter_physical_devices(struct loader_instance *inst, struct loader_icd_term *icd_term, LUID luid, + uint32_t *icd_phys_devs_array_count, struct loader_icd_physical_devices *icd_phys_devs_array) { uint32_t count = 0; VkResult res = icd_term->scanned_icd->EnumerateAdapterPhysicalDevices(icd_term->instance, luid, &count, NULL); @@ -856,7 +856,6 @@ VkResult enumerate_adapter_physical_devices(struct loader_instance *inst, struct } if (!already_enumerated) { next_icd_phys_devs->device_count = count; - next_icd_phys_devs->icd_index = icd_idx; next_icd_phys_devs->icd_term = icd_term; next_icd_phys_devs->windows_adapter_luid = luid; (*icd_phys_devs_array_count)++; @@ -982,18 +981,20 @@ VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, uint (*icd_phys_devs_array)[*icd_phys_devs_array_count].physical_devices = NULL; icd_term = inst->icd_terms; - for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) { + while (NULL != icd_term) { // This is the new behavior, which cannot be run unless the ICD provides EnumerateAdapterPhysicalDevices if (icd_term->scanned_icd->EnumerateAdapterPhysicalDevices == NULL) { + icd_term = icd_term->next; continue; } - res = enumerate_adapter_physical_devices(inst, icd_term, icd_idx, description.AdapterLuid, icd_phys_devs_array_count, + res = enumerate_adapter_physical_devices(inst, icd_term, description.AdapterLuid, icd_phys_devs_array_count, *icd_phys_devs_array); if (res == VK_ERROR_OUT_OF_HOST_MEMORY) { adapter->lpVtbl->Release(adapter); goto out; } + icd_term = icd_term->next; } adapter->lpVtbl->Release(adapter); diff --git a/loader/trampoline.c b/loader/trampoline.c index ba35c3f1..14766b88 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -138,8 +138,7 @@ LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDev // sufficient if (!strcmp(name, "GetDeviceQueue2")) { struct loader_device *dev = NULL; - uint32_t index = 0; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL != icd_term && dev != NULL) { const struct loader_instance *inst = icd_term->this_instance; uint32_t api_version = @@ -769,6 +768,10 @@ out: free_loader_settings(ptr_instance, &ptr_instance->settings); + loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->surfaces_list); + loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_utils_messengers_list); + loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_report_callbacks_list); + loader_instance_heap_free(ptr_instance, ptr_instance->disp); // Remove any created VK_EXT_debug_report or VK_EXT_debug_utils items destroy_debug_callbacks_chain(ptr_instance, pAllocator); @@ -842,6 +845,10 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, free_loader_settings(ptr_instance, &ptr_instance->settings); + loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->surfaces_list); + loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_utils_messengers_list); + loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->debug_report_callbacks_list); + loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->expanded_activated_layer_list); loader_destroy_pointer_layer_list(ptr_instance, &ptr_instance->app_activated_layer_list); diff --git a/loader/wsi.c b/loader/wsi.c index ad4d6b90..5183f11f 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -180,8 +180,6 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance loader_inst->disp->layer_inst_disp.DestroySurfaceKHR(loader_inst->instance, surface, pAllocator); } -// TODO probably need to lock around all the loader_get_instance() calls. - // This is the instance chain terminator function for DestroySurfaceKHR VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) { @@ -189,25 +187,21 @@ VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkS VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface); if (NULL != icd_surface) { - if (NULL != icd_surface->real_icd_surfaces) { - uint32_t i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (NULL != icd_term->dispatch.DestroySurfaceKHR && - (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[i]) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator); - icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)(uintptr_t)NULL; - } - } else { - // The real_icd_surface for any ICD not supporting the - // proper interface version should be NULL. If not, then - // we have a problem. - assert((VkSurfaceKHR)(uintptr_t)NULL == icd_surface->real_icd_surfaces[i]); + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { + if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { + if (NULL != icd_term->dispatch.DestroySurfaceKHR && icd_term->surface_list.list[icd_surface->surface_index]) { + icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, + icd_term->surface_list.list[icd_surface->surface_index], pAllocator); + icd_term->surface_list.list[icd_surface->surface_index] = (VkSurfaceKHR)(uintptr_t)NULL; } + } else { + // The real_icd_surface for any ICD not supporting the + // proper interface version should be NULL. If not, then + // we have a problem. + assert((VkSurfaceKHR)(uintptr_t)NULL == icd_term->surface_list.list[icd_surface->surface_index]); } - loader_instance_heap_free(loader_inst, icd_surface->real_icd_surfaces); } - + loader_release_object_from_list(&loader_inst->surfaces_list, icd_surface->surface_index); loader_instance_heap_free(loader_inst, (void *)(uintptr_t)surface); } } @@ -259,10 +253,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkP } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; - if (NULL != icd_surface->real_icd_surfaces && - (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR( - phys_dev_term->phys_dev, queueFamilyIndex, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSupported); + phys_dev_term->phys_dev, queueFamilyIndex, icd_term->surface_list.list[icd_surface->surface_index], pSupported); } return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, surface, pSupported); @@ -313,10 +308,12 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKH } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; - if (NULL != icd_surface->real_icd_surfaces && - (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { + if (NULL != phys_dev_term->this_icd_term->surface_list.list && + phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) { return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR( - phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSurfaceCapabilities); + phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index], + pSurfaceCapabilities); } return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, pSurfaceCapabilities); @@ -369,11 +366,12 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkP } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; - if (NULL != icd_surface->real_icd_surfaces && - (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { - return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, - icd_surface->real_icd_surfaces[phys_dev_term->icd_index], - pSurfaceFormatCount, pSurfaceFormats); + if (NULL != phys_dev_term->this_icd_term->surface_list.list && + phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) { + return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR( + phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index], + pSurfaceFormatCount, pSurfaceFormats); } return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount, @@ -427,10 +425,12 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKH } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; - if (NULL != icd_surface->real_icd_surfaces && - (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { + if (NULL != phys_dev_term->this_icd_term->surface_list.list && + phys_dev_term->this_icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index]) { return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR( - phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pPresentModeCount, pPresentModes); + phys_dev_term->phys_dev, phys_dev_term->this_icd_term->surface_list.list[icd_surface->surface_index], pPresentModeCount, + pPresentModes); } return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount, @@ -462,9 +462,8 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice devic VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "vkCreateSwapchainKHR Terminator: device handle. This is likely the result of a " @@ -485,20 +484,19 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, co return VK_SUCCESS; } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface; - if (NULL != icd_surface->real_icd_surfaces) { - if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { - // We found the ICD, and there is an ICD KHR surface - // associated with it, so copy the CreateInfo struct - // and point it at the ICD's surface. - VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR)); - if (NULL == pCreateCopy) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR)); - pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index]; - return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, - pSwapchain); + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { + // We found the ICD, and there is an ICD KHR surface + // associated with it, so copy the CreateInfo struct + // and point it at the ICD's surface. + VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR)); + if (NULL == pCreateCopy) { + return VK_ERROR_OUT_OF_HOST_MEMORY; } + memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR)); + pCreateCopy->surface = icd_term->surface_list.list[icd_surface->surface_index]; + return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain); } return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); } @@ -550,25 +548,72 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, co return disp->QueuePresentKHR(queue, pPresentInfo); } -VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size) { +VkResult allocate_icd_surface_struct(struct loader_instance *instance, size_t base_size, size_t platform_size, + VkIcdSurface **out_icd_surface) { + uint32_t next_index = 0; + VkIcdSurface *icd_surface = NULL; + VkResult res = loader_get_next_available_entry(instance, &instance->surfaces_list, &next_index); + if (res != VK_SUCCESS) { + goto out; + } + // Next, if so, proceed with the implementation of this function: - VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (pIcdSurface != NULL) { - // Setup the new sizes and offsets so we can grow the structures in the - // future without having problems - pIcdSurface->base_size = (uint32_t)base_size; - pIcdSurface->platform_size = (uint32_t)platform_size; - pIcdSurface->non_platform_offset = (uint32_t)((uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface); - pIcdSurface->entire_size = sizeof(VkIcdSurface); - - pIcdSurface->real_icd_surfaces = loader_instance_heap_calloc(instance, sizeof(VkSurfaceKHR) * instance->icd_terms_count, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (pIcdSurface->real_icd_surfaces == NULL) { - loader_instance_heap_free(instance, pIcdSurface); - pIcdSurface = NULL; + icd_surface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (icd_surface == NULL) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + goto out; + } + // Setup the new sizes and offsets so we can grow the structures in the + // future without having problems + icd_surface->base_size = (uint32_t)base_size; + icd_surface->platform_size = (uint32_t)platform_size; + icd_surface->non_platform_offset = (uint32_t)((uint8_t *)(&icd_surface->base_size) - (uint8_t *)icd_surface); + icd_surface->entire_size = sizeof(VkIcdSurface); + icd_surface->surface_index = next_index; + + for (struct loader_icd_term *icd_term = instance->icd_terms; icd_term != NULL; icd_term = icd_term->next) { + if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { + if (icd_term->surface_list.list == NULL) { + res = + loader_init_generic_list(instance, (struct loader_generic_list *)&icd_term->surface_list, sizeof(VkSurfaceKHR)); + if (res != VK_SUCCESS) { + goto out; + } + } else if (icd_term->surface_list.capacity <= next_index * sizeof(VkSurfaceKHR)) { + res = loader_resize_generic_list(instance, (struct loader_generic_list *)&icd_term->surface_list); + if (res != VK_SUCCESS) { + goto out; + } + } + } + } + + *out_icd_surface = icd_surface; +out: + if (res != VK_SUCCESS) { + loader_instance_heap_free(instance, icd_surface); + // cleanup of icd_term->surface_list is done during instance destruction + } + return res; +} + +void cleanup_surface_creation(struct loader_instance *loader_inst, VkResult result, VkIcdSurface *icd_surface, + const VkAllocationCallbacks *pAllocator) { + if (VK_SUCCESS != result && NULL != icd_surface) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index] && NULL != icd_term->dispatch.DestroySurfaceKHR) { + icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[icd_surface->surface_index], + pAllocator); + } + } + if (loader_inst->surfaces_list.list && + loader_inst->surfaces_list.capacity > icd_surface->surface_index * sizeof(VkBool32)) { + loader_inst->surfaces_list.list[icd_surface->surface_index] = VK_FALSE; } + loader_instance_heap_free(loader_inst, icd_surface); } - return pIcdSurface; } #if defined(VK_USE_PLATFORM_WIN32_KHR) @@ -592,9 +637,9 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance // This is the instance chain terminator function for CreateWin32SurfaceKHR VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // Initialize pSurface to NULL just to be safe. *pSurface = VK_NULL_HANDLE; @@ -603,53 +648,40 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance insta if (!loader_inst->wsi_win32_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_win32_surface extension not enabled. vkCreateWin32SurfaceKHR not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->win_surf.base), sizeof(pIcdSurface->win_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = + allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->win_surf.base), sizeof(icd_surface->win_surf), &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32; - pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance; - pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd; + icd_surface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32; + icd_surface->win_surf.hinstance = pCreateInfo->hinstance; + icd_surface->win_surf.hwnd = pCreateInfo->hwnd; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) { - vkRes = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: - - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); + return result; } // This is the trampoline entrypoint for @@ -713,62 +745,50 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstanc VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_wayland_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_wayland_surface extension not enabled. vkCreateWaylandSurfaceKHR not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->wayland_surf.base), sizeof(pIcdSurface->wayland_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->wayland_surf.base), sizeof(icd_surface->wayland_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND; - pIcdSurface->wayland_surf.display = pCreateInfo->display; - pIcdSurface->wayland_surf.surface = pCreateInfo->surface; + icd_surface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND; + icd_surface->wayland_surf.display = pCreateInfo->display; + icd_surface->wayland_surf.surface = pCreateInfo->surface; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) { - vkRes = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } // This is the trampoline entrypoint for @@ -835,62 +855,50 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance in // This is the instance chain terminator function for CreateXcbSurfaceKHR VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_xcb_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_xcb_surface extension not enabled. vkCreateXcbSurfaceKHR not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->xcb_surf.base), sizeof(pIcdSurface->xcb_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = + allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xcb_surf.base), sizeof(icd_surface->xcb_surf), &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB; - pIcdSurface->xcb_surf.connection = pCreateInfo->connection; - pIcdSurface->xcb_surf.window = pCreateInfo->window; + icd_surface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB; + icd_surface->xcb_surf.connection = pCreateInfo->connection; + icd_surface->xcb_surf.window = pCreateInfo->window; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) { - vkRes = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } // This is the trampoline entrypoint for @@ -960,62 +968,50 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance i // This is the instance chain terminator function for CreateXlibSurfaceKHR VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_xlib_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_xlib_surface extension not enabled. vkCreateXlibSurfaceKHR not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->xlib_surf.base), sizeof(pIcdSurface->xlib_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = + allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xlib_surf.base), sizeof(icd_surface->xlib_surf), &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB; - pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy; - pIcdSurface->xlib_surf.window = pCreateInfo->window; + icd_surface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB; + icd_surface->xlib_surf.dpy = pCreateInfo->dpy; + icd_surface->xlib_surf.window = pCreateInfo->window; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) { - vkRes = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } // This is the trampoline entrypoint for @@ -1084,63 +1080,50 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance in const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_directfb_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_EXT_directfb_surface extension not enabled. vkCreateDirectFBSurfaceEXT not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = - AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->directfb_surf.base), sizeof(pIcdSurface->directfb_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->directfb_surf.base), sizeof(icd_surface->directfb_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->directfb_surf.base.platform = VK_ICD_WSI_PLATFORM_DIRECTFB; - pIcdSurface->directfb_surf.dfb = pCreateInfo->dfb; - pIcdSurface->directfb_surf.surface = pCreateInfo->surface; + icd_surface->directfb_surf.base.platform = VK_ICD_WSI_PLATFORM_DIRECTFB; + icd_surface->directfb_surf.dfb = pCreateInfo->dfb; + icd_surface->directfb_surf.surface = pCreateInfo->surface; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateDirectFBSurfaceEXT) { - vkRes = icd_term->dispatch.CreateDirectFBSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateDirectFBSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } // This is the trampoline entrypoint for @@ -1219,16 +1202,16 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance ins } // Next, if so, proceed with the implementation of this function: - VkIcdSurfaceAndroid *pIcdSurface = + VkIcdSurfaceAndroid *icd_surface = loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceAndroid), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (pIcdSurface == NULL) { + if (icd_surface == NULL) { return VK_ERROR_OUT_OF_HOST_MEMORY; } - pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_ANDROID; - pIcdSurface->window = pCreateInfo->window; + icd_surface->base.platform = VK_ICD_WSI_PLATFORM_ANDROID; + icd_surface->window = pCreateInfo->window; - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; return VK_SUCCESS; } @@ -1254,58 +1237,47 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance in const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - struct loader_instance *inst = loader_get_instance(instance); - VkIcdSurface *pIcdSurface = NULL; - VkResult vkRes = VK_SUCCESS; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); - if (!inst->wsi_headless_surface_enabled) { - loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, + // First, check to ensure the appropriate extension was enabled: + struct loader_instance *loader_inst = loader_get_instance(instance); + if (!loader_inst->wsi_headless_surface_enabled) { + loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_EXT_headless_surface extension not enabled. " "vkCreateHeadlessSurfaceEXT not executed!"); return VK_SUCCESS; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->headless_surf.base), sizeof(pIcdSurface->headless_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->headless_surf.base), sizeof(icd_surface->headless_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->headless_surf.base.platform = VK_ICD_WSI_PLATFORM_HEADLESS; + icd_surface->headless_surf.base.platform = VK_ICD_WSI_PLATFORM_HEADLESS; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) { - vkRes = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(inst, pIcdSurface); - } - - return vkRes; + return result; } // Ensure we are properly setting VK_USE_PLATFORM_METAL_EXT, VK_USE_PLATFORM_IOS_MVK, and VK_USE_PLATFORM_MACOS_MVK. @@ -1356,61 +1328,49 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance // This is the instance chain terminator function for CreateMacOSSurfaceKHR VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_macos_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_MVK_macos_surface extension not enabled. vkCreateMacOSSurfaceMVK not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->macos_surf.base), sizeof(pIcdSurface->macos_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->macos_surf.base), sizeof(icd_surface->macos_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->macos_surf.base.platform = VK_ICD_WSI_PLATFORM_MACOS; - pIcdSurface->macos_surf.pView = pCreateInfo->pView; + icd_surface->macos_surf.base.platform = VK_ICD_WSI_PLATFORM_MACOS; + icd_surface->macos_surf.pView = pCreateInfo->pView; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) { - vkRes = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } #endif // VK_USE_PLATFORM_MACOS_MVK @@ -1447,16 +1407,16 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instanc } // Next, if so, proceed with the implementation of this function: - VkIcdSurfaceIOS *pIcdSurface = + VkIcdSurfaceIOS *icd_surface = loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceIOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (pIcdSurface == NULL) { + if (icd_surface == NULL) { return VK_ERROR_OUT_OF_HOST_MEMORY; } - pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_IOS; - pIcdSurface->pView = pCreateInfo->pView; + icd_surface->base.platform = VK_ICD_WSI_PLATFORM_IOS; + icd_surface->pView = pCreateInfo->pView; - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; return VK_SUCCESS; } @@ -1486,60 +1446,49 @@ vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptor VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_ggp_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_GGP_stream_descriptor_surface extension not enabled. vkCreateStreamDescriptorSurfaceGGP not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->ggp_surf.base), sizeof(pIcdSurface->ggp_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = + allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->ggp_surf.base), sizeof(icd_surface->ggp_surf), &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->ggp_surf.base.platform = VK_ICD_WSI_PLATFORM_GGP; - pIcdSurface->ggp_surf.streamDescriptor = pCreateInfo->streamDescriptor; + icd_surface->ggp_surf.base.platform = VK_ICD_WSI_PLATFORM_GGP; + icd_surface->ggp_surf.streamDescriptor = pCreateInfo->streamDescriptor; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) { - vkRes = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP( + icd_term->instance, pCreateInfo, pAllocator, &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - return vkRes; + return result; } #endif // VK_USE_PLATFORM_GGP @@ -1563,7 +1512,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { VkResult result = VK_SUCCESS; VkIcdSurface *icd_surface = NULL; - uint32_t i; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); @@ -1573,9 +1522,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta } // Next, if so, proceed with the implementation of this function: - icd_surface = AllocateIcdSurfaceStruct(loader_inst, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf)); - if (icd_surface == NULL) { - result = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } @@ -1583,13 +1532,12 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta icd_surface->metal_surf.pLayer = pCreateInfo->pLayer; // Loop through each ICD and determine if they need to create a surface - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { - if (icd_term->dispatch.CreateMetalSurfaceEXT != NULL) { + if (NULL != icd_term->dispatch.CreateMetalSurfaceEXT) { result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator, - &icd_surface->real_icd_surfaces[i]); - if (result != VK_SUCCESS) { + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } @@ -1598,18 +1546,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance insta *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: - if (result != VK_SUCCESS && icd_surface != NULL) { - if (icd_surface->real_icd_surfaces != NULL) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) { - if (icd_surface->real_icd_surfaces[i] == VK_NULL_HANDLE && icd_term->dispatch.DestroySurfaceKHR != NULL) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, icd_surface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, icd_surface); - } + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); + return result; } @@ -1635,62 +1574,50 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(VkInstance VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_screen_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_QNX_screen_surface extension not enabled. vkCreateScreenSurfaceQNX not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->screen_surf.base), sizeof(pIcdSurface->screen_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->screen_surf.base), sizeof(icd_surface->screen_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->screen_surf.base.platform = VK_ICD_WSI_PLATFORM_SCREEN; - pIcdSurface->screen_surf.context = pCreateInfo->context; - pIcdSurface->screen_surf.window = pCreateInfo->window; + icd_surface->screen_surf.base.platform = VK_ICD_WSI_PLATFORM_SCREEN; + icd_surface->screen_surf.context = pCreateInfo->context; + icd_surface->screen_surf.window = pCreateInfo->window; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX) { - vkRes = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } // This is the trampoline entrypoint for @@ -1755,61 +1682,49 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(VkInstance inst // This is the instance chain terminator function for CreateViSurfaceNN VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); // First, check to ensure the appropriate extension was enabled: struct loader_instance *loader_inst = loader_get_instance(instance); if (!loader_inst->wsi_vi_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_NN_vi_surface extension not enabled. vkCreateViSurfaceNN not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->vi_surf.base), sizeof(pIcdSurface->vi_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = + allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->vi_surf.base), sizeof(icd_surface->vi_surf), &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->vi_surf.base.platform = VK_ICD_WSI_PLATFORM_VI; - pIcdSurface->vi_surf.window = pCreateInfo->window; + icd_surface->vi_surf.base.platform = VK_ICD_WSI_PLATFORM_VI; + icd_surface->vi_surf.window = pCreateInfo->window; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateViSurfaceNN) { - vkRes = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } #endif // VK_USE_PLATFORM_VI_NN @@ -2081,66 +1996,55 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstanc const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - struct loader_instance *inst = loader_get_instance(instance); - VkIcdSurface *pIcdSurface = NULL; - VkResult vkRes = VK_SUCCESS; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; + loader_platform_thread_lock_mutex(&loader_lock); - if (!inst->wsi_display_enabled) { - loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0, + // First, check to ensure the appropriate extension was enabled: + struct loader_instance *loader_inst = loader_get_instance(instance); + if (!loader_inst->wsi_display_enabled) { + loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base), sizeof(pIcdSurface->display_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->display_surf.base), sizeof(icd_surface->display_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY; - pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode; - pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex; - pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex; - pIcdSurface->display_surf.transform = pCreateInfo->transform; - pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha; - pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode; - pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent; + icd_surface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY; + icd_surface->display_surf.displayMode = pCreateInfo->displayMode; + icd_surface->display_surf.planeIndex = pCreateInfo->planeIndex; + icd_surface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex; + icd_surface->display_surf.transform = pCreateInfo->transform; + icd_surface->display_surf.globalAlpha = pCreateInfo->globalAlpha; + icd_surface->display_surf.alphaMode = pCreateInfo->alphaMode; + icd_surface->display_surf.imageExtent = pCreateInfo->imageExtent; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) { - vkRes = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); + loader_platform_thread_unlock_mutex(&loader_lock); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(inst, pIcdSurface); - } - - return vkRes; + return result; } // EXT_display_swapchain Extension command @@ -2162,9 +2066,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice dev const VkSwapchainCreateInfoKHR *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "vkCreateSharedSwapchainsKHR Terminator: Invalid device handle. This is likely the result of a " @@ -2179,7 +2082,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice dev return VK_SUCCESS; } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface; - if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { // We found the ICD, and there is an ICD KHR surface // associated with it, so copy the CreateInfo struct // and point it at the ICD's surface. @@ -2189,7 +2094,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice dev } memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount); for (uint32_t sc = 0; sc < swapchainCount; sc++) { - pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index]; + pCreateCopy[sc].surface = icd_term->surface_list.list[icd_surface->surface_index]; } return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy, pAllocator, pSwapchains); @@ -2224,9 +2129,8 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR *pModes) { - uint32_t icd_index = 0; struct loader_device *dev; - struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); + struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev); if (NULL == icd_term || NULL == dev) { loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "vkGetDeviceGroupSurfacePresentModesKHR: Invalid device " @@ -2241,9 +2145,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(V return VK_SUCCESS; } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; - if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR( - device, icd_surface->real_icd_surfaces[icd_index], pModes); + device, icd_term->surface_list.list[icd_surface->surface_index], pModes); } return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes); } @@ -2278,10 +2184,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDevicePresentRectanglesKHR( return VK_SUCCESS; } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface); - uint8_t icd_index = phys_dev_term->icd_index; - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR( - phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[icd_index], pRectCount, pRects); + phys_dev_term->phys_dev, icd_term->surface_list.list[icd_surface->surface_index], pRectCount, pRects); } return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(phys_dev_term->phys_dev, surface, pRectCount, pRects); } @@ -2532,9 +2439,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstan const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { - VkResult vkRes = VK_SUCCESS; - VkIcdSurface *pIcdSurface = NULL; - uint32_t i = 0; + VkResult result = VK_SUCCESS; + VkIcdSurface *icd_surface = NULL; // Initialize pSurface to NULL just to be safe. *pSurface = VK_NULL_HANDLE; @@ -2544,52 +2450,38 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstan loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, "VK_FUCHSIA_imagepipe_surface extension not enabled. " "vkCreateImagePipeSurfaceFUCHSIA not executed!"); - vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; + result = VK_ERROR_EXTENSION_NOT_PRESENT; goto out; } // Next, if so, proceed with the implementation of this function: - pIcdSurface = - AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->imagepipe_surf.base), sizeof(pIcdSurface->imagepipe_surf)); - if (pIcdSurface == NULL) { - vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->imagepipe_surf.base), sizeof(icd_surface->imagepipe_surf), + &icd_surface); + if (VK_SUCCESS != result) { goto out; } - pIcdSurface->imagepipe_surf.base.platform = VK_ICD_WSI_PLATFORM_FUCHSIA; + icd_surface->imagepipe_surf.base.platform = VK_ICD_WSI_PLATFORM_FUCHSIA; // Loop through each ICD and determine if they need to create a surface - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { + for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) { if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) { - vkRes = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator, - &pIcdSurface->real_icd_surfaces[i]); - if (VK_SUCCESS != vkRes) { + result = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator, + &icd_term->surface_list.list[icd_surface->surface_index]); + if (VK_SUCCESS != result) { goto out; } } } } - *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface; + *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface; out: + cleanup_surface_creation(loader_inst, result, icd_surface, pAllocator); - if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { - if (NULL != pIcdSurface->real_icd_surfaces) { - i = 0; - for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { - if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] && - NULL != icd_term->dispatch.DestroySurfaceKHR) { - icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); - } - } - loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces); - } - loader_instance_heap_free(loader_inst, pIcdSurface); - } - - return vkRes; + return result; } #endif // VK_USE_PLATFORM_FUCHSIA @@ -2614,6 +2506,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance; + VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface; if (!loader_inst->wsi_surface_enabled) { loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0, @@ -2621,9 +2514,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K return VK_SUCCESS; } - VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface); - uint8_t icd_index = phys_dev_term->icd_index; - if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) { VkBaseOutStructure *pNext = (VkBaseOutStructure *)pSurfaceCapabilities->pNext; while (pNext != NULL) { @@ -2637,9 +2527,11 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K } // Pass the call to the driver, possibly unwrapping the ICD surface - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo; - info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; + info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index]; return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceCapabilities); } else { @@ -2661,8 +2553,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2K // Write to the VkSurfaceCapabilities2KHR struct VkSurfaceKHR surface = pSurfaceInfo->surface; - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) { - surface = icd_surface->real_icd_surfaces[icd_index]; + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { + surface = icd_term->surface_list.list[icd_surface->surface_index]; } // If the icd doesn't support VK_KHR_surface, then there are no capabilities @@ -2714,13 +2608,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk } VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface); - uint8_t icd_index = phys_dev_term->icd_index; if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) { // Pass the call to the driver, possibly unwrapping the ICD surface - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) { + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo; - info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; + info_copy.surface = icd_term->surface_list.list[icd_surface->surface_index]; return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount, pSurfaceFormats); } else { @@ -2740,8 +2635,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(Vk } VkSurfaceKHR surface = pSurfaceInfo->surface; - if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) { - surface = icd_surface->real_icd_surfaces[icd_index]; + if (NULL != icd_term->surface_list.list && + icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && + icd_term->surface_list.list[icd_surface->surface_index]) { + surface = icd_term->surface_list.list[icd_surface->surface_index]; } // If the icd doesn't support VK_KHR_surface, then there are no formats diff --git a/loader/wsi.h b/loader/wsi.h index 07cc3f2d..57675154 100644 --- a/loader/wsi.h +++ b/loader/wsi.h @@ -66,7 +66,7 @@ typedef struct { uint32_t platform_size; // Size of corresponding VkIcdSurfaceXXX uint32_t non_platform_offset; // Start offset to base_size uint32_t entire_size; // Size of entire VkIcdSurface - VkSurfaceKHR *real_icd_surfaces; + uint32_t surface_index; // This surface's index into each drivers list of created surfaces } VkIcdSurface; bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr); diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py index 62114f55..58413042 100644 --- a/scripts/loader_extension_generator.py +++ b/scripts/loader_extension_generator.py @@ -542,7 +542,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): protos += 'VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev) {\n' protos += ' struct loader_device *found_dev;\n' protos += ' // The device going in is a trampoline device\n' - protos += ' struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev, NULL);\n' + protos += ' struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev);\n' protos += '\n' protos += ' if (icd_term)\n' protos += ' loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,\n' @@ -1087,14 +1087,14 @@ class LoaderExtensionOutputGenerator(OutputGenerator): requires_terminator = 1 always_use_param_name = False surface_type_to_replace = 'VkSurfaceKHR' - surface_name_replacement = 'icd_surface->real_icd_surfaces[icd_index]' + surface_name_replacement = 'icd_term->surface_list[icd_surface->surface_index]' if param.type == 'VkPhysicalDeviceSurfaceInfo2KHR': has_surface = 1 surface_var_name = param.name + '->surface' requires_terminator = 1 update_structure_surface = 1 update_structure_string = ' VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;\n' - update_structure_string += ' info_copy.surface = icd_surface->real_icd_surfaces[icd_index];\n' + update_structure_string += ' info_copy.surface = icd_term->surface_list[icd_surface->surface_index];\n' always_use_param_name = False surface_type_to_replace = 'VkPhysicalDeviceSurfaceInfo2KHR' surface_name_replacement = '&info_copy' @@ -1255,9 +1255,8 @@ class LoaderExtensionOutputGenerator(OutputGenerator): funcs += ' }\n' if has_surface == 1: - funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(%s);\n' % (surface_var_name) - funcs += ' uint8_t icd_index = phys_dev_term->icd_index;\n' - funcs += ' if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {\n' + funcs += ' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(%s);\n' % (surface_var_name) + funcs += ' if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR) && icd_term->surface_list[icd_surface->surface_index]) {\n' # If there's a structure with a surface, we need to update its internals with the correct surface for the ICD if update_structure_surface == 1: @@ -1324,10 +1323,9 @@ class LoaderExtensionOutputGenerator(OutputGenerator): phys_dev_check = 'VK_OBJECT_TYPE_PHYSICAL_DEVICE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT' surf_check = 'VK_OBJECT_TYPE_SURFACE_KHR' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT' inst_check = 'VK_OBJECT_TYPE_INSTANCE' if is_debug_utils else 'VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT' - funcs += ' uint32_t icd_index = 0;\n' funcs += ' struct loader_device *dev;\n' - funcs += f' struct loader_icd_term *icd_term = loader_get_icd_and_device({ ext_cmd.params[0].name}, &dev, &icd_index);\n' - funcs += f' if (NULL == icd_term || NULL == dev) {{\n' + funcs += f' struct loader_icd_term *icd_term = loader_get_icd_and_device({ ext_cmd.params[0].name}, &dev);\n' + funcs += ' if (NULL == icd_term || NULL == dev) {\n' funcs += f' loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.name[2:]}: Invalid device handle");\n' funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n' funcs += ' }\n' @@ -1341,8 +1339,9 @@ class LoaderExtensionOutputGenerator(OutputGenerator): funcs += f' }} else if ({debug_struct_name}->objectType == {surf_check}) {{\n' funcs += ' if (NULL != dev && NULL != dev->loader_dispatch.core_dispatch.CreateSwapchainKHR) {\n' funcs += f' VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t){debug_struct_name}->{member_name};\n' - funcs += ' if (NULL != icd_surface->real_icd_surfaces) {\n' - funcs += f' {local_struct}.{member_name} = (uint64_t)icd_surface->real_icd_surfaces[icd_index];\n' + funcs += ' if (NULL != icd_term->surface_list.list && icd_term->surface_list.capacity > icd_surface->surface_index * sizeof(VkSurfaceKHR)\n' + funcs += ' && icd_term->surface_list.list[icd_surface->surface_index]) {\n' + funcs += f' {local_struct}.{member_name} = (uint64_t)icd_term->surface_list.list[icd_surface->surface_index];\n' funcs += ' }\n' funcs += ' }\n' funcs += ' // If this is an instance we have to replace it with the proper one for the next call.\n' @@ -1355,7 +1354,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): dispatch = 'dev->loader_dispatch.' else: funcs += f' struct loader_dev_dispatch_table *dispatch_table = loader_get_dev_dispatch({ext_cmd.params[0].name});\n' - funcs += f' if (NULL == dispatch_table) {{\n' + funcs += ' if (NULL == dispatch_table) {\n' funcs += f' loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, "{ext_cmd.ext_name}: Invalid device handle");\n' funcs += ' abort(); /* Intentionally fail so user can correct issue. */\n' funcs += ' }\n' @@ -1374,7 +1373,7 @@ class LoaderExtensionOutputGenerator(OutputGenerator): if param.type == 'VkPhysicalDevice': funcs += 'phys_dev_term->phys_dev' elif param.type == 'VkSurfaceKHR': - funcs += 'icd_surface->real_icd_surfaces[icd_index]' + funcs += 'icd_term->surface_list[icd_surface->surface_index]' elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pNameInfo': funcs += '&local_name_info' elif ('DebugMarkerSetObject' in ext_cmd.name or 'SetDebugUtilsObject' in ext_cmd.name) and param.name == 'pTagInfo':