char *next = loader_get_next_path(name);
if (strlen(name) > 0) {
+ bool found = false;
for (uint32_t i = 0; i < source_list->count; i++) {
struct loader_layer_properties *source_prop = &source_list->list[i];
- if (0 == strcmp(name, source_prop->info.layerName) &&
- !loader_find_layer_name_in_list(source_prop->info.layerName, target_list)) {
- if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
- res = loader_add_layer_properties_to_list(inst, target_list, 1, source_prop);
- if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
- res = loader_add_layer_properties_to_list(inst, expanded_target_list, 1, source_prop);
- if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
- } else {
- res = loader_add_meta_layer(inst, enable_filter, disable_filter, source_prop, target_list,
- expanded_target_list, source_list, NULL);
- if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
+ if (0 == strcmp(name, source_prop->info.layerName)) {
+ found = true;
+ // Only add it if it doesn't already appear in the layer list
+ if (!loader_find_layer_name_in_list(source_prop->info.layerName, target_list)) {
+ if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
+ res = loader_add_layer_properties_to_list(inst, target_list, 1, source_prop);
+ if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
+ res = loader_add_layer_properties_to_list(inst, expanded_target_list, 1, source_prop);
+ if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
+ } else {
+ res = loader_add_meta_layer(inst, enable_filter, disable_filter, source_prop, target_list,
+ expanded_target_list, source_list, NULL);
+ if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
+ }
+ break;
}
- break;
}
}
+ if (!found) {
+ loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_LAYER_BIT, 0,
+ "Layer \"%s\" was not found but was requested by env var VK_INSTANCE_LAYERS!", name);
+ }
}
name = next;
}
ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var"));
}
+// Verify that layers enabled through VK_INSTANCE_LAYERS which were not found get the proper error message
+TEST(TestLayers, NonExistantLayerInVK_INSTANCE_LAYERS) {
+ FrameworkEnvironment env;
+ env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+ env.get_test_icd().add_physical_device({});
+
+ const char* layer_name = "VK_LAYER_test_layer";
+ env.add_explicit_layer(
+ ManifestLayer{}.add_layer(
+ ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
+ "test_layer.json");
+
+ EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS", "VK_LAYER_I_dont_exist"};
+ {
+ InstWrapper inst{env.vulkan_functions};
+ FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+ inst.CheckCreate();
+
+ ASSERT_TRUE(
+ env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!"));
+ auto phys_dev = inst.GetPhysDev();
+ uint32_t count = 1;
+ ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr));
+ ASSERT_EQ(0U, count);
+ }
+ // Make sure layers that do exist are loaded
+ env.debug_log.clear();
+ layers_enable_env_var.add_to_list(layer_name);
+ {
+ InstWrapper inst{env.vulkan_functions};
+ FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+ inst.CheckCreate();
+ ASSERT_TRUE(
+ env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!"));
+ auto phys_dev = inst.GetPhysDev();
+ uint32_t count = 1;
+ VkLayerProperties enabled_layer_prop{};
+ ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &enabled_layer_prop));
+ ASSERT_EQ(1U, count);
+ ASSERT_TRUE(string_eq(enabled_layer_prop.layerName, layer_name));
+ }
+ // Make sure that if the layer appears twice in the env-var nothing bad happens
+ env.debug_log.clear();
+ layers_enable_env_var.add_to_list("VK_LAYER_I_dont_exist");
+ {
+ InstWrapper inst{env.vulkan_functions};
+ FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+ inst.CheckCreate();
+ ASSERT_TRUE(
+ env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!"));
+ auto phys_dev = inst.GetPhysDev();
+ uint32_t count = 1;
+ VkLayerProperties enabled_layer_prop{};
+ ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &enabled_layer_prop));
+ ASSERT_EQ(1U, count);
+ ASSERT_TRUE(string_eq(enabled_layer_prop.layerName, layer_name));
+ }
+}
+
+// Verify that if the same layer appears twice in VK_INSTANCE_LAYERS nothing bad happens
+TEST(TestLayers, DuplicatesInEnvironVK_INSTANCE_LAYERS) {
+ FrameworkEnvironment env;
+ env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
+ env.get_test_icd().add_physical_device({});
+
+ const char* layer_name = "VK_LAYER_test_layer";
+ env.add_explicit_layer(
+ ManifestLayer{}.add_layer(
+ ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
+ "test_layer.json");
+
+ EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS"};
+
+ layers_enable_env_var.add_to_list(layer_name);
+ layers_enable_env_var.add_to_list(layer_name);
+
+ InstWrapper inst{env.vulkan_functions};
+ FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
+ inst.CheckCreate();
+ auto phys_dev = inst.GetPhysDev();
+ uint32_t count = 1;
+ VkLayerProperties enabled_layer_prop{};
+ ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &enabled_layer_prop));
+ ASSERT_EQ(1U, count);
+ ASSERT_TRUE(string_eq(enabled_layer_prop.layerName, layer_name));
+}
+
TEST(TestLayers, AppEnabledExplicitLayerFails) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));