Document VK_DRIVER_FILES ability to look in folders
authorCharles Giessen <charles@lunarg.com>
Wed, 9 Aug 2023 19:48:01 +0000 (13:48 -0600)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Wed, 9 Aug 2023 21:11:04 +0000 (15:11 -0600)
Orinigally VK_ICD_FILENAMES was documented to only be able to use full paths to
ICD Manifest files. This is untrue, as VK_ICD_FILENAMES, and its replacement
VK_DRIVER_FILES is able to find drivers using full paths as well as paths to
folders containing manifest files. This commit amends the documentation to
reflect that capability as well as adding a test for that use case.

docs/LoaderDriverInterface.md
docs/LoaderInterfaceArchitecture.md
tests/framework/test_environment.cpp
tests/framework/test_environment.h
tests/loader_envvar_tests.cpp

index fd865a324d4df4de7a39f025bd5906c33a86c8cf..da5f5de01d9d9c880ab77d07acb2de39389e2174 100644 (file)
@@ -120,8 +120,9 @@ If both `VK_DRIVER_FILES` and `VK_ICD_FILENAMES` environment variables are
 present, then the newer `VK_DRIVER_FILES` will be used, and the values in
 `VK_ICD_FILENAMES` will be ignored.
 
-The `VK_DRIVER_FILES` environment variable is a list of Driver Manifest
-files, containing the full path to the driver JSON Manifest file.
+The `VK_DRIVER_FILES` environment variable is a list of paths to Driver Manifest
+files, containing the full path to the driver JSON Manifest file, and/or paths
+to folders containing Driver Manifest files.
 This list is colon-separated on Linux and macOS, and semicolon-separated on
 Windows.
 Typically, `VK_DRIVER_FILES` will only contain a full pathname to one info
@@ -135,7 +136,7 @@ Driver in addition to the standard drivers (without replacing the standard
 search paths.
 The `VK_ADD_DRIVER_FILES` environment variable can be used to add a list of
 Driver Manifest files, containing the full path to the driver JSON Manifest
-file.
+file, and/or paths to folders containing Driver Manifest files.
 This list is colon-separated on Linux and macOS, and semicolon-separated on
 Windows.
 It will be added prior to the standard driver search files.
index c676f3f5b98eef5619ed79fc9d6cbdefaf5c77b7..dc9347b990ba3dc3a4ddf8df3aa8e403b2bf178a 100644 (file)
@@ -632,14 +632,15 @@ discovery.
     <td><small>
         Force the loader to use the specific driver JSON files.
         The value contains a list of delimited full path listings to
-        driver JSON Manifest files.<br/>
+        driver JSON Manifest files and/or
+        paths to folders containing driver JSON files.<br/>
         <br/>
         This has replaced the older deprecated environment variable
         <i>VK_ICD_FILENAMES</i>, however the older environment variable will
-        continue to work for some time.
+        continue to work.
     </small></td>
     <td><small>
-        If a global path to the JSON file is not used, issues may be encountered.
+        If a relative path not used, issues may be encountered.
         <br/> <br/>
         <a href="#elevated-privilege-caveats">
             Ignored when running Vulkan application with elevated privileges.
index deec5e46cd542f1f7578c889ce31152062462e49..60acbdc80457433f439237938b31b0ac31539688 100644 (file)
@@ -508,11 +508,19 @@ TestICD& FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
 #endif
                 break;
             case (ManifestDiscoveryType::env_var):
-                env_var_vk_icd_filenames.add_to_list((folder->location() / full_json_name).str());
+                if (icd_details.is_dir) {
+                    env_var_vk_icd_filenames.add_to_list(folder->location().str());
+                } else {
+                    env_var_vk_icd_filenames.add_to_list((folder->location() / full_json_name).str());
+                }
                 platform_shim->add_known_path(folder->location());
                 break;
             case (ManifestDiscoveryType::add_env_var):
-                add_env_var_vk_icd_filenames.add_to_list((folder->location() / full_json_name).str());
+                if (icd_details.is_dir) {
+                    add_env_var_vk_icd_filenames.add_to_list(folder->location().str());
+                } else {
+                    add_env_var_vk_icd_filenames.add_to_list((folder->location() / full_json_name).str());
+                }
                 platform_shim->add_known_path(folder->location());
                 break;
             case (ManifestDiscoveryType::macos_bundle):
index 8535c0b597880c381965839c6eda600d069c7e91..be36c175daa5dcd8d604bc1308fd9c004a221c13 100644 (file)
@@ -536,7 +536,8 @@ struct TestICDDetails {
     BUILDER_VALUE(TestICDDetails, bool, disable_icd_inc, false);
     BUILDER_VALUE(TestICDDetails, ManifestDiscoveryType, discovery_type, ManifestDiscoveryType::generic);
     BUILDER_VALUE(TestICDDetails, bool, is_fake, false);
-    // Dont add any path information to the library_path - force the use of the default search paths
+    // If discovery type is env-var, is_dir controls whether to use the path to the file or folder the manifest is in
+    BUILDER_VALUE(TestICDDetails, bool, is_dir, false);
     BUILDER_VALUE(TestICDDetails, LibraryPathType, library_path_type, LibraryPathType::absolute);
 };
 
@@ -547,7 +548,7 @@ struct TestLayerDetails {
     BUILDER_VALUE(TestLayerDetails, std::string, json_name, "test_layer");
     BUILDER_VALUE(TestLayerDetails, ManifestDiscoveryType, discovery_type, ManifestDiscoveryType::generic);
     BUILDER_VALUE(TestLayerDetails, bool, is_fake, false);
-    // If discovery type is env-var, is_dir controls whether the env-var has the full name to the manifest or just the folder
+    // If discovery type is env-var, is_dir controls whether to use the path to the file or folder the manifest is in
     BUILDER_VALUE(TestLayerDetails, bool, is_dir, true);
     BUILDER_VALUE(TestLayerDetails, LibraryPathType, library_path_type, LibraryPathType::absolute);
 };
index 729ba46b5fafc96661ec1ffb6a65237bcebce206..3bb7515e8bcef8947f65bb32784199344c9dfd52 100644 (file)
@@ -134,6 +134,52 @@ TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVar) {
     env.platform_shim->set_elevated_privilege(false);
 }
 
