diff --git a/docs/LoaderApplicationInterface.md b/docs/LoaderApplicationInterface.md index d8454f1fb..c05f2f46b 100644 --- a/docs/LoaderApplicationInterface.md +++ b/docs/LoaderApplicationInterface.md @@ -472,18 +472,23 @@ This can be accomplished in one of two ways: [VkConfig](https://github.com/LunarG/VulkanTools/blob/main/vkconfig/README.md) tool shipped with the Vulkan SDK. 2. Directing the loader to look for layers in specific files and/or folders by using the -`VK_LAYER_PATH` environment variable. +`VK_LAYER_PATH` and/or `VK_IMPLICIT_LAYER_PATH` environment variables. -The `VK_LAYER_PATH` environment variable can contain multiple paths separated by -the operating-system specific path separator. +The `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` environment variables can contain multiple +paths separated by the operating-system specific path separator. On Windows, this is a semicolon (`;`), while on Linux and macOS it is a colon (`:`). If `VK_LAYER_PATH` exists, the files and/or folders listed will be scanned for explicit layer manifest files. Implicit layer discovery is unaffected by this environment variable. -Each directory listed should be the full pathname of a folder containing layer -manifest files. + +If `VK_IMPLICIT_LAYER_PATH` exists, the files and/or folders listed will be scanned for +implicit layer manifest files. +Explicit layer discovery is unaffected by this environment variable. + +Each directory listed in `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` should be the full +pathname of a folder containing layer manifest files. See the [Table of Debug Environment Variables](LoaderInterfaceArchitecture.md#table-of-debug-environment-variables) @@ -493,9 +498,9 @@ for more details. #### Exception for Elevated Privileges -For security reasons, `VK_LAYER_PATH` is ignored if running with elevated -privileges. -Because of this, `VK_LAYER_PATH` can only be used for applications that do not +For security reasons, `VK_LAYER_PATH` and `VK_IMPLICIT_LAYER_PATH` are ignored if running +with elevated privileges. +Because of this, the environment variables can only be used for applications that do not use elevated privileges. For more information see diff --git a/docs/LoaderInterfaceArchitecture.md b/docs/LoaderInterfaceArchitecture.md index b61e3f3cf..724bb33b4 100644 --- a/docs/LoaderInterfaceArchitecture.md +++ b/docs/LoaderInterfaceArchitecture.md @@ -430,6 +430,8 @@ These behaviors also result in ignoring certain environment variables, such as: * `VK_ADD_DRIVER_FILES` * `VK_LAYER_PATH` * `VK_ADD_LAYER_PATH` + * `VK_IMPLICIT_LAYER_PATH` + * `VK_ADD_IMPLICIT_LAYER_PATH` * `XDG_CONFIG_HOME` (Linux/Mac-specific) * `XDG_DATA_HOME` (Linux/Mac-specific) @@ -606,8 +608,8 @@ discovery. Provide a list of additional paths that the loader will use to search - for layers in addition to the loader's standard Layer library search - folder when looking for explicit layer manifest files. + for explicit layers in addition to the loader's standard layer library + search paths when looking for layer manifest files. The paths will be added first, prior to the list of folders that would be searched normally. @@ -624,6 +626,31 @@ discovery.   VK_ADD_LAYER_PATH=
     <path_a>;<path_b> + + + + VK_ADD_IMPLICIT_LAYER_PATH + + + Provide a list of additional paths that the loader will use to search + for implicit layers in addition to the loader's standard layer library + search paths when looking for layer manifest files. + The paths will be added first, prior to the list of folders that would + be searched normally. + + + + Ignored when running Vulkan application with elevated privileges. + + + + export
+   VK_ADD_IMPLICIT_LAYER_PATH=
+      <path_a>:<path_b>

+ set
+   VK_ADD_IMPLICIT_LAYER_PATH=
+      <path_a>;<path_b>
+ @@ -661,8 +688,8 @@ discovery. VK_LAYER_PATH - Override the loader's standard Layer library search folders and use the - provided delimited file and/or folders to locate explicit layer manifest files. + Override the loader's standard explicit layer search paths and use the + provided delimited files and/or folders to locate layer manifest files. @@ -678,6 +705,27 @@ discovery.      <path_a>;<path_b> + + + VK_IMPLICIT_LAYER_PATH + + Override the loader's standard implicit layer search paths and use the + provided delimited files and/or folders to locate layer manifest files. + + + + Ignored when running Vulkan application with elevated privileges. + + + + export
+   VK_IMPLICIT_LAYER_PATH=
+      <path_a>:<path_b>

+ set
+   VK_IMPLICIT_LAYER_PATH=
+      <path_a>;<path_b> +
+ VK_LOADER_DEBUG diff --git a/docs/LoaderLayerInterface.md b/docs/LoaderLayerInterface.md index 08a417550..68d00d847 100644 --- a/docs/LoaderLayerInterface.md +++ b/docs/LoaderLayerInterface.md @@ -256,8 +256,18 @@ of search folders and will therefore be searched first. If `VK_LAYER_PATH` is present, then `VK_ADD_LAYER_PATH` will not be used by the loader and any values will be ignored. -For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored -if running with elevated privileges. +If `VK_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the paths +defined by that variable for implicit layer manifest files instead of using the +information provided by the implicit layer registry keys. + +If `VK_ADD_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the provided +paths for implicit layer manifest files in addition to using the information +provided by the implicit layer registry keys. +The paths provided by `VK_ADD_IMPLICIT_LAYER_PATH` are added before the standard list +of search folders and will therefore be searched first. + +For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`, +and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running with elevated privileges. See [Exception for Elevated Privileges](#exception-for-elevated-privileges) for more info. @@ -353,8 +363,21 @@ of search folders and will therefore be searched first. If `VK_LAYER_PATH` is present, then `VK_ADD_LAYER_PATH` will not be used by the loader and any values will be ignored. -For security reasons, both `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored -if running with elevated privileges. +If `VK_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the paths +defined by that variable for implicit layer manifest files instead of using the +information provided by the standard implicit layer paths mentioned above. + +If `VK_ADD_IMPLICIT_LAYER_PATH` is defined, then the loader will look at the +provided paths for implicit layer manifest files in addition to using the +information provided by the standard implicit layer paths mentioned above. +The paths provided by `VK_ADD_IMPLICIT_LAYER_PATH` are added before the standard +list of search folders and will therefore be searched first. + +If `VK_IMPLICIT_LAYER_PATH` is present, then `VK_ADD_IMPLICIT_LAYER_PATH` will +not be used by the loader and any values will be ignored. + +For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH`, +and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running with elevated privileges. See [Exception for Elevated Privileges](#exception-for-elevated-privileges) for more info. @@ -367,10 +390,10 @@ See in the [LoaderApplicationInterface.md document](LoaderApplicationInterface.md) for more information on this. -It is also important to note that while both `VK_LAYER_PATH` and -`VK_ADD_LAYER_PATH` will point the loader paths to search for finding the -manifest files, it does not guarantee the library files mentioned by the -manifest will immediately be found. +It is also important to note that while `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, +`VK_IMPLICIT_LAYER_PATH`, and `VK_ADD_IMPLICIT_LAYER_PATH` will point the +loader at paths to search for finding the manifest files, it does not guarantee +the library files mentioned by the manifest will immediately be found. Often, the layer manifest file will point to the library file using a relative or absolute path. When a relative or absolute path is used, the loader can typically find the @@ -438,8 +461,8 @@ following: The loader supports filter environment variables which can forcibly enable and disable known layers. Known layers are those that are already found by the loader taking into account -default search paths and other environment variables -(like `VK_LAYER_PATH` or `VK_ADD_LAYER_PATH`). +default search paths and environment variables `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, +`VK_IMPLICIT_LAYER_PATH`, and `VK_ADD_IMPLICIT_LAYER_PATH`. The filter variables will be compared against the layer name provided in the layer's manifest file. @@ -548,8 +571,9 @@ override any disables supplied in `VK_LOADER_LAYERS_DISABLE`. ### Exception for Elevated Privileges -For security reasons, `VK_LAYER_PATH` and `VK_ADD_LAYER_PATH` are ignored if -running the Vulkan application with elevated privileges. +For security reasons, `VK_LAYER_PATH`, `VK_ADD_LAYER_PATH`, `VK_IMPLICIT_LAYER_PATH` +and `VK_ADD_IMPLICIT_LAYER_PATH` are ignored if running the Vulkan application +with elevated privileges. This is because they may insert new libraries into the executable process that are not normally found by the loader. Because of this, these environment variables can only be used for applications @@ -2696,9 +2720,9 @@ Android Vulkan documentation. LLP_LOADER_13 A loader must not load from user-defined paths (including the - use of either VK_LAYER_PATH or VK_ADD_LAYER_PATH - environment variables) when running elevated (Administrator/Super-user) - applications.
+ use of VK_LAYER_PATH, VK_ADD_LAYER_PATH, VK_IMPLICIT_LAYER_PATH, + or VK_ADD_IMPLICIT_LAYER_PATH environment variables) when running + elevated (Administrator/Super-user) applications.
This is for security reasons. The behavior is undefined and may result in computer security lapses, diff --git a/loader/loader.c b/loader/loader.c index 525334c7c..53304e7b2 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -3148,6 +3148,8 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu #endif break; case LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER: + override_env = loader_secure_getenv(VK_IMPLICIT_LAYER_PATH_ENV_VAR, inst); + additional_env = loader_secure_getenv(VK_ADDITIONAL_IMPLICIT_LAYER_PATH_ENV_VAR, inst); #if COMMON_UNIX_PLATFORMS relative_location = VK_ILAYERS_INFO_RELATIVE_DIR; #endif @@ -3156,8 +3158,8 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu #endif break; case LOADER_DATA_FILE_MANIFEST_EXPLICIT_LAYER: - override_env = loader_secure_getenv(VK_LAYER_PATH_ENV_VAR, inst); - additional_env = loader_secure_getenv(VK_ADDITIONAL_LAYER_PATH_ENV_VAR, inst); + override_env = loader_secure_getenv(VK_EXPLICIT_LAYER_PATH_ENV_VAR, inst); + additional_env = loader_secure_getenv(VK_ADDITIONAL_EXPLICIT_LAYER_PATH_ENV_VAR, inst); #if COMMON_UNIX_PLATFORMS relative_location = VK_ELAYERS_INFO_RELATIVE_DIR; #endif diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h index a70ba71a8..367d0522d 100644 --- a/loader/vk_loader_platform.h +++ b/loader/vk_loader_platform.h @@ -100,10 +100,10 @@ // Environment Variable information #define VK_ICD_FILENAMES_ENV_VAR "VK_ICD_FILENAMES" // Deprecated in v1.3.207 loader #define VK_DRIVER_FILES_ENV_VAR "VK_DRIVER_FILES" -#define VK_LAYER_PATH_ENV_VAR "VK_LAYER_PATH" +#define VK_EXPLICIT_LAYER_PATH_ENV_VAR "VK_LAYER_PATH" // Support added in v1.3.207 loader #define VK_ADDITIONAL_DRIVER_FILES_ENV_VAR "VK_ADD_DRIVER_FILES" -#define VK_ADDITIONAL_LAYER_PATH_ENV_VAR "VK_ADD_LAYER_PATH" +#define VK_ADDITIONAL_EXPLICIT_LAYER_PATH_ENV_VAR "VK_ADD_LAYER_PATH" // Support added in v1.3.234 loader #define VK_LAYERS_ENABLE_ENV_VAR "VK_LOADER_LAYERS_ENABLE" #define VK_LAYERS_DISABLE_ENV_VAR "VK_LOADER_LAYERS_DISABLE" @@ -115,6 +115,9 @@ #define VK_LOADER_DISABLE_ALL_LAYERS_VAR_3 "**" #define VK_LOADER_DISABLE_IMPLICIT_LAYERS_VAR "~implicit~" #define VK_LOADER_DISABLE_EXPLICIT_LAYERS_VAR "~explicit~" +// Support added in v1.3.295 loader +#define VK_IMPLICIT_LAYER_PATH_ENV_VAR "VK_IMPLICIT_LAYER_PATH" +#define VK_ADDITIONAL_IMPLICIT_LAYER_PATH_ENV_VAR "VK_ADD_IMPLICIT_LAYER_PATH" // Override layer information #define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override" diff --git a/tests/framework/shim/shim_common.cpp b/tests/framework/shim/shim_common.cpp index df5c55273..c35f1c896 100644 --- a/tests/framework/shim/shim_common.cpp +++ b/tests/framework/shim/shim_common.cpp @@ -219,6 +219,9 @@ void PlatformShim::redirect_category(std::filesystem::path const& new_path, Mani if (category == ManifestCategory::explicit_layer) { parse_and_add_env_var_override(paths, get_env_var("VK_LAYER_PATH", false)); // don't report failure } + if (category == ManifestCategory::implicit_layer) { + parse_and_add_env_var_override(paths, get_env_var("VK_IMPLICIT_LAYER_PATH", false)); // don't report failure + } parse_and_add_env_var_override(paths, FALLBACK_DATA_DIRS); parse_and_add_env_var_override(paths, FALLBACK_CONFIG_DIRS); diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index ddd989fc6..1f8a02a23 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -400,6 +400,8 @@ FrameworkEnvironment::FrameworkEnvironment(FrameworkSettings const& settings) no folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_env_var_layer_folder")); folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_add_env_var_layer_folder")); folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_layer_manifests")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_env_var_layer_manifests")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_add_env_var_layer_manifests")); folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("override_layer_manifests")); folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("app_package_manifests")); folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("macos_bundle")); @@ -579,20 +581,40 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife if (category == ManifestCategory::implicit_layer) fs_ptr = &get_folder(ManifestLocation::implicit_layer); break; case (ManifestDiscoveryType::env_var): - fs_ptr = &get_folder(ManifestLocation::explicit_layer_env_var); - if (layer_details.is_dir) { - env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location())); - } else { - env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name)); + if (category == ManifestCategory::explicit_layer) { + fs_ptr = &get_folder(ManifestLocation::explicit_layer_env_var); + if (layer_details.is_dir) { + env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location())); + } else { + env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name)); + } + } + if (category == ManifestCategory::implicit_layer) { + fs_ptr = &get_folder(ManifestLocation::implicit_layer_env_var); + if (layer_details.is_dir) { + env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location())); + } else { + env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name)); + } } platform_shim->add_known_path(fs_ptr->location()); break; case (ManifestDiscoveryType::add_env_var): - fs_ptr = &get_folder(ManifestLocation::explicit_layer_add_env_var); - if (layer_details.is_dir) { - add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location())); - } else { - add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name)); + if (category == ManifestCategory::explicit_layer) { + fs_ptr = &get_folder(ManifestLocation::explicit_layer_add_env_var); + if (layer_details.is_dir) { + add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location())); + } else { + add_env_var_vk_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name)); + } + } + if (category == ManifestCategory::implicit_layer) { + fs_ptr = &get_folder(ManifestLocation::implicit_layer_add_env_var); + if (layer_details.is_dir) { + add_env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location())); + } else { + add_env_var_vk_implicit_layer_paths.add_to_list(narrow(fs_ptr->location() / layer_details.json_name)); + } } platform_shim->add_known_path(fs_ptr->location()); break; diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index 3167f03c8..ff0f30059 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -621,11 +621,13 @@ enum class ManifestLocation { explicit_layer_env_var = 4, explicit_layer_add_env_var = 5, implicit_layer = 6, - override_layer = 7, - windows_app_package = 8, - macos_bundle = 9, - unsecured_location = 10, - settings_location = 11, + implicit_layer_env_var = 7, + implicit_layer_add_env_var = 8, + override_layer = 9, + windows_app_package = 10, + macos_bundle = 11, + unsecured_location = 12, + settings_location = 13, }; struct FrameworkSettings { @@ -697,6 +699,8 @@ struct FrameworkEnvironment { EnvVarWrapper add_env_var_vk_icd_filenames{"VK_ADD_DRIVER_FILES"}; EnvVarWrapper env_var_vk_layer_paths{"VK_LAYER_PATH"}; EnvVarWrapper add_env_var_vk_layer_paths{"VK_ADD_LAYER_PATH"}; + EnvVarWrapper env_var_vk_implicit_layer_paths{"VK_IMPLICIT_LAYER_PATH"}; + EnvVarWrapper add_env_var_vk_implicit_layer_paths{"VK_ADD_IMPLICIT_LAYER_PATH"}; LoaderSettings loader_settings; // the current settings written to disk private: diff --git a/tests/loader_envvar_tests.cpp b/tests/loader_envvar_tests.cpp index 30824f5f9..c94c2ecdd 100644 --- a/tests/loader_envvar_tests.cpp +++ b/tests/loader_envvar_tests.cpp @@ -239,7 +239,7 @@ TEST(EnvVarICDOverrideSetup, XDGContainsJsonFile) { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); } #endif @@ -382,6 +382,107 @@ TEST(EnvVarICDOverrideSetup, TestOnlyAddLayerEnvVar) { env.platform_shim->set_elevated_privilege(false); } +// Test VK_IMPLICIT_LAYER_PATH environment variable +TEST(EnvVarICDOverrideSetup, TestOnlyImplicitLayerEnvVar) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0"); + env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::implicit_layer_env_var).location()); + + const char* layer_name = "TestLayer"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(layer_name) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("DISABLE_ENV")), + "test_layer.json") + .set_discovery_type(ManifestDiscoveryType::env_var)); + + // Now set up a layer path that includes default and user-specified locations, + // so that the test app can find them. Include some badly specified elements as well. + // Need to redirect the 'home' directory + std::filesystem::path HOME = "/home/fake_home"; + EnvVarWrapper home_env_var{"HOME", HOME}; + std::string vk_implicit_layer_path = ":/tmp/carol::::/:"; + vk_implicit_layer_path += (HOME / "/ with spaces/:::::/tandy:"); + EnvVarWrapper implicit_layer_path_env_var{"VK_IMPLICIT_LAYER_PATH", vk_implicit_layer_path}; + InstWrapper inst1{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); + inst1.CheckCreate(); + + auto active_layers1 = inst1.GetActiveLayers(inst1.GetPhysDev(), 1); + ASSERT_TRUE(string_eq(active_layers1.at(0).layerName, layer_name)); + + // look for VK_IMPLICIT_LAYER_PATHS + EXPECT_TRUE(env.debug_log.find("/tmp/carol")); + EXPECT_TRUE(env.debug_log.find("/tandy")); + EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/"))); + + env.debug_log.clear(); + + env.platform_shim->set_elevated_privilege(true); + + InstWrapper inst2{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); + inst2.CheckCreate(); + + auto active_layers2 = inst2.GetActiveLayers(inst2.GetPhysDev(), 0); + ASSERT_TRUE(active_layers2.empty()); + + EXPECT_FALSE(env.debug_log.find("/tmp/carol")); + + env.platform_shim->set_elevated_privilege(false); +} + +// Test VK_ADD_IMPLICIT_LAYER_PATH environment variable +TEST(EnvVarICDOverrideSetup, TestOnlyAddImplicitLayerEnvVar) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0"); + env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::implicit_layer_add_env_var).location()); + + const char* layer_name = "TestLayer"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(layer_name) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("DISABLE_ENV")), + "test_layer.json") + .set_discovery_type(ManifestDiscoveryType::add_env_var)); + + // Set up a layer path that includes default and user-specified locations, + // so that the test app can find them. Include some badly specified elements as well. + // Need to redirect the 'home' directory + std::filesystem::path HOME = "/home/fake_home"; + EnvVarWrapper home_env_var{"HOME", HOME}; + std::string vk_add_implicit_layer_path = ":/tmp/carol::::/:"; + vk_add_implicit_layer_path += (HOME / "/ with spaces/:::::/tandy:"); + EnvVarWrapper add_implicit_layer_path_env_var{"VK_ADD_LAYER_PATH", vk_add_implicit_layer_path}; + + InstWrapper inst1{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); + inst1.CheckCreate(); + + auto active_layers1 = inst1.GetActiveLayers(inst1.GetPhysDev(), 1); + ASSERT_TRUE(string_eq(active_layers1.at(0).layerName, layer_name)); + + // look for VK_ADD_IMPLICIT_LAYER_PATHS + EXPECT_TRUE(env.debug_log.find("/tmp/carol")); + EXPECT_TRUE(env.debug_log.find("/tandy")); + EXPECT_TRUE(env.debug_log.find((HOME / "/ with spaces/"))); + + env.debug_log.clear(); + + env.platform_shim->set_elevated_privilege(true); + + InstWrapper inst2{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); + inst2.CheckCreate(); + + auto active_layers2 = inst2.GetActiveLayers(inst2.GetPhysDev(), 0); + ASSERT_TRUE(active_layers2.empty()); + + EXPECT_FALSE(env.debug_log.find("/tmp/carol")); + + env.platform_shim->set_elevated_privilege(false); +} + #endif // Test that the driver filter select will only enable driver manifest files that match the filter diff --git a/tests/loader_layer_tests.cpp b/tests/loader_layer_tests.cpp index e06d88ec7..f2cc7bd8a 100644 --- a/tests/loader_layer_tests.cpp +++ b/tests/loader_layer_tests.cpp @@ -31,7 +31,7 @@ void CheckLogForLayerString(FrameworkEnvironment& env, const char* implicit_laye { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); if (check_for_enable) { ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name)); } else { @@ -119,7 +119,7 @@ TEST(ImplicitLayers, OnlyDisableEnvVar) { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.add_layer(implicit_layer_name); - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name)); } } @@ -962,7 +962,6 @@ TEST(ImplicitLayers, DuplicateLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* same_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) @@ -1009,6 +1008,177 @@ TEST(ImplicitLayers, DuplicateLayers) { ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } +TEST(ImplicitLayers, VkImplicitLayerPathEnvVar) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + + // verify layer loads successfully when setting VK_IMPLICIT_LAYER_PATH to a full filepath + const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(regular_layer_name_1) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Yikes")), + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_is_dir(false)); + + InstWrapper inst(env.vulkan_functions); + inst.CheckCreate(); + auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); + EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name_1)); +} + +TEST(ImplicitLayers, VkImplicitLayerPathEnvVarContainsMultipleFilePaths) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + + // verify layers load successfully when setting VK_IMPLICIT_LAYER_PATH to multiple full filepaths + const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(regular_layer_name_1) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Yikes")), + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_is_dir(false)); + + const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(regular_layer_name_2) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Yikes")), + "regular_layer_2.json") + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_is_dir(false)); + + InstWrapper inst(env.vulkan_functions); + inst.CheckCreate(); + auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); + EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); +} + +TEST(ImplicitLayers, VkImplicitLayerPathEnvVarIsDirectory) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + + // verify layers load successfully when setting VK_IMPLICIT_LAYER_PATH to a directory + const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(regular_layer_name_1) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Yikes")), + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::env_var)); + + const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(regular_layer_name_2) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Yikes")), + "regular_layer_2.json") + .set_discovery_type(ManifestDiscoveryType::env_var)); + + InstWrapper inst(env.vulkan_functions); + inst.CheckCreate(); + auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); + EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); +} + +// Test to make sure order layers are found in VK_IMPLICIT_LAYER_PATH is what decides which layer is loaded +TEST(ImplicitLayers, DuplicateLayersInVkImplicitLayerPath) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + + const char* layer_name = "VK_LAYER_RegularLayer1"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(layer_name) + .set_description("actually_layer_1") + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Boo!")), + "layer.json") + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_is_dir(true)); + auto& layer1 = env.get_test_layer(0); + layer1.set_description("actually_layer_1"); + + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(layer_name) + .set_description("actually_layer_2") + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Ah!")), + "layer.json") + // putting it in a separate folder then manually adding the folder to VK_IMPLICIT_LAYER_PATH + .set_discovery_type(ManifestDiscoveryType::override_folder) + .set_is_dir(true)); + auto& layer2 = env.get_test_layer(1); + layer2.set_description("actually_layer_2"); + env.env_var_vk_implicit_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location().string()); + + auto layer_props = env.GetLayerProperties(2); + ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName)); + ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); + ASSERT_TRUE(string_eq(layer_name, layer_props[1].layerName)); + ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); + + EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"}; + inst_layers_env_var.add_to_list(layer_name); + + InstWrapper inst{env.vulkan_functions}; + inst.CheckCreate(); + + // Expect the first layer added to be found + auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); + ASSERT_TRUE(string_eq(layer_name, enabled_layer_props[0].layerName)); + ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[0].description)); +} + +TEST(ImplicitLayers, DuplicateLayersInVK_ADD_IMPLICIT_LAYER_PATH) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + + const char* same_layer_name_1 = "VK_LAYER_RegularLayer1"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(same_layer_name_1) + .set_description("actually_layer_1") + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Red")), + "regular_layer_1.json") + // use override folder as just a folder and manually set the VK_ADD_IMPLICIT_LAYER_PATH env-var to it + .set_discovery_type(ManifestDiscoveryType::override_folder) + .set_is_dir(true)); + auto& layer1 = env.get_test_layer(0); + layer1.set_description("actually_layer_1"); + layer1.set_make_spurious_log_in_create_instance("actually_layer_1"); + env.add_env_var_vk_implicit_layer_paths.add_to_list(narrow(env.get_folder(ManifestLocation::override_layer).location())); + + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(same_layer_name_1) + .set_description("actually_layer_2") + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Blue")), + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::add_env_var) + .set_is_dir(true)); + auto& layer2 = env.get_test_layer(1); + layer2.set_description("actually_layer_2"); + layer2.set_make_spurious_log_in_create_instance("actually_layer_2"); + + auto layer_props = env.GetLayerProperties(2); + ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName)); + ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName)); + ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); + ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); + + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.CheckCreate(); + auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); + ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); + ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); + ASSERT_TRUE(env.debug_log.find("actually_layer_1")); + ASSERT_FALSE(env.debug_log.find("actually_layer_2")); +} + // Meta layer which contains component layers that do not exist. TEST(MetaLayers, InvalidComponentLayer) { FrameworkEnvironment env; @@ -1078,13 +1248,13 @@ TEST(MetaLayers, ExplicitMetaLayer) { } { // don't enable the layer, shouldn't find any layers when calling vkEnumerateDeviceLayerProperties InstWrapper inst{env.vulkan_functions}; - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(meta_layer_name); - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name}, layer_props)); } @@ -2112,7 +2282,6 @@ TEST(ExplicitLayers, MultipleLayersInSingleManifest) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; const char* regular_layer_name_3 = "VK_LAYER_RegularLayer3"; @@ -2196,70 +2365,81 @@ TEST(ExplicitLayers, VkLayerPathEnvVar) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - { - // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath - const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; - env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} - .set_name(regular_layer_name_1) - .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), - "regular_layer_1.json") - .set_discovery_type(ManifestDiscoveryType::env_var) - .set_is_dir(false)); - - InstWrapper inst(env.vulkan_functions); - inst.create_info.add_layer(regular_layer_name_1); - inst.CheckCreate(VK_SUCCESS); - auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); - EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name_1)); - } - { - // verify layers load successfully when setting VK_LAYER_PATH to multiple full filepaths - const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; - env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} - .set_name(regular_layer_name_1) - .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), - "regular_layer_1.json") - .set_discovery_type(ManifestDiscoveryType::env_var) - .set_is_dir(false)); - - const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; - env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} - .set_name(regular_layer_name_2) - .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), - "regular_layer_2.json") - .set_discovery_type(ManifestDiscoveryType::env_var) - .set_is_dir(false)); - - InstWrapper inst(env.vulkan_functions); - inst.create_info.add_layer(regular_layer_name_1); - inst.create_info.add_layer(regular_layer_name_2); - inst.CheckCreate(VK_SUCCESS); - auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); - EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); - } - { - // verify layers load successfully when setting VK_LAYER_PATH to a directory - const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; - env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} - .set_name(regular_layer_name_1) - .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), - "regular_layer_1.json") - .set_discovery_type(ManifestDiscoveryType::env_var)); - - const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; - env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} - .set_name(regular_layer_name_2) - .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), - "regular_layer_2.json") - .set_discovery_type(ManifestDiscoveryType::env_var)); - - InstWrapper inst(env.vulkan_functions); - inst.create_info.add_layer(regular_layer_name_1); - inst.create_info.add_layer(regular_layer_name_2); - inst.CheckCreate(VK_SUCCESS); - auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); - EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); - } + // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath + const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; + env.add_explicit_layer( + TestLayerDetails( + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_is_dir(false)); + + InstWrapper inst(env.vulkan_functions); + inst.create_info.add_layer(regular_layer_name_1); + inst.CheckCreate(); + auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); + EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name_1)); +} + +TEST(ExplicitLayers, VkLayerPathEnvVarContainsMultipleFilepaths) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + + // verify layers load successfully when setting VK_LAYER_PATH to multiple full filepaths + const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; + env.add_explicit_layer( + TestLayerDetails( + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_is_dir(false)); + + const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; + env.add_explicit_layer( + TestLayerDetails( + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "regular_layer_2.json") + .set_discovery_type(ManifestDiscoveryType::env_var) + .set_is_dir(false)); + + InstWrapper inst(env.vulkan_functions); + inst.create_info.add_layer(regular_layer_name_1); + inst.create_info.add_layer(regular_layer_name_2); + inst.CheckCreate(); + auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); + EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); +} + +TEST(ExplicitLayers, VkLayerPathEnvVarIsDirectory) { + FrameworkEnvironment env; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); + + // verify layers load successfully when setting VK_LAYER_PATH to a directory + const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; + env.add_explicit_layer( + TestLayerDetails( + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "regular_layer_1.json") + .set_discovery_type(ManifestDiscoveryType::env_var)); + + const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; + env.add_explicit_layer( + TestLayerDetails( + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "regular_layer_2.json") + .set_discovery_type(ManifestDiscoveryType::env_var)); + + InstWrapper inst(env.vulkan_functions); + inst.create_info.add_layer(regular_layer_name_1); + inst.create_info.add_layer(regular_layer_name_2); + inst.CheckCreate(); + auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); + EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); } TEST(ExplicitLayers, DuplicateLayersInVK_LAYER_PATH) { @@ -2341,7 +2521,6 @@ TEST(ExplicitLayers, DuplicateLayersInVK_ADD_LAYER_PATH) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* same_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) @@ -2416,7 +2595,6 @@ TEST(ExplicitLayers, CorrectOrderOfEnvVarEnabledLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_1) @@ -2527,7 +2705,6 @@ TEST(ExplicitLayers, CorrectOrderOfEnvVarEnabledLayersFromSystemLocations) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_1) @@ -2587,7 +2764,6 @@ TEST(ExplicitLayers, CorrectOrderOfApplicationEnabledLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); - // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_1) diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp index 366936fa5..a54b10cd1 100644 --- a/tests/loader_regression_tests.cpp +++ b/tests/loader_regression_tests.cpp @@ -394,7 +394,7 @@ TEST(EnumerateDeviceExtensionProperties, ZeroPhysicalDeviceExtensions) { InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)); - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); auto phys_dev = inst.GetPhysDev(); DeviceWrapper dev{inst}; @@ -810,7 +810,7 @@ TEST(EnumeratePhysicalDevices, ZeroPhysicalDevices) { env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)); - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); uint32_t count = 0; ASSERT_EQ(VK_ERROR_INITIALIZATION_FAILED, env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &count, nullptr)); @@ -1460,7 +1460,7 @@ TEST(TryLoadWrongBinaries, WrongImplicit) { // We don't want to return VK_ERROR_LAYER_NOT_PRESENT for missing implicit layers because it's not the // application asking for them. - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); #if !defined(__APPLE__) // Should get an info message for the bad implicit layer @@ -1593,7 +1593,7 @@ TEST(TryLoadWrongBinaries, BadImplicit) { // We don't want to return VK_ERROR_LAYER_NOT_PRESENT for missing implicit layers because it's not the // application asking for them. - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); // Should get an info message for the bad implicit ASSERT_TRUE(log.find(std::string("Requested layer \"") + std::string(layer_name) + std::string("\" failed to load."))); diff --git a/tests/loader_settings_tests.cpp b/tests/loader_settings_tests.cpp index 4bb60cdde..8d4a7481c 100644 --- a/tests/loader_settings_tests.cpp +++ b/tests/loader_settings_tests.cpp @@ -1086,6 +1086,185 @@ TEST(SettingsFile, EnvVarsWork_VK_ADD_LAYER_PATH) { } } +TEST(SettingsFile, EnvVarsWork_VK_IMPLICIT_LAYER_PATH) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); + + const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1"; + env.add_explicit_layer(TestLayerDetails{ + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "explicit_test_layer1.json"} + .set_discovery_type(ManifestDiscoveryType::env_var)); + + const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1"; + env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(implicit_layer_name1) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Domierigato")), + "implicit_layer1.json"); + const char* settings_layer_path = "VK_LAYER_Regular_TestLayer2"; + env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(settings_layer_path) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Domierigato")), + "implicit_test_layer2.json"}); + + { + auto layer_props = env.GetLayerProperties(3); + ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layer_props.at(1).layerName, settings_layer_path)); + ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1)); + + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.CheckCreate(); + ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); + ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_path)); + } + { + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.create_info.add_layer(explicit_layer_name1); + inst.CheckCreate(); + ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3); + ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_path)); + ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1)); + } + env.update_loader_settings(env.loader_settings.add_app_specific_setting( + AppSpecificSettings{} + .add_stderr_log_filter("all") + .add_layer_configuration(LoaderSettingsLayerConfiguration{} + .set_name(settings_layer_path) + .set_control("on") + .set_path(env.get_shimmed_layer_manifest_path(2)) + .set_treat_as_implicit_manifest(true)) + .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location")))); + { + auto layer_props = env.GetLayerProperties(3); + ASSERT_TRUE(string_eq(layer_props.at(0).layerName, settings_layer_path)); + ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1)); + + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.CheckCreate(); + ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); + ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_layer_path)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1)); + } + { + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.create_info.add_layer(explicit_layer_name1); + inst.CheckCreate(); + ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3); + ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_layer_path)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1)); + } +} + +TEST(SettingsFile, EnvVarsWork_VK_ADD_IMPLICIT_LAYER_PATH) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); + + const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1"; + env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(implicit_layer_name1) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("Domierigato")), + "implicit_layer1.json"); + const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1"; + env.add_explicit_layer(TestLayerDetails{ + ManifestLayer{}.add_layer( + ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), + "explicit_test_layer1.json"} + .set_discovery_type(ManifestDiscoveryType::add_env_var)); + const char* settings_layer_name = "VK_LAYER_Regular_TestLayer2"; + env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(settings_layer_name) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("gozaimasu")), + "implicit_test_layer2.json"}); + + { + auto layer_props = env.GetLayerProperties(3); + ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layer_props.at(1).layerName, settings_layer_name)); + ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1)); + + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.CheckCreate(); + ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); + ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name)); + } + { + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.create_info.add_layer(explicit_layer_name1); + inst.CheckCreate(); + ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3); + ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name)); + ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1)); + } + + env.update_loader_settings(env.loader_settings.add_app_specific_setting( + AppSpecificSettings{} + .add_stderr_log_filter("all") + .add_layer_configuration(LoaderSettingsLayerConfiguration{} + .set_name(explicit_layer_name1) + .set_control("on") + .set_path(env.get_shimmed_layer_manifest_path(1))) + .add_layer_configuration(LoaderSettingsLayerConfiguration{} + .set_name(settings_layer_name) + .set_control("on") + .set_path(env.get_shimmed_layer_manifest_path(2)) + .set_treat_as_implicit_manifest(true)) + .add_layer_configuration(LoaderSettingsLayerConfiguration{} + .set_name(implicit_layer_name1) + .set_control("on") + .set_path(env.get_shimmed_layer_manifest_path(0)) + .set_treat_as_implicit_manifest(true)))); + { + auto layer_props = env.GetLayerProperties(3); + ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1)); + ASSERT_TRUE(string_eq(layer_props.at(1).layerName, settings_layer_name)); + ASSERT_TRUE(string_eq(layer_props.at(2).layerName, implicit_layer_name1)); + + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.CheckCreate(); + ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3); + ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name)); + ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1)); + } + { + InstWrapper inst{env.vulkan_functions}; + FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); + inst.create_info.add_layer(explicit_layer_name1); + inst.CheckCreate(); + ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env))); + auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3); + ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1)); + ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name)); + ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1)); + } +} + TEST(SettingsFile, EnvVarsWork_VK_INSTANCE_LAYERS) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); @@ -1386,7 +1565,7 @@ TEST(SettingsFile, ImplicitLayerDisableEnvironmentVariableOverriden) { { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); - inst.CheckCreate(VK_SUCCESS); + inst.CheckCreate(); if (check_for_enable) { ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name)); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); diff --git a/tests/loader_testing_main.cpp b/tests/loader_testing_main.cpp index f6e3d71b3..20af4f54c 100644 --- a/tests/loader_testing_main.cpp +++ b/tests/loader_testing_main.cpp @@ -73,6 +73,8 @@ int main(int argc, char** argv) { EnvVarWrapper vk_add_driver_files_env_var{"VK_ADD_DRIVER_FILES"}; EnvVarWrapper vk_layer_path_env_var{"VK_LAYER_PATH"}; EnvVarWrapper vk_add_layer_path_env_var{"VK_ADD_LAYER_PATH"}; + EnvVarWrapper vk_implicit_layer_path_env_var{"VK_IMPLICIT_LAYER_PATH"}; + EnvVarWrapper vk_add_implicit_layer_path_env_var{"VK_ADD_IMPLICIT_LAYER_PATH"}; EnvVarWrapper vk_instance_layers_env_var{"VK_INSTANCE_LAYERS"}; EnvVarWrapper vk_loader_drivers_select_env_var{"VK_LOADER_DRIVERS_SELECT"}; EnvVarWrapper vk_loader_drivers_disable_env_var{"VK_LOADER_DRIVERS_DISABLE"};