From b773bf9fa29e31e7d001b2a82a74b1c877aeb8f0 Mon Sep 17 00:00:00 2001 From: Mark Young Date: Fri, 11 Nov 2016 09:31:55 -0700 Subject: loader: Fix failure on ICD loading Piers (Nvidia) discovered a bug where the ICD would fail in different ways depending on which ICD failed to load properly during the vkCreateInstance call. If the first ICD failed, but the second one succeeded, everything would work fine, if the second failed, but the first succeeded, it would fail completely because the last ICD failed. Change-Id: I9f63146e60baf1ff310c948d8ef84c645519c075 --- loader/loader.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'loader/loader.c') diff --git a/loader/loader.c b/loader/loader.c index 2e9f09ea..b433237a 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -4137,6 +4137,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( char **filtered_extension_names = NULL; VkInstanceCreateInfo icd_create_info; VkResult res = VK_SUCCESS; + bool one_icd_successful = false; struct loader_instance *ptr_instance = (struct loader_instance *)*pInstance; memcpy(&icd_create_info, pCreateInfo, sizeof(icd_create_info)); @@ -4223,12 +4224,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&icd_exts); - res = ptr_instance->icd_tramp_list.scanned_list[i].CreateInstance( - &icd_create_info, pAllocator, &(icd_term->instance)); - if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { + VkResult icd_result = + ptr_instance->icd_tramp_list.scanned_list[i].CreateInstance( + &icd_create_info, pAllocator, &(icd_term->instance)); + if (VK_ERROR_OUT_OF_HOST_MEMORY == icd_result) { // If out of memory, bail immediately. + res = VK_ERROR_OUT_OF_HOST_MEMORY; goto out; - } else if (VK_SUCCESS != res) { + } else if (VK_SUCCESS != icd_result) { loader_log(ptr_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "ICD ignored: failed to CreateInstance in ICD %d", i); ptr_instance->icd_terms = icd_term->next; @@ -4245,14 +4248,16 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( "entrypoints with ICD"); continue; } + + // If we made it this far, at least one ICD was successful + one_icd_successful = true; } - /* - * If no ICDs were added to instance list and res is unchanged - * from it's initial value, the loader was unable to find - * a suitable ICD. - */ - if (VK_SUCCESS == res && ptr_instance->icd_terms == NULL) { + // If no ICDs were added to instance list and res is unchanged + // from it's initial value, the loader was unable to find + // a suitable ICD. + if (VK_SUCCESS == res && + (ptr_instance->icd_terms == NULL || !one_icd_successful)) { res = VK_ERROR_INCOMPATIBLE_DRIVER; } -- cgit v1.2.3