Skip to content

Commit

Permalink
Fix layers with pre-inst funcs from being loaded erroneously
Browse files Browse the repository at this point in the history
The loader_scan_for_implicit_layers function was not removing inactive layers
from the list of layers gotten from the loader settings file. This caused
layers with pre-instance functions to loaded and executed.
For example, layers with an enable-environment field shouldn't be
loaded unless their respective env-var was set.
This lack of filtering didn't change the list of layers active during
vkCreateInstance, but does cause adverse side effects during pre-instance
API function calls.
  • Loading branch information
charles-lunarg committed Nov 15, 2024
1 parent c32d00e commit 87f86a4
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 0 deletions.
11 changes: 11 additions & 0 deletions loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -3979,6 +3979,17 @@ VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct lo
goto out;
}

// Remove layers from settings file that are off, are implicit, or are implicit layers that aren't active
for (uint32_t i = 0; i < settings_layers.count; ++i) {
if (settings_layers.list[i].settings_control_value == LOADER_SETTINGS_LAYER_CONTROL_OFF ||
settings_layers.list[i].settings_control_value == LOADER_SETTINGS_LAYER_UNORDERED_LAYER_LOCATION ||
(settings_layers.list[i].type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER) == VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER ||
!loader_implicit_layer_is_enabled(inst, layer_filters, &settings_layers.list[i])) {
loader_remove_layer_in_list(inst, &settings_layers, i);
i--;
}
}

// If we should not look for layers using other mechanisms, assign settings_layers to instance_layers and jump to the
// output
if (!should_search_for_other_layers) {
Expand Down
214 changes: 214 additions & 0 deletions tests/loader_settings_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2143,6 +2143,220 @@ TEST(SettingsFile, ImplicitLayersNotAccidentallyEnabled) {
ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_names.at(9)));
}
}

TEST(SettingsFile, ImplicitLayersPreInstanceEnumInstLayerProps) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";

env.add_implicit_layer(
ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
ManifestLayer::LayerDescription{}
.set_name(implicit_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_disable_environment("DISABLE_ME")
.add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
.set_vk_func("vkEnumerateInstanceLayerProperties")
.set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
"implicit_test_layer.json");

env.update_loader_settings(
env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
LoaderSettingsLayerConfiguration{}
.set_name(implicit_layer_name)
.set_path(env.get_shimmed_layer_manifest_path(0))
.set_control("auto")
.set_treat_as_implicit_manifest(true))));

uint32_t layer_props = 43;
auto& layer = env.get_test_layer(0);
layer.set_reported_layer_props(layer_props);

uint32_t count = 0;
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
ASSERT_EQ(count, layer_props);
}

TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceEnumInstLayerProps) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";

env.add_implicit_layer(
ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
ManifestLayer::LayerDescription{}
.set_name(implicit_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_disable_environment("DISABLE_ME")
.set_enable_environment("ENABLE_ME")
.add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
.set_vk_func("vkEnumerateInstanceLayerProperties")
.set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
"implicit_test_layer.json");

env.update_loader_settings(
env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
LoaderSettingsLayerConfiguration{}
.set_name(implicit_layer_name)
.set_path(env.get_shimmed_layer_manifest_path(0))
.set_control("auto")
.set_treat_as_implicit_manifest(true))));

uint32_t layer_props = 43;
auto& layer = env.get_test_layer(0);
layer.set_reported_layer_props(layer_props);

uint32_t count = 0;
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
ASSERT_EQ(count, 1U);
std::array<VkLayerProperties, 1> layers{};
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, layers.data()));
ASSERT_EQ(count, 1U);
ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name));
}

TEST(SettingsFile, ImplicitLayersPreInstanceEnumInstExtProps) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";

env.add_implicit_layer(
ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
ManifestLayer::LayerDescription{}
.set_name(implicit_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_disable_environment("DISABLE_ME")
.add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
.set_vk_func("vkEnumerateInstanceExtensionProperties")
.set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
"implicit_test_layer.json");

env.update_loader_settings(
env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
LoaderSettingsLayerConfiguration{}
.set_name(implicit_layer_name)
.set_path(env.get_shimmed_layer_manifest_path(0))
.set_control("auto")
.set_treat_as_implicit_manifest(true))));

uint32_t ext_props = 52;
auto& layer = env.get_test_layer(0);
layer.set_reported_extension_props(ext_props);

uint32_t count = 0;
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
ASSERT_EQ(count, ext_props);
}

TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceEnumInstExtProps) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";

env.add_implicit_layer(
ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
ManifestLayer::LayerDescription{}
.set_name(implicit_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_disable_environment("DISABLE_ME")
.set_enable_environment("ENABLE_ME")
.add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
.set_vk_func("vkEnumerateInstanceExtensionProperties")
.set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
"implicit_test_layer.json");

env.update_loader_settings(
env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
LoaderSettingsLayerConfiguration{}
.set_name(implicit_layer_name)
.set_path(env.get_shimmed_layer_manifest_path(0))
.set_control("auto")
.set_treat_as_implicit_manifest(true))));

uint32_t ext_props = 52;
auto& layer = env.get_test_layer(0);
layer.set_reported_extension_props(ext_props);

auto extensions = env.GetInstanceExtensions(4);
EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME));
EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME));
EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME));
}

TEST(SettingsFile, ImplicitLayersPreInstanceVersion) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
.add_physical_device({})
.set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3));

const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";

env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
ManifestLayer::LayerDescription{}
.set_name(implicit_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3))
.set_disable_environment("DISABLE_ME")
.add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
.set_vk_func("vkEnumerateInstanceVersion")
.set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
"implicit_test_layer.json");

env.update_loader_settings(
env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
LoaderSettingsLayerConfiguration{}
.set_name(implicit_layer_name)
.set_path(env.get_shimmed_layer_manifest_path(0))
.set_control("auto")
.set_treat_as_implicit_manifest(true))));

uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
auto& layer = env.get_test_layer(0);
layer.set_reported_instance_version(layer_version);

uint32_t version = 0;
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
ASSERT_EQ(version, layer_version);
}

TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceVersion) {
FrameworkEnvironment env;
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
.add_physical_device({})
.set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3));

const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";

env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
ManifestLayer::LayerDescription{}
.set_name(implicit_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3))
.set_disable_environment("DISABLE_ME")
.set_enable_environment("ENABLE_ME")
.add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
.set_vk_func("vkEnumerateInstanceVersion")
.set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
"implicit_test_layer.json");

env.update_loader_settings(
env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
LoaderSettingsLayerConfiguration{}
.set_name(implicit_layer_name)
.set_path(env.get_shimmed_layer_manifest_path(0))
.set_control("auto")
.set_treat_as_implicit_manifest(true))));

uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
auto& layer = env.get_test_layer(0);
layer.set_reported_instance_version(layer_version);

uint32_t version = 0;
ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
ASSERT_EQ(version, VK_HEADER_VERSION_COMPLETE);
}

// Settings can say which filters to use - make sure those are propagated & treated correctly
TEST(SettingsFile, StderrLogFilters) {
FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
Expand Down

0 comments on commit 87f86a4

Please sign in to comment.