diff --git a/loader/loader.c b/loader/loader.c index 1f3f8536a..643aa682d 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -3321,6 +3321,9 @@ VkResult loader_add_layer_properties(const struct loader_instance *inst, struct } else { do { result = loader_read_layer_json(inst, layer_instance_list, layer_node, json_version, is_implicit, filename); + if (result == VK_ERROR_OUT_OF_HOST_MEMORY) { + goto out; + } layer_node = layer_node->next; } while (layer_node != NULL); } @@ -4383,7 +4386,7 @@ VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_laye // actually present in the available layer list res = verify_all_meta_layers(inst, filters, ®ular_instance_layers, &override_layer_valid); if (VK_ERROR_OUT_OF_HOST_MEMORY == res) { - return res; + goto out; } if (override_layer_valid) { diff --git a/loader/settings.c b/loader/settings.c index 6a3fe14a9..11939d060 100644 --- a/loader/settings.c +++ b/loader/settings.c @@ -497,13 +497,13 @@ VkResult get_unix_settings_path(const struct loader_instance* inst, char** setti VkResult res = check_if_settings_path_exists( inst, xdg_config_home, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } res = check_if_settings_path_exists(inst, xdg_data_home, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } @@ -513,14 +513,14 @@ VkResult get_unix_settings_path(const struct loader_instance* inst, char** setti if (NULL == xdg_config_home || '\0' == xdg_config_home[0]) { res = check_if_settings_path_exists( inst, home, "/.config/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } } if (NULL == xdg_data_home || '\0' == xdg_data_home[0]) { res = check_if_settings_path_exists( inst, home, "/.local/share/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } } @@ -528,26 +528,26 @@ VkResult get_unix_settings_path(const struct loader_instance* inst, char** setti res = check_if_settings_path_exists(inst, xdg_config_dirs, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } res = check_if_settings_path_exists(inst, SYSCONFDIR, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } #if defined(EXTRASYSCONFDIR) res = check_if_settings_path_exists(inst, EXTRASYSCONFDIR, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } #endif res = check_if_settings_path_exists(inst, xdg_data_dirs, "/" VULKAN_DIR "/loader_settings.d/" VK_LOADER_SETTINGS_FILENAME, settings_file_path); - if (res == VK_SUCCESS) { + if (res == VK_SUCCESS || res == VK_ERROR_OUT_OF_HOST_MEMORY) { return res; } diff --git a/tests/loader_alloc_callback_tests.cpp b/tests/loader_alloc_callback_tests.cpp index f006e9a85..4cbb133b3 100644 --- a/tests/loader_alloc_callback_tests.cpp +++ b/tests/loader_alloc_callback_tests.cpp @@ -59,8 +59,8 @@ class MemoryTracker { std::unordered_map allocations; void* allocate(size_t size, size_t alignment, VkSystemAllocationScope alloc_scope) { - if ((settings.should_fail_on_allocation && allocation_count == settings.fail_after_allocations) || - (settings.should_fail_after_set_number_of_calls && call_count == settings.fail_after_calls)) { + if ((settings.should_fail_on_allocation && allocation_count >= settings.fail_after_allocations) || + (settings.should_fail_after_set_number_of_calls && call_count >= settings.fail_after_calls)) { return nullptr; } call_count++; @@ -97,7 +97,7 @@ class MemoryTracker { } growing_reallocations_to_skip--; } - if (size >= original_size && settings.should_fail_after_set_number_of_calls && call_count == settings.fail_after_calls) + if (size >= original_size && settings.should_fail_after_set_number_of_calls && call_count >= settings.fail_after_calls) return nullptr; call_count++; if (size == 0) { @@ -914,6 +914,21 @@ TEST(Allocation, CreateInstanceDeviceIntentionalAllocFail) { ddl_list.driverCount = 1; ddl_list.pDrivers = &ddl_info; + const char* regular_layer_name = "VK_LAYER_TestLayer"; + env.add_explicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(regular_layer_name) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) + .add_device_extension({"NeverGonnaLetYouDown"}))); + + const char* override_layer_name = "VK_LAYER_LUNARG_override"; + env.add_implicit_layer({}, ManifestLayer{} + .set_file_format_version(ManifestVersion{1, 1, 2}) + .add_layer(ManifestLayer::LayerDescription{} + .set_name(override_layer_name) + .set_disable_environment("DISABLE_ENV") + .add_component_layer(regular_layer_name))); + const char* layer_name = "VK_LAYER_ImplicitAllocFail"; env.add_implicit_layer({}, ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) @@ -980,6 +995,20 @@ TEST(Allocation, CreateInstanceDeviceIntentionalAllocFail) { ASSERT_EQ(family.queueCount, family_count); ASSERT_EQ(family.timestampValidBits, 0U); + uint32_t extension_count = 0; + result = env.vulkan_functions.vkEnumerateDeviceExtensionProperties(physical_devices.at(1), nullptr, &extension_count, + nullptr); + if (result == VK_ERROR_OUT_OF_HOST_MEMORY) { + break; + } + + std::vector queried_extensions{extension_count}; + result = env.vulkan_functions.vkEnumerateDeviceExtensionProperties(physical_devices.at(1), nullptr, &extension_count, + queried_extensions.data()); + if (result == VK_ERROR_OUT_OF_HOST_MEMORY) { + break; + } + DeviceCreateInfo dev_create_info; dev_create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));