diff --git a/loader/debug_utils.c b/loader/debug_utils.c index 6656eb77c3..8a12d4a00e 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 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstanc // 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 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstanc // 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 b8ed8a33eb..ad5fe0c1d1 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 b74369c86e..3fa7593b57 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 76f5729880..e0259f03a6 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 @@ VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance 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 @@ -6194,7 +6266,6 @@ VkResult setup_loader_term_phys_devs(struct loader_instance *inst) { goto out; } 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; @@ -6939,7 +7010,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 @@ -6975,7 +7046,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]; } @@ -7006,7 +7076,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, @@ -7037,7 +7106,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) { @@ -7050,6 +7118,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 6bd7115f4c..7be68f97f0 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 53ee0f0dc3..0b76387e97 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 e0b3db81b2..4c12be600f 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 5fbf8d6b42..964592007c 100644 --- a/loader/loader_windows.c +++ b/loader/loader_windows.c @@ -795,8 +795,8 @@ VkResult windows_read_data_files_in_registry(const struct loader_instance *inst, 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); @@ -858,7 +858,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)++; @@ -984,18 +983,19 @@ 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) { 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 ba35c3f1ff..14766b88ec 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 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr 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 ad4d6b9053..5183f11f1f 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 07cc3f2d0d..57675154ff 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 62114f55a2..58413042e1 100644 --- a/scripts/loader_extension_generator.py +++ b/scripts/loader_extension_generator.py @@ -542,7 +542,7 @@ def OutputUtilitiesInSource(self): 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 @@ def CreateTrampTermFuncs(self): 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 @@ def CreateTrampTermFuncs(self): 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 @@ def CreateTrampTermFuncs(self): 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 @@ def CreateTrampTermFuncs(self): 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 @@ def CreateTrampTermFuncs(self): 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 @@ def CreateTrampTermFuncs(self): 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':