Skip to content

Commit 9f5ae79

Browse files
committedApr 18, 2023
Log ERROR when layers in VK_INSTANCE_LAYERS are missing
It is unhelpful to have zero diagnostics emitted when the layers listed in VK_INSTANCE_LAYERS are not found.
1 parent 55a3cf2 commit 9f5ae79

File tree

2 files changed

+107
-12
lines changed

2 files changed

+107
-12
lines changed
 

‎loader/loader_environment.c

+20-12
Original file line numberDiff line numberDiff line change
@@ -439,24 +439,32 @@ VkResult loader_add_environment_layers(struct loader_instance *inst, const enum
439439
char *next = loader_get_next_path(name);
440440

441441
if (strlen(name) > 0) {
442+
bool found = false;
442443
for (uint32_t i = 0; i < source_list->count; i++) {
443444
struct loader_layer_properties *source_prop = &source_list->list[i];
444445

445-
if (0 == strcmp(name, source_prop->info.layerName) &&
446-
!loader_find_layer_name_in_list(source_prop->info.layerName, target_list)) {
447-
if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
448-
res = loader_add_layer_properties_to_list(inst, target_list, 1, source_prop);
449-
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
450-
res = loader_add_layer_properties_to_list(inst, expanded_target_list, 1, source_prop);
451-
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
452-
} else {
453-
res = loader_add_meta_layer(inst, enable_filter, disable_filter, source_prop, target_list,
454-
expanded_target_list, source_list, NULL);
455-
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
446+
if (0 == strcmp(name, source_prop->info.layerName)) {
447+
found = true;
448+
// Only add it if it doesn't already appear in the layer list
449+
if (!loader_find_layer_name_in_list(source_prop->info.layerName, target_list)) {
450+
if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
451+
res = loader_add_layer_properties_to_list(inst, target_list, 1, source_prop);
452+
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
453+
res = loader_add_layer_properties_to_list(inst, expanded_target_list, 1, source_prop);
454+
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
455+
} else {
456+
res = loader_add_meta_layer(inst, enable_filter, disable_filter, source_prop, target_list,
457+
expanded_target_list, source_list, NULL);
458+
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out;
459+
}
460+
break;
456461
}
457-
break;
458462
}
459463
}
464+
if (!found) {
465+
loader_log(inst, VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_LAYER_BIT, 0,
466+
"Layer \"%s\" was not found but was requested by env var VK_INSTANCE_LAYERS!", name);
467+
}
460468
}
461469
name = next;
462470
}

‎tests/loader_layer_tests.cpp

+87
Original file line numberDiff line numberDiff line change
@@ -4768,6 +4768,93 @@ TEST(TestLayers, EnvironVkInstanceLayersAndDisableFilters) {
47684768
ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var"));
47694769
}
47704770

4771+
// Verify that layers enabled through VK_INSTANCE_LAYERS which were not found get the proper error message
4772+
TEST(TestLayers, NonExistantLayerInVK_INSTANCE_LAYERS) {
4773+
FrameworkEnvironment env;
4774+
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
4775+
env.get_test_icd().add_physical_device({});
4776+
4777+
const char* layer_name = "VK_LAYER_test_layer";
4778+
env.add_explicit_layer(
4779+
ManifestLayer{}.add_layer(
4780+
ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
4781+
"test_layer.json");
4782+
4783+
EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS", "VK_LAYER_I_dont_exist"};
4784+
{
4785+
InstWrapper inst{env.vulkan_functions};
4786+
FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
4787+
inst.CheckCreate();
4788+
4789+
ASSERT_TRUE(
4790+
env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!"));
4791+
auto phys_dev = inst.GetPhysDev();
4792+
uint32_t count = 1;
4793+
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr));
4794+
ASSERT_EQ(0U, count);
4795+
}
4796+
// Make sure layers that do exist are loaded
4797+
env.debug_log.clear();
4798+
layers_enable_env_var.add_to_list(layer_name);
4799+
{
4800+
InstWrapper inst{env.vulkan_functions};
4801+
FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
4802+
inst.CheckCreate();
4803+
ASSERT_TRUE(
4804+
env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!"));
4805+
auto phys_dev = inst.GetPhysDev();
4806+
uint32_t count = 1;
4807+
VkLayerProperties enabled_layer_prop{};
4808+
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &enabled_layer_prop));
4809+
ASSERT_EQ(1U, count);
4810+
ASSERT_TRUE(string_eq(enabled_layer_prop.layerName, layer_name));
4811+
}
4812+
// Make sure that if the layer appears twice in the env-var nothing bad happens
4813+
env.debug_log.clear();
4814+
layers_enable_env_var.add_to_list("VK_LAYER_I_dont_exist");
4815+
{
4816+
InstWrapper inst{env.vulkan_functions};
4817+
FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
4818+
inst.CheckCreate();
4819+
ASSERT_TRUE(
4820+
env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!"));
4821+
auto phys_dev = inst.GetPhysDev();
4822+
uint32_t count = 1;
4823+
VkLayerProperties enabled_layer_prop{};
4824+
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &enabled_layer_prop));
4825+
ASSERT_EQ(1U, count);
4826+
ASSERT_TRUE(string_eq(enabled_layer_prop.layerName, layer_name));
4827+
}
4828+
}
4829+
4830+
// Verify that if the same layer appears twice in VK_INSTANCE_LAYERS nothing bad happens
4831+
TEST(TestLayers, DuplicatesInEnvironVK_INSTANCE_LAYERS) {
4832+
FrameworkEnvironment env;
4833+
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
4834+
env.get_test_icd().add_physical_device({});
4835+
4836+
const char* layer_name = "VK_LAYER_test_layer";
4837+
env.add_explicit_layer(
4838+
ManifestLayer{}.add_layer(
4839+
ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
4840+
"test_layer.json");
4841+
4842+
EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS"};
4843+
4844+
layers_enable_env_var.add_to_list(layer_name);
4845+
layers_enable_env_var.add_to_list(layer_name);
4846+
4847+
InstWrapper inst{env.vulkan_functions};
4848+
FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
4849+
inst.CheckCreate();
4850+
auto phys_dev = inst.GetPhysDev();
4851+
uint32_t count = 1;
4852+
VkLayerProperties enabled_layer_prop{};
4853+
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &enabled_layer_prop));
4854+
ASSERT_EQ(1U, count);
4855+
ASSERT_TRUE(string_eq(enabled_layer_prop.layerName, layer_name));
4856+
}
4857+
47714858
TEST(TestLayers, AppEnabledExplicitLayerFails) {
47724859
FrameworkEnvironment env;
47734860
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));

0 commit comments

Comments
 (0)
Please sign in to comment.