Skip to content

Commit bf546ec

Browse files
Fix duplicate layer output with the settings file
When there exists a layer in the settings file with the same name as a layer in the default search paths with a different library_path, the loader was mistaking it as a 'distinct' layer. Because the settings file allows specifying layers by their path & whether to enable/disable them, it is possible to exactly specify which layers will load, including duplicates.
1 parent 05fdd86 commit bf546ec

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

loader/settings.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,10 @@ TEST_FUNCTION_EXPORT VkResult get_settings_layers(const struct loader_instance*
10411041
// Skip comparing to UNORDERED_LAYER_LOCATION
10421042
// If layer_property is a regular layer, check if the lib_path is the same.
10431043
// Make sure that the lib_name pointers are non-null before calling strcmp.
1044-
bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct loader_layer_properties* layer_property) {
1044+
// consider_lib_path - true if comparison should include the library_path in distinguishing layers. Used to prevent duplicates
1045+
// between settings file provided layers and default found layers
1046+
bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct loader_layer_properties* layer_property,
1047+
bool consider_lib_path) {
10451048
// If the layer is a meta layer, just check against the name
10461049
for (uint32_t i = 0; i < layer_list->count; i++) {
10471050
if (0 == strncmp(layer_list->list[i].info.layerName, layer_property->info.layerName, VK_MAX_EXTENSION_NAME_SIZE)) {
@@ -1051,6 +1054,9 @@ bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct load
10511054
if (VK_LAYER_TYPE_FLAG_META_LAYER == (layer_property->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
10521055
return true;
10531056
}
1057+
if (!consider_lib_path) {
1058+
return true;
1059+
}
10541060
if (layer_list->list[i].lib_name && layer_property->lib_name) {
10551061
return strcmp(layer_list->list[i].lib_name, layer_property->lib_name) == 0;
10561062
}
@@ -1099,7 +1105,7 @@ VkResult combine_settings_layers_with_regular_layers(const struct loader_instanc
10991105

11001106
// Insert the settings layers into output_layers up to unordered_layer_index
11011107
for (uint32_t i = 0; i < unordered_layer_location_index; i++) {
1102-
if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i])) {
1108+
if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i], true)) {
11031109
res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
11041110
if (VK_SUCCESS != res) {
11051111
goto out;
@@ -1109,8 +1115,8 @@ VkResult combine_settings_layers_with_regular_layers(const struct loader_instanc
11091115

11101116
for (uint32_t i = 0; i < regular_layers->count; i++) {
11111117
// Check if its already been put in the output_layers list as well as the remaining settings_layers
1112-
bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, &regular_layers->list[i]) ||
1113-
check_if_layer_is_in_list(settings_layers, &regular_layers->list[i]);
1118+
bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, &regular_layers->list[i], false) ||
1119+
check_if_layer_is_in_list(settings_layers, &regular_layers->list[i], false);
11141120
// If it isn't found, add it
11151121
if (!regular_layer_is_ordered) {
11161122
res = loader_append_layer_property(inst, output_layers, &regular_layers->list[i]);
@@ -1126,9 +1132,11 @@ VkResult combine_settings_layers_with_regular_layers(const struct loader_instanc
11261132
// Insert the rest of the settings layers into combined_layers from unordered_layer_index to the end
11271133
// start at one after the unordered_layer_index
11281134
for (uint32_t i = unordered_layer_location_index + 1; i < settings_layers->count; i++) {
1129-
res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
1130-
if (VK_SUCCESS != res) {
1131-
goto out;
1135+
if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i], true)) {
1136+
res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
1137+
if (VK_SUCCESS != res) {
1138+
goto out;
1139+
}
11321140
}
11331141
}
11341142

tests/loader_settings_tests.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3088,6 +3088,41 @@ TEST(SettingsFile, EnvVarsWorkTogether) {
30883088
}
30893089
}
30903090

3091+
TEST(SettingsFile, DontAllowDuplicatesBetweenSettingsLayersAndDefaultLayers) {
3092+
FrameworkEnvironment env;
3093+
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
3094+
3095+
const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
3096+
env.add_explicit_layer(
3097+
ManifestLayer{}.add_layer(
3098+
ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
3099+
"explicit_test_layer1.json");
3100+
3101+
env.add_explicit_layer(TestLayerDetails{
3102+
ManifestLayer{}.add_layer(
3103+
ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
3104+
"explicit_test_layer2.json"}
3105+
.set_discovery_type(ManifestDiscoveryType::override_folder));
3106+
3107+
env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
3108+
AppSpecificSettings{}
3109+
.add_stderr_log_filter("all")
3110+
.add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
3111+
.add_layer_configuration(LoaderSettingsLayerConfiguration{}
3112+
.set_name(explicit_layer_name1)
3113+
.set_path(env.get_shimmed_layer_manifest_path(1))
3114+
.set_control("on"))));
3115+
3116+
auto layer_props = env.GetLayerProperties(1);
3117+
ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
3118+
3119+
InstWrapper inst{env.vulkan_functions};
3120+
inst.CheckCreate();
3121+
3122+
auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
3123+
ASSERT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name1));
3124+
}
3125+
30913126
// additional drivers being provided by settings file
30923127
TEST(SettingsFile, AdditionalDrivers) {
30933128
FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};

0 commit comments

Comments
 (0)