+// Test VK_DRIVER_FILES environment variable containing a path to a folder
+TEST(EnvVarICDOverrideSetup, TestOnlyDriverEnvVarInFolder) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var).set_is_dir(false));
+    env.get_test_icd(0).add_physical_device("pd0");
+
+    InstWrapper inst1{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log);
+    inst1.CheckCreate();
+    EXPECT_FALSE(
+        env.debug_log.find("Ignoring override VK_ICD_FILENAMES, VK_DRIVER_FILES, and VK_ADD_DRIVER_FILES due to high-integrity"));
+
+    std::array<VkPhysicalDevice, 5> phys_devs_array;
+    uint32_t phys_dev_count = 1;
+    ASSERT_EQ(inst1->vkEnumeratePhysicalDevices(inst1.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
+    ASSERT_EQ(phys_dev_count, 1U);
+
+    for (uint32_t add = 0; add < 2; ++add) {
+        env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_NONE).set_discovery_type(ManifestDiscoveryType::env_var))
+            .add_physical_device("pd" + std::to_string(add) + "0")
+            .add_physical_device("pd" + std::to_string(add) + "1");
+    }
+
+    env.debug_log.clear();
+
+    InstWrapper inst2{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log);
+    inst2.CheckCreate();
+
+    phys_dev_count = 5;
+    ASSERT_EQ(inst2->vkEnumeratePhysicalDevices(inst2.inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
+    ASSERT_EQ(phys_dev_count, 5U);
+
+    env.debug_log.clear();
+
+    env.platform_shim->set_elevated_privilege(true);
+
+    InstWrapper inst3{env.vulkan_functions};
+    FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log);
+    inst3.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
+
+    EXPECT_TRUE(env.debug_log.find("vkCreateInstance: Found no drivers!"));
+
+    env.platform_shim->set_elevated_privilege(false);
+}
+
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__)
 // Make sure the loader reports the correct message based on if LOADER_USE_UNSAFE_FILE_SEARCH is set or not
 TEST(EnvVarICDOverrideSetup, NonSecureEnvVarLookup) {