• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 The Khronos Group Inc.
3  * Copyright (c) 2023 Valve Corporation
4  * Copyright (c) 2023 LunarG, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and/or associated documentation files (the "Materials"), to
8  * deal in the Materials without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Materials, and to permit persons to whom the Materials are
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice(s) and this permission notice shall be included in
14  * all copies or substantial portions of the Materials.
15  *
16  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  *
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23  * USE OR OTHER DEALINGS IN THE MATERIALS.
24  *
25  * Author: Charles Giessen <charles@lunarg.com>
26  */
27 
28 #include "test_environment.h"
29 
30 #include <fstream>
31 
get_settings_location_log_message(FrameworkEnvironment const & env,bool use_secure=false)32 std::string get_settings_location_log_message([[maybe_unused]] FrameworkEnvironment const& env,
33                                               [[maybe_unused]] bool use_secure = false) {
34     std::string s = "Using layer configurations found in loader settings from ";
35 #if defined(WIN32)
36     return s + (env.get_folder(ManifestLocation::settings_location).location() / "vk_loader_settings.json").string();
37 #elif COMMON_UNIX_PLATFORMS
38     if (use_secure)
39         return s + "/etc/vulkan/loader_settings.d/vk_loader_settings.json";
40     else
41         return s + "/home/fake_home/.local/share/vulkan/loader_settings.d/vk_loader_settings.json";
42 #endif
43 }
44 enum class LayerType {
45     exp,
46     imp,
47     imp_with_enable_env,
48 };
add_layer_and_settings(FrameworkEnvironment & env,const char * layer_name,LayerType layer_type,const char * control)49 const char* add_layer_and_settings(FrameworkEnvironment& env, const char* layer_name, LayerType layer_type, const char* control) {
50     if (layer_type == LayerType::imp) {
51         env.add_implicit_layer(
52             ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
53                                           .set_name(layer_name)
54                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
55                                           .set_disable_environment("BADGER" + std::to_string(env.layers.size()))),
56             std::string(layer_name) + std::to_string(env.layers.size()) + ".json");
57     } else if (layer_type == LayerType::imp_with_enable_env) {
58         env.add_implicit_layer(
59             ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
60                                           .set_name(layer_name)
61                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
62                                           .set_disable_environment("BADGER" + std::to_string(env.layers.size()))
63                                           .set_enable_environment("MUSHROOM" + std::to_string(env.layers.size()))),
64             std::string(layer_name) + std::to_string(env.layers.size()) + ".json");
65     } else if (layer_type == LayerType::exp) {
66         env.add_explicit_layer(TestLayerDetails{
67             ManifestLayer{}.add_layer(
68                 ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
69             std::string(layer_name) + std::to_string(env.layers.size()) + ".json"});
70     } else {
71         abort();
72     }
73     env.loader_settings.app_specific_settings.back().add_layer_configuration(
74         LoaderSettingsLayerConfiguration{}
75             .set_name(layer_name)
76             .set_control(control)
77             .set_treat_as_implicit_manifest(layer_type != LayerType::exp)
78             .set_path(env.get_shimmed_layer_manifest_path(env.layers.size() - 1)));
79     return layer_name;
80 }
81 
82 // Make sure settings layer is found and that a layer defined in it is loaded
TEST(SettingsFile,FileExist)83 TEST(SettingsFile, FileExist) {
84     FrameworkEnvironment env{};
85     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
86     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
87     const char* regular_layer_name = add_layer_and_settings(env, "VK_LAYER_TestLayer_0", LayerType::exp, "on");
88     env.update_loader_settings(env.loader_settings);
89     {
90         auto layer_props = env.GetLayerProperties(1);
91         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
92 
93         InstWrapper inst{env.vulkan_functions};
94         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
95         inst.CheckCreate();
96 
97         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
98         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
99         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, regular_layer_name));
100     }
101 }
102 
103 // Make sure that if the settings file is in a user local path, that it isn't used when running with elevated privileges
TEST(SettingsFile,SettingsInUnsecuredLocation)104 TEST(SettingsFile, SettingsInUnsecuredLocation) {
105     FrameworkEnvironment env{};
106     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
107     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
108     env.add_explicit_layer(TestLayerDetails{
109         ManifestLayer{}.add_layer(
110             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
111         "regular_test_layer.json"}
112                                .set_discovery_type(ManifestDiscoveryType::override_folder));
113     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
114         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
115                                                                                        .set_name(regular_layer_name)
116                                                                                        .set_path(env.get_layer_manifest_path())
117                                                                                        .set_control("on"))));
118     {
119         auto layer_props = env.GetLayerProperties(1);
120         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
121 
122         InstWrapper inst{env.vulkan_functions};
123         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
124         inst.CheckCreate();
125 
126         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
127         env.debug_log.clear();
128         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
129         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
130     }
131     env.platform_shim->set_elevated_privilege(true);
132     {
133         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
134 
135         InstWrapper inst{env.vulkan_functions};
136         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
137         inst.CheckCreate();
138 
139         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
140         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
141     }
142 }
143 
TEST(SettingsFile,SettingsInSecuredLocation)144 TEST(SettingsFile, SettingsInSecuredLocation) {
145     FrameworkEnvironment env{FrameworkSettings{}.set_secure_loader_settings(true)};
146     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
147     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
148     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
149     env.add_explicit_layer(TestLayerDetails{
150         ManifestLayer{}.add_layer(
151             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
152         "regular_test_layer.json"}
153                                .set_discovery_type(ManifestDiscoveryType::override_folder));
154     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
155         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
156                                                                                        .set_name(regular_layer_name)
157                                                                                        .set_path(env.get_layer_manifest_path())
158                                                                                        .set_control("on"))));
159     {
160         auto layer_props = env.GetLayerProperties(1);
161         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
162 
163         InstWrapper inst{env.vulkan_functions};
164         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
165         inst.CheckCreate();
166 
167         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env, true)));
168         env.debug_log.clear();
169         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
170         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
171     }
172     env.platform_shim->set_elevated_privilege(true);
173     {
174         auto layer_props = env.GetLayerProperties(1);
175         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
176 
177         InstWrapper inst{env.vulkan_functions};
178         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
179         inst.CheckCreate();
180 
181         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env, true)));
182         env.debug_log.clear();
183         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
184         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
185     }
186 }
187 
188 // Make sure settings file can have multiple sets of settings
TEST(SettingsFile,SupportsMultipleSettingsSimultaneously)189 TEST(SettingsFile, SupportsMultipleSettingsSimultaneously) {
190     FrameworkEnvironment env{};
191     const char* app_specific_layer_name = "VK_LAYER_TestLayer_0";
192     env.add_explicit_layer(TestLayerDetails{
193         ManifestLayer{}.add_layer(
194             ManifestLayer::LayerDescription{}.set_name(app_specific_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
195         "VK_LAYER_app_specific.json"}
196                                .set_discovery_type(ManifestDiscoveryType::override_folder));
197     const char* global_layer_name = "VK_LAYER_TestLayer_1";
198     env.add_explicit_layer(TestLayerDetails{
199         ManifestLayer{}.add_layer(
200             ManifestLayer::LayerDescription{}.set_name(global_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
201         "VK_LAYER_global.json"}
202                                .set_discovery_type(ManifestDiscoveryType::override_folder));
203     env.update_loader_settings(
204         env.loader_settings
205             // configuration that matches the current executable path - but dont set the app-key just yet
206             .add_app_specific_setting(AppSpecificSettings{}
207                                           .add_stderr_log_filter("all")
208                                           .add_layer_configuration(LoaderSettingsLayerConfiguration{}
209                                                                        .set_name(app_specific_layer_name)
210                                                                        .set_path(env.get_layer_manifest_path(0))
211                                                                        .set_control("on"))
212                                           .add_app_key("key0"))
213             // configuration that should never be used
214             .add_app_specific_setting(
215                 AppSpecificSettings{}
216                     .add_stderr_log_filter("all")
217                     .add_layer_configuration(
218                         LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_haha").set_path("/made/up/path").set_control("auto"))
219                     .add_layer_configuration(LoaderSettingsLayerConfiguration{}
220                                                  .set_name("VK_LAYER_haha2")
221                                                  .set_path("/made/up/path2")
222                                                  .set_control("auto"))
223                     .add_app_key("key1")
224                     .add_app_key("key2"))
225             // Add a global configuration
226             .add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
227                 LoaderSettingsLayerConfiguration{}
228                     .set_name(global_layer_name)
229                     .set_path(env.get_layer_manifest_path(1))
230                     .set_control("on"))));
231     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
232     {
233         auto layer_props = env.GetLayerProperties(1);
234         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, global_layer_name));
235 
236         // Check that the global config is used
237         InstWrapper inst{env.vulkan_functions};
238         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
239         inst.CheckCreate();
240         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
241         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
242         ASSERT_TRUE(string_eq(layers.at(0).layerName, global_layer_name));
243     }
244     env.debug_log.clear();
245     // Set one set to contain the current executable path
246     env.loader_settings.app_specific_settings.at(0).add_app_key(test_platform_executable_path());
247     env.update_loader_settings(env.loader_settings);
248     {
249         auto layer_props = env.GetLayerProperties(1);
250         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, app_specific_layer_name));
251 
252         InstWrapper inst{env.vulkan_functions};
253         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
254         inst.CheckCreate();
255         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
256         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
257         ASSERT_TRUE(string_eq(layers.at(0).layerName, app_specific_layer_name));
258     }
259 }
260 
261 // Make sure layers found through the settings file are enableable by environment variables
TEST(SettingsFile,LayerAutoEnabledByEnvVars)262 TEST(SettingsFile, LayerAutoEnabledByEnvVars) {
263     FrameworkEnvironment env{};
264     env.loader_settings.set_file_format_version({1, 0, 0});
265     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
266 
267     const char* layer_name = "VK_LAYER_automatic";
268     env.add_explicit_layer(
269         TestLayerDetails{ManifestLayer{}.add_layer(
270                              ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
271                          "layer_name.json"}
272             .set_discovery_type(ManifestDiscoveryType::override_folder));
273 
274     env.update_loader_settings(
275         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
276             LoaderSettingsLayerConfiguration{}.set_name(layer_name).set_path(env.get_layer_manifest_path(0)).set_control("auto"))));
277     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
278     {
279         EnvVarWrapper instance_layers{"VK_INSTANCE_LAYERS", layer_name};
280         auto layer_props = env.GetLayerProperties(1);
281         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, layer_name));
282 
283         InstWrapper inst{env.vulkan_functions};
284         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
285         inst.CheckCreate();
286         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
287         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
288         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
289     }
290     env.debug_log.clear();
291 
292     {
293         EnvVarWrapper loader_layers_enable{"VK_LOADER_LAYERS_ENABLE", layer_name};
294         auto layer_props = env.GetLayerProperties(1);
295         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, layer_name));
296         InstWrapper inst{env.vulkan_functions};
297         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
298         inst.CheckCreate();
299         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
300         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
301         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
302     }
303 }
304 
305 // Make sure layers are disallowed from loading if the settings file says so
TEST(SettingsFile,LayerDisablesImplicitLayer)306 TEST(SettingsFile, LayerDisablesImplicitLayer) {
307     FrameworkEnvironment env{};
308     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
309     const char* implicit_layer_name = "VK_LAYER_Implicit_TestLayer";
310     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
311                                                          .set_name(implicit_layer_name)
312                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
313                                                          .set_disable_environment("oof")),
314                            "implicit_test_layer.json");
315 
316     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
317         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
318             LoaderSettingsLayerConfiguration{}
319                 .set_name(implicit_layer_name)
320                 .set_path(env.get_shimmed_layer_manifest_path(0))
321                 .set_control("off")
322                 .set_treat_as_implicit_manifest(true))));
323     {
324         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
325         InstWrapper inst{env.vulkan_functions};
326         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
327         inst.CheckCreate();
328 
329         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
330         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
331     }
332 }
333 
334 // Implicit layers should be reordered by the settings file
TEST(SettingsFile,ImplicitLayersDontInterfere)335 TEST(SettingsFile, ImplicitLayersDontInterfere) {
336     FrameworkEnvironment env{};
337     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
338     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
339     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
340                                                          .set_name(implicit_layer_name1)
341                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
342                                                          .set_disable_environment("oof")),
343                            "implicit_test_layer1.json");
344     const char* implicit_layer_name2 = "VK_LAYER_Implicit_TestLayer2";
345     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
346                                                          .set_name(implicit_layer_name2)
347                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
348                                                          .set_disable_environment("oof")),
349                            "implicit_test_layer2.json");
350     // validate order when settings file is not present
351     {
352         auto layer_props = env.GetLayerProperties(2);
353         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
354         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name2));
355 
356         InstWrapper inst{env.vulkan_functions};
357         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
358         inst.CheckCreate();
359         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
360         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
361         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
362         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name2));
363     }
364     // Now setup the settings file to contain a specific order
365     env.update_loader_settings(
366         LoaderSettings{}.add_app_specific_setting(AppSpecificSettings{}
367                                                       .add_stderr_log_filter("all")
368                                                       .add_layer_configuration(LoaderSettingsLayerConfiguration{}
369                                                                                    .set_name(implicit_layer_name1)
370                                                                                    .set_path(env.get_shimmed_layer_manifest_path(0))
371                                                                                    .set_control("auto")
372                                                                                    .set_treat_as_implicit_manifest(true))
373                                                       .add_layer_configuration(LoaderSettingsLayerConfiguration{}
374                                                                                    .set_name(implicit_layer_name2)
375                                                                                    .set_path(env.get_shimmed_layer_manifest_path(1))
376                                                                                    .set_control("auto")
377                                                                                    .set_treat_as_implicit_manifest(true))));
378     {
379         auto layer_props = env.GetLayerProperties(2);
380         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
381         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name2));
382 
383         InstWrapper inst{env.vulkan_functions};
384         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
385         inst.CheckCreate();
386         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
387         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
388         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
389         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name2));
390     }
391 
392     // Flip the order and store the settings in the env for later use in the test
393     env.loader_settings =
394         LoaderSettings{}.add_app_specific_setting(AppSpecificSettings{}
395                                                       .add_stderr_log_filter("all")
396                                                       .add_layer_configuration(LoaderSettingsLayerConfiguration{}
397                                                                                    .set_name(implicit_layer_name2)
398                                                                                    .set_path(env.get_shimmed_layer_manifest_path(1))
399                                                                                    .set_control("auto")
400                                                                                    .set_treat_as_implicit_manifest(true))
401                                                       .add_layer_configuration(LoaderSettingsLayerConfiguration{}
402                                                                                    .set_name(implicit_layer_name1)
403                                                                                    .set_path(env.get_shimmed_layer_manifest_path(0))
404                                                                                    .set_control("auto")
405                                                                                    .set_treat_as_implicit_manifest(true)));
406     env.update_loader_settings(env.loader_settings);
407 
408     {
409         auto layer_props = env.GetLayerProperties(2);
410         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name2));
411         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
412 
413         InstWrapper inst{env.vulkan_functions};
414         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
415         inst.CheckCreate();
416         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
417         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
418         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name2));
419         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
420     }
421 
422     // Now add an explicit layer into the middle and verify that is in the correct location
423     const char* explicit_layer_name3 = "VK_LAYER_Explicit_TestLayer3";
424     env.add_explicit_layer(
425         ManifestLayer{}.add_layer(
426             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
427         "explicit_test_layer3.json");
428     env.loader_settings.app_specific_settings.at(0).layer_configurations.insert(
429         env.loader_settings.app_specific_settings.at(0).layer_configurations.begin() + 1,
430         LoaderSettingsLayerConfiguration{}
431             .set_name(explicit_layer_name3)
432             .set_path(env.get_shimmed_layer_manifest_path(2))
433             .set_control("on"));
434     env.update_loader_settings(env.loader_settings);
435     {
436         auto layer_props = env.GetLayerProperties(3);
437         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name2));
438         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name3));
439         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, implicit_layer_name1));
440 
441         InstWrapper inst{env.vulkan_functions};
442         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
443         inst.CheckCreate();
444         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
445         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
446         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name2));
447         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name3));
448         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
449     }
450 }
451 
452 // Make sure layers that are disabled can't be enabled by the application
TEST(SettingsFile,ApplicationEnablesIgnored)453 TEST(SettingsFile, ApplicationEnablesIgnored) {
454     FrameworkEnvironment env{};
455     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
456     const char* explicit_layer_name = "VK_LAYER_TestLayer";
457     env.add_explicit_layer(
458         ManifestLayer{}.add_layer(
459             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
460         "regular_test_layer.json");
461 
462     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
463         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
464             LoaderSettingsLayerConfiguration{}
465                 .set_name(explicit_layer_name)
466                 .set_path(env.get_shimmed_layer_manifest_path(0))
467                 .set_control("off"))));
468     {
469         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
470         InstWrapper inst{env.vulkan_functions};
471         inst.create_info.add_layer(explicit_layer_name);
472         ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT));
473     }
474 }
475 
TEST(SettingsFile,LayerListIsEmpty)476 TEST(SettingsFile, LayerListIsEmpty) {
477     FrameworkEnvironment env{};
478     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
479     const char* implicit_layer_name = "VK_LAYER_TestLayer";
480     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
481                                                          .set_name(implicit_layer_name)
482                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
483                                                          .set_disable_environment("HeeHee")),
484                            "regular_test_layer.json");
485 
486     JsonWriter writer{};
487     writer.StartObject();
488     writer.AddKeyedString("file_format_version", "1.0.0");
489     writer.StartKeyedObject("settings");
490     writer.StartKeyedObject("layers");
491     writer.EndObject();
492     writer.EndObject();
493     writer.EndObject();
494     env.write_settings_file(writer.output);
495 
496     ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
497 
498     InstWrapper inst{env.vulkan_functions};
499     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
500     inst.CheckCreate();
501     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
502     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
503 }
504 
505 // If a settings file exists but contains no valid settings - don't consider it
TEST(SettingsFile,InvalidSettingsFile)506 TEST(SettingsFile, InvalidSettingsFile) {
507     FrameworkEnvironment env{};
508     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
509     const char* explicit_layer_name = "VK_LAYER_TestLayer";
510     env.add_explicit_layer(
511         ManifestLayer{}.add_layer(
512             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
513         "regular_test_layer.json");
514     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
515     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
516                                                          .set_name(implicit_layer_name)
517                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
518                                                          .set_disable_environment("foobarbaz")),
519                            "implicit_test_layer.json");
520     auto check_integrity = [&env, explicit_layer_name, implicit_layer_name]() {
521         auto layer_props = env.GetLayerProperties(2);
522         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name));
523         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name));
524         InstWrapper inst{env.vulkan_functions};
525         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
526         inst.create_info.add_layer(explicit_layer_name);
527         inst.CheckCreate();
528         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
529         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
530         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name));
531         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name));
532     };
533 
534     {
535         std::fstream fuzzer_output_json_file{FUZZER_OUTPUT_JSON_FILE, std::ios_base::in};
536         ASSERT_TRUE(fuzzer_output_json_file.is_open());
537         std::stringstream fuzzer_output_json;
538         fuzzer_output_json << fuzzer_output_json_file.rdbuf();
539         env.write_settings_file(fuzzer_output_json.str());
540 
541         check_integrity();
542     }
543 
544     // No actual settings
545     {
546         JsonWriter writer{};
547         writer.StartObject();
548         writer.AddKeyedString("file_format_version", "0.0.0");
549         writer.EndObject();
550         env.write_settings_file(writer.output);
551 
552         check_integrity();
553     }
554 
555     {
556         JsonWriter writer{};
557         writer.StartObject();
558         writer.AddKeyedString("file_format_version", "0.0.0");
559         writer.StartKeyedArray("settings_array");
560         writer.EndArray();
561         writer.StartKeyedObject("settings");
562         writer.EndObject();
563         writer.EndObject();
564         env.write_settings_file(writer.output);
565 
566         check_integrity();
567     }
568 
569     {
570         JsonWriter writer{};
571         writer.StartObject();
572         for (uint32_t i = 0; i < 3; i++) {
573             writer.StartKeyedArray("settings_array");
574             writer.EndArray();
575             writer.StartKeyedObject("boogabooga");
576             writer.EndObject();
577             writer.StartKeyedObject("settings");
578             writer.EndObject();
579         }
580         writer.EndObject();
581         env.write_settings_file(writer.output);
582 
583         check_integrity();
584     }
585 }
586 
587 // Unknown layers are put in the correct location
TEST(SettingsFile,UnknownLayersInRightPlace)588 TEST(SettingsFile, UnknownLayersInRightPlace) {
589     FrameworkEnvironment env{};
590     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
591     const char* explicit_layer_name1 = "VK_LAYER_TestLayer1";
592     env.add_explicit_layer(
593         ManifestLayer{}.add_layer(
594             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
595         "regular_test_layer1.json");
596     const char* implicit_layer_name1 = "VK_LAYER_ImplicitTestLayer1";
597     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
598                                                          .set_name(implicit_layer_name1)
599                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
600                                                          .set_disable_environment("foobarbaz")),
601                            "implicit_test_layer1.json");
602     const char* explicit_layer_name2 = "VK_LAYER_TestLayer2";
603     env.add_explicit_layer(
604         ManifestLayer{}.add_layer(
605             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
606         "regular_test_layer2.json");
607     const char* implicit_layer_name2 = "VK_LAYER_ImplicitTestLayer2";
608     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
609                                                          .set_name(implicit_layer_name2)
610                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
611                                                          .set_disable_environment("foobarbaz")),
612                            "implicit_test_layer2.json");
613 
614     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
615         AppSpecificSettings{}
616             .add_stderr_log_filter("all")
617             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
618                                          .set_name(explicit_layer_name2)
619                                          .set_path(env.get_shimmed_layer_manifest_path(2))
620                                          .set_control("on"))
621             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
622             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
623                                          .set_name(implicit_layer_name2)
624                                          .set_path(env.get_shimmed_layer_manifest_path(3))
625                                          .set_control("on")
626                                          .set_treat_as_implicit_manifest(true))));
627 
628     auto layer_props = env.GetLayerProperties(4);
629     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name2));
630     ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
631     ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
632     ASSERT_TRUE(string_eq(layer_props.at(3).layerName, implicit_layer_name2));
633     InstWrapper inst{env.vulkan_functions};
634     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
635     inst.create_info.add_layer(explicit_layer_name1);
636     inst.CheckCreate();
637     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
638     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
639     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name2));
640     ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
641     ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
642     ASSERT_TRUE(string_eq(layer_props.at(3).layerName, implicit_layer_name2));
643 }
644 
645 // Settings file allows loading multiple layers with the same name - as long as the path is different
TEST(SettingsFile,MultipleLayersWithSameName)646 TEST(SettingsFile, MultipleLayersWithSameName) {
647     FrameworkEnvironment env{};
648     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
649 
650     const char* explicit_layer_name = "VK_LAYER_TestLayer";
651     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
652                                                          .set_name(explicit_layer_name)
653                                                          .set_description("0000")
654                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
655                            "regular_test_layer1.json");
656 
657     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
658                                                          .set_name(explicit_layer_name)
659                                                          .set_description("1111")
660                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
661                            "regular_test_layer2.json");
662 
663     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
664         AppSpecificSettings{}
665             .add_stderr_log_filter("all")
666             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
667                                          .set_name(explicit_layer_name)
668                                          .set_path(env.get_shimmed_layer_manifest_path(0))
669                                          .set_control("on"))
670             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
671                                          .set_name(explicit_layer_name)
672                                          .set_path(env.get_shimmed_layer_manifest_path(1))
673                                          .set_control("on"))));
674     auto layer_props = env.GetLayerProperties(2);
675     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name));
676     ASSERT_TRUE(string_eq(layer_props.at(0).description, "0000"));
677     ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name));
678     ASSERT_TRUE(string_eq(layer_props.at(1).description, "1111"));
679     InstWrapper inst{env.vulkan_functions};
680     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
681     inst.CheckCreate();
682     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
683     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
684     ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name));
685     ASSERT_TRUE(string_eq(layers.at(0).description, "0000"));
686     ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name));
687     ASSERT_TRUE(string_eq(layers.at(1).description, "1111"));
688 }
689 
690 // Settings file shouldn't be able to cause the same layer from the same path twice
TEST(SettingsFile,MultipleLayersWithSamePath)691 TEST(SettingsFile, MultipleLayersWithSamePath) {
692     FrameworkEnvironment env{};
693     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
694 
695     const char* explicit_layer_name = "VK_LAYER_TestLayer";
696     env.add_explicit_layer(
697         ManifestLayer{}.add_layer(
698             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
699         "regular_test_layer1.json");
700 
701     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
702         AppSpecificSettings{}
703             .add_stderr_log_filter("all")
704             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
705                                          .set_name(explicit_layer_name)
706                                          .set_path(env.get_shimmed_layer_manifest_path(0))
707                                          .set_control("on"))
708             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
709                                          .set_name(explicit_layer_name)
710                                          .set_path(env.get_shimmed_layer_manifest_path(0))
711                                          .set_control("on"))));
712 
713     auto layer_props = env.GetLayerProperties(1);
714     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name));
715 
716     InstWrapper inst{env.vulkan_functions};
717     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
718     inst.CheckCreate();
719     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
720     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
721     ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name));
722 }
723 
724 // Settings contains a layer whose name doesn't match the one found in the layer manifest - make sure the layer from the settings
725 // file is removed
TEST(SettingsFile,MismatchedLayerNameAndManifestPath)726 TEST(SettingsFile, MismatchedLayerNameAndManifestPath) {
727     FrameworkEnvironment env{};
728     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
729 
730     const char* manifest_explicit_layer_name = "VK_LAYER_MANIFEST_TestLayer";
731     const char* settings_explicit_layer_name = "VK_LAYER_Settings_TestLayer";
732     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
733                                                          .set_name(manifest_explicit_layer_name)
734                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
735                            "regular_test_layer1.json");
736 
737     const char* implicit_layer_name = "VK_LAYER_Implicit_TestLayer";
738     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
739                                                          .set_name(implicit_layer_name)
740                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
741                                                          .set_disable_environment("oof")),
742                            "implicit_test_layer.json");
743 
744     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
745         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
746             LoaderSettingsLayerConfiguration{}
747                 .set_name(settings_explicit_layer_name)
748                 .set_path(env.get_shimmed_layer_manifest_path(0))
749                 .set_control("on"))));
750 
751     ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
752 
753     InstWrapper inst{env.vulkan_functions};
754     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
755     inst.CheckCreate();
756     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
757     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
758 }
759 
760 // Settings file should take precedence over the meta layer, if present
TEST(SettingsFile,ImplicitLayerWithEnableEnvironment)761 TEST(SettingsFile, ImplicitLayerWithEnableEnvironment) {
762     FrameworkEnvironment env{};
763     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
764 
765     const char* explicit_layer_1 = "VK_LAYER_Regular_TestLayer";
766     env.add_explicit_layer(
767         ManifestLayer{}.add_layer(
768             ManifestLayer::LayerDescription{}.set_name(explicit_layer_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
769         "explicit_test_layer1.json");
770 
771     const char* implicit_layer_1 = "VK_LAYER_RegularImplicit_TestLayer";
772     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
773                                                          .set_name(implicit_layer_1)
774                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
775                                                          .set_disable_environment("AndISaidHey")
776                                                          .set_enable_environment("WhatsGoingOn")),
777                            "implicit_layer1.json");
778 
779     const char* explicit_layer_2 = "VK_LAYER_Regular_TestLayer1";
780     env.add_explicit_layer(TestLayerDetails(
781         ManifestLayer{}.add_layer(
782             ManifestLayer::LayerDescription{}.set_name(explicit_layer_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
783         "explicit_test_layer2.json"));
784 
785     const char* implicit_layer_2 = "VK_LAYER_RegularImplicit_TestLayer2";
786     env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
787                                                                           .set_name(implicit_layer_2)
788                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
789                                                                           .set_disable_environment("HeyHeyHeyyaya")
790                                                                           .set_enable_environment("HeyHeyHeyhey")),
791                                             "implicit_layer2.json"));
792     const char* explicit_layer_3 = "VK_LAYER_Regular_TestLayer3";
793     env.add_explicit_layer(TestLayerDetails(
794         ManifestLayer{}.add_layer(
795             ManifestLayer::LayerDescription{}.set_name(explicit_layer_3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
796         "explicit_test_layer3.json"));
797     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
798         AppSpecificSettings{}
799             .add_stderr_log_filter("all")
800             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
801                                          .set_name(explicit_layer_1)
802                                          .set_path(env.get_shimmed_layer_manifest_path(0))
803                                          .set_control("auto")
804                                          .set_treat_as_implicit_manifest(false))
805             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
806             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
807                                          .set_name(implicit_layer_1)
808                                          .set_path(env.get_shimmed_layer_manifest_path(1))
809                                          .set_control("auto")
810                                          .set_treat_as_implicit_manifest(true))
811             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
812                                          .set_name(explicit_layer_2)
813                                          .set_path(env.get_shimmed_layer_manifest_path(2))
814                                          .set_control("auto")
815                                          .set_treat_as_implicit_manifest(false))
816             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
817                                          .set_name(implicit_layer_2)
818                                          .set_path(env.get_shimmed_layer_manifest_path(3))
819                                          .set_control("auto")
820                                          .set_treat_as_implicit_manifest(true))
821             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
822                                          .set_name(explicit_layer_3)
823                                          .set_path(env.get_shimmed_layer_manifest_path(4))
824                                          .set_control("on")
825                                          .set_treat_as_implicit_manifest(false))));
826     {
827         auto layer_props = env.GetLayerProperties(5);
828         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_1));
829         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_1));
830         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_2));
831         ASSERT_TRUE(string_eq(layer_props.at(3).layerName, implicit_layer_2));
832         ASSERT_TRUE(string_eq(layer_props.at(4).layerName, explicit_layer_3));
833 
834         InstWrapper inst{env.vulkan_functions};
835         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
836         inst.CheckCreate();
837         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
838         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
839         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_3));
840     }
841     {
842         EnvVarWrapper enable_meta_layer{"WhatsGoingOn", "1"};
843         auto layer_props = env.GetLayerProperties(5);
844         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_1));
845         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_1));
846         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_2));
847         ASSERT_TRUE(string_eq(layer_props.at(3).layerName, implicit_layer_2));
848         ASSERT_TRUE(string_eq(layer_props.at(4).layerName, explicit_layer_3));
849 
850         InstWrapper inst{env.vulkan_functions};
851         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
852         inst.CheckCreate();
853         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
854         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
855         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_1));
856         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_3));
857     }
858     {
859         EnvVarWrapper enable_meta_layer{"HeyHeyHeyhey", "1"};
860         auto layer_props = env.GetLayerProperties(5);
861         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_1));
862         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_1));
863         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_2));
864         ASSERT_TRUE(string_eq(layer_props.at(3).layerName, implicit_layer_2));
865         ASSERT_TRUE(string_eq(layer_props.at(4).layerName, explicit_layer_3));
866 
867         InstWrapper inst{env.vulkan_functions};
868         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
869         inst.CheckCreate();
870         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
871         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
872         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_2));
873         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_3));
874     }
875 }
876 
877 // Settings file should take precedence over the meta layer, if present
TEST(SettingsFile,MetaLayerAlsoActivates)878 TEST(SettingsFile, MetaLayerAlsoActivates) {
879     FrameworkEnvironment env{};
880     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
881 
882     const char* settings_explicit_layer_name = "VK_LAYER_Regular_TestLayer";
883     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
884                                                          .set_name(settings_explicit_layer_name)
885                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
886                            "explicit_test_layer.json");
887 
888     const char* settings_implicit_layer_name = "VK_LAYER_RegularImplicit_TestLayer";
889     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
890                                                          .set_name(settings_implicit_layer_name)
891                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
892                                                          .set_disable_environment("AndISaidHey")
893                                                          .set_enable_environment("WhatsGoingOn")),
894                            "implicit_layer.json");
895 
896     const char* component_explicit_layer_name1 = "VK_LAYER_Component_TestLayer1";
897     env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
898                                                                           .set_name(component_explicit_layer_name1)
899                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
900                                             "component_test_layer1.json"));
901 
902     const char* component_explicit_layer_name2 = "VK_LAYER_Component_TestLayer2";
903     env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
904                                                                           .set_name(component_explicit_layer_name2)
905                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
906                                             "component_test_layer2.json"));
907 
908     const char* meta_layer_name1 = "VK_LAYER_meta_layer1";
909     env.add_implicit_layer(
910         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
911                                                                          .set_name(meta_layer_name1)
912                                                                          .add_component_layer(component_explicit_layer_name2)
913                                                                          .add_component_layer(component_explicit_layer_name1)
914                                                                          .set_disable_environment("NotGonnaWork")),
915         "meta_test_layer.json");
916 
917     const char* meta_layer_name2 = "VK_LAYER_meta_layer2";
918     env.add_implicit_layer(
919         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
920                                                                          .set_name(meta_layer_name2)
921                                                                          .add_component_layer(component_explicit_layer_name1)
922                                                                          .set_disable_environment("ILikeTrains")
923                                                                          .set_enable_environment("BakedBeans")),
924         "not_automatic_meta_test_layer.json");
925 
926     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
927         AppSpecificSettings{}
928             .add_stderr_log_filter("all")
929             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
930                                          .set_name(settings_explicit_layer_name)
931                                          .set_path(env.get_shimmed_layer_manifest_path(0))
932                                          .set_control("on")
933                                          .set_treat_as_implicit_manifest(false))
934             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
935             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
936                                          .set_name(settings_implicit_layer_name)
937                                          .set_path(env.get_shimmed_layer_manifest_path(1))
938                                          .set_control("auto")
939                                          .set_treat_as_implicit_manifest(true))));
940     {
941         EnvVarWrapper enable_meta_layer{"WhatsGoingOn", "1"};
942         auto layer_props = env.GetLayerProperties(6);
943         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, settings_explicit_layer_name));
944         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, meta_layer_name1));
945         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, meta_layer_name2));
946         ASSERT_TRUE(string_eq(layer_props.at(3).layerName, component_explicit_layer_name1));
947         ASSERT_TRUE(string_eq(layer_props.at(4).layerName, component_explicit_layer_name2));
948         ASSERT_TRUE(string_eq(layer_props.at(5).layerName, settings_implicit_layer_name));
949 
950         InstWrapper inst{env.vulkan_functions};
951         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
952         inst.CheckCreate();
953         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
954         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 5);
955         ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_explicit_layer_name));
956         ASSERT_TRUE(string_eq(layers.at(1).layerName, component_explicit_layer_name2));
957         ASSERT_TRUE(string_eq(layers.at(2).layerName, component_explicit_layer_name1));
958         ASSERT_TRUE(string_eq(layers.at(3).layerName, meta_layer_name1));
959         ASSERT_TRUE(string_eq(layers.at(4).layerName, settings_implicit_layer_name));
960     }
961     {
962         EnvVarWrapper enable_meta_layer{"BakedBeans", "1"};
963         auto layer_props = env.GetLayerProperties(6);
964         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, settings_explicit_layer_name));
965         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, meta_layer_name1));
966         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, meta_layer_name2));
967         ASSERT_TRUE(string_eq(layer_props.at(3).layerName, component_explicit_layer_name1));
968         ASSERT_TRUE(string_eq(layer_props.at(4).layerName, component_explicit_layer_name2));
969         ASSERT_TRUE(string_eq(layer_props.at(5).layerName, settings_implicit_layer_name));
970 
971         InstWrapper inst{env.vulkan_functions};
972         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
973         inst.CheckCreate();
974         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
975         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 5);
976         ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_explicit_layer_name));
977         ASSERT_TRUE(string_eq(layers.at(1).layerName, component_explicit_layer_name2));
978         ASSERT_TRUE(string_eq(layers.at(2).layerName, component_explicit_layer_name1));
979         ASSERT_TRUE(string_eq(layers.at(3).layerName, meta_layer_name1));
980         ASSERT_TRUE(string_eq(layers.at(4).layerName, meta_layer_name2));
981     }
982 }
983 
984 // Layers are correctly ordered by settings file.
TEST(SettingsFile,LayerOrdering)985 TEST(SettingsFile, LayerOrdering) {
986     FrameworkEnvironment env{};
987     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
988 
989     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
990     env.add_explicit_layer(
991         ManifestLayer{}.add_layer(
992             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
993         "explicit_test_layer1.json");
994 
995     const char* explicit_layer_name2 = "VK_LAYER_Regular_TestLayer2";
996     env.add_explicit_layer(
997         ManifestLayer{}.add_layer(
998             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
999         "explicit_test_layer2.json");
1000 
1001     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
1002     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1003                                                          .set_name(implicit_layer_name1)
1004                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1005                                                          .set_disable_environment("Domierigato")),
1006                            "implicit_layer1.json");
1007 
1008     const char* implicit_layer_name2 = "VK_LAYER_Implicit_TestLayer2";
1009     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1010                                                          .set_name(implicit_layer_name2)
1011                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1012                                                          .set_disable_environment("Mistehrobato")),
1013                            "implicit_layer2.json");
1014 
1015     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
1016 
1017     std::vector<LoaderSettingsLayerConfiguration> layer_configs{4};
1018     layer_configs.at(0)
1019         .set_name(explicit_layer_name1)
1020         .set_path(env.get_shimmed_layer_manifest_path(0))
1021         .set_control("on")
1022         .set_treat_as_implicit_manifest(false);
1023     layer_configs.at(1)
1024         .set_name(explicit_layer_name2)
1025         .set_path(env.get_shimmed_layer_manifest_path(1))
1026         .set_control("on")
1027         .set_treat_as_implicit_manifest(false);
1028     layer_configs.at(2)
1029         .set_name(implicit_layer_name1)
1030         .set_path(env.get_shimmed_layer_manifest_path(2))
1031         .set_control("on")
1032         .set_treat_as_implicit_manifest(true);
1033     layer_configs.at(3)
1034         .set_name(implicit_layer_name2)
1035         .set_path(env.get_shimmed_layer_manifest_path(3))
1036         .set_control("on")
1037         .set_treat_as_implicit_manifest(true);
1038 
1039     std::sort(layer_configs.begin(), layer_configs.end());
1040     uint32_t permutation_count = 0;
1041     do {
1042         env.loader_settings.app_specific_settings.at(0).layer_configurations.clear();
1043         env.loader_settings.app_specific_settings.at(0).add_layer_configurations(layer_configs);
1044         env.update_loader_settings(env.loader_settings);
1045 
1046         auto layer_props = env.GetLayerProperties(4);
1047         for (uint32_t i = 0; i < 4; i++) {
1048             ASSERT_TRUE(layer_configs.at(i).name == layer_props.at(i).layerName);
1049         }
1050 
1051         InstWrapper inst{env.vulkan_functions};
1052         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1053         inst.CheckCreate();
1054         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1055         auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
1056         for (uint32_t i = 0; i < 4; i++) {
1057             ASSERT_TRUE(layer_configs.at(i).name == active_layers.at(i).layerName);
1058         }
1059         env.debug_log.clear();
1060         permutation_count++;
1061     } while (std::next_permutation(layer_configs.begin(), layer_configs.end()));
1062     ASSERT_EQ(permutation_count, 24U);  // should be this many orderings
1063 }
1064 
TEST(SettingsFile,EnvVarsWork_VK_LAYER_PATH)1065 TEST(SettingsFile, EnvVarsWork_VK_LAYER_PATH) {
1066     FrameworkEnvironment env{};
1067     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1068 
1069     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
1070     env.add_explicit_layer(TestLayerDetails{
1071         ManifestLayer{}.add_layer(
1072             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1073         "explicit_test_layer1.json"}
1074                                .set_discovery_type(ManifestDiscoveryType::env_var));
1075 
1076     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
1077     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1078                                                          .set_name(implicit_layer_name1)
1079                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1080                                                          .set_disable_environment("Domierigato")),
1081                            "implicit_layer1.json");
1082     const char* non_env_var_layer_name2 = "VK_LAYER_Regular_TestLayer2";
1083     env.add_explicit_layer(TestLayerDetails{
1084         ManifestLayer{}.add_layer(
1085             ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1086         "explicit_test_layer2.json"});
1087 
1088     {
1089         auto layer_props = env.GetLayerProperties(2);
1090         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
1091         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name1));
1092 
1093         InstWrapper inst{env.vulkan_functions};
1094         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1095         inst.CheckCreate();
1096         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1097         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1098         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1099     }
1100     {
1101         InstWrapper inst{env.vulkan_functions};
1102         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1103         inst.create_info.add_layer(explicit_layer_name1);
1104         inst.CheckCreate();
1105         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1106         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1107         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1108         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name1));
1109     }
1110     env.update_loader_settings(env.loader_settings.add_app_specific_setting(
1111         AppSpecificSettings{}
1112             .add_stderr_log_filter("all")
1113             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1114                                          .set_name(non_env_var_layer_name2)
1115                                          .set_control("on")
1116                                          .set_path(env.get_shimmed_layer_manifest_path(2)))
1117             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))));
1118     {
1119         auto layer_props = env.GetLayerProperties(3);
1120         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, non_env_var_layer_name2));
1121         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
1122         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
1123 
1124         InstWrapper inst{env.vulkan_functions};
1125         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1126         inst.CheckCreate();
1127         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1128         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1129         ASSERT_TRUE(string_eq(layers.at(0).layerName, non_env_var_layer_name2));
1130         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
1131     }
1132     {
1133         InstWrapper inst{env.vulkan_functions};
1134         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1135         inst.create_info.add_layer(explicit_layer_name1);
1136         inst.CheckCreate();
1137         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1138         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1139         ASSERT_TRUE(string_eq(layers.at(0).layerName, non_env_var_layer_name2));
1140         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
1141         ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1));
1142     }
1143 }
1144 
TEST(SettingsFile,EnvVarsWork_VK_ADD_LAYER_PATH)1145 TEST(SettingsFile, EnvVarsWork_VK_ADD_LAYER_PATH) {
1146     FrameworkEnvironment env{};
1147     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1148 
1149     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
1150     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1151                                                          .set_name(implicit_layer_name1)
1152                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1153                                                          .set_disable_environment("Domierigato")),
1154                            "implicit_layer1.json");
1155     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
1156     env.add_explicit_layer(TestLayerDetails{
1157         ManifestLayer{}.add_layer(
1158             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1159         "explicit_test_layer1.json"}
1160                                .set_discovery_type(ManifestDiscoveryType::add_env_var));
1161     const char* non_env_var_layer_name2 = "VK_LAYER_Regular_TestLayer2";
1162     env.add_explicit_layer(TestLayerDetails{
1163         ManifestLayer{}.add_layer(
1164             ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1165         "explicit_test_layer2.json"});
1166 
1167     {
1168         auto layer_props = env.GetLayerProperties(3);
1169         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
1170         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name1));
1171         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, non_env_var_layer_name2));
1172 
1173         InstWrapper inst{env.vulkan_functions};
1174         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1175         inst.CheckCreate();
1176         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1177         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1178         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1179     }
1180     {
1181         InstWrapper inst{env.vulkan_functions};
1182         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1183         inst.create_info.add_layer(explicit_layer_name1);
1184         inst.CheckCreate();
1185         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1186         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1187         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1188         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name1));
1189     }
1190 
1191     env.update_loader_settings(env.loader_settings.add_app_specific_setting(
1192         AppSpecificSettings{}
1193             .add_stderr_log_filter("all")
1194             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1195                                          .set_name(explicit_layer_name1)
1196                                          .set_control("on")
1197                                          .set_path(env.get_shimmed_layer_manifest_path(1)))
1198             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1199                                          .set_name(non_env_var_layer_name2)
1200                                          .set_control("on")
1201                                          .set_path(env.get_shimmed_layer_manifest_path(2)))
1202             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1203                                          .set_name(implicit_layer_name1)
1204                                          .set_control("on")
1205                                          .set_path(env.get_shimmed_layer_manifest_path(0))
1206                                          .set_treat_as_implicit_manifest(true))));
1207     {
1208         auto layer_props = env.GetLayerProperties(3);
1209         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
1210         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, non_env_var_layer_name2));
1211         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, implicit_layer_name1));
1212 
1213         InstWrapper inst{env.vulkan_functions};
1214         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1215         inst.CheckCreate();
1216         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1217         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1218         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1219         ASSERT_TRUE(string_eq(layers.at(1).layerName, non_env_var_layer_name2));
1220         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
1221     }
1222     {
1223         InstWrapper inst{env.vulkan_functions};
1224         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1225         inst.create_info.add_layer(explicit_layer_name1);
1226         inst.CheckCreate();
1227         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1228         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1229         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1230         ASSERT_TRUE(string_eq(layers.at(1).layerName, non_env_var_layer_name2));
1231         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
1232     }
1233 }
1234 
TEST(SettingsFile,EnvVarsWork_VK_IMPLICIT_LAYER_PATH)1235 TEST(SettingsFile, EnvVarsWork_VK_IMPLICIT_LAYER_PATH) {
1236     FrameworkEnvironment env{};
1237     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1238 
1239     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
1240     env.add_explicit_layer(TestLayerDetails{
1241         ManifestLayer{}.add_layer(
1242             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1243         "explicit_test_layer1.json"}
1244                                .set_discovery_type(ManifestDiscoveryType::env_var));
1245 
1246     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
1247     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1248                                                          .set_name(implicit_layer_name1)
1249                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1250                                                          .set_disable_environment("Domierigato")),
1251                            "implicit_layer1.json");
1252     const char* settings_layer_path = "VK_LAYER_Regular_TestLayer2";
1253     env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1254                                                                           .set_name(settings_layer_path)
1255                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1256                                                                           .set_disable_environment("Domierigato")),
1257                                             "implicit_test_layer2.json"});
1258 
1259     {
1260         auto layer_props = env.GetLayerProperties(3);
1261         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
1262         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, settings_layer_path));
1263         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
1264 
1265         InstWrapper inst{env.vulkan_functions};
1266         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1267         inst.CheckCreate();
1268         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1269         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1270         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1271         ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_path));
1272     }
1273     {
1274         InstWrapper inst{env.vulkan_functions};
1275         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1276         inst.create_info.add_layer(explicit_layer_name1);
1277         inst.CheckCreate();
1278         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1279         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1280         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1281         ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_path));
1282         ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1));
1283     }
1284     env.update_loader_settings(env.loader_settings.add_app_specific_setting(
1285         AppSpecificSettings{}
1286             .add_stderr_log_filter("all")
1287             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1288                                          .set_name(settings_layer_path)
1289                                          .set_control("on")
1290                                          .set_path(env.get_shimmed_layer_manifest_path(2))
1291                                          .set_treat_as_implicit_manifest(true))
1292             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))));
1293     {
1294         auto layer_props = env.GetLayerProperties(3);
1295         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, settings_layer_path));
1296         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
1297         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
1298 
1299         InstWrapper inst{env.vulkan_functions};
1300         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1301         inst.CheckCreate();
1302         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1303         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1304         ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_layer_path));
1305         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
1306     }
1307     {
1308         InstWrapper inst{env.vulkan_functions};
1309         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1310         inst.create_info.add_layer(explicit_layer_name1);
1311         inst.CheckCreate();
1312         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1313         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1314         ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_layer_path));
1315         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
1316         ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1));
1317     }
1318 }
1319 
TEST(SettingsFile,EnvVarsWork_VK_ADD_IMPLICIT_LAYER_PATH)1320 TEST(SettingsFile, EnvVarsWork_VK_ADD_IMPLICIT_LAYER_PATH) {
1321     FrameworkEnvironment env{};
1322     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1323 
1324     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
1325     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1326                                                          .set_name(implicit_layer_name1)
1327                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1328                                                          .set_disable_environment("Domierigato")),
1329                            "implicit_layer1.json");
1330     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
1331     env.add_explicit_layer(TestLayerDetails{
1332         ManifestLayer{}.add_layer(
1333             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1334         "explicit_test_layer1.json"}
1335                                .set_discovery_type(ManifestDiscoveryType::add_env_var));
1336     const char* settings_layer_name = "VK_LAYER_Regular_TestLayer2";
1337     env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1338                                                                           .set_name(settings_layer_name)
1339                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1340                                                                           .set_disable_environment("gozaimasu")),
1341                                             "implicit_test_layer2.json"});
1342 
1343     {
1344         auto layer_props = env.GetLayerProperties(3);
1345         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
1346         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, settings_layer_name));
1347         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
1348 
1349         InstWrapper inst{env.vulkan_functions};
1350         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1351         inst.CheckCreate();
1352         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1353         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1354         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1355         ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name));
1356     }
1357     {
1358         InstWrapper inst{env.vulkan_functions};
1359         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1360         inst.create_info.add_layer(explicit_layer_name1);
1361         inst.CheckCreate();
1362         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1363         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1364         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1365         ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name));
1366         ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1));
1367     }
1368 
1369     env.update_loader_settings(env.loader_settings.add_app_specific_setting(
1370         AppSpecificSettings{}
1371             .add_stderr_log_filter("all")
1372             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1373                                          .set_name(explicit_layer_name1)
1374                                          .set_control("on")
1375                                          .set_path(env.get_shimmed_layer_manifest_path(1)))
1376             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1377                                          .set_name(settings_layer_name)
1378                                          .set_control("on")
1379                                          .set_path(env.get_shimmed_layer_manifest_path(2))
1380                                          .set_treat_as_implicit_manifest(true))
1381             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1382                                          .set_name(implicit_layer_name1)
1383                                          .set_control("on")
1384                                          .set_path(env.get_shimmed_layer_manifest_path(0))
1385                                          .set_treat_as_implicit_manifest(true))));
1386     {
1387         auto layer_props = env.GetLayerProperties(3);
1388         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
1389         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, settings_layer_name));
1390         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, implicit_layer_name1));
1391 
1392         InstWrapper inst{env.vulkan_functions};
1393         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1394         inst.CheckCreate();
1395         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1396         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1397         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1398         ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name));
1399         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
1400     }
1401     {
1402         InstWrapper inst{env.vulkan_functions};
1403         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1404         inst.create_info.add_layer(explicit_layer_name1);
1405         inst.CheckCreate();
1406         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1407         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1408         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1409         ASSERT_TRUE(string_eq(layers.at(1).layerName, settings_layer_name));
1410         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
1411     }
1412 }
1413 
TEST(SettingsFile,EnvVarsWork_VK_INSTANCE_LAYERS)1414 TEST(SettingsFile, EnvVarsWork_VK_INSTANCE_LAYERS) {
1415     FrameworkEnvironment env{};
1416     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1417 
1418     const char* filler_layer_name = "VK_LAYER_filler";
1419     env.add_explicit_layer(TestLayerDetails{
1420         ManifestLayer{}.add_layer(
1421             ManifestLayer::LayerDescription{}.set_name(filler_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1422         "filler_layer.json"});
1423 
1424     const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer1";
1425     env.add_explicit_layer(TestLayerDetails{
1426         ManifestLayer{}.add_layer(
1427             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1428         "explicit_test_layer1.json"});
1429 
1430     {
1431         EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS", explicit_layer_name};
1432         auto layer_props = env.GetLayerProperties(2);
1433         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, filler_layer_name));
1434         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name));
1435 
1436         InstWrapper inst{env.vulkan_functions};
1437         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1438         inst.CheckCreate();
1439         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1440         auto layer = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1441         ASSERT_TRUE(string_eq(layer.at(0).layerName, explicit_layer_name));
1442     }
1443     env.update_loader_settings(env.loader_settings.add_app_specific_setting(
1444         AppSpecificSettings{}
1445             .add_stderr_log_filter("all")
1446             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1447                                          .set_name(filler_layer_name)
1448                                          .set_control("auto")
1449                                          .set_path(env.get_shimmed_layer_manifest_path(0)))
1450             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1451                                          .set_name(explicit_layer_name)
1452                                          .set_control("off")
1453                                          .set_path(env.get_shimmed_layer_manifest_path(1)))));
1454     {
1455         auto layer_props = env.GetLayerProperties(1);
1456         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, filler_layer_name));
1457 
1458         InstWrapper inst{env.vulkan_functions};
1459         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1460         inst.CheckCreate();
1461         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1462         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1463     }
1464     EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS", explicit_layer_name};
1465     {
1466         auto layer_props = env.GetLayerProperties(1);
1467         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, filler_layer_name));
1468 
1469         InstWrapper inst{env.vulkan_functions};
1470         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1471         inst.CheckCreate();
1472         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1473         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1474     }
1475     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).control = "auto";
1476     env.update_loader_settings(env.loader_settings);
1477     {
1478         auto layer_props = env.GetLayerProperties(2);
1479         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, filler_layer_name));
1480         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name));
1481 
1482         InstWrapper inst{env.vulkan_functions};
1483         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1484         inst.CheckCreate();
1485         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1486         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1487         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name));
1488     }
1489     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).control = "on";
1490     env.update_loader_settings(env.loader_settings);
1491     {
1492         auto layer_props = env.GetLayerProperties(2);
1493         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, filler_layer_name));
1494         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name));
1495 
1496         InstWrapper inst{env.vulkan_functions};
1497         inst.CheckCreate();
1498         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1499         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name));
1500     }
1501 }
1502 
TEST(SettingsFile,EnvVarsWork_VK_INSTANCE_LAYERS_multiple_layers)1503 TEST(SettingsFile, EnvVarsWork_VK_INSTANCE_LAYERS_multiple_layers) {
1504     FrameworkEnvironment env{};
1505     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1506 
1507     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
1508     env.add_explicit_layer(TestLayerDetails{
1509         ManifestLayer{}.add_layer(
1510             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1511         "explicit_test_layer1.json"});
1512 
1513     const char* explicit_layer_name2 = "VK_LAYER_Regular_TestLayer2";
1514     env.add_explicit_layer(TestLayerDetails{
1515         ManifestLayer{}.add_layer(
1516             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1517         "explicit_test_layer2.json"});
1518 
1519     const char* explicit_layer_name3 = "VK_LAYER_Regular_TestLayer3";
1520     env.add_explicit_layer(TestLayerDetails{
1521         ManifestLayer{}.add_layer(
1522             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1523         "explicit_test_layer3.json"});
1524 
1525     EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS"};
1526     vk_instance_layers.add_to_list(explicit_layer_name2);
1527     vk_instance_layers.add_to_list(explicit_layer_name1);
1528     {
1529         auto layer_props = env.GetLayerProperties(3);
1530         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
1531         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name2));
1532         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name3));
1533 
1534         InstWrapper inst{env.vulkan_functions};
1535         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1536         inst.CheckCreate();
1537         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1538         auto layer = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1539         ASSERT_TRUE(string_eq(layer.at(0).layerName, explicit_layer_name2));
1540         ASSERT_TRUE(string_eq(layer.at(1).layerName, explicit_layer_name1));
1541     }
1542     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configurations(
1543         {LoaderSettingsLayerConfiguration{}
1544              .set_name(explicit_layer_name1)
1545              .set_control("off")
1546              .set_path(env.get_shimmed_layer_manifest_path(0)),
1547          LoaderSettingsLayerConfiguration{}
1548              .set_name(explicit_layer_name2)
1549              .set_control("off")
1550              .set_path(env.get_shimmed_layer_manifest_path(1)),
1551          LoaderSettingsLayerConfiguration{}
1552              .set_name(explicit_layer_name3)
1553              .set_control("auto")
1554              .set_path(env.get_shimmed_layer_manifest_path(2))}));
1555     env.update_loader_settings(env.loader_settings);
1556     {
1557         auto layer_props = env.GetLayerProperties(1);
1558         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name3));
1559 
1560         InstWrapper inst{env.vulkan_functions};
1561         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1562         inst.CheckCreate();
1563         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1564         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1565     }
1566     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).control = "auto";
1567     env.update_loader_settings(env.loader_settings);
1568     {
1569         auto layer_props = env.GetLayerProperties(2);
1570         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
1571         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name3));
1572 
1573         InstWrapper inst{env.vulkan_functions};
1574         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1575         inst.CheckCreate();
1576         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1577         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1578         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1579     }
1580     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).control = "on";
1581     env.update_loader_settings(env.loader_settings);
1582     {
1583         auto layer_props = env.GetLayerProperties(2);
1584         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
1585         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name3));
1586 
1587         InstWrapper inst{env.vulkan_functions};
1588         inst.CheckCreate();
1589         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1590         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1591     }
1592     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).control = "off";
1593     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).control = "auto";
1594     env.update_loader_settings(env.loader_settings);
1595     {
1596         auto layer_props = env.GetLayerProperties(2);
1597         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name2));
1598         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name3));
1599 
1600         InstWrapper inst{env.vulkan_functions};
1601         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1602         inst.CheckCreate();
1603         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1604         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1605         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name2));
1606     }
1607     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).control = "on";
1608     env.update_loader_settings(env.loader_settings);
1609     {
1610         auto layer_props = env.GetLayerProperties(2);
1611         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name2));
1612         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name3));
1613 
1614         InstWrapper inst{env.vulkan_functions};
1615         inst.CheckCreate();
1616         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1617         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name2));
1618     }
1619     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).control = "auto";
1620     env.update_loader_settings(env.loader_settings);
1621     {
1622         auto layer_props = env.GetLayerProperties(2);
1623         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name2));
1624         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name3));
1625 
1626         InstWrapper inst{env.vulkan_functions};
1627         inst.CheckCreate();
1628         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1629         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name2));
1630     }
1631     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).control = "on";
1632     env.update_loader_settings(env.loader_settings);
1633     {
1634         auto layer_props = env.GetLayerProperties(3);
1635         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
1636         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name2));
1637         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name3));
1638 
1639         InstWrapper inst{env.vulkan_functions};
1640         inst.CheckCreate();
1641         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1642         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1643         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name2));
1644     }
1645 }
1646 
1647 // Make sure that layers disabled by settings file aren't enabled by VK_LOADER_LAYERS_ENABLE
TEST(SettingsFile,EnvVarsWork_VK_LOADER_LAYERS_ENABLE)1648 TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_ENABLE) {
1649     FrameworkEnvironment env{};
1650     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1651 
1652     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
1653     const char* explicit_layer_name = add_layer_and_settings(env, "VK_LAYER_Regular_TestLayer1", LayerType::exp, "off");
1654     env.update_loader_settings(env.loader_settings);
1655 
1656     EnvVarWrapper vk_instance_layers{"VK_LOADER_LAYERS_ENABLE", explicit_layer_name};
1657     ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
1658 
1659     InstWrapper inst{env.vulkan_functions};
1660     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1661     inst.CheckCreate();
1662     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1663     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1664 }
1665 
TEST(SettingsFile,settings_disable_layer_enabled_by_env_vars)1666 TEST(SettingsFile, settings_disable_layer_enabled_by_env_vars) {
1667     FrameworkEnvironment env{};
1668     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1669     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
1670     std::vector<const char*> layer_names;
1671     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_alpha", LayerType::imp, "auto"));
1672     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_bravo", LayerType::imp, "auto"));
1673     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_charlie", LayerType::imp, "auto"));
1674     env.loader_settings.app_specific_settings.back().add_layer_configuration(
1675         LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"));
1676     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_delta", LayerType::exp, "auto"));
1677     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_echo", LayerType::exp, "auto"));
1678     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_foxtrot", LayerType::exp, "auto"));
1679     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_gamma", LayerType::exp, "auto"));
1680     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_indigo", LayerType::exp, "auto"));
1681     auto disable_layer_name = add_layer_and_settings(env, "VK_LAYER_juniper", LayerType::exp, "off");
1682     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_kangaroo", LayerType::exp, "on"));
1683     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_lima", LayerType::exp, "auto"));
1684     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_mango", LayerType::exp, "auto"));
1685 
1686     env.update_loader_settings(env.loader_settings);
1687     {
1688         EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS", disable_layer_name};
1689         auto layer_props = env.GetLayerProperties(11);
1690         for (size_t i = 0; i < layer_props.size(); i++) {
1691             ASSERT_TRUE(string_eq(layer_names.at(i), layer_props.at(i).layerName));
1692         }
1693         InstWrapper inst{env.vulkan_functions};
1694         inst.CheckCreate();
1695         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
1696         ASSERT_TRUE(string_eq(layer_names.at(0), layers.at(0).layerName));
1697         ASSERT_TRUE(string_eq(layer_names.at(1), layers.at(1).layerName));
1698         ASSERT_TRUE(string_eq(layer_names.at(2), layers.at(2).layerName));
1699         ASSERT_TRUE(string_eq(layer_names.at(8), layers.at(3).layerName));
1700     }
1701     {
1702         EnvVarWrapper vk_instance_layers{"VK_LOADER_LAYERS_ENABLE", disable_layer_name};
1703         auto layer_props = env.GetLayerProperties(11);
1704         for (size_t i = 0; i < layer_props.size(); i++) {
1705             ASSERT_TRUE(string_eq(layer_names.at(i), layer_props.at(i).layerName));
1706         }
1707         InstWrapper inst{env.vulkan_functions};
1708         inst.CheckCreate();
1709         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
1710         ASSERT_TRUE(string_eq(layer_names.at(0), layers.at(0).layerName));
1711         ASSERT_TRUE(string_eq(layer_names.at(1), layers.at(1).layerName));
1712         ASSERT_TRUE(string_eq(layer_names.at(2), layers.at(2).layerName));
1713         ASSERT_TRUE(string_eq(layer_names.at(8), layers.at(3).layerName));
1714     }
1715     {
1716         auto layer_props = env.GetLayerProperties(11);
1717         for (size_t i = 0; i < layer_props.size(); i++) {
1718             ASSERT_TRUE(string_eq(layer_names.at(i), layer_props.at(i).layerName));
1719         }
1720         InstWrapper inst{env.vulkan_functions};
1721         inst.create_info.add_layer(disable_layer_name);
1722         inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
1723     }
1724 }
1725 
1726 // Make sure that layers enabled by settings file aren't disabled by VK_LOADER_LAYERS_ENABLE
TEST(SettingsFile,EnvVarsWork_VK_LOADER_LAYERS_DISABLE)1727 TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_DISABLE) {
1728     FrameworkEnvironment env{};
1729     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1730 
1731     const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer1";
1732     env.add_explicit_layer(TestLayerDetails{
1733         ManifestLayer{}.add_layer(
1734             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1735         "explicit_test_layer1.json"});
1736 
1737     env.update_loader_settings(
1738         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1739             LoaderSettingsLayerConfiguration{}
1740                 .set_name(explicit_layer_name)
1741                 .set_control("on")
1742                 .set_path(env.get_shimmed_layer_manifest_path(0)))));
1743 
1744     EnvVarWrapper vk_instance_layers{"VK_LOADER_LAYERS_DISABLE", explicit_layer_name};
1745     auto layer_props = env.GetLayerProperties(1);
1746     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name));
1747 
1748     InstWrapper inst{env.vulkan_functions};
1749     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1750     inst.CheckCreate();
1751     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1752     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1753     ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name));
1754 }
1755 
1756 #if defined(WIN32)
TEST(SettingsFile,MultipleKeysInRegistryInUnsecureLocation)1757 TEST(SettingsFile, MultipleKeysInRegistryInUnsecureLocation) {
1758     FrameworkEnvironment env{};
1759     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1760     env.platform_shim->add_unsecured_manifest(ManifestCategory::settings, "jank_path");
1761     env.platform_shim->add_unsecured_manifest(ManifestCategory::settings, "jank_path2");
1762 
1763     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
1764     env.add_explicit_layer(TestLayerDetails{
1765         ManifestLayer{}.add_layer(
1766             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1767         "regular_test_layer.json"}
1768                                .set_discovery_type(ManifestDiscoveryType::override_folder));
1769     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
1770         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
1771                                                                                        .set_name(regular_layer_name)
1772                                                                                        .set_path(env.get_layer_manifest_path())
1773                                                                                        .set_control("on"))));
1774     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
1775 
1776     auto layer_props = env.GetLayerProperties(1);
1777     EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
1778 
1779     InstWrapper inst{env.vulkan_functions};
1780     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1781     inst.CheckCreate();
1782 
1783     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1784     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1785     ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
1786 }
1787 
TEST(SettingsFile,MultipleKeysInRegistryInSecureLocation)1788 TEST(SettingsFile, MultipleKeysInRegistryInSecureLocation) {
1789     FrameworkEnvironment env{FrameworkSettings{}.set_secure_loader_settings(true)};
1790     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1791     env.platform_shim->add_manifest(ManifestCategory::settings, "jank_path");
1792     env.platform_shim->add_manifest(ManifestCategory::settings, "jank_path2");
1793 
1794     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
1795     env.add_explicit_layer(TestLayerDetails{
1796         ManifestLayer{}.add_layer(
1797             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1798         "regular_test_layer.json"}
1799                                .set_discovery_type(ManifestDiscoveryType::override_folder));
1800     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
1801         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(LoaderSettingsLayerConfiguration{}
1802                                                                                        .set_name(regular_layer_name)
1803                                                                                        .set_path(env.get_layer_manifest_path())
1804                                                                                        .set_control("on"))));
1805     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
1806 
1807     // Make sure it works if the settings file is in the HKEY_LOCAL_MACHINE
1808     env.platform_shim->set_elevated_privilege(true);
1809     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
1810     {
1811         auto layer_props = env.GetLayerProperties(1);
1812         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
1813 
1814         InstWrapper inst{env.vulkan_functions};
1815         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1816         inst.CheckCreate();
1817 
1818         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1819         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1820         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
1821     }
1822 }
1823 #endif
1824 
1825 // Preinstance functions respect the settings file
TEST(SettingsFile,PreInstanceFunctions)1826 TEST(SettingsFile, PreInstanceFunctions) {
1827     FrameworkEnvironment env;
1828     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
1829 
1830     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
1831 
1832     env.add_implicit_layer(
1833         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
1834             ManifestLayer::LayerDescription{}
1835                 .set_name(implicit_layer_name)
1836                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1837                 .set_disable_environment("DISABLE_ME")
1838                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
1839                                                .set_vk_func("vkEnumerateInstanceLayerProperties")
1840                                                .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
1841                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
1842                                                .set_vk_func("vkEnumerateInstanceExtensionProperties")
1843                                                .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
1844                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
1845                                                .set_vk_func("vkEnumerateInstanceVersion")
1846                                                .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
1847         "implicit_test_layer.json");
1848 
1849     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1850         LoaderSettingsLayerConfiguration{}
1851             .set_name(implicit_layer_name)
1852             .set_control("on")
1853             .set_path(env.get_shimmed_layer_manifest_path(0))
1854             .set_treat_as_implicit_manifest(true)));
1855     env.update_loader_settings(env.loader_settings);
1856     {
1857         auto& layer = env.get_test_layer(0);
1858         // Check layer props
1859         uint32_t layer_props = 43;
1860         layer.set_reported_layer_props(layer_props);
1861 
1862         uint32_t count = 0;
1863         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1864         ASSERT_EQ(count, layer_props);
1865 
1866         // check extension props
1867         uint32_t ext_props = 52;
1868         layer.set_reported_extension_props(ext_props);
1869         count = 0;
1870         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
1871         ASSERT_EQ(count, ext_props);
1872 
1873         // check version
1874         uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
1875         layer.set_reported_instance_version(layer_version);
1876 
1877         uint32_t version = 0;
1878         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
1879         ASSERT_EQ(version, layer_version);
1880     }
1881     // control is set to off
1882     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off");
1883     env.update_loader_settings(env.loader_settings);
1884 
1885     {
1886         auto& layer = env.get_test_layer(0);
1887         // Check layer props
1888         uint32_t layer_props = 43;
1889         layer.set_reported_layer_props(layer_props);
1890 
1891         uint32_t count = 0;
1892         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1893         ASSERT_EQ(count, 0U);  // dont use the intercepted count
1894 
1895         // check extension props
1896         uint32_t ext_props = 52;
1897         layer.set_reported_extension_props(ext_props);
1898         count = 0;
1899         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
1900         ASSERT_EQ(count, 4U);  // dont use the intercepted count - use default count
1901 
1902         // check version
1903         uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
1904         layer.set_reported_instance_version(layer_version);
1905 
1906         uint32_t version = 0;
1907         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
1908         ASSERT_EQ(version, VK_HEADER_VERSION_COMPLETE);
1909     }
1910 
1911     // control is set to auto
1912     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto");
1913     env.update_loader_settings(env.loader_settings);
1914 
1915     {
1916         auto& layer = env.get_test_layer(0);
1917         // Check layer props
1918         uint32_t layer_props = 43;
1919         layer.set_reported_layer_props(layer_props);
1920 
1921         uint32_t count = 0;
1922         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1923         ASSERT_EQ(count, layer_props);
1924 
1925         // check extension props
1926         uint32_t ext_props = 52;
1927         layer.set_reported_extension_props(ext_props);
1928         count = 0;
1929         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
1930         ASSERT_EQ(count, ext_props);
1931 
1932         // check version
1933         uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
1934         layer.set_reported_instance_version(layer_version);
1935 
1936         uint32_t version = 0;
1937         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
1938         ASSERT_EQ(version, layer_version);
1939     }
1940 }
1941 
1942 // If an implicit layer's disable environment variable is set, but the settings file says to turn the layer on, the layer should be
1943 // activated.
TEST(SettingsFile,ImplicitLayerDisableEnvironmentVariableOverriden)1944 TEST(SettingsFile, ImplicitLayerDisableEnvironmentVariableOverriden) {
1945     FrameworkEnvironment env;
1946     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
1947 
1948     const char* filler_layer_name = "VK_LAYER_filler";
1949     env.add_explicit_layer(
1950         ManifestLayer{}.add_layer(
1951             ManifestLayer::LayerDescription{}.set_name(filler_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1952         "explicit_test_layer.json");
1953 
1954     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
1955     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1956                                                          .set_name(implicit_layer_name)
1957                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1958                                                          .set_disable_environment("DISABLE_ME")
1959                                                          .set_enable_environment("ENABLE_ME")),
1960                            "implicit_test_layer.json");
1961     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configurations(
1962         {LoaderSettingsLayerConfiguration{}
1963              .set_name(filler_layer_name)
1964              .set_path(env.get_shimmed_layer_manifest_path(0))
1965              .set_control("auto")
1966              .set_treat_as_implicit_manifest(false),
1967          LoaderSettingsLayerConfiguration{}
1968              .set_name(implicit_layer_name)
1969              .set_path(env.get_shimmed_layer_manifest_path(1))
1970              .set_control("auto")
1971              .set_treat_as_implicit_manifest(true)}));
1972 
1973     auto check_log_for_insert_instance_layer_string = [&env, implicit_layer_name](bool check_for_enable) {
1974         {
1975             InstWrapper inst{env.vulkan_functions};
1976             FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1977             inst.CheckCreate();
1978             if (check_for_enable) {
1979                 ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name));
1980                 auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1981                 ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name));
1982             } else {
1983                 ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name));
1984                 ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1985             }
1986         }
1987         env.debug_log.clear();
1988     };
1989 
1990     // control is set to on
1991     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).set_control("on");
1992     env.update_loader_settings(env.loader_settings);
1993     {
1994         EnvVarWrapper enable_env_var{"ENABLE_ME"};
1995         EnvVarWrapper disable_env_var{"DISABLE_ME"};
1996 
1997         auto layers = env.GetLayerProperties(2);
1998         ASSERT_TRUE(string_eq(layers[0].layerName, filler_layer_name));
1999         ASSERT_TRUE(string_eq(layers[1].layerName, implicit_layer_name));
2000 
2001         check_log_for_insert_instance_layer_string(true);
2002 
2003         enable_env_var.set_new_value("0");
2004         check_log_for_insert_instance_layer_string(true);
2005 
2006         enable_env_var.set_new_value("1");
2007         check_log_for_insert_instance_layer_string(true);
2008 
2009         enable_env_var.remove_value();
2010 
2011         disable_env_var.set_new_value("0");
2012         check_log_for_insert_instance_layer_string(true);
2013 
2014         disable_env_var.set_new_value("1");
2015         check_log_for_insert_instance_layer_string(true);
2016 
2017         enable_env_var.set_new_value("1");
2018         disable_env_var.set_new_value("1");
2019         check_log_for_insert_instance_layer_string(true);
2020     }
2021 
2022     // control is set to off
2023     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).set_control("off");
2024     env.update_loader_settings(env.loader_settings);
2025     {
2026         EnvVarWrapper enable_env_var{"ENABLE_ME"};
2027         EnvVarWrapper disable_env_var{"DISABLE_ME"};
2028 
2029         auto layers = env.GetLayerProperties(1);
2030         ASSERT_TRUE(string_eq(layers[0].layerName, filler_layer_name));
2031 
2032         check_log_for_insert_instance_layer_string(false);
2033 
2034         enable_env_var.set_new_value("0");
2035         check_log_for_insert_instance_layer_string(false);
2036 
2037         enable_env_var.set_new_value("1");
2038         check_log_for_insert_instance_layer_string(false);
2039 
2040         enable_env_var.remove_value();
2041 
2042         disable_env_var.set_new_value("0");
2043         check_log_for_insert_instance_layer_string(false);
2044 
2045         disable_env_var.set_new_value("1");
2046         check_log_for_insert_instance_layer_string(false);
2047 
2048         enable_env_var.set_new_value("1");
2049         disable_env_var.set_new_value("1");
2050         check_log_for_insert_instance_layer_string(false);
2051     }
2052 
2053     // control is set to auto
2054     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(1).set_control("auto");
2055     env.update_loader_settings(env.loader_settings);
2056     {
2057         EnvVarWrapper enable_env_var{"ENABLE_ME"};
2058         EnvVarWrapper disable_env_var{"DISABLE_ME"};
2059 
2060         auto layers = env.GetLayerProperties(2);
2061         ASSERT_TRUE(string_eq(layers[0].layerName, filler_layer_name));
2062         ASSERT_TRUE(string_eq(layers[1].layerName, implicit_layer_name));
2063 
2064         check_log_for_insert_instance_layer_string(false);
2065 
2066         enable_env_var.set_new_value("0");
2067         check_log_for_insert_instance_layer_string(false);
2068 
2069         enable_env_var.set_new_value("1");
2070         check_log_for_insert_instance_layer_string(true);
2071 
2072         enable_env_var.remove_value();
2073 
2074         disable_env_var.set_new_value("0");
2075         check_log_for_insert_instance_layer_string(false);
2076 
2077         disable_env_var.set_new_value("1");
2078         check_log_for_insert_instance_layer_string(false);
2079 
2080         enable_env_var.set_new_value("1");
2081         disable_env_var.set_new_value("1");
2082         check_log_for_insert_instance_layer_string(false);
2083     }
2084 }
2085 
TEST(SettingsFile,ImplicitLayersNotAccidentallyEnabled)2086 TEST(SettingsFile, ImplicitLayersNotAccidentallyEnabled) {
2087     FrameworkEnvironment env{};
2088     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
2089     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
2090     std::vector<const char*> layer_names;
2091 
2092     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_alpha", LayerType::imp, "auto"));
2093     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_bravo", LayerType::imp_with_enable_env, "auto"));
2094     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_charlie", LayerType::imp_with_enable_env, "auto"));
2095     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_delta", LayerType::imp_with_enable_env, "auto"));
2096 
2097     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_echo", LayerType::exp, "auto"));
2098     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_foxtrot", LayerType::exp, "auto"));
2099     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_gamma", LayerType::exp, "auto"));
2100     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_indigo", LayerType::exp, "auto"));
2101     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_juniper", LayerType::exp, "auto"));
2102 
2103     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_kangaroo", LayerType::exp, "on"));
2104 
2105     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_lima", LayerType::exp, "auto"));
2106     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_mango", LayerType::exp, "auto"));
2107     layer_names.push_back(add_layer_and_settings(env, "VK_LAYER_niagara", LayerType::exp, "auto"));
2108 
2109     env.update_loader_settings(env.loader_settings);
2110     {
2111         auto layer_props = env.GetLayerProperties(13);
2112         for (size_t i = 0; i < layer_props.size(); i++) {
2113             ASSERT_TRUE(string_eq(layer_names.at(i), layer_props.at(i).layerName));
2114         }
2115         InstWrapper inst{env.vulkan_functions};
2116         inst.CheckCreate();
2117         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
2118         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_names.at(0)));
2119         ASSERT_TRUE(string_eq(layers.at(1).layerName, layer_names.at(9)));
2120     }
2121 
2122     {
2123         EnvVarWrapper env_var{"MUSHROOM1", "1"};
2124         auto layer_props = env.GetLayerProperties(13);
2125         for (size_t i = 0; i < layer_props.size(); i++) {
2126             ASSERT_TRUE(string_eq(layer_names.at(i), layer_props.at(i).layerName));
2127         }
2128         InstWrapper inst{env.vulkan_functions};
2129         inst.CheckCreate();
2130         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
2131         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_names.at(0)));
2132         ASSERT_TRUE(string_eq(layers.at(1).layerName, layer_names.at(1)));
2133         ASSERT_TRUE(string_eq(layers.at(2).layerName, layer_names.at(9)));
2134     }
2135     {
2136         EnvVarWrapper env_var{"BADGER0", "1"};
2137         auto layer_props = env.GetLayerProperties(13);
2138         for (size_t i = 0; i < layer_props.size(); i++) {
2139             ASSERT_TRUE(string_eq(layer_names.at(i), layer_props.at(i).layerName));
2140         }
2141         InstWrapper inst{env.vulkan_functions};
2142         inst.CheckCreate();
2143         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2144         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_names.at(9)));
2145     }
2146 }
2147 
TEST(SettingsFile,ImplicitLayersPreInstanceEnumInstLayerProps)2148 TEST(SettingsFile, ImplicitLayersPreInstanceEnumInstLayerProps) {
2149     FrameworkEnvironment env;
2150     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2151     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
2152 
2153     env.add_implicit_layer(
2154         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
2155             ManifestLayer::LayerDescription{}
2156                 .set_name(implicit_layer_name)
2157                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2158                 .set_disable_environment("DISABLE_ME")
2159                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
2160                                                .set_vk_func("vkEnumerateInstanceLayerProperties")
2161                                                .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
2162         "implicit_test_layer.json");
2163 
2164     env.update_loader_settings(
2165         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
2166             LoaderSettingsLayerConfiguration{}
2167                 .set_name(implicit_layer_name)
2168                 .set_path(env.get_shimmed_layer_manifest_path(0))
2169                 .set_control("auto")
2170                 .set_treat_as_implicit_manifest(true))));
2171 
2172     uint32_t layer_props = 43;
2173     auto& layer = env.get_test_layer(0);
2174     layer.set_reported_layer_props(layer_props);
2175 
2176     uint32_t count = 0;
2177     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2178     ASSERT_EQ(count, layer_props);
2179 }
2180 
TEST(SettingsFile,EnableEnvironmentImplicitLayersPreInstanceEnumInstLayerProps)2181 TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceEnumInstLayerProps) {
2182     FrameworkEnvironment env;
2183     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2184     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
2185 
2186     env.add_implicit_layer(
2187         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
2188             ManifestLayer::LayerDescription{}
2189                 .set_name(implicit_layer_name)
2190                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2191                 .set_disable_environment("DISABLE_ME")
2192                 .set_enable_environment("ENABLE_ME")
2193                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
2194                                                .set_vk_func("vkEnumerateInstanceLayerProperties")
2195                                                .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
2196         "implicit_test_layer.json");
2197 
2198     env.update_loader_settings(
2199         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
2200             LoaderSettingsLayerConfiguration{}
2201                 .set_name(implicit_layer_name)
2202                 .set_path(env.get_shimmed_layer_manifest_path(0))
2203                 .set_control("auto")
2204                 .set_treat_as_implicit_manifest(true))));
2205 
2206     uint32_t layer_props = 43;
2207     auto& layer = env.get_test_layer(0);
2208     layer.set_reported_layer_props(layer_props);
2209 
2210     uint32_t count = 0;
2211     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2212     ASSERT_EQ(count, 1U);
2213     std::array<VkLayerProperties, 1> layers{};
2214     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, layers.data()));
2215     ASSERT_EQ(count, 1U);
2216     ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name));
2217 }
2218 
TEST(SettingsFile,ImplicitLayersPreInstanceEnumInstExtProps)2219 TEST(SettingsFile, ImplicitLayersPreInstanceEnumInstExtProps) {
2220     FrameworkEnvironment env;
2221     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2222     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
2223 
2224     env.add_implicit_layer(
2225         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
2226             ManifestLayer::LayerDescription{}
2227                 .set_name(implicit_layer_name)
2228                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2229                 .set_disable_environment("DISABLE_ME")
2230                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
2231                                                .set_vk_func("vkEnumerateInstanceExtensionProperties")
2232                                                .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
2233         "implicit_test_layer.json");
2234 
2235     env.update_loader_settings(
2236         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
2237             LoaderSettingsLayerConfiguration{}
2238                 .set_name(implicit_layer_name)
2239                 .set_path(env.get_shimmed_layer_manifest_path(0))
2240                 .set_control("auto")
2241                 .set_treat_as_implicit_manifest(true))));
2242 
2243     uint32_t ext_props = 52;
2244     auto& layer = env.get_test_layer(0);
2245     layer.set_reported_extension_props(ext_props);
2246 
2247     uint32_t count = 0;
2248     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
2249     ASSERT_EQ(count, ext_props);
2250 }
2251 
TEST(SettingsFile,EnableEnvironmentImplicitLayersPreInstanceEnumInstExtProps)2252 TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceEnumInstExtProps) {
2253     FrameworkEnvironment env;
2254     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2255     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
2256 
2257     env.add_implicit_layer(
2258         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
2259             ManifestLayer::LayerDescription{}
2260                 .set_name(implicit_layer_name)
2261                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2262                 .set_disable_environment("DISABLE_ME")
2263                 .set_enable_environment("ENABLE_ME")
2264                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
2265                                                .set_vk_func("vkEnumerateInstanceExtensionProperties")
2266                                                .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
2267         "implicit_test_layer.json");
2268 
2269     env.update_loader_settings(
2270         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
2271             LoaderSettingsLayerConfiguration{}
2272                 .set_name(implicit_layer_name)
2273                 .set_path(env.get_shimmed_layer_manifest_path(0))
2274                 .set_control("auto")
2275                 .set_treat_as_implicit_manifest(true))));
2276 
2277     uint32_t ext_props = 52;
2278     auto& layer = env.get_test_layer(0);
2279     layer.set_reported_extension_props(ext_props);
2280 
2281     auto extensions = env.GetInstanceExtensions(4);
2282     EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME));
2283     EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME));
2284     EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME));
2285     EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME));
2286 }
2287 
TEST(SettingsFile,ImplicitLayersPreInstanceVersion)2288 TEST(SettingsFile, ImplicitLayersPreInstanceVersion) {
2289     FrameworkEnvironment env;
2290     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
2291         .add_physical_device({})
2292         .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3));
2293 
2294     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
2295 
2296     env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
2297                                ManifestLayer::LayerDescription{}
2298                                    .set_name(implicit_layer_name)
2299                                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2300                                    .set_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3))
2301                                    .set_disable_environment("DISABLE_ME")
2302                                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
2303                                                                   .set_vk_func("vkEnumerateInstanceVersion")
2304                                                                   .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
2305                            "implicit_test_layer.json");
2306 
2307     env.update_loader_settings(
2308         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
2309             LoaderSettingsLayerConfiguration{}
2310                 .set_name(implicit_layer_name)
2311                 .set_path(env.get_shimmed_layer_manifest_path(0))
2312                 .set_control("auto")
2313                 .set_treat_as_implicit_manifest(true))));
2314 
2315     uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
2316     auto& layer = env.get_test_layer(0);
2317     layer.set_reported_instance_version(layer_version);
2318 
2319     uint32_t version = 0;
2320     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
2321     ASSERT_EQ(version, layer_version);
2322 }
2323 
TEST(SettingsFile,EnableEnvironmentImplicitLayersPreInstanceVersion)2324 TEST(SettingsFile, EnableEnvironmentImplicitLayersPreInstanceVersion) {
2325     FrameworkEnvironment env;
2326     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA))
2327         .add_physical_device({})
2328         .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3));
2329 
2330     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
2331 
2332     env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
2333                                ManifestLayer::LayerDescription{}
2334                                    .set_name(implicit_layer_name)
2335                                    .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2336                                    .set_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3))
2337                                    .set_disable_environment("DISABLE_ME")
2338                                    .set_enable_environment("ENABLE_ME")
2339                                    .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
2340                                                                   .set_vk_func("vkEnumerateInstanceVersion")
2341                                                                   .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
2342                            "implicit_test_layer.json");
2343 
2344     env.update_loader_settings(
2345         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
2346             LoaderSettingsLayerConfiguration{}
2347                 .set_name(implicit_layer_name)
2348                 .set_path(env.get_shimmed_layer_manifest_path(0))
2349                 .set_control("auto")
2350                 .set_treat_as_implicit_manifest(true))));
2351 
2352     uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
2353     auto& layer = env.get_test_layer(0);
2354     layer.set_reported_instance_version(layer_version);
2355 
2356     uint32_t version = 0;
2357     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
2358     ASSERT_EQ(version, VK_HEADER_VERSION_COMPLETE);
2359 }
2360 
2361 // Settings can say which filters to use - make sure those are propagated & treated correctly
TEST(SettingsFile,StderrLogFilters)2362 TEST(SettingsFile, StderrLogFilters) {
2363     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
2364     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
2365     const char* explicit_layer_name = "Regular_TestLayer1";
2366     env.add_explicit_layer(TestLayerDetails{
2367         ManifestLayer{}.add_layer(
2368             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2369         "explicit_test_layer1.json"});
2370     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
2371         AppSpecificSettings{}
2372             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
2373                                          .set_name(explicit_layer_name)
2374                                          .set_path(env.get_shimmed_layer_manifest_path())
2375                                          .set_control("on"))
2376             .add_layer_configuration(
2377                 LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("on"))));
2378 
2379     std::string expected_output_verbose;
2380     expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Configurations count = 2\n";
2381     expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [0] ----\n";
2382     expected_output_verbose += std::string("[Vulkan Loader] DEBUG:          Name: ") + explicit_layer_name + "\n";
2383     expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: " + env.get_shimmed_layer_manifest_path().string() + "\n";
2384     expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
2385     expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: on\n";
2386     expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [1] ----\n";
2387     expected_output_verbose += "[Vulkan Loader] DEBUG:          Name: VK_LAYER_missing\n";
2388     expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: /road/to/nowhere\n";
2389     expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
2390     expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: on\n";
2391     expected_output_verbose += "[Vulkan Loader] DEBUG:          ---------------------------------\n";
2392 
2393     std::string expected_output_info =
2394         std::string("[Vulkan Loader] INFO:           ") + get_settings_location_log_message(env) + "\n";
2395 
2396     std::string expected_output_warning = "[Vulkan Loader] WARNING:        Layer name " + std::string(explicit_layer_name) +
2397                                           " does not conform to naming standard (Policy #LLP_LAYER_3)\n";
2398 
2399     std::string expected_output_error =
2400         "[Vulkan Loader] ERROR:          loader_get_json: Failed to open JSON file /road/to/nowhere\n";
2401 
2402     env.loader_settings.app_specific_settings.at(0).stderr_log = {"all"};
2403     env.update_loader_settings(env.loader_settings);
2404     {
2405         InstWrapper inst{env.vulkan_functions};
2406         inst.CheckCreate();
2407 
2408         ASSERT_TRUE(env.platform_shim->find_in_log(
2409             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: ERROR | "
2410             "WARNING | INFO | DEBUG | PERF | DRIVER | LAYER\n"));
2411         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
2412         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
2413         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
2414         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_error));
2415         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2416         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2417     }
2418     env.platform_shim->clear_logs();
2419     env.loader_settings.app_specific_settings.at(0).stderr_log = {"error", "warn", "info", "debug"};
2420     env.update_loader_settings(env.loader_settings);
2421     {
2422         InstWrapper inst{env.vulkan_functions};
2423         inst.CheckCreate();
2424 
2425         ASSERT_TRUE(
2426             env.platform_shim->find_in_log("[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard "
2427                                            "Error: ERROR | WARNING | INFO | DEBUG\n"));
2428         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
2429         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
2430         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
2431         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_error));
2432         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2433         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2434     }
2435     env.platform_shim->clear_logs();
2436     env.loader_settings.app_specific_settings.at(0).stderr_log = {"warn", "info", "debug"};
2437     env.update_loader_settings(env.loader_settings);
2438     {
2439         InstWrapper inst{env.vulkan_functions};
2440         inst.CheckCreate();
2441 
2442         ASSERT_TRUE(env.platform_shim->find_in_log(
2443             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: WARNING | INFO | DEBUG\n"));
2444         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
2445         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
2446         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
2447         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_error));
2448         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2449         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2450     }
2451     env.platform_shim->clear_logs();
2452     env.loader_settings.app_specific_settings.at(0).stderr_log = {"debug"};
2453     env.update_loader_settings(env.loader_settings);
2454     {
2455         InstWrapper inst{env.vulkan_functions};
2456         inst.CheckCreate();
2457 
2458         ASSERT_TRUE(env.platform_shim->find_in_log(
2459             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: DEBUG\n"));
2460         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
2461         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
2462         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
2463         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_error));
2464         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2465         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2466     }
2467     env.platform_shim->clear_logs();
2468     env.loader_settings.app_specific_settings.at(0).stderr_log = {"info"};
2469     env.update_loader_settings(env.loader_settings);
2470     {
2471         InstWrapper inst{env.vulkan_functions};
2472         inst.CheckCreate();
2473 
2474         ASSERT_FALSE(env.platform_shim->find_in_log(
2475             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: INFO\n"));
2476         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
2477         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_info));
2478         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
2479         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_error));
2480         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2481         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2482     }
2483     env.platform_shim->clear_logs();
2484     env.loader_settings.app_specific_settings.at(0).stderr_log = {"warn"};
2485     env.update_loader_settings(env.loader_settings);
2486     {
2487         InstWrapper inst{env.vulkan_functions};
2488         inst.CheckCreate();
2489 
2490         ASSERT_FALSE(env.platform_shim->find_in_log(
2491             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: WARNING\n"));
2492         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
2493         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
2494         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
2495         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_error));
2496         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2497         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2498     }
2499     env.platform_shim->clear_logs();
2500     env.loader_settings.app_specific_settings.at(0).stderr_log = {"error"};
2501     env.update_loader_settings(env.loader_settings);
2502     {
2503         InstWrapper inst{env.vulkan_functions};
2504         inst.CheckCreate();
2505 
2506         ASSERT_FALSE(env.platform_shim->find_in_log(
2507             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error: ERROR\n"));
2508         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
2509         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
2510         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
2511         ASSERT_TRUE(env.platform_shim->find_in_log(expected_output_error));
2512         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2513         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2514     }
2515     env.platform_shim->clear_logs();
2516     env.loader_settings.app_specific_settings.at(0).stderr_log = {""};  // Empty string shouldn't be misinterpreted
2517     env.update_loader_settings(env.loader_settings);
2518     {
2519         InstWrapper inst{env.vulkan_functions};
2520         inst.CheckCreate();
2521 
2522         ASSERT_FALSE(env.platform_shim->find_in_log(
2523             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error:"));
2524         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
2525         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
2526         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
2527         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_error));
2528         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2529         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2530     }
2531     env.platform_shim->clear_logs();
2532     env.loader_settings.app_specific_settings.at(0).stderr_log = {};  // No string in the log
2533     env.update_loader_settings(env.loader_settings);
2534     {
2535         InstWrapper inst{env.vulkan_functions};
2536         inst.CheckCreate();
2537 
2538         ASSERT_FALSE(env.platform_shim->find_in_log(
2539             "[Vulkan Loader] DEBUG:          Loader Settings Filters for Logging to Standard Error:"));
2540         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_verbose));
2541         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_info));
2542         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_warning));
2543         ASSERT_FALSE(env.platform_shim->find_in_log(expected_output_error));
2544         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2545         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2546     }
2547 }
2548 
2549 // Settings can say which filters to use - make sure the lack of this filter works correctly with VK_LOADER_DEBUG
TEST(SettingsFile,StderrLog_NoOutput)2550 TEST(SettingsFile, StderrLog_NoOutput) {
2551     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("")};
2552     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
2553     const char* explicit_layer_name = "Regular_TestLayer1";
2554     env.add_explicit_layer(TestLayerDetails{
2555         ManifestLayer{}.add_layer(
2556             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2557         "explicit_test_layer1.json"});
2558     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
2559         AppSpecificSettings{}
2560             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
2561                                          .set_name(explicit_layer_name)
2562                                          .set_path(env.get_shimmed_layer_manifest_path())
2563                                          .set_control("auto"))
2564             .add_layer_configuration(
2565                 LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("auto"))));
2566     env.loader_settings.app_specific_settings.at(0).stderr_log = {""};
2567     env.update_loader_settings(env.loader_settings);
2568 
2569     {
2570         InstWrapper inst{env.vulkan_functions};
2571         inst.CheckCreate();
2572         EXPECT_TRUE(env.platform_shim->fputs_stderr_log.empty());
2573 
2574         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 0);
2575         EXPECT_TRUE(active_layer_props.size() == 0);
2576     }
2577     // Check if an empty string (vs lack of the stderr_log field) produces correct output
2578     env.loader_settings.app_specific_settings.at(0).stderr_log = {};
2579     env.update_loader_settings(env.loader_settings);
2580     {
2581         InstWrapper inst{env.vulkan_functions};
2582         inst.CheckCreate();
2583 
2584         EXPECT_TRUE(env.platform_shim->fputs_stderr_log.empty());
2585         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 0);
2586         EXPECT_TRUE(active_layer_props.size() == 0);
2587     }
2588 
2589     env.loader_settings.app_specific_settings.at(0).stderr_log.clear();
2590     env.update_loader_settings(env.loader_settings);
2591     {
2592         EnvVarWrapper instance_layers{"VK_INSTANCE_LAYERS", explicit_layer_name};
2593 
2594         InstWrapper inst{env.vulkan_functions};
2595         inst.CheckCreate();
2596         EXPECT_TRUE(env.platform_shim->fputs_stderr_log.empty());
2597 
2598         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2599         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2600     }
2601 
2602     {
2603         EnvVarWrapper instance_layers{"VK_LOADER_LAYERS_ENABLE", explicit_layer_name};
2604 
2605         InstWrapper inst{env.vulkan_functions};
2606         inst.CheckCreate();
2607 
2608         EXPECT_TRUE(env.platform_shim->fputs_stderr_log.empty());
2609         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2610         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2611     }
2612     env.loader_settings.app_specific_settings.at(0).stderr_log = {};
2613     env.update_loader_settings(env.loader_settings);
2614     {
2615         EnvVarWrapper instance_layers{"VK_INSTANCE_LAYERS", explicit_layer_name};
2616 
2617         InstWrapper inst{env.vulkan_functions};
2618         inst.CheckCreate();
2619         EXPECT_TRUE(env.platform_shim->fputs_stderr_log.empty());
2620 
2621         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2622         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2623     }
2624 
2625     {
2626         EnvVarWrapper instance_layers{"VK_LOADER_LAYERS_ENABLE", explicit_layer_name};
2627 
2628         InstWrapper inst{env.vulkan_functions};
2629         inst.CheckCreate();
2630 
2631         EXPECT_TRUE(env.platform_shim->fputs_stderr_log.empty());
2632         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2633         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
2634     }
2635 }
2636 
2637 // Settings can say which filters to use - make sure the lack of this filter works correctly with VK_LOADER_DEBUG
TEST(SettingsFile,NoStderr_log_but_VK_LOADER_DEBUG)2638 TEST(SettingsFile, NoStderr_log_but_VK_LOADER_DEBUG) {
2639     FrameworkEnvironment env{FrameworkSettings{}.set_log_filter("all")};
2640     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
2641 
2642     const char* explicit_layer_name = "Regular_TestLayer1";
2643 
2644     env.add_explicit_layer(TestLayerDetails{
2645         ManifestLayer{}.add_layer(
2646             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2647         "explicit_test_layer1.json"});
2648 
2649     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
2650         AppSpecificSettings{}
2651             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
2652                                          .set_name(explicit_layer_name)
2653                                          .set_path(env.get_shimmed_layer_manifest_path())
2654                                          .set_control("auto"))
2655             .add_layer_configuration(
2656                 LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("auto"))));
2657     env.loader_settings.app_specific_settings.at(0).stderr_log = {};
2658     env.update_loader_settings(env.loader_settings);
2659 
2660     std::string expected_output_verbose;
2661     expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Configurations count = 2\n";
2662     expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [0] ----\n";
2663     expected_output_verbose += std::string("[Vulkan Loader] DEBUG:          Name: ") + explicit_layer_name + "\n";
2664     expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: " + env.get_shimmed_layer_manifest_path().string() + "\n";
2665     expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
2666     expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: auto\n";
2667     expected_output_verbose += "[Vulkan Loader] DEBUG:          ---- Layer Configuration [1] ----\n";
2668     expected_output_verbose += "[Vulkan Loader] DEBUG:          Name: VK_LAYER_missing\n";
2669     expected_output_verbose += "[Vulkan Loader] DEBUG:          Path: /road/to/nowhere\n";
2670     expected_output_verbose += "[Vulkan Loader] DEBUG:          Layer Type: Explicit\n";
2671     expected_output_verbose += "[Vulkan Loader] DEBUG:          Control: auto\n";
2672     expected_output_verbose += "[Vulkan Loader] DEBUG:          ---------------------------------\n";
2673 
2674     std::string expected_output_info =
2675         std::string("[Vulkan Loader] INFO:           ") + get_settings_location_log_message(env) + "\n";
2676 
2677     std::string expected_output_warning =
2678         "[Vulkan Loader] WARNING:        Layer name Regular_TestLayer1 does not conform to naming standard (Policy #LLP_LAYER_3)\n";
2679 
2680     std::string expected_output_error =
2681         "[Vulkan Loader] ERROR:          loader_get_json: Failed to open JSON file /road/to/nowhere\n";
2682 
2683     env.platform_shim->clear_logs();
2684     {
2685         InstWrapper inst{env.vulkan_functions};
2686         inst.CheckCreate();
2687         EXPECT_TRUE(env.platform_shim->find_in_log(expected_output_verbose));
2688         EXPECT_TRUE(env.platform_shim->find_in_log(expected_output_info));
2689         EXPECT_TRUE(env.platform_shim->find_in_log(expected_output_warning));
2690         EXPECT_TRUE(env.platform_shim->find_in_log(expected_output_error));
2691 
2692         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 0);
2693         EXPECT_TRUE(active_layer_props.size() == 0);
2694     }
2695 }
TEST(SettingsFile,ManyLayersEnabledInManyWays)2696 TEST(SettingsFile, ManyLayersEnabledInManyWays) {
2697     FrameworkEnvironment env{};
2698     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
2699     const char* layer1 = "VK_LAYER_layer1";
2700     env.add_explicit_layer(
2701         TestLayerDetails{ManifestLayer{}.add_layer(
2702                              ManifestLayer::LayerDescription{}.set_name(layer1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2703                          "explicit_layer1.json"});
2704     const char* layer2 = "VK_LAYER_layer2";
2705     env.add_explicit_layer(
2706         TestLayerDetails{ManifestLayer{}.add_layer(
2707                              ManifestLayer::LayerDescription{}.set_name(layer2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2708                          "explicit_layer2.json"});
2709     const char* layer3 = "VK_LAYER_layer3";
2710     env.add_explicit_layer(
2711         TestLayerDetails{ManifestLayer{}.add_layer(
2712                              ManifestLayer::LayerDescription{}.set_name(layer3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2713                          "explicit_layer3.json"});
2714     const char* layer4 = "VK_LAYER_layer4";
2715     env.add_explicit_layer(
2716         TestLayerDetails{ManifestLayer{}.add_layer(
2717                              ManifestLayer::LayerDescription{}.set_name(layer4).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2718                          "explicit_layer4.json"});
2719     const char* layer5 = "VK_LAYER_layer5";
2720     env.add_explicit_layer(
2721         TestLayerDetails{ManifestLayer{}.add_layer(
2722                              ManifestLayer::LayerDescription{}.set_name(layer5).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2723                          "explicit_layer5.json"});
2724 
2725     env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
2726         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configurations(
2727             {LoaderSettingsLayerConfiguration{}.set_name(layer1).set_path(env.get_shimmed_layer_manifest_path(0)).set_control("on"),
2728              LoaderSettingsLayerConfiguration{}
2729                  .set_name(layer2)
2730                  .set_path(env.get_shimmed_layer_manifest_path(1))
2731                  .set_control("auto"),
2732              LoaderSettingsLayerConfiguration{}
2733                  .set_name(layer3)
2734                  .set_path(env.get_shimmed_layer_manifest_path(2))
2735                  .set_control("auto"),
2736              LoaderSettingsLayerConfiguration{}
2737                  .set_name(layer4)
2738                  .set_path(env.get_shimmed_layer_manifest_path(3))
2739                  .set_control("auto"),
2740              LoaderSettingsLayerConfiguration{}
2741                  .set_name(layer5)
2742                  .set_path(env.get_shimmed_layer_manifest_path(4))
2743                  .set_control("on")}));
2744     env.update_loader_settings(env.loader_settings);
2745 
2746     EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS", layer2};
2747     EnvVarWrapper vk_loader_layers_enable{"VK_LOADER_LAYERS_ENABLE", layer1};
2748 
2749     auto layers = env.GetLayerProperties(5);
2750     ASSERT_TRUE(string_eq(layers[0].layerName, layer1));
2751     ASSERT_TRUE(string_eq(layers[1].layerName, layer2));
2752     ASSERT_TRUE(string_eq(layers[2].layerName, layer3));
2753     ASSERT_TRUE(string_eq(layers[3].layerName, layer4));
2754     ASSERT_TRUE(string_eq(layers[4].layerName, layer5));
2755 
2756     InstWrapper inst{env.vulkan_functions};
2757     inst.CheckCreate();
2758 
2759     auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 3);
2760     EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, layer1));
2761     EXPECT_TRUE(string_eq(active_layer_props.at(1).layerName, layer2));
2762     EXPECT_TRUE(string_eq(active_layer_props.at(2).layerName, layer5));
2763 }
2764 
2765 // Enough layers exist that arrays need to be resized - make sure that works
TEST(SettingsFile,TooManyLayers)2766 TEST(SettingsFile, TooManyLayers) {
2767     FrameworkEnvironment env{};
2768     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
2769     env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
2770         AppSpecificSettings{}.add_stderr_log_filter("all"));
2771     std::string layer_name = "VK_LAYER_regular_layer_name_";
2772     uint32_t layer_count = 40;
2773     for (uint32_t i = 0; i < layer_count; i++) {
2774         env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2775                                                                               .set_name(layer_name + std::to_string(i))
2776                                                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2777                                                 layer_name + std::to_string(i) + ".json"}
2778                                    .set_discovery_type(ManifestDiscoveryType::override_folder));
2779         env.loader_settings.app_specific_settings.at(0).add_layer_configuration(LoaderSettingsLayerConfiguration{}
2780                                                                                     .set_name(layer_name + std::to_string(i))
2781                                                                                     .set_path(env.get_layer_manifest_path(i))
2782                                                                                     .set_control("on"));
2783     }
2784     env.update_loader_settings(env.loader_settings);
2785 
2786     {
2787         auto layer_props = env.GetLayerProperties(40);
2788         for (uint32_t i = 0; i < layer_count; i++) {
2789             std::string expected_layer_name = layer_name + std::to_string(i);
2790             EXPECT_TRUE(string_eq(layer_props.at(i).layerName, expected_layer_name.c_str()));
2791         }
2792         InstWrapper inst{env.vulkan_functions};
2793         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
2794         inst.CheckCreate();
2795 
2796         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
2797         env.debug_log.clear();
2798         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 40);
2799         for (uint32_t i = 0; i < layer_count; i++) {
2800             std::string expected_layer_name = layer_name + std::to_string(i);
2801             EXPECT_TRUE(string_eq(layers.at(i).layerName, expected_layer_name.c_str()));
2802         }
2803     }
2804     env.loader_settings.app_specific_settings.at(0).layer_configurations.clear();
2805 
2806     // Now reverse the order to make sure adding the 'last' layer first works
2807     for (uint32_t i = 0; i < layer_count; i++) {
2808         env.loader_settings.app_specific_settings.at(0).add_layer_configuration(
2809             LoaderSettingsLayerConfiguration{}
2810                 .set_name(layer_name + std::to_string(layer_count - i - 1))
2811                 .set_path(env.get_layer_manifest_path(layer_count - i - 1))
2812                 .set_control("on"));
2813     }
2814     env.update_loader_settings(env.loader_settings);
2815 
2816     {
2817         auto layer_props = env.GetLayerProperties(40);
2818         for (uint32_t i = 0; i < layer_count; i++) {
2819             std::string expected_layer_name = layer_name + std::to_string(layer_count - i - 1);
2820             EXPECT_TRUE(string_eq(layer_props.at(i).layerName, expected_layer_name.c_str()));
2821         }
2822         InstWrapper inst{env.vulkan_functions};
2823         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
2824         inst.CheckCreate();
2825 
2826         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
2827         env.debug_log.clear();
2828         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 40);
2829         for (uint32_t i = 0; i < layer_count; i++) {
2830             std::string expected_layer_name = layer_name + std::to_string(layer_count - i - 1);
2831             EXPECT_TRUE(string_eq(layers.at(i).layerName, expected_layer_name.c_str()));
2832         }
2833     }
2834 }
2835 
TEST(SettingsFile,EnvVarsWorkTogether)2836 TEST(SettingsFile, EnvVarsWorkTogether) {
2837     FrameworkEnvironment env{};
2838     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device(PhysicalDevice{}.set_deviceName("regular").finish());
2839     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::env_var))
2840         .add_physical_device(PhysicalDevice{}.set_deviceName("env_var").finish());
2841     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::add_env_var))
2842         .add_physical_device(PhysicalDevice{}.set_deviceName("add_env_var").finish());
2843 
2844     const char* regular_explicit_layer = "VK_LAYER_regular_explicit_layer";
2845     env.add_explicit_layer(TestLayerDetails{
2846         ManifestLayer{}.add_layer(
2847             ManifestLayer::LayerDescription{}.set_name(regular_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2848         "regular_explicit_layer.json"});
2849     const char* regular_explicit_layer_settings_file_set_on = "VK_LAYER_regular_explicit_layer_settings_file_set_on";
2850     env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2851                                                                           .set_name(regular_explicit_layer_settings_file_set_on)
2852                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2853                                             "regular_explicit_layer_settings_file_set_on.json"});
2854 
2855     const char* env_var_explicit_layer = "VK_LAYER_env_var_explicit_layer";
2856     env.add_explicit_layer(TestLayerDetails{
2857         ManifestLayer{}.add_layer(
2858             ManifestLayer::LayerDescription{}.set_name(env_var_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2859         "env_var_explicit_layer.json"}
2860                                .set_discovery_type(ManifestDiscoveryType::env_var));
2861 
2862     const char* add_env_var_explicit_layer = "VK_LAYER_add_env_var_explicit_layer";
2863     env.add_explicit_layer(TestLayerDetails{
2864         ManifestLayer{}.add_layer(
2865             ManifestLayer::LayerDescription{}.set_name(add_env_var_explicit_layer).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2866         "add_env_var_explicit_layer.json"}
2867                                .set_discovery_type(ManifestDiscoveryType::add_env_var));
2868 
2869     const char* regular_implicit_layer = "VK_LAYER_regular_implicit_layer";
2870     env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2871                                                                           .set_disable_environment("A")
2872                                                                           .set_name(regular_implicit_layer)
2873                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2874                                             "regular_implicit_layer.json"});
2875 
2876     const char* env_var_implicit_layer = "VK_LAYER_env_var_implicit_layer";
2877     env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2878                                                                           .set_disable_environment("B")
2879                                                                           .set_name(env_var_implicit_layer)
2880                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2881                                             "env_var_implicit_layer.json"}
2882                                .set_discovery_type(ManifestDiscoveryType::env_var));
2883 
2884     const char* add_env_var_implicit_layer = "VK_LAYER_add_env_var_implicit_layer";
2885     env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2886                                                                           .set_disable_environment("C")
2887                                                                           .set_name(add_env_var_implicit_layer)
2888                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
2889                                             "add_env_var_implicit_layer.json"}
2890                                .set_discovery_type(ManifestDiscoveryType::add_env_var));
2891 
2892     // Settings file only contains the one layer it wants enabled
2893     env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
2894         AppSpecificSettings{}
2895             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
2896                                          .set_name(regular_implicit_layer)
2897                                          .set_path(env.get_shimmed_layer_manifest_path(4))
2898                                          .set_control("auto")
2899                                          .set_treat_as_implicit_manifest(true))
2900             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
2901                                          .set_name(regular_explicit_layer)
2902                                          .set_path(env.get_shimmed_layer_manifest_path(0))
2903                                          .set_control("auto"))
2904             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
2905                                          .set_name(regular_explicit_layer_settings_file_set_on)
2906                                          .set_path(env.get_shimmed_layer_manifest_path(1))
2907                                          .set_control("on"))
2908             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location")));
2909     env.update_loader_settings(env.loader_settings);
2910 
2911     {  // VK_INSTANCE_LAYERS
2912         EnvVarWrapper instance_layers{"VK_INSTANCE_LAYERS", regular_explicit_layer};
2913         InstWrapper inst{env.vulkan_functions};
2914         inst.CheckCreate();
2915         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
2916         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_implicit_layer));
2917         EXPECT_TRUE(string_eq(layers.at(1).layerName, regular_explicit_layer));
2918         EXPECT_TRUE(string_eq(layers.at(2).layerName, regular_explicit_layer_settings_file_set_on));
2919         EXPECT_TRUE(string_eq(layers.at(3).layerName, env_var_implicit_layer));
2920         EXPECT_TRUE(env.platform_shim->find_in_log(
2921             "env var 'VK_INSTANCE_LAYERS' defined and adding layers: VK_LAYER_regular_explicit_layer"));
2922     }
2923     env.platform_shim->clear_logs();
2924     {  // VK_LOADER_LAYERS_ENABLE
2925         EnvVarWrapper env_var_enable{"VK_LOADER_LAYERS_ENABLE", regular_explicit_layer};
2926         InstWrapper inst{env.vulkan_functions};
2927         inst.CheckCreate();
2928         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
2929         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_implicit_layer));
2930         EXPECT_TRUE(string_eq(layers.at(1).layerName, regular_explicit_layer));
2931         EXPECT_TRUE(string_eq(layers.at(2).layerName, regular_explicit_layer_settings_file_set_on));
2932         EXPECT_TRUE(string_eq(layers.at(3).layerName, env_var_implicit_layer));
2933         EXPECT_TRUE(env.platform_shim->find_in_log(
2934             "Layer \"VK_LAYER_regular_explicit_layer\" forced enabled due to env var 'VK_LOADER_LAYERS_ENABLE'"));
2935     }
2936     env.platform_shim->clear_logs();
2937     {                                                                        // VK_LOADER_LAYERS_DISABLE
2938         EnvVarWrapper env_var_disable{"VK_LOADER_LAYERS_DISABLE", "~all~"};  // ignored by settings file
2939         InstWrapper inst{env.vulkan_functions};
2940         inst.CheckCreate();
2941         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
2942         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_explicit_layer_settings_file_set_on));
2943         EXPECT_TRUE(
2944             env.platform_shim->find_in_log("Layer \"VK_LAYER_env_var_implicit_layer\" forced disabled because name matches filter "
2945                                            "of env var 'VK_LOADER_LAYERS_DISABLE'"));
2946     }
2947     env.platform_shim->clear_logs();
2948 
2949     {  // VK_LOADER_LAYERS_ALLOW
2950         EnvVarWrapper env_var_allow{"VK_LOADER_LAYERS_ALLOW", regular_implicit_layer};
2951         // Allow only makes sense when the disable env-var is also set
2952         EnvVarWrapper env_var_disable{"VK_LOADER_LAYERS_DISABLE", "~implicit~"};
2953 
2954         InstWrapper inst{env.vulkan_functions};
2955         inst.CheckCreate();
2956         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
2957         // The regular_implicit_layer is set to "auto" so is affected by environment variables
2958         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_implicit_layer));
2959         EXPECT_TRUE(string_eq(layers.at(1).layerName, regular_explicit_layer_settings_file_set_on));
2960 
2961         EXPECT_TRUE(
2962             env.platform_shim->find_in_log("Layer \"VK_LAYER_env_var_implicit_layer\" forced disabled because name matches filter "
2963                                            "of env var 'VK_LOADER_LAYERS_DISABLE'"));
2964     }
2965     env.platform_shim->clear_logs();
2966 
2967     {  // VK_LAYER_PATH
2968         // VK_LAYER_PATH is set by add_explicit_layer()
2969         InstWrapper inst{env.vulkan_functions};
2970         inst.create_info.add_layer(env_var_explicit_layer);
2971         inst.CheckCreate();
2972         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
2973         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_implicit_layer));
2974         EXPECT_TRUE(string_eq(layers.at(1).layerName, regular_explicit_layer_settings_file_set_on));
2975         EXPECT_TRUE(string_eq(layers.at(2).layerName, env_var_implicit_layer));
2976         EXPECT_TRUE(string_eq(layers.at(3).layerName, env_var_explicit_layer));
2977         EXPECT_TRUE(env.platform_shim->find_in_log("Insert instance layer \"VK_LAYER_env_var_explicit_layer\""));
2978     }
2979     env.platform_shim->clear_logs();
2980     {  // VK_IMPLICIT_LAYER_PATH
2981         // VK_IMPLICIT_LAYER_PATH is set by add_implicit_layer()
2982         InstWrapper inst{env.vulkan_functions};
2983         inst.CheckCreate();
2984         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
2985         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_implicit_layer));
2986         EXPECT_TRUE(string_eq(layers.at(1).layerName, regular_explicit_layer_settings_file_set_on));
2987         EXPECT_TRUE(string_eq(layers.at(2).layerName, env_var_implicit_layer));
2988         EXPECT_TRUE(env.platform_shim->find_in_log("Insert instance layer \"VK_LAYER_env_var_implicit_layer\""));
2989     }
2990     env.platform_shim->clear_logs();
2991     {  // VK_ADD_LAYER_PATH
2992         // VK_ADD_LAYER_PATH is set by add_explicit_layer(), but we need to disable VK_LAYER_PATH
2993         // since VK_LAYER_PATH overrides VK_ADD_LAYER_PATH
2994         EnvVarWrapper env_var_vk_layer_path{"VK_LAYER_PATH", ""};
2995         env_var_vk_layer_path.remove_value();
2996         InstWrapper inst{env.vulkan_functions};
2997         inst.create_info.add_layer(add_env_var_explicit_layer);
2998         inst.CheckCreate();
2999         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
3000         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_implicit_layer));
3001         EXPECT_TRUE(string_eq(layers.at(1).layerName, regular_explicit_layer_settings_file_set_on));
3002         EXPECT_TRUE(string_eq(layers.at(2).layerName, env_var_implicit_layer));
3003         EXPECT_TRUE(string_eq(layers.at(3).layerName, add_env_var_explicit_layer));
3004         EXPECT_TRUE(env.platform_shim->find_in_log("Insert instance layer \"VK_LAYER_add_env_var_explicit_layer\""));
3005     }
3006     env.platform_shim->clear_logs();
3007     {  // VK_ADD_IMPLICIT_LAYER_PATH
3008         // VK_ADD_IMPLICIT_LAYER_PATH is set by add_explicit_layer(), but we need to disable VK_LAYER_PATH
3009         // since VK_IMPLICIT_LAYER_PATH overrides VK_ADD_IMPLICIT_LAYER_PATH
3010         EnvVarWrapper env_var_vk_layer_path{"VK_IMPLICIT_LAYER_PATH", ""};
3011         env_var_vk_layer_path.remove_value();
3012         InstWrapper inst{env.vulkan_functions};
3013         inst.CheckCreate();
3014         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
3015         EXPECT_TRUE(string_eq(layers.at(0).layerName, regular_implicit_layer));
3016         EXPECT_TRUE(string_eq(layers.at(1).layerName, regular_explicit_layer_settings_file_set_on));
3017         EXPECT_TRUE(string_eq(layers.at(2).layerName, add_env_var_implicit_layer));
3018         EXPECT_TRUE(env.platform_shim->find_in_log("Insert instance layer \"VK_LAYER_add_env_var_implicit_layer\""));
3019     }
3020 }
3021