Clarify behavior of override_paths + VK_LAYER_PATH
authorCharles Giessen <charles@lunarg.com>
Fri, 11 Feb 2022 16:52:00 +0000 (09:52 -0700)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Fri, 11 Feb 2022 21:16:05 +0000 (14:16 -0700)
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.

docs/LoaderLayerInterface.md
tests/framework/test_environment.cpp
tests/framework/test_environment.h
tests/loader_layer_tests.cpp
tests/loader_regression_tests.cpp

index 95a1ccd8fc3b0be9f0c17072fc240ecc342b5363..2f2a4097dd84a2777c81be53c4144810224f5e59 100644 (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
index 9c91a1bc0af1458e8cc11abfcf5c9d6058c65f6e..f60948f196923d0491f6ef3a023dc16895bf1802 100644 (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,
index 3a80af61625b3e50e52dce7751eb0fa7491aa5b4..5e70b53dd217bb88e191746262893cca9d503ace 100644 (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);
 };
index 1e508a0545252bbf02b869d8e8085cc554b831db..dfa7a58f00e7e758496c288652ed5ad337271c36 100644 (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({});
index 1b943891818beeb19e320110ca31baf59243e7a1..4ce8263c8d7ad9400d663ee6cfd37e868639a9a1 100644 (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