Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions loader/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,10 @@ TEST_FUNCTION_EXPORT VkResult get_settings_layers(const struct loader_instance*
// Skip comparing to UNORDERED_LAYER_LOCATION
// If layer_property is a regular layer, check if the lib_path is the same.
// Make sure that the lib_name pointers are non-null before calling strcmp.
bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct loader_layer_properties* layer_property) {
// consider_lib_path - true if comparison should include the library_path in distinguishing layers. Used to prevent duplicates
// between settings file provided layers and default found layers
bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct loader_layer_properties* layer_property,
bool consider_lib_path) {
// If the layer is a meta layer, just check against the name
for (uint32_t i = 0; i < layer_list->count; i++) {
if (0 == strncmp(layer_list->list[i].info.layerName, layer_property->info.layerName, VK_MAX_EXTENSION_NAME_SIZE)) {
Expand All @@ -1044,6 +1047,9 @@ bool check_if_layer_is_in_list(struct loader_layer_list* layer_list, struct load
if (VK_LAYER_TYPE_FLAG_META_LAYER == (layer_property->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
return true;
}
if (!consider_lib_path) {
return true;
}
if (layer_list->list[i].lib_name && layer_property->lib_name) {
return strcmp(layer_list->list[i].lib_name, layer_property->lib_name) == 0;
}
Expand Down Expand Up @@ -1092,7 +1098,7 @@ VkResult combine_settings_layers_with_regular_layers(const struct loader_instanc

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

for (uint32_t i = 0; i < regular_layers->count; i++) {
// Check if its already been put in the output_layers list as well as the remaining settings_layers
bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, &regular_layers->list[i]) ||
check_if_layer_is_in_list(settings_layers, &regular_layers->list[i]);
bool regular_layer_is_ordered = check_if_layer_is_in_list(output_layers, &regular_layers->list[i], false) ||
check_if_layer_is_in_list(settings_layers, &regular_layers->list[i], false);
// If it isn't found, add it
if (!regular_layer_is_ordered) {
res = loader_append_layer_property(inst, output_layers, &regular_layers->list[i]);
Expand All @@ -1119,9 +1125,11 @@ VkResult combine_settings_layers_with_regular_layers(const struct loader_instanc
// Insert the rest of the settings layers into combined_layers from unordered_layer_index to the end
// start at one after the unordered_layer_index
for (uint32_t i = unordered_layer_location_index + 1; i < settings_layers->count; i++) {
res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
if (VK_SUCCESS != res) {
goto out;
if (!check_if_layer_is_in_list(output_layers, &settings_layers->list[i], true)) {
res = loader_append_layer_property(inst, output_layers, &settings_layers->list[i]);
if (VK_SUCCESS != res) {
goto out;
}
}
}

Expand Down
35 changes: 35 additions & 0 deletions tests/loader_settings_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3089,6 +3089,41 @@ TEST(SettingsFile, EnvVarsWorkTogether) {
}
}

TEST(SettingsFile, DontAllowDuplicatesBetweenSettingsLayersAndDefaultLayers) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});

const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
env.add_explicit_layer(
ManifestLayer{}.add_layer(
ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
"explicit_test_layer1.json");

env.add_explicit_layer(TestLayerDetails{
ManifestLayer{}.add_layer(
ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
"explicit_test_layer2.json"}
.set_discovery_type(ManifestDiscoveryType::override_folder));

env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
AppSpecificSettings{}
.add_stderr_log_filter("all")
.add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
.add_layer_configuration(LoaderSettingsLayerConfiguration{}
.set_name(explicit_layer_name1)
.set_path(env.get_shimmed_layer_manifest_path(1))
.set_control("on"))));

auto layer_props = env.GetLayerProperties(1);
ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));

InstWrapper inst{env.vulkan_functions};
inst.CheckCreate();

auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
ASSERT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name1));
}

// additional drivers being provided by settings file
TEST(SettingsFile, AdditionalDrivers) {
FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
Expand Down