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
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.
<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.
#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):
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);
};
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);
};
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) {