Clarify behavior of override_paths + VK_LAYER_PATH

If a meta layer which contains `override_paths` is active, all of the paths in
VK_LAYER_PATH are ignored when searchign for explicit layers. This may be changed
changed in the future but for now is better tested and documented.
This commit is contained in:
Charles Giessen 2022-02-11 09:52:00 -07:00 committed by Charles Giessen
parent f64401a3e5
commit 0a7407b151
5 changed files with 64 additions and 3 deletions

View File

@ -1038,7 +1038,7 @@ override layer global and applies it to every application upon startup.
If the override layer contains `override_paths`, then it uses this list of
paths exclusively for component layers.
Thus, it ignores both the default explicit and implicit layer layer search
locations.
locations as well as paths set by environment variables like `VK_LAYER_PATH`.
If any component layer is not present in the provided override paths, the meta
layer is disabled.
@ -1379,6 +1379,12 @@ layer is not applied.
So if an override meta layer wants to mix default and custom layer locations,
the override paths must contain both custom and default layer locations.
* If the override layer is both present and contains `override_paths`, the
paths from the environment variable `VK_LAYER_PATH` are ignored when searching
for explicit layers.
For example, when both the meta layer override paths and `VK_LAYER_PATH` are
present, none of the layers in `VK_LAYER_PATH` are discoverable, and the
loader will not find them.
## Layer Manifest File Format
The Khronos loader uses manifest files to discover available layer libraries

View File

@ -221,10 +221,14 @@ void FrameworkEnvironment::add_fake_explicit_layer(ManifestLayer layer_manifest,
add_layer_impl(fake_details, explicit_layer_folder, ManifestCategory::explicit_layer);
}
void FrameworkEnvironment::add_implicit_layer(TestLayerDetails layer_details) noexcept {
add_layer_impl(layer_details, implicit_layer_folder, ManifestCategory::implicit_layer);
add_layer_impl(layer_details,
layer_details.destination_folder == nullptr ? implicit_layer_folder : *layer_details.destination_folder,
ManifestCategory::implicit_layer);
}
void FrameworkEnvironment::add_explicit_layer(TestLayerDetails layer_details) noexcept {
add_layer_impl(layer_details, explicit_layer_folder, ManifestCategory::explicit_layer);
add_layer_impl(layer_details,
layer_details.destination_folder == nullptr ? explicit_layer_folder : *layer_details.destination_folder,
ManifestCategory::explicit_layer);
}
void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, fs::FolderManager& folder_manager,

View File

@ -304,6 +304,7 @@ struct TestLayerDetails {
: layer_manifest(layer_manifest), json_name(json_name) {}
BUILDER_VALUE(TestLayerDetails, ManifestLayer, layer_manifest, {});
BUILDER_VALUE(TestLayerDetails, std::string, json_name, "test_layer");
BUILDER_VALUE(TestLayerDetails, fs::FolderManager*, destination_folder, nullptr);
BUILDER_VALUE(TestLayerDetails, bool, add_to_regular_search_paths, true);
BUILDER_VALUE(TestLayerDetails, bool, is_fake, false);
};

View File

@ -842,10 +842,58 @@ TEST_F(OverrideMetaLayer, BasicOverridePathsIgnoreOtherLayers) {
InstWrapper inst{env->vulkan_functions};
inst.create_info.set_api_version(1, 1, 0);
inst.create_info.add_layer(regular_layer_name);
FillDebugUtilsCreateDetails(inst.create_info, env->debug_log);
inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
ASSERT_FALSE(env->debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
}
TEST_F(OverrideMetaLayer, OverridePathsInteractionWithVK_LAYER_PATH) {
env->get_test_icd().add_physical_device({});
fs::FolderManager vk_layer_path_folder{FRAMEWORK_BUILD_DIRECTORY, "vk_layer_folder"};
set_env_var("VK_LAYER_PATH", vk_layer_path_folder.location().str());
fs::FolderManager override_path_folder{FRAMEWORK_BUILD_DIRECTORY, "override_path_folder"};
// add explicit layer to VK_LAYER_PATH folder
const char* env_var_layer_name = "VK_LAYER_env_var_set_path";
env->add_explicit_layer(TestLayerDetails{ManifestLayer{}
.set_file_format_version(ManifestVersion(1, 2, 0))
.add_layer(ManifestLayer::LayerDescription{}
.set_name(env_var_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
"regular_test_layer.json"}
.set_destination_folder(&vk_layer_path_folder));
// add layer to regular explicit layer folder
const char* regular_layer_name = "VK_LAYER_regular_layer_path";
env->add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
.set_name(regular_layer_name)
.set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
.set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
"regular_test_layer.json"}
.set_destination_folder(&override_path_folder));
env->add_implicit_layer(ManifestLayer{}
.set_file_format_version(ManifestVersion(1, 2, 0))
.add_layer(ManifestLayer::LayerDescription{}
.set_name(lunarg_meta_layer_name)
.set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
.add_component_layer(regular_layer_name)
.set_disable_environment("DisableMeIfYouCan")
.add_override_path(override_path_folder.location().str())),
"meta_test_layer.json");
InstWrapper inst{env->vulkan_functions};
inst.create_info.set_api_version(1, 1, 0);
inst.create_info.add_layer(env_var_layer_name);
FillDebugUtilsCreateDetails(inst.create_info, env->debug_log);
inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
ASSERT_FALSE(env->debug_log.find(std::string("Insert instance layer ") + env_var_layer_name));
remove_env_var("VK_LAYER_PATH");
}
// Make sure that implicit layers not in the override paths aren't found by mistake
TEST_F(OverrideMetaLayer, OverridePathsEnableImplicitLayerInDefaultPaths) {
env->get_test_icd().add_physical_device({});

View File

@ -1115,6 +1115,8 @@ TEST(EnvironmentVariables, VK_LAYER_PATH) {
EXPECT_TRUE(env.debug_log.find("/tmp/carol"));
EXPECT_TRUE(env.debug_log.find("/tandy"));
EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/").str()));
remove_env_var("VK_LAYER_PATH");
}
#endif