diff options
| author | Mark Young <marky@lunarg.com> | 2016-08-19 15:25:08 -0600 |
|---|---|---|
| committer | Mark Young <marky@lunarg.com> | 2016-08-19 15:35:41 -0600 |
| commit | a150d387b5fa20155b8210b6a4ac90b274f199ed (patch) | |
| tree | d8111cc1c8890d4fc74eccafb9ea01108e46f033 | |
| parent | c79277ae0703934a65bdab11629664c863768751 (diff) | |
| download | usermoji-a150d387b5fa20155b8210b6a4ac90b274f199ed.tar.xz | |
loader: Fix CTS failures in simulate_oom tests.
The simulate_oom tests continue the trend of testing what happens
when the user-provided allocators fail. It validates two things:
1) That the loader returns the proper error message when this
occurs.
2) That the loader cleans up any allocated items prior to
returning.
Change-Id: Ic80ff4345e1f3524d5e11ce787b10c391a37d760
| -rw-r--r-- | loader/loader.c | 354 | ||||
| -rw-r--r-- | loader/loader.h | 8 | ||||
| -rw-r--r-- | loader/trampoline.c | 19 |
3 files changed, 257 insertions, 124 deletions
diff --git a/loader/loader.c b/loader/loader.c index 6b228935..485e387f 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -716,29 +716,29 @@ void loader_delete_layer_properties(const struct loader_instance *inst, } } -static void loader_add_instance_extensions( +static VkResult loader_add_instance_extensions( const struct loader_instance *inst, const PFN_vkEnumerateInstanceExtensionProperties fp_get_props, const char *lib_name, struct loader_extension_list *ext_list) { uint32_t i, count = 0; VkExtensionProperties *ext_props; - VkResult res; + VkResult res = VK_SUCCESS; if (!fp_get_props) { /* No EnumerateInstanceExtensionProperties defined */ - return; + goto out; } res = fp_get_props(NULL, &count, NULL); if (res != VK_SUCCESS) { loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Error getting Instance extension count from %s", lib_name); - return; + goto out; } if (count == 0) { /* No ExtensionProperties to report */ - return; + goto out; } ext_props = loader_stack_alloc(count * sizeof(VkExtensionProperties)); @@ -747,7 +747,7 @@ static void loader_add_instance_extensions( if (res != VK_SUCCESS) { loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Error getting Instance extensions from %s", lib_name); - return; + goto out; } for (i = 0; i < count; i++) { @@ -763,11 +763,17 @@ static void loader_add_instance_extensions( loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Instance Extension: %s (%s) version %s", ext_props[i].extensionName, lib_name, spec_version); - loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]); + res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]); + if (res != VK_SUCCESS) { + loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, + "Failed to add %s to Instance extension list", + lib_name); + goto out; + } } } - - return; +out: + return res; } /* @@ -782,9 +788,10 @@ loader_init_device_extensions(const struct loader_instance *inst, VkResult res; uint32_t i; - if (!loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, - sizeof(VkExtensionProperties))) { - return VK_ERROR_OUT_OF_HOST_MEMORY; + res = loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, + sizeof(VkExtensionProperties)); + if (VK_SUCCESS != res) { + return res; } for (i = 0; i < count; i++) { @@ -851,18 +858,18 @@ VkResult loader_add_device_extensions(const struct loader_instance *inst, return VK_SUCCESS; } -bool loader_init_generic_list(const struct loader_instance *inst, +VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size) { list_info->capacity = 32 * element_size; list_info->list = loader_instance_heap_alloc( inst, list_info->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); if (list_info->list == NULL) { - return false; + return VK_ERROR_OUT_OF_HOST_MEMORY; } memset(list_info->list, 0, list_info->capacity); list_info->count = 0; - return true; + return VK_SUCCESS; } void loader_destroy_generic_list(const struct loader_instance *inst, @@ -886,13 +893,13 @@ VkResult loader_add_to_ext_list(const struct loader_instance *inst, const VkExtensionProperties *cur_ext; if (ext_list->list == NULL || ext_list->capacity == 0) { - loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, + VkResult res = loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, sizeof(VkExtensionProperties)); + if (VK_SUCCESS != res) { + return res; + } } - if (ext_list->list == NULL) - return VK_ERROR_OUT_OF_HOST_MEMORY; - for (i = 0; i < prop_list_count; i++) { cur_ext = &props[i]; @@ -937,13 +944,14 @@ loader_add_to_dev_ext_list(const struct loader_instance *inst, uint32_t entry_count, char **entrys) { uint32_t idx; if (ext_list->list == NULL || ext_list->capacity == 0) { - loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, - sizeof(struct loader_dev_ext_props)); + VkResult res = loader_init_generic_list( + inst, (struct loader_generic_list *)ext_list, + sizeof(struct loader_dev_ext_props)); + if (VK_SUCCESS != res) { + return res; + } } - if (ext_list->list == NULL) - return VK_ERROR_OUT_OF_HOST_MEMORY; - // look for duplicates if (has_vk_dev_ext_property(props, ext_list)) { return VK_SUCCESS; @@ -1177,7 +1185,6 @@ get_dev_extension_property(const char *name, return NULL; } - /* * For Instance extensions implemented within the loader (i.e. DEBUG_REPORT * the extension must provide two entry points for the loader to use: @@ -1198,26 +1205,42 @@ get_dev_extension_property(const char *name, * linked directly with the loader. */ -void loader_get_icd_loader_instance_extensions( +VkResult loader_get_icd_loader_instance_extensions( const struct loader_instance *inst, struct loader_icd_libs *icd_libs, struct loader_extension_list *inst_exts) { struct loader_extension_list icd_exts; + VkResult res = VK_SUCCESS; + loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Build ICD instance extension list"); + // traverse scanned icd list adding non-duplicate extensions to the list for (uint32_t i = 0; i < icd_libs->count; i++) { - loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts, - sizeof(VkExtensionProperties)); - loader_add_instance_extensions( + res = loader_init_generic_list(inst, + (struct loader_generic_list *)&icd_exts, + sizeof(VkExtensionProperties)); + if (VK_SUCCESS != res) { + goto out; + } + res = loader_add_instance_extensions( inst, icd_libs->list[i].EnumerateInstanceExtensionProperties, icd_libs->list[i].lib_name, &icd_exts); - loader_add_to_ext_list(inst, inst_exts, icd_exts.count, icd_exts.list); + if (VK_SUCCESS == res) { + res = loader_add_to_ext_list(inst, inst_exts, icd_exts.count, + icd_exts.list); + } loader_destroy_generic_list(inst, (struct loader_generic_list *)&icd_exts); + if (VK_SUCCESS != res) { + goto out; + } }; // Traverse loader's extensions, adding non-duplicate extensions to the list debug_report_add_instance_extensions(inst, inst_exts); + +out: + return res; } struct loader_icd *loader_get_icd_and_device(const VkDevice device, @@ -1433,9 +1456,10 @@ static VkResult loader_scanned_icd_init(const struct loader_instance *inst, return err; } -static void loader_scanned_icd_add(const struct loader_instance *inst, - struct loader_icd_libs *icd_libs, - const char *filename, uint32_t api_version) { +static VkResult loader_scanned_icd_add(const struct loader_instance *inst, + struct loader_icd_libs *icd_libs, + const char *filename, + uint32_t api_version) { loader_platform_dl_handle handle; PFN_vkCreateInstance fp_create_inst; PFN_vkEnumerateInstanceExtensionProperties fp_get_inst_ext_props; @@ -1443,6 +1467,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, PFN_vkNegotiateLoaderICDInterfaceVersion fp_negotiate_icd_version; struct loader_scanned_icds *new_node; uint32_t interface_vers; + VkResult res = VK_SUCCESS; /* TODO implement smarter opening/closing of libraries. For now this * function leaves libraries open and the scanned_icd_clear closes them */ @@ -1450,7 +1475,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, if (!handle) { loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, loader_platform_open_library_error(filename)); - return; + goto out; } // Get and settle on an ICD interface version @@ -1463,7 +1488,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, "ICD (%s) doesn't support interface version compatible" "with loader, skip this ICD %s", filename); - return; + goto out; } fp_get_proc_addr = @@ -1477,7 +1502,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, loader_platform_get_proc_address_error( "vk_icdGetInstanceProcAddr")); - return; + goto out; } else { loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Using deprecated ICD interface of " @@ -1492,7 +1517,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, "Couldn't get vkCreateInstance via dlsym/loadlibrary " "for ICD %s", filename); - return; + goto out; } fp_get_inst_ext_props = loader_platform_get_proc_address( handle, "vkEnumerateInstanceExtensionProperties"); @@ -1501,7 +1526,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, "Couldn't get vkEnumerateInstanceExtensionProperties " "via dlsym/loadlibrary for ICD %s", filename); - return; + goto out; } } else { // Use newer interface version 1 or later @@ -1515,7 +1540,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, "Couldn't get vkCreateInstance via " "vk_icdGetInstanceProcAddr for ICD %s", filename); - return; + goto out; } fp_get_inst_ext_props = (PFN_vkEnumerateInstanceExtensionProperties)fp_get_proc_addr( @@ -1525,7 +1550,7 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, "Couldn't get vkEnumerateInstanceExtensionProperties " "via vk_icdGetInstanceProcAddr for ICD %s", filename); - return; + goto out; } } @@ -1537,9 +1562,10 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, inst, icd_libs->list, icd_libs->capacity, icd_libs->capacity * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); if (NULL == icd_libs->list) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "realloc failed on icd library list"); - return; + goto out; } // double capacity icd_libs->capacity *= 2; @@ -1556,12 +1582,17 @@ static void loader_scanned_icd_add(const struct loader_instance *inst, new_node->lib_name = (char *)loader_instance_heap_alloc( inst, strlen(filename) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); if (NULL == new_node->lib_name) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Out of memory can't add icd"); - return; + goto out; } strcpy(new_node->lib_name, filename); icd_libs->count++; + +out: + + return res; } static bool loader_icd_init_entrys(struct loader_icd *icd, VkInstance inst, @@ -1776,43 +1807,60 @@ static void loader_get_fullpath(const char *file, const char *dirs, * A pointer to a cJSON object representing the JSON parse tree. * This returned buffer should be freed by caller. */ -static cJSON *loader_get_json(const struct loader_instance *inst, - const char *filename) { - FILE *file; +static VkResult loader_get_json(const struct loader_instance *inst, + const char *filename, cJSON **json) { + FILE *file = NULL; char *json_buf; - cJSON *json; size_t len; + VkResult res = VK_SUCCESS; + + if (NULL == json) { + res = VK_ERROR_INITIALIZATION_FAILED; + goto out; + } + + *json = NULL; + file = fopen(filename, "rb"); if (!file) { + res = VK_ERROR_INITIALIZATION_FAILED; loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Couldn't open JSON file %s", filename); - return NULL; + goto out; } fseek(file, 0, SEEK_END); len = ftell(file); fseek(file, 0, SEEK_SET); json_buf = (char *)loader_stack_alloc(len + 1); if (json_buf == NULL) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Out of memory can't get JSON file"); - fclose(file); - return NULL; + goto out; } if (fread(json_buf, sizeof(char), len, file) != len) { + res = VK_ERROR_INITIALIZATION_FAILED; loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "fread failed can't get JSON file"); - fclose(file); - return NULL; + goto out; } - fclose(file); json_buf[len] = '\0'; // parse text from file - json = cJSON_Parse(json_buf); - if (json == NULL) + *json = cJSON_Parse(json_buf); + if (*json == NULL) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Can't parse JSON file %s", filename); - return json; + goto out; + } + +out: + if (NULL != file) { + fclose(file); + } + + return res; } /** @@ -2828,6 +2876,7 @@ VkResult loader_icd_scan(const struct loader_instance *inst, VkResult res = VK_SUCCESS; bool lockedMutex = false; cJSON *json = NULL; + uint32_t num_good_icds = 0; memset(&manifest_files, 0, sizeof(struct loader_manifest_files)); @@ -2851,22 +2900,29 @@ VkResult loader_icd_scan(const struct loader_instance *inst, continue; } - json = loader_get_json(inst, file_str); - if (!json) { + res = loader_get_json(inst, file_str, &json); + if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { + break; + } else if (VK_SUCCESS != res || NULL == json) { continue; } + cJSON *item, *itemICD; item = cJSON_GetObjectItem(json, "file_format_version"); if (item == NULL) { - res = VK_ERROR_INITIALIZATION_FAILED; - goto out; + if (num_good_icds == 0) { + res = VK_ERROR_INITIALIZATION_FAILED; + } + continue; } char *file_vers = cJSON_Print(item); if (NULL == file_vers) { // Only reason the print can fail is if there was an allocation // issue - res = VK_ERROR_OUT_OF_HOST_MEMORY; - goto out; + if (num_good_icds == 0) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + } + continue; } loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Found manifest file %s, version %s", file_str, file_vers); @@ -2899,6 +2955,9 @@ VkResult loader_icd_scan(const struct loader_instance *inst, "Can't find \"library_path\" in ICD JSON file " "%s, skipping", file_str); + if (num_good_icds == 0) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + } cJSON_Free(temp); cJSON_Delete(json); json = NULL; @@ -2907,9 +2966,21 @@ VkResult loader_icd_scan(const struct loader_instance *inst, // strip out extra quotes temp[strlen(temp) - 1] = '\0'; char *library_path = loader_stack_alloc(strlen(temp) + 1); + if (NULL == library_path) { + loader_log( + inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, + "Can't allocate space for \"library_path\" in ICD " + "JSON file %s, skipping", + file_str); + res = VK_ERROR_OUT_OF_HOST_MEMORY; + cJSON_Free(temp); + cJSON_Delete(json); + json = NULL; + goto out; + } strcpy(library_path, &temp[1]); cJSON_Free(temp); - if (!library_path || strlen(library_path) == 0) { + if (strlen(library_path) == 0) { loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Can't find \"library_path\" in ICD JSON file " "%s, skipping", @@ -2951,7 +3022,11 @@ VkResult loader_icd_scan(const struct loader_instance *inst, vers = loader_make_version(temp); cJSON_Free(temp); } - loader_scanned_icd_add(inst, icds, fullpath, vers); + res = loader_scanned_icd_add(inst, icds, fullpath, vers); + if (VK_SUCCESS != res) { + goto out; + } + num_good_icds++; } else { loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Can't find \"library_path\" object in ICD JSON " @@ -3033,8 +3108,10 @@ void loader_layer_scan(const struct loader_instance *inst, continue; // parse file into JSON struct - json = loader_get_json(inst, file_str); - if (!json) { + VkResult res = loader_get_json(inst, file_str, &json); + if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { + break; + } else if (VK_SUCCESS != res || NULL == json) { continue; } @@ -3096,8 +3173,10 @@ void loader_implicit_layer_scan(const struct loader_instance *inst, } // parse file into JSON struct - json = loader_get_json(inst, file_str); - if (!json) { + res = loader_get_json(inst, file_str, &json); + if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { + break; + } else if (VK_SUCCESS != res || NULL == json) { continue; } @@ -4017,7 +4096,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( filtered_extension_names = loader_stack_alloc(pCreateInfo->enabledExtensionCount * sizeof(char *)); if (!filtered_extension_names) { - return VK_ERROR_OUT_OF_HOST_MEMORY; + res = VK_ERROR_OUT_OF_HOST_MEMORY; + goto out; } icd_create_info.ppEnabledExtensionNames = (const char *const *)filtered_extension_names; @@ -4025,13 +4105,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( for (uint32_t i = 0; i < ptr_instance->icd_libs.count; i++) { icd = loader_icd_add(ptr_instance, &ptr_instance->icd_libs.list[i]); if (NULL == icd) { - while (NULL != ptr_instance->icds) { - icd = ptr_instance->icds; - ptr_instance->icds = icd->next; - icd->DestroyInstance(icd->instance, pAllocator); - loader_icd_destroy(ptr_instance, icd, pAllocator); - } - return VK_ERROR_OUT_OF_HOST_MEMORY; + res = VK_ERROR_OUT_OF_HOST_MEMORY; + goto out; } icd_create_info.enabledExtensionCount = 0; struct loader_extension_list icd_exts; @@ -4040,13 +4115,28 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( "Build ICD instance extension list"); // traverse scanned icd list adding non-duplicate extensions to the // list - loader_init_generic_list(ptr_instance, + res = loader_init_generic_list(ptr_instance, (struct loader_generic_list *)&icd_exts, sizeof(VkExtensionProperties)); - loader_add_instance_extensions( + if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { + // If out of memory, bail immediately. + goto out; + } else if (VK_SUCCESS != res) { + // Keep trying if there was some other error. + continue; + } + + res = loader_add_instance_extensions( ptr_instance, icd->this_icd_lib->EnumerateInstanceExtensionProperties, icd->this_icd_lib->lib_name, &icd_exts); + if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { + // If out of memory, bail immediately. + goto out; + } else if (VK_SUCCESS != res) { + // Keep trying if there was some other error. + continue; + } for (uint32_t j = 0; j < pCreateInfo->enabledExtensionCount; j++) { prop = get_extension_property( @@ -4064,17 +4154,23 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( res = ptr_instance->icd_libs.list[i].CreateInstance( &icd_create_info, pAllocator, &(icd->instance)); - if (res == VK_SUCCESS) - success = loader_icd_init_entrys( - icd, icd->instance, - ptr_instance->icd_libs.list[i].GetInstanceProcAddr); + if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { + // If out of memory, bail immediately. + goto out; + } else if (VK_SUCCESS != res) { + // Keep trying if there was some other error. + loader_log(ptr_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, + "ICD ignored: failed to CreateInstance in ICD %d", i); + continue; + } - if (res != VK_SUCCESS || !success) { - ptr_instance->icds = ptr_instance->icds->next; - loader_icd_destroy(ptr_instance, icd, pAllocator); - loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, + if (!loader_icd_init_entrys( + icd, icd->instance, + ptr_instance->icd_libs.list[i].GetInstanceProcAddr)) { + loader_log(ptr_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "ICD ignored: failed to CreateInstance and find " "entrypoints with ICD"); + continue; } } @@ -4083,15 +4179,24 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance( * from it's initial value, the loader was unable to find * a suitable ICD. */ - if (ptr_instance->icds == NULL) { - if (res == VK_SUCCESS) { - return VK_ERROR_INCOMPATIBLE_DRIVER; - } else { - return res; + if (VK_SUCCESS == res && ptr_instance->icds == NULL) { + res = VK_ERROR_INCOMPATIBLE_DRIVER; + } + +out: + + if (VK_SUCCESS != res) { + while (NULL != ptr_instance->icds) { + icd = ptr_instance->icds; + ptr_instance->icds = icd->next; + if (NULL != icd->instance) { + icd->DestroyInstance(icd->instance, pAllocator); + } + loader_icd_destroy(ptr_instance, icd, pAllocator); } } - return VK_SUCCESS; + return res; } VKAPI_ATTR void VKAPI_CALL terminator_DestroyInstance( @@ -4180,10 +4285,10 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice( (const char *const *)filtered_extension_names; /* Get the physical device (ICD) extensions */ - if (!loader_init_generic_list(phys_dev->this_icd->this_instance, + res = loader_init_generic_list(phys_dev->this_icd->this_instance, (struct loader_generic_list *)&icd_exts, - sizeof(VkExtensionProperties))) { - res = VK_ERROR_OUT_OF_HOST_MEMORY; + sizeof(VkExtensionProperties)); + if (VK_SUCCESS != res) { goto out; } @@ -4420,7 +4525,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties( uint32_t *pPropertyCount, VkExtensionProperties *pProperties) { struct loader_physical_device *phys_dev; - struct loader_layer_list implicit_layer_list; + struct loader_layer_list implicit_layer_list = {0}; + struct loader_extension_list all_exts = {0}; + struct loader_extension_list icd_exts = {0}; assert(pLayerName == NULL || strlen(pLayerName) == 0); @@ -4437,10 +4544,14 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties( /* get device extensions */ res = icd->EnumerateDeviceExtensionProperties(phys_dev->phys_dev, NULL, &icd_ext_count, pProperties); - if (res != VK_SUCCESS) - return res; + if (res != VK_SUCCESS) { + goto out; + } - loader_init_layer_list(icd->this_instance, &implicit_layer_list); + if (!loader_init_layer_list(icd->this_instance, &implicit_layer_list)) { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + goto out; + } loader_add_layer_implicit( icd->this_instance, VK_LAYER_TYPE_INSTANCE_IMPLICIT, @@ -4450,22 +4561,24 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties( * it depends on results of environment variables (which can change). */ if (pProperties != NULL) { - struct loader_extension_list icd_exts; /* initialize dev_extension list within the physicalDevice object */ res = loader_init_device_extensions(icd->this_instance, phys_dev, icd_ext_count, pProperties, &icd_exts); - if (res != VK_SUCCESS) - return res; + if (res != VK_SUCCESS) { + goto out; + } /* we need to determine which implicit layers are active, * and then add their extensions. This can't be cached as * it depends on results of environment variables (which can * change). */ - struct loader_extension_list all_exts = {0}; - loader_add_to_ext_list(icd->this_instance, &all_exts, icd_exts.count, - icd_exts.list); + res = loader_add_to_ext_list(icd->this_instance, &all_exts, + icd_exts.count, icd_exts.list); + if (res != VK_SUCCESS) { + goto out; + } loader_add_layer_implicit( icd->this_instance, VK_LAYER_TYPE_INSTANCE_IMPLICIT, @@ -4475,10 +4588,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties( for (uint32_t j = 0; j < implicit_layer_list.list[i].device_extension_list.count; j++) { - loader_add_to_ext_list(icd->this_instance, &all_exts, 1, - &implicit_layer_list.list[i] - .device_extension_list.list[j] - .props); + res = loader_add_to_ext_list(icd->this_instance, &all_exts, 1, + &implicit_layer_list.list[i] + .device_extension_list.list[j] + .props); + if (res != VK_SUCCESS) { + goto out; + } } } uint32_t capacity = *pPropertyCount; @@ -4494,10 +4610,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties( } else { *pPropertyCount = all_exts.count; } - loader_destroy_generic_list(icd->this_instance, - (struct loader_generic_list *)&all_exts); - loader_destroy_generic_list(icd->this_instance, - (struct loader_generic_list *)&icd_exts); } else { /* just return the count; need to add in the count of implicit layer * extensions @@ -4511,8 +4623,22 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties( res = VK_SUCCESS; } - loader_destroy_generic_list( - icd->this_instance, (struct loader_generic_list *)&implicit_layer_list); +out: + + if (NULL != implicit_layer_list.list) { + loader_destroy_generic_list( + icd->this_instance, + (struct loader_generic_list *)&implicit_layer_list); + } + if (NULL != all_exts.list) { + loader_destroy_generic_list(icd->this_instance, + (struct loader_generic_list *)&all_exts); + } + if (NULL != icd_exts.list) { + loader_destroy_generic_list(icd->this_instance, + (struct loader_generic_list *)&icd_exts); + } + return res; } diff --git a/loader/loader.h b/loader/loader.h index cb5f2063..5a1515e4 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -449,9 +449,9 @@ VkResult loader_add_device_extensions(const struct loader_instance *inst, VkPhysicalDevice physical_device, const char *lib_name, struct loader_extension_list *ext_list); -bool loader_init_generic_list(const struct loader_instance *inst, - struct loader_generic_list *list_info, - size_t element_size); +VkResult loader_init_generic_list(const struct loader_instance *inst, + struct loader_generic_list *list_info, + size_t element_size); void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list); void loader_destroy_layer_list(const struct loader_instance *inst, @@ -489,7 +489,7 @@ void loader_layer_scan(const struct loader_instance *inst, struct loader_layer_list *instance_layers); void loader_implicit_layer_scan(const struct loader_instance *inst, struct loader_layer_list *instance_layers); -void loader_get_icd_loader_instance_extensions( +VkResult loader_get_icd_loader_instance_extensions( const struct loader_instance *inst, struct loader_icd_libs *icd_libs, struct loader_extension_list *inst_exts); struct loader_icd *loader_get_icd_and_device(const VkDevice device, diff --git a/loader/trampoline.c b/loader/trampoline.c index e2c32058..b0f61383 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -177,8 +177,11 @@ vkEnumerateInstanceExtensionProperties(const char *pLayerName, goto out; } /* get extensions from all ICD's, merge so no duplicates */ - loader_get_icd_loader_instance_extensions(NULL, &icd_libs, - &local_ext_list); + res = loader_get_icd_loader_instance_extensions(NULL, &icd_libs, + &local_ext_list); + if (VK_SUCCESS != res) { + goto out; + } loader_scanned_icd_clear(NULL, &icd_libs); // Append implicit layers. @@ -366,8 +369,11 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( } /* get extensions from all ICD's, merge so no duplicates, then validate */ - loader_get_icd_loader_instance_extensions( + res = loader_get_icd_loader_instance_extensions( ptr_instance, &ptr_instance->icd_libs, &ptr_instance->ext_list); + if (res != VK_SUCCESS) { + goto out; + } res = loader_validate_instance_extensions( ptr_instance, &ptr_instance->ext_list, &ptr_instance->instance_layer_list, &ici); @@ -658,9 +664,10 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( /* Get the physical device (ICD) extensions */ struct loader_extension_list icd_exts; icd_exts.list = NULL; - if (!loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts, - sizeof(VkExtensionProperties))) { - res = VK_ERROR_OUT_OF_HOST_MEMORY; + res = + loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts, + sizeof(VkExtensionProperties)); + if (VK_SUCCESS != res) { goto out; } |
