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 
get_settings_location_log_message([[maybe_unused]] FrameworkEnvironment const& env, [[maybe_unused]] bool use_secure = false)30 std::string get_settings_location_log_message([[maybe_unused]] FrameworkEnvironment const& env,
31                                               [[maybe_unused]] bool use_secure = false) {
32     std::string s = "Using layer configurations found in loader settings from ";
33 #if defined(WIN32)
34     return s + env.get_folder(ManifestLocation::settings_location).location().str() + "\\vk_loader_settings.json";
35 #elif COMMON_UNIX_PLATFORMS
36     if (use_secure)
37         return s + "/etc/vulkan/loader_settings.d/vk_loader_settings.json";
38     else
39         return s + "/home/fake_home/.local/share/vulkan/loader_settings.d/vk_loader_settings.json";
40 #endif
41 }
42 
43 // Make sure settings layer is found and that a layer defined in it is loaded
TEST(SettingsFile, FileExist)44 TEST(SettingsFile, FileExist) {
45     FrameworkEnvironment env{};
46     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
47     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
48     env.add_explicit_layer(TestLayerDetails{
49         ManifestLayer{}.add_layer(
50             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
51         "regular_test_layer.json"}
52                                .set_discovery_type(ManifestDiscoveryType::override_folder));
53     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
54         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
55             LoaderSettingsLayerConfiguration{}
56                 .set_name(regular_layer_name)
57                 .set_path(env.get_shimmed_layer_manifest_path().str())
58                 .set_control("on"))));
59     {
60         auto layer_props = env.GetLayerProperties(1);
61         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
62 
63         InstWrapper inst{env.vulkan_functions};
64         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
65         inst.CheckCreate();
66 
67         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
68         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
69         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, regular_layer_name));
70     }
71 }
72 
73 // 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)74 TEST(SettingsFile, SettingsInUnsecuredLocation) {
75     FrameworkEnvironment env{};
76     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
77     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
78     env.add_explicit_layer(TestLayerDetails{
79         ManifestLayer{}.add_layer(
80             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
81         "regular_test_layer.json"}
82                                .set_discovery_type(ManifestDiscoveryType::override_folder));
83     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
84         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
85             LoaderSettingsLayerConfiguration{}
86                 .set_name(regular_layer_name)
87                 .set_path(env.get_layer_manifest_path().str())
88                 .set_control("on"))));
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         env.debug_log.clear();
99         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
100         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
101     }
102     env.platform_shim->set_elevated_privilege(true);
103     {
104         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
105 
106         InstWrapper inst{env.vulkan_functions};
107         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
108         inst.CheckCreate();
109 
110         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
111         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
112     }
113 }
114 
TEST(SettingsFile, SettingsInSecuredLocation)115 TEST(SettingsFile, SettingsInSecuredLocation) {
116     FrameworkEnvironment env{FrameworkSettings{}.set_secure_loader_settings(true)};
117     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
118     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
119     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
120     env.add_explicit_layer(TestLayerDetails{
121         ManifestLayer{}.add_layer(
122             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
123         "regular_test_layer.json"}
124                                .set_discovery_type(ManifestDiscoveryType::override_folder));
125     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
126         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
127             LoaderSettingsLayerConfiguration{}
128                 .set_name(regular_layer_name)
129                 .set_path(env.get_layer_manifest_path().str())
130                 .set_control("on"))));
131     {
132         auto layer_props = env.GetLayerProperties(1);
133         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
134 
135         InstWrapper inst{env.vulkan_functions};
136         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
137         inst.CheckCreate();
138 
139         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env, true)));
140         env.debug_log.clear();
141         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
142         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
143     }
144     env.platform_shim->set_elevated_privilege(true);
145     {
146         auto layer_props = env.GetLayerProperties(1);
147         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
148 
149         InstWrapper inst{env.vulkan_functions};
150         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
151         inst.CheckCreate();
152 
153         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env, true)));
154         env.debug_log.clear();
155         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
156         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
157     }
158 }
159 
160 // Make sure settings file can have multiple sets of settings
TEST(SettingsFile, SupportsMultipleSetingsSimultaneously)161 TEST(SettingsFile, SupportsMultipleSetingsSimultaneously) {
162     FrameworkEnvironment env{};
163     const char* app_specific_layer_name = "VK_LAYER_TestLayer_0";
164     env.add_explicit_layer(TestLayerDetails{
165         ManifestLayer{}.add_layer(
166             ManifestLayer::LayerDescription{}.set_name(app_specific_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
167         "VK_LAYER_app_specific.json"}
168                                .set_discovery_type(ManifestDiscoveryType::override_folder));
169     const char* global_layer_name = "VK_LAYER_TestLayer_1";
170     env.add_explicit_layer(TestLayerDetails{
171         ManifestLayer{}.add_layer(
172             ManifestLayer::LayerDescription{}.set_name(global_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
173         "VK_LAYER_global.json"}
174                                .set_discovery_type(ManifestDiscoveryType::override_folder));
175     env.update_loader_settings(
176         env.loader_settings
177             // configuration that matches the current executable path - but dont set the app-key just yet
178             .add_app_specific_setting(AppSpecificSettings{}
179                                           .add_stderr_log_filter("all")
180                                           .add_layer_configuration(LoaderSettingsLayerConfiguration{}
181                                                                        .set_name(app_specific_layer_name)
182                                                                        .set_path(env.get_layer_manifest_path(0).str())
183                                                                        .set_control("on"))
184                                           .add_app_key("key0"))
185             // configuration that should never be used
186             .add_app_specific_setting(
187                 AppSpecificSettings{}
188                     .add_stderr_log_filter("all")
189                     .add_layer_configuration(
190                         LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_haha").set_path("/made/up/path").set_control("auto"))
191                     .add_layer_configuration(LoaderSettingsLayerConfiguration{}
192                                                  .set_name("VK_LAYER_haha2")
193                                                  .set_path("/made/up/path2")
194                                                  .set_control("auto"))
195                     .add_app_key("key1")
196                     .add_app_key("key2"))
197             // Add a global configuration
198             .add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
199                 LoaderSettingsLayerConfiguration{}
200                     .set_name(global_layer_name)
201                     .set_path(env.get_layer_manifest_path(1).str())
202                     .set_control("on"))));
203     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
204     {
205         auto layer_props = env.GetLayerProperties(1);
206         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, global_layer_name));
207 
208         // Check that the global config is used
209         InstWrapper inst{env.vulkan_functions};
210         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
211         inst.CheckCreate();
212         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
213         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
214         ASSERT_TRUE(string_eq(layers.at(0).layerName, global_layer_name));
215     }
216     env.debug_log.clear();
217     // Set one set to contain the current executable path
218     env.loader_settings.app_specific_settings.at(0).add_app_key(fs::fixup_backslashes_in_path(test_platform_executable_path()));
219     env.update_loader_settings(env.loader_settings);
220     {
221         auto layer_props = env.GetLayerProperties(1);
222         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, app_specific_layer_name));
223 
224         InstWrapper inst{env.vulkan_functions};
225         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
226         inst.CheckCreate();
227         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
228         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
229         ASSERT_TRUE(string_eq(layers.at(0).layerName, app_specific_layer_name));
230     }
231 }
232 
233 // Make sure layers found through the settings file are enableable by environment variables
TEST(SettingsFile, LayerAutoEnabledByEnvVars)234 TEST(SettingsFile, LayerAutoEnabledByEnvVars) {
235     FrameworkEnvironment env{};
236     env.loader_settings.set_file_format_version({1, 0, 0});
237     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
238 
239     const char* layer_name = "VK_LAYER_automatic";
240     env.add_explicit_layer(
241         TestLayerDetails{ManifestLayer{}.add_layer(
242                              ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
243                          "layer_name.json"}
244             .set_discovery_type(ManifestDiscoveryType::override_folder));
245 
246     env.update_loader_settings(
247         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
248             LoaderSettingsLayerConfiguration{}
249                 .set_name(layer_name)
250                 .set_path(env.get_layer_manifest_path(0).str())
251                 .set_control("auto"))));
252     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
253     {
254         EnvVarWrapper instance_layers{"VK_INSTANCE_LAYERS", layer_name};
255         auto layer_props = env.GetLayerProperties(1);
256         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, layer_name));
257 
258         InstWrapper inst{env.vulkan_functions};
259         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
260         inst.CheckCreate();
261         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
262         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
263         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
264     }
265     env.debug_log.clear();
266 
267     {
268         EnvVarWrapper loader_layers_enable{"VK_LOADER_LAYERS_ENABLE", layer_name};
269         auto layer_props = env.GetLayerProperties(1);
270         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, layer_name));
271         InstWrapper inst{env.vulkan_functions};
272         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
273         inst.CheckCreate();
274         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
275         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
276         ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name));
277     }
278 }
279 
280 // Make sure layers are disallowed from loading if the settings file says so
TEST(SettingsFile, LayerDisablesImplicitLayer)281 TEST(SettingsFile, LayerDisablesImplicitLayer) {
282     FrameworkEnvironment env{};
283     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
284     const char* implicit_layer_name = "VK_LAYER_Implicit_TestLayer";
285     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
286                                                          .set_name(implicit_layer_name)
287                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
288                                                          .set_disable_environment("oof")),
289                            "implicit_test_layer.json");
290 
291     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
292         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
293             LoaderSettingsLayerConfiguration{}
294                 .set_name(implicit_layer_name)
295                 .set_path(env.get_shimmed_layer_manifest_path(0).str())
296                 .set_control("off")
297                 .set_treat_as_implicit_manifest(true))));
298     {
299         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
300         InstWrapper inst{env.vulkan_functions};
301         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
302         inst.CheckCreate();
303 
304         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
305         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
306     }
307 }
308 
309 // Implicit layers should be reordered by the settings file
TEST(SettingsFile, ImplicitLayersDontInterfere)310 TEST(SettingsFile, ImplicitLayersDontInterfere) {
311     FrameworkEnvironment env{};
312     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
313     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
314     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
315                                                          .set_name(implicit_layer_name1)
316                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
317                                                          .set_disable_environment("oof")),
318                            "implicit_test_layer1.json");
319     const char* implicit_layer_name2 = "VK_LAYER_Implicit_TestLayer2";
320     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
321                                                          .set_name(implicit_layer_name2)
322                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
323                                                          .set_disable_environment("oof")),
324                            "implicit_test_layer2.json");
325     // validate order when settings file is not present
326     {
327         auto layer_props = env.GetLayerProperties(2);
328         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
329         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name2));
330 
331         InstWrapper inst{env.vulkan_functions};
332         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
333         inst.CheckCreate();
334         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
335         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
336         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
337         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name2));
338     }
339     // Now setup the settings file to contain a specific order
340     env.update_loader_settings(LoaderSettings{}.add_app_specific_setting(
341         AppSpecificSettings{}
342             .add_stderr_log_filter("all")
343             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
344                                          .set_name(implicit_layer_name1)
345                                          .set_path(env.get_shimmed_layer_manifest_path(0).str())
346                                          .set_control("auto")
347                                          .set_treat_as_implicit_manifest(true))
348             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
349                                          .set_name(implicit_layer_name2)
350                                          .set_path(env.get_shimmed_layer_manifest_path(1).str())
351                                          .set_control("auto")
352                                          .set_treat_as_implicit_manifest(true))));
353     {
354         auto layer_props = env.GetLayerProperties(2);
355         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
356         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name2));
357 
358         InstWrapper inst{env.vulkan_functions};
359         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
360         inst.CheckCreate();
361         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
362         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
363         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
364         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name2));
365     }
366 
367     // Flip the order and store the settings in the env for later use in the test
368     env.loader_settings = LoaderSettings{}.add_app_specific_setting(
369         AppSpecificSettings{}
370             .add_stderr_log_filter("all")
371             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
372                                          .set_name(implicit_layer_name2)
373                                          .set_path(env.get_shimmed_layer_manifest_path(1).str())
374                                          .set_control("auto")
375                                          .set_treat_as_implicit_manifest(true))
376             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
377                                          .set_name(implicit_layer_name1)
378                                          .set_path(env.get_shimmed_layer_manifest_path(0).str())
379                                          .set_control("auto")
380                                          .set_treat_as_implicit_manifest(true)));
381     env.update_loader_settings(env.loader_settings);
382 
383     {
384         auto layer_props = env.GetLayerProperties(2);
385         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name2));
386         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
387 
388         InstWrapper inst{env.vulkan_functions};
389         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
390         inst.CheckCreate();
391         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
392         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
393         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name2));
394         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
395     }
396 
397     // Now add an explicit layer into the middle and verify that is in the correct location
398     const char* explicit_layer_name3 = "VK_LAYER_Explicit_TestLayer3";
399     env.add_explicit_layer(
400         ManifestLayer{}.add_layer(
401             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
402         "explicit_test_layer3.json");
403     env.loader_settings.app_specific_settings.at(0).layer_configurations.insert(
404         env.loader_settings.app_specific_settings.at(0).layer_configurations.begin() + 1,
405         LoaderSettingsLayerConfiguration{}
406             .set_name(explicit_layer_name3)
407             .set_path(env.get_shimmed_layer_manifest_path(2).str())
408             .set_control("on"));
409     env.update_loader_settings(env.loader_settings);
410     {
411         auto layer_props = env.GetLayerProperties(3);
412         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name2));
413         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name3));
414         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, implicit_layer_name1));
415 
416         InstWrapper inst{env.vulkan_functions};
417         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
418         inst.CheckCreate();
419         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
420         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
421         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name2));
422         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name3));
423         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
424     }
425 }
426 
427 // Make sure layers that are disabled can't be enabled by the application
TEST(SettingsFile, ApplicationEnablesIgnored)428 TEST(SettingsFile, ApplicationEnablesIgnored) {
429     FrameworkEnvironment env{};
430     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
431     const char* explicit_layer_name = "VK_LAYER_TestLayer";
432     env.add_explicit_layer(
433         ManifestLayer{}.add_layer(
434             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
435         "regular_test_layer.json");
436 
437     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
438         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
439             LoaderSettingsLayerConfiguration{}
440                 .set_name(explicit_layer_name)
441                 .set_path(env.get_shimmed_layer_manifest_path(0).str())
442                 .set_control("off"))));
443     {
444         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
445         InstWrapper inst{env.vulkan_functions};
446         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
447         inst.create_info.add_layer(explicit_layer_name);
448         ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT));
449     }
450 }
451 
TEST(SettingsFile, LayerListIsEmpty)452 TEST(SettingsFile, LayerListIsEmpty) {
453     FrameworkEnvironment env{};
454     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
455     const char* implicit_layer_name = "VK_LAYER_TestLayer";
456     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
457                                                          .set_name(implicit_layer_name)
458                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
459                                                          .set_disable_environment("HeeHee")),
460                            "regular_test_layer.json");
461 
462     JsonWriter writer{};
463     writer.StartObject();
464     writer.AddKeyedString("file_format_version", "1.0.0");
465     writer.StartKeyedObject("settings");
466     writer.StartKeyedObject("layers");
467     writer.EndObject();
468     writer.EndObject();
469     writer.EndObject();
470     env.write_settings_file(writer.output);
471 
472     ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
473 
474     InstWrapper inst{env.vulkan_functions};
475     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
476     inst.CheckCreate();
477     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
478     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
479 }
480 
481 // If a settings file exists but contains no valid settings - don't consider it
TEST(SettingsFile, InvalidSettingsFile)482 TEST(SettingsFile, InvalidSettingsFile) {
483     FrameworkEnvironment env{};
484     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
485     const char* explicit_layer_name = "VK_LAYER_TestLayer";
486     env.add_explicit_layer(
487         ManifestLayer{}.add_layer(
488             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
489         "regular_test_layer.json");
490     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
491     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
492                                                          .set_name(implicit_layer_name)
493                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
494                                                          .set_disable_environment("foobarbaz")),
495                            "implicit_test_layer.json");
496     auto check_integrity = [&env, explicit_layer_name, implicit_layer_name]() {
497         auto layer_props = env.GetLayerProperties(2);
498         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name));
499         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name));
500         InstWrapper inst{env.vulkan_functions};
501         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
502         inst.create_info.add_layer(explicit_layer_name);
503         inst.CheckCreate();
504         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
505         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
506         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name));
507         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name));
508     };
509 
510     {
511         std::fstream fuzzer_output_json_file{FUZZER_OUTPUT_JSON_FILE, std::ios_base::in};
512         ASSERT_TRUE(fuzzer_output_json_file.is_open());
513         std::stringstream fuzzer_output_json;
514         fuzzer_output_json << fuzzer_output_json_file.rdbuf();
515         env.write_settings_file(fuzzer_output_json.str());
516 
517         check_integrity();
518     }
519 
520     // No actual settings
521     {
522         JsonWriter writer{};
523         writer.StartObject();
524         writer.AddKeyedString("file_format_version", "0.0.0");
525         writer.EndObject();
526         env.write_settings_file(writer.output);
527 
528         check_integrity();
529     }
530 
531     {
532         JsonWriter writer{};
533         writer.StartObject();
534         writer.AddKeyedString("file_format_version", "0.0.0");
535         writer.StartKeyedArray("settings_array");
536         writer.EndArray();
537         writer.StartKeyedObject("settings");
538         writer.EndObject();
539         writer.EndObject();
540         env.write_settings_file(writer.output);
541 
542         check_integrity();
543     }
544 
545     {
546         JsonWriter writer{};
547         writer.StartObject();
548         for (uint32_t i = 0; i < 3; i++) {
549             writer.StartKeyedArray("settings_array");
550             writer.EndArray();
551             writer.StartKeyedObject("boogabooga");
552             writer.EndObject();
553             writer.StartKeyedObject("settings");
554             writer.EndObject();
555         }
556         writer.EndObject();
557         env.write_settings_file(writer.output);
558 
559         check_integrity();
560     }
561 }
562 
563 // Unknown layers are put in the correct location
TEST(SettingsFile, UnknownLayersInRightPlace)564 TEST(SettingsFile, UnknownLayersInRightPlace) {
565     FrameworkEnvironment env{};
566     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
567     const char* explicit_layer_name1 = "VK_LAYER_TestLayer1";
568     env.add_explicit_layer(
569         ManifestLayer{}.add_layer(
570             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
571         "regular_test_layer1.json");
572     const char* implicit_layer_name1 = "VK_LAYER_ImplicitTestLayer1";
573     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
574                                                          .set_name(implicit_layer_name1)
575                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
576                                                          .set_disable_environment("foobarbaz")),
577                            "implicit_test_layer1.json");
578     const char* explicit_layer_name2 = "VK_LAYER_TestLayer2";
579     env.add_explicit_layer(
580         ManifestLayer{}.add_layer(
581             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
582         "regular_test_layer2.json");
583     const char* implicit_layer_name2 = "VK_LAYER_ImplicitTestLayer2";
584     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
585                                                          .set_name(implicit_layer_name2)
586                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
587                                                          .set_disable_environment("foobarbaz")),
588                            "implicit_test_layer2.json");
589 
590     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
591         AppSpecificSettings{}
592             .add_stderr_log_filter("all")
593             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
594                                          .set_name(explicit_layer_name2)
595                                          .set_path(env.get_shimmed_layer_manifest_path(2).str())
596                                          .set_control("on"))
597             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
598             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
599                                          .set_name(implicit_layer_name2)
600                                          .set_path(env.get_shimmed_layer_manifest_path(3).str())
601                                          .set_control("on")
602                                          .set_treat_as_implicit_manifest(true))));
603 
604     auto layer_props = env.GetLayerProperties(4);
605     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name2));
606     ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
607     ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
608     ASSERT_TRUE(string_eq(layer_props.at(3).layerName, implicit_layer_name2));
609     InstWrapper inst{env.vulkan_functions};
610     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
611     inst.create_info.add_layer(explicit_layer_name1);
612     inst.CheckCreate();
613     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
614     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
615     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name2));
616     ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
617     ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
618     ASSERT_TRUE(string_eq(layer_props.at(3).layerName, implicit_layer_name2));
619 }
620 
621 // Settings file allows loading multiple layers with the same name - as long as the path is different
TEST(SettingsFile, MultipleLayersWithSameName)622 TEST(SettingsFile, MultipleLayersWithSameName) {
623     FrameworkEnvironment env{};
624     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
625 
626     const char* explicit_layer_name = "VK_LAYER_TestLayer";
627     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
628                                                          .set_name(explicit_layer_name)
629                                                          .set_description("0000")
630                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
631                            "regular_test_layer1.json");
632 
633     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
634                                                          .set_name(explicit_layer_name)
635                                                          .set_description("1111")
636                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
637                            "regular_test_layer2.json");
638 
639     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
640         AppSpecificSettings{}
641             .add_stderr_log_filter("all")
642             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
643                                          .set_name(explicit_layer_name)
644                                          .set_path(env.get_shimmed_layer_manifest_path(0).str())
645                                          .set_control("on"))
646             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
647                                          .set_name(explicit_layer_name)
648                                          .set_path(env.get_shimmed_layer_manifest_path(1).str())
649                                          .set_control("on"))));
650     auto layer_props = env.GetLayerProperties(2);
651     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name));
652     ASSERT_TRUE(string_eq(layer_props.at(0).description, "0000"));
653     ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name));
654     ASSERT_TRUE(string_eq(layer_props.at(1).description, "1111"));
655     InstWrapper inst{env.vulkan_functions};
656     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
657     inst.CheckCreate();
658     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
659     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
660     ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name));
661     ASSERT_TRUE(string_eq(layers.at(0).description, "0000"));
662     ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name));
663     ASSERT_TRUE(string_eq(layers.at(1).description, "1111"));
664 }
665 
666 // Settings file shouldn't be able to cause the same layer from the same path twice
TEST(SettingsFile, MultipleLayersWithSamePath)667 TEST(SettingsFile, MultipleLayersWithSamePath) {
668     FrameworkEnvironment env{};
669     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
670 
671     const char* explicit_layer_name = "VK_LAYER_TestLayer";
672     env.add_explicit_layer(
673         ManifestLayer{}.add_layer(
674             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
675         "regular_test_layer1.json");
676 
677     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
678         AppSpecificSettings{}
679             .add_stderr_log_filter("all")
680             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
681                                          .set_name(explicit_layer_name)
682                                          .set_path(env.get_shimmed_layer_manifest_path(0).str())
683                                          .set_control("on"))
684             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
685                                          .set_name(explicit_layer_name)
686                                          .set_path(env.get_shimmed_layer_manifest_path(0).str())
687                                          .set_control("on"))));
688 
689     auto layer_props = env.GetLayerProperties(1);
690     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name));
691 
692     InstWrapper inst{env.vulkan_functions};
693     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
694     inst.CheckCreate();
695     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
696     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
697     ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name));
698 }
699 
700 // Settings contains a layer whose name doesn't match the one found in the layer manifest - make sure the layer from the settings
701 // file is removed
TEST(SettingsFile, MismatchedLayerNameAndManifestPath)702 TEST(SettingsFile, MismatchedLayerNameAndManifestPath) {
703     FrameworkEnvironment env{};
704     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
705 
706     const char* manifest_explicit_layer_name = "VK_LAYER_MANIFEST_TestLayer";
707     const char* settings_explicit_layer_name = "VK_LAYER_Settings_TestLayer";
708     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
709                                                          .set_name(manifest_explicit_layer_name)
710                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
711                            "regular_test_layer1.json");
712 
713     const char* implicit_layer_name = "VK_LAYER_Implicit_TestLayer";
714     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
715                                                          .set_name(implicit_layer_name)
716                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
717                                                          .set_disable_environment("oof")),
718                            "implicit_test_layer.json");
719 
720     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
721         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
722             LoaderSettingsLayerConfiguration{}
723                 .set_name(settings_explicit_layer_name)
724                 .set_path(env.get_shimmed_layer_manifest_path(0).str())
725                 .set_control("on"))));
726 
727     ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
728 
729     InstWrapper inst{env.vulkan_functions};
730     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
731     inst.CheckCreate();
732     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
733     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
734 }
735 
736 // Settings file should take precedence over the meta layer, if present
TEST(SettingsFile, MetaLayerAlsoActivates)737 TEST(SettingsFile, MetaLayerAlsoActivates) {
738     FrameworkEnvironment env{};
739     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
740 
741     const char* settings_explicit_layer_name = "VK_LAYER_Regular_TestLayer";
742     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
743                                                          .set_name(settings_explicit_layer_name)
744                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
745                            "explicit_test_layer.json");
746 
747     const char* settings_implicit_layer_name = "VK_LAYER_RegularImplicit_TestLayer";
748     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
749                                                          .set_name(settings_implicit_layer_name)
750                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
751                                                          .set_disable_environment("AndISaidHey")
752                                                          .set_enable_environment("WhatsGoingOn")),
753                            "implicit_layer.json");
754 
755     const char* component_explicit_layer_name1 = "VK_LAYER_Component_TestLayer1";
756     env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
757                                                                           .set_name(component_explicit_layer_name1)
758                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
759                                             "component_test_layer1.json"));
760 
761     const char* component_explicit_layer_name2 = "VK_LAYER_Component_TestLayer2";
762     env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
763                                                                           .set_name(component_explicit_layer_name2)
764                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
765                                             "component_test_layer2.json"));
766 
767     const char* meta_layer_name1 = "VK_LAYER_meta_layer1";
768     env.add_implicit_layer(
769         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
770                                                                          .set_name(meta_layer_name1)
771                                                                          .add_component_layer(component_explicit_layer_name2)
772                                                                          .add_component_layer(component_explicit_layer_name1)
773                                                                          .set_disable_environment("NotGonnaWork")),
774         "meta_test_layer.json");
775 
776     const char* meta_layer_name2 = "VK_LAYER_meta_layer2";
777     env.add_implicit_layer(
778         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{}
779                                                                          .set_name(meta_layer_name2)
780                                                                          .add_component_layer(component_explicit_layer_name1)
781                                                                          .set_disable_environment("ILikeTrains")
782                                                                          .set_enable_environment("BakedBeans")),
783         "not_automatic_meta_test_layer.json");
784 
785     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
786         AppSpecificSettings{}
787             .add_stderr_log_filter("all")
788             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
789                                          .set_name(settings_explicit_layer_name)
790                                          .set_path(env.get_shimmed_layer_manifest_path(0).str())
791                                          .set_control("on")
792                                          .set_treat_as_implicit_manifest(false))
793             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))
794             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
795                                          .set_name(settings_implicit_layer_name)
796                                          .set_path(env.get_shimmed_layer_manifest_path(1).str())
797                                          .set_control("auto")
798                                          .set_treat_as_implicit_manifest(true))));
799     {
800         EnvVarWrapper enable_meta_layer{"WhatsGoingOn", "1"};
801         auto layer_props = env.GetLayerProperties(6);
802         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, settings_explicit_layer_name));
803         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, meta_layer_name1));
804         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, meta_layer_name2));
805         ASSERT_TRUE(string_eq(layer_props.at(3).layerName, component_explicit_layer_name1));
806         ASSERT_TRUE(string_eq(layer_props.at(4).layerName, component_explicit_layer_name2));
807         ASSERT_TRUE(string_eq(layer_props.at(5).layerName, settings_implicit_layer_name));
808 
809         InstWrapper inst{env.vulkan_functions};
810         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
811         inst.CheckCreate();
812         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
813         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 5);
814         ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_explicit_layer_name));
815         ASSERT_TRUE(string_eq(layers.at(1).layerName, component_explicit_layer_name2));
816         ASSERT_TRUE(string_eq(layers.at(2).layerName, component_explicit_layer_name1));
817         ASSERT_TRUE(string_eq(layers.at(3).layerName, meta_layer_name1));
818         ASSERT_TRUE(string_eq(layers.at(4).layerName, settings_implicit_layer_name));
819     }
820     {
821         EnvVarWrapper enable_meta_layer{"BakedBeans", "1"};
822         auto layer_props = env.GetLayerProperties(6);
823         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, settings_explicit_layer_name));
824         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, meta_layer_name1));
825         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, meta_layer_name2));
826         ASSERT_TRUE(string_eq(layer_props.at(3).layerName, component_explicit_layer_name1));
827         ASSERT_TRUE(string_eq(layer_props.at(4).layerName, component_explicit_layer_name2));
828         ASSERT_TRUE(string_eq(layer_props.at(5).layerName, settings_implicit_layer_name));
829 
830         InstWrapper inst{env.vulkan_functions};
831         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
832         inst.CheckCreate();
833         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
834         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 5);
835         ASSERT_TRUE(string_eq(layers.at(0).layerName, settings_explicit_layer_name));
836         ASSERT_TRUE(string_eq(layers.at(1).layerName, component_explicit_layer_name2));
837         ASSERT_TRUE(string_eq(layers.at(2).layerName, component_explicit_layer_name1));
838         ASSERT_TRUE(string_eq(layers.at(3).layerName, meta_layer_name1));
839         ASSERT_TRUE(string_eq(layers.at(4).layerName, meta_layer_name2));
840     }
841 }
842 
843 // Layers are correctly ordered by settings file.
TEST(SettingsFile, LayerOrdering)844 TEST(SettingsFile, LayerOrdering) {
845     FrameworkEnvironment env{};
846     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
847 
848     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
849     env.add_explicit_layer(
850         ManifestLayer{}.add_layer(
851             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
852         "explicit_test_layer1.json");
853 
854     const char* explicit_layer_name2 = "VK_LAYER_Regular_TestLayer2";
855     env.add_explicit_layer(
856         ManifestLayer{}.add_layer(
857             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
858         "explicit_test_layer2.json");
859 
860     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
861     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
862                                                          .set_name(implicit_layer_name1)
863                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
864                                                          .set_disable_environment("Domierigato")),
865                            "implicit_layer1.json");
866 
867     const char* implicit_layer_name2 = "VK_LAYER_Implicit_TestLayer2";
868     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
869                                                          .set_name(implicit_layer_name2)
870                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
871                                                          .set_disable_environment("Mistehrobato")),
872                            "implicit_layer2.json");
873 
874     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all"));
875 
876     std::vector<LoaderSettingsLayerConfiguration> layer_configs{4};
877     layer_configs.at(0)
878         .set_name(explicit_layer_name1)
879         .set_path(env.get_shimmed_layer_manifest_path(0).str())
880         .set_control("on")
881         .set_treat_as_implicit_manifest(false);
882     layer_configs.at(1)
883         .set_name(explicit_layer_name2)
884         .set_path(env.get_shimmed_layer_manifest_path(1).str())
885         .set_control("on")
886         .set_treat_as_implicit_manifest(false);
887     layer_configs.at(2)
888         .set_name(implicit_layer_name1)
889         .set_path(env.get_shimmed_layer_manifest_path(2).str())
890         .set_control("on")
891         .set_treat_as_implicit_manifest(true);
892     layer_configs.at(3)
893         .set_name(implicit_layer_name2)
894         .set_path(env.get_shimmed_layer_manifest_path(3).str())
895         .set_control("on")
896         .set_treat_as_implicit_manifest(true);
897 
898     std::sort(layer_configs.begin(), layer_configs.end());
899     uint32_t permutation_count = 0;
900     do {
901         env.loader_settings.app_specific_settings.at(0).layer_configurations.clear();
902         env.loader_settings.app_specific_settings.at(0).add_layer_configurations(layer_configs);
903         env.update_loader_settings(env.loader_settings);
904 
905         auto layer_props = env.GetLayerProperties(4);
906         for (uint32_t i = 0; i < 4; i++) {
907             ASSERT_TRUE(layer_configs.at(i).name == layer_props.at(i).layerName);
908         }
909 
910         InstWrapper inst{env.vulkan_functions};
911         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
912         inst.CheckCreate();
913         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
914         auto active_layers = inst.GetActiveLayers(inst.GetPhysDev(), 4);
915         for (uint32_t i = 0; i < 4; i++) {
916             ASSERT_TRUE(layer_configs.at(i).name == active_layers.at(i).layerName);
917         }
918         env.debug_log.clear();
919         permutation_count++;
920     } while (std::next_permutation(layer_configs.begin(), layer_configs.end()));
921     ASSERT_EQ(permutation_count, 24U);  // should be this many orderings
922 }
923 
TEST(SettingsFile, EnvVarsWork_VK_LAYER_PATH)924 TEST(SettingsFile, EnvVarsWork_VK_LAYER_PATH) {
925     FrameworkEnvironment env{};
926     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
927 
928     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
929     env.add_explicit_layer(TestLayerDetails{
930         ManifestLayer{}.add_layer(
931             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
932         "explicit_test_layer1.json"}
933                                .set_discovery_type(ManifestDiscoveryType::env_var));
934 
935     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
936     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
937                                                          .set_name(implicit_layer_name1)
938                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
939                                                          .set_disable_environment("Domierigato")),
940                            "implicit_layer1.json");
941     const char* non_env_var_layer_name2 = "VK_LAYER_Regular_TestLayer2";
942     env.add_explicit_layer(TestLayerDetails{
943         ManifestLayer{}.add_layer(
944             ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
945         "explicit_test_layer2.json"});
946 
947     {
948         auto layer_props = env.GetLayerProperties(2);
949         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
950         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name1));
951 
952         InstWrapper inst{env.vulkan_functions};
953         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
954         inst.CheckCreate();
955         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
956         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
957         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
958     }
959     {
960         InstWrapper inst{env.vulkan_functions};
961         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
962         inst.create_info.add_layer(explicit_layer_name1);
963         inst.CheckCreate();
964         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
965         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
966         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
967         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name1));
968     }
969     env.update_loader_settings(env.loader_settings.add_app_specific_setting(
970         AppSpecificSettings{}
971             .add_stderr_log_filter("all")
972             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
973                                          .set_name(non_env_var_layer_name2)
974                                          .set_control("on")
975                                          .set_path(env.get_shimmed_layer_manifest_path(2).str()))
976             .add_layer_configuration(LoaderSettingsLayerConfiguration{}.set_control("unordered_layer_location"))));
977     {
978         auto layer_props = env.GetLayerProperties(3);
979         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, non_env_var_layer_name2));
980         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, implicit_layer_name1));
981         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, explicit_layer_name1));
982 
983         InstWrapper inst{env.vulkan_functions};
984         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
985         inst.CheckCreate();
986         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
987         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
988         ASSERT_TRUE(string_eq(layers.at(0).layerName, non_env_var_layer_name2));
989         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
990     }
991     {
992         InstWrapper inst{env.vulkan_functions};
993         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
994         inst.create_info.add_layer(explicit_layer_name1);
995         inst.CheckCreate();
996         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
997         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
998         ASSERT_TRUE(string_eq(layers.at(0).layerName, non_env_var_layer_name2));
999         ASSERT_TRUE(string_eq(layers.at(1).layerName, implicit_layer_name1));
1000         ASSERT_TRUE(string_eq(layers.at(2).layerName, explicit_layer_name1));
1001     }
1002 }
1003 
TEST(SettingsFile, EnvVarsWork_VK_ADD_LAYER_PATH)1004 TEST(SettingsFile, EnvVarsWork_VK_ADD_LAYER_PATH) {
1005     FrameworkEnvironment env{};
1006     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1007 
1008     const char* implicit_layer_name1 = "VK_LAYER_Implicit_TestLayer1";
1009     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1010                                                          .set_name(implicit_layer_name1)
1011                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1012                                                          .set_disable_environment("Domierigato")),
1013                            "implicit_layer1.json");
1014     const char* explicit_layer_name1 = "VK_LAYER_Regular_TestLayer1";
1015     env.add_explicit_layer(TestLayerDetails{
1016         ManifestLayer{}.add_layer(
1017             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1018         "explicit_test_layer1.json"}
1019                                .set_discovery_type(ManifestDiscoveryType::add_env_var));
1020     const char* non_env_var_layer_name2 = "VK_LAYER_Regular_TestLayer2";
1021     env.add_explicit_layer(TestLayerDetails{
1022         ManifestLayer{}.add_layer(
1023             ManifestLayer::LayerDescription{}.set_name(non_env_var_layer_name2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1024         "explicit_test_layer2.json"});
1025 
1026     {
1027         auto layer_props = env.GetLayerProperties(3);
1028         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, implicit_layer_name1));
1029         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, explicit_layer_name1));
1030         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, non_env_var_layer_name2));
1031 
1032         InstWrapper inst{env.vulkan_functions};
1033         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1034         inst.CheckCreate();
1035         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1036         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1037         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1038     }
1039     {
1040         InstWrapper inst{env.vulkan_functions};
1041         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1042         inst.create_info.add_layer(explicit_layer_name1);
1043         inst.CheckCreate();
1044         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1045         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2);
1046         ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name1));
1047         ASSERT_TRUE(string_eq(layers.at(1).layerName, explicit_layer_name1));
1048     }
1049 
1050     env.update_loader_settings(env.loader_settings.add_app_specific_setting(
1051         AppSpecificSettings{}
1052             .add_stderr_log_filter("all")
1053             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1054                                          .set_name(explicit_layer_name1)
1055                                          .set_control("on")
1056                                          .set_path(env.get_shimmed_layer_manifest_path(1).str()))
1057             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1058                                          .set_name(non_env_var_layer_name2)
1059                                          .set_control("on")
1060                                          .set_path(env.get_shimmed_layer_manifest_path(2).str()))
1061             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1062                                          .set_name(implicit_layer_name1)
1063                                          .set_control("on")
1064                                          .set_path(env.get_shimmed_layer_manifest_path(0).str())
1065                                          .set_treat_as_implicit_manifest(true))));
1066     {
1067         auto layer_props = env.GetLayerProperties(3);
1068         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name1));
1069         ASSERT_TRUE(string_eq(layer_props.at(1).layerName, non_env_var_layer_name2));
1070         ASSERT_TRUE(string_eq(layer_props.at(2).layerName, implicit_layer_name1));
1071 
1072         InstWrapper inst{env.vulkan_functions};
1073         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1074         inst.CheckCreate();
1075         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1076         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1077         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1078         ASSERT_TRUE(string_eq(layers.at(1).layerName, non_env_var_layer_name2));
1079         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
1080     }
1081     {
1082         InstWrapper inst{env.vulkan_functions};
1083         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1084         inst.create_info.add_layer(explicit_layer_name1);
1085         inst.CheckCreate();
1086         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1087         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 3);
1088         ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name1));
1089         ASSERT_TRUE(string_eq(layers.at(1).layerName, non_env_var_layer_name2));
1090         ASSERT_TRUE(string_eq(layers.at(2).layerName, implicit_layer_name1));
1091     }
1092 }
1093 
TEST(SettingsFile, EnvVarsWork_VK_INSTANCE_LAYERS)1094 TEST(SettingsFile, EnvVarsWork_VK_INSTANCE_LAYERS) {
1095     FrameworkEnvironment env{};
1096     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1097 
1098     const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer1";
1099     env.add_explicit_layer(TestLayerDetails{
1100         ManifestLayer{}.add_layer(
1101             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1102         "explicit_test_layer1.json"});
1103 
1104     {
1105         EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS", explicit_layer_name};
1106         auto layer_props = env.GetLayerProperties(1);
1107         ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name));
1108 
1109         InstWrapper inst{env.vulkan_functions};
1110         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1111         inst.CheckCreate();
1112         ASSERT_FALSE(env.debug_log.find(get_settings_location_log_message(env)));
1113         auto layer = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1114         ASSERT_TRUE(string_eq(layer.at(0).layerName, explicit_layer_name));
1115     }
1116     env.update_loader_settings(
1117         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1118             LoaderSettingsLayerConfiguration{}
1119                 .set_name(explicit_layer_name)
1120                 .set_control("off")
1121                 .set_path(env.get_shimmed_layer_manifest_path(0).str()))));
1122     {
1123         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
1124 
1125         InstWrapper inst{env.vulkan_functions};
1126         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1127         inst.CheckCreate();
1128         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1129         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1130     }
1131     {
1132         EnvVarWrapper vk_instance_layers{"VK_INSTANCE_LAYERS", explicit_layer_name};
1133         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
1134 
1135         InstWrapper inst{env.vulkan_functions};
1136         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1137         inst.CheckCreate();
1138         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1139         ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1140     }
1141 }
1142 // Make sure that layers disabled by settings file aren't enabled by VK_LOADER_LAYERS_ENABLE
TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_ENABLE)1143 TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_ENABLE) {
1144     FrameworkEnvironment env{};
1145     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1146 
1147     const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer1";
1148     env.add_explicit_layer(TestLayerDetails{
1149         ManifestLayer{}.add_layer(
1150             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1151         "explicit_test_layer1.json"});
1152 
1153     env.update_loader_settings(
1154         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1155             LoaderSettingsLayerConfiguration{}
1156                 .set_name(explicit_layer_name)
1157                 .set_control("off")
1158                 .set_path(env.get_shimmed_layer_manifest_path(0).str()))));
1159 
1160     EnvVarWrapper vk_instance_layers{"VK_LOADER_LAYERS_ENABLE", explicit_layer_name};
1161     ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
1162 
1163     InstWrapper inst{env.vulkan_functions};
1164     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1165     inst.CheckCreate();
1166     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1167     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1168 }
1169 // Make sure that layers enabled by settings file aren't disabled by VK_LOADER_LAYERS_ENABLE
TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_DISABLE)1170 TEST(SettingsFile, EnvVarsWork_VK_LOADER_LAYERS_DISABLE) {
1171     FrameworkEnvironment env{};
1172     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1173 
1174     const char* explicit_layer_name = "VK_LAYER_Regular_TestLayer1";
1175     env.add_explicit_layer(TestLayerDetails{
1176         ManifestLayer{}.add_layer(
1177             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1178         "explicit_test_layer1.json"});
1179 
1180     env.update_loader_settings(
1181         env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1182             LoaderSettingsLayerConfiguration{}
1183                 .set_name(explicit_layer_name)
1184                 .set_control("on")
1185                 .set_path(env.get_shimmed_layer_manifest_path(0).str()))));
1186 
1187     EnvVarWrapper vk_instance_layers{"VK_LOADER_LAYERS_DISABLE", explicit_layer_name};
1188     auto layer_props = env.GetLayerProperties(1);
1189     ASSERT_TRUE(string_eq(layer_props.at(0).layerName, explicit_layer_name));
1190 
1191     InstWrapper inst{env.vulkan_functions};
1192     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1193     inst.CheckCreate();
1194     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1195     ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1196 }
1197 
1198 #if defined(WIN32)
TEST(SettingsFile, MultipleKeysInRegistryInUnsecureLocation)1199 TEST(SettingsFile, MultipleKeysInRegistryInUnsecureLocation) {
1200     FrameworkEnvironment env{};
1201     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1202     env.platform_shim->add_unsecured_manifest(ManifestCategory::settings, "jank_path");
1203     env.platform_shim->add_unsecured_manifest(ManifestCategory::settings, "jank_path2");
1204 
1205     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
1206     env.add_explicit_layer(TestLayerDetails{
1207         ManifestLayer{}.add_layer(
1208             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1209         "regular_test_layer.json"}
1210                                .set_discovery_type(ManifestDiscoveryType::override_folder));
1211     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
1212         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1213             LoaderSettingsLayerConfiguration{}
1214                 .set_name(regular_layer_name)
1215                 .set_path(env.get_layer_manifest_path().str())
1216                 .set_control("on"))));
1217     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
1218 
1219     auto layer_props = env.GetLayerProperties(1);
1220     EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
1221 
1222     InstWrapper inst{env.vulkan_functions};
1223     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1224     inst.CheckCreate();
1225 
1226     ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1227     env.debug_log.clear();
1228     auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1229     ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
1230 }
1231 
TEST(SettingsFile, MultipleKeysInRegistryInSecureLocation)1232 TEST(SettingsFile, MultipleKeysInRegistryInSecureLocation) {
1233     FrameworkEnvironment env{FrameworkSettings{}.set_secure_loader_settings(true)};
1234     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1235     env.platform_shim->add_manifest(ManifestCategory::settings, "jank_path");
1236     env.platform_shim->add_manifest(ManifestCategory::settings, "jank_path2");
1237 
1238     const char* regular_layer_name = "VK_LAYER_TestLayer_0";
1239     env.add_explicit_layer(TestLayerDetails{
1240         ManifestLayer{}.add_layer(
1241             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1242         "regular_test_layer.json"}
1243                                .set_discovery_type(ManifestDiscoveryType::override_folder));
1244     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
1245         AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1246             LoaderSettingsLayerConfiguration{}
1247                 .set_name(regular_layer_name)
1248                 .set_path(env.get_layer_manifest_path().str())
1249                 .set_control("on"))));
1250     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
1251 
1252     // Make sure it works if the settings file is in the HKEY_LOCAL_MACHINE
1253     env.platform_shim->set_elevated_privilege(true);
1254     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
1255     {
1256         auto layer_props = env.GetLayerProperties(1);
1257         EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name));
1258 
1259         InstWrapper inst{env.vulkan_functions};
1260         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1261         inst.CheckCreate();
1262 
1263         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1264         env.debug_log.clear();
1265         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1266         ASSERT_TRUE(string_eq(layers.at(0).layerName, regular_layer_name));
1267     }
1268 }
1269 #endif
1270 
1271 // Preinstance functions respect the settings file
TEST(SettingsFile, PreInstanceFunctions)1272 TEST(SettingsFile, PreInstanceFunctions) {
1273     FrameworkEnvironment env;
1274     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
1275 
1276     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
1277 
1278     env.add_implicit_layer(
1279         ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(
1280             ManifestLayer::LayerDescription{}
1281                 .set_name(implicit_layer_name)
1282                 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1283                 .set_disable_environment("DISABLE_ME")
1284                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
1285                                                .set_vk_func("vkEnumerateInstanceLayerProperties")
1286                                                .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))
1287                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
1288                                                .set_vk_func("vkEnumerateInstanceExtensionProperties")
1289                                                .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))
1290                 .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
1291                                                .set_vk_func("vkEnumerateInstanceVersion")
1292                                                .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
1293         "implicit_test_layer.json");
1294 
1295     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1296         LoaderSettingsLayerConfiguration{}
1297             .set_name(implicit_layer_name)
1298             .set_control("on")
1299             .set_path(env.get_shimmed_layer_manifest_path(0).str())
1300             .set_treat_as_implicit_manifest(true)));
1301     env.update_loader_settings(env.loader_settings);
1302     {
1303         auto& layer = env.get_test_layer(0);
1304         // Check layer props
1305         uint32_t layer_props = 43;
1306         layer.set_reported_layer_props(layer_props);
1307 
1308         uint32_t count = 0;
1309         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1310         ASSERT_EQ(count, layer_props);
1311 
1312         // check extension props
1313         uint32_t ext_props = 52;
1314         layer.set_reported_extension_props(ext_props);
1315         count = 0;
1316         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
1317         ASSERT_EQ(count, ext_props);
1318 
1319         // check version
1320         uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
1321         layer.set_reported_instance_version(layer_version);
1322 
1323         uint32_t version = 0;
1324         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
1325         ASSERT_EQ(version, layer_version);
1326     }
1327     // control is set to off
1328     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off");
1329     env.update_loader_settings(env.loader_settings);
1330 
1331     {
1332         auto& layer = env.get_test_layer(0);
1333         // Check layer props
1334         uint32_t layer_props = 43;
1335         layer.set_reported_layer_props(layer_props);
1336 
1337         uint32_t count = 0;
1338         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1339         ASSERT_EQ(count, 0U);  // dont use the intercepted count
1340 
1341         // check extension props
1342         uint32_t ext_props = 52;
1343         layer.set_reported_extension_props(ext_props);
1344         count = 0;
1345         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
1346         ASSERT_EQ(count, 4U);  // dont use the intercepted count - use default count
1347 
1348         // check version
1349         uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
1350         layer.set_reported_instance_version(layer_version);
1351 
1352         uint32_t version = 0;
1353         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
1354         ASSERT_EQ(version, VK_HEADER_VERSION_COMPLETE);
1355     }
1356 
1357     // control is set to auto
1358     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto");
1359     env.update_loader_settings(env.loader_settings);
1360 
1361     {
1362         auto& layer = env.get_test_layer(0);
1363         // Check layer props
1364         uint32_t layer_props = 43;
1365         layer.set_reported_layer_props(layer_props);
1366 
1367         uint32_t count = 0;
1368         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1369         ASSERT_EQ(count, layer_props);
1370 
1371         // check extension props
1372         uint32_t ext_props = 52;
1373         layer.set_reported_extension_props(ext_props);
1374         count = 0;
1375         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
1376         ASSERT_EQ(count, ext_props);
1377 
1378         // check version
1379         uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
1380         layer.set_reported_instance_version(layer_version);
1381 
1382         uint32_t version = 0;
1383         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
1384         ASSERT_EQ(version, layer_version);
1385     }
1386 }
1387 
1388 // If an implicit layer's disable environment variable is set, but the settings file says to turn the layer on, the layer should be
1389 // activated.
TEST(SettingsFile, ImplicitLayerDisableEnvironmentVariableOverriden)1390 TEST(SettingsFile, ImplicitLayerDisableEnvironmentVariableOverriden) {
1391     auto check_log_for_insert_instance_layer_string = [](FrameworkEnvironment& env, const char* implicit_layer_name,
1392                                                          bool check_for_enable) {
1393         {
1394             InstWrapper inst{env.vulkan_functions};
1395             FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1396             inst.CheckCreate(VK_SUCCESS);
1397             if (check_for_enable) {
1398                 ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name));
1399                 auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1400                 ASSERT_TRUE(string_eq(layers.at(0).layerName, implicit_layer_name));
1401             } else {
1402                 ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name));
1403                 ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0));
1404             }
1405         }
1406         env.debug_log.clear();
1407     };
1408 
1409     FrameworkEnvironment env;
1410     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
1411     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
1412 
1413     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1414                                                          .set_name(implicit_layer_name)
1415                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1416                                                          .set_disable_environment("DISABLE_ME")
1417                                                          .set_enable_environment("ENABLE_ME")),
1418                            "implicit_test_layer.json");
1419     env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration(
1420         LoaderSettingsLayerConfiguration{}
1421             .set_name(implicit_layer_name)
1422             .set_path(env.get_shimmed_layer_manifest_path(0).str())
1423             .set_treat_as_implicit_manifest(true)));
1424 
1425     // control is set to on
1426     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("on");
1427     env.update_loader_settings(env.loader_settings);
1428     {
1429         EnvVarWrapper enable_env_var{"ENABLE_ME"};
1430         EnvVarWrapper disable_env_var{"DISABLE_ME"};
1431 
1432         auto layers = env.GetLayerProperties(1);
1433         ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
1434 
1435         check_log_for_insert_instance_layer_string(env, implicit_layer_name, true);
1436 
1437         enable_env_var.set_new_value("0");
1438         check_log_for_insert_instance_layer_string(env, implicit_layer_name, true);
1439 
1440         enable_env_var.set_new_value("1");
1441         check_log_for_insert_instance_layer_string(env, implicit_layer_name, true);
1442 
1443         enable_env_var.remove_value();
1444 
1445         disable_env_var.set_new_value("0");
1446         check_log_for_insert_instance_layer_string(env, implicit_layer_name, true);
1447 
1448         disable_env_var.set_new_value("1");
1449         check_log_for_insert_instance_layer_string(env, implicit_layer_name, true);
1450 
1451         enable_env_var.set_new_value("1");
1452         disable_env_var.set_new_value("1");
1453         check_log_for_insert_instance_layer_string(env, implicit_layer_name, true);
1454     }
1455 
1456     // control is set to off
1457     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off");
1458     env.update_loader_settings(env.loader_settings);
1459     {
1460         EnvVarWrapper enable_env_var{"ENABLE_ME"};
1461         EnvVarWrapper disable_env_var{"DISABLE_ME"};
1462 
1463         ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0));
1464 
1465         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1466 
1467         enable_env_var.set_new_value("0");
1468         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1469 
1470         enable_env_var.set_new_value("1");
1471         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1472 
1473         enable_env_var.remove_value();
1474 
1475         disable_env_var.set_new_value("0");
1476         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1477 
1478         disable_env_var.set_new_value("1");
1479         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1480 
1481         enable_env_var.set_new_value("1");
1482         disable_env_var.set_new_value("1");
1483         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1484     }
1485 
1486     // control is set to auto
1487     env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto");
1488     env.update_loader_settings(env.loader_settings);
1489     {
1490         EnvVarWrapper enable_env_var{"ENABLE_ME"};
1491         EnvVarWrapper disable_env_var{"DISABLE_ME"};
1492 
1493         auto layers = env.GetLayerProperties(1);
1494         ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name));
1495 
1496         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1497 
1498         enable_env_var.set_new_value("0");
1499         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1500 
1501         enable_env_var.set_new_value("1");
1502         check_log_for_insert_instance_layer_string(env, implicit_layer_name, true);
1503 
1504         enable_env_var.remove_value();
1505 
1506         disable_env_var.set_new_value("0");
1507         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1508 
1509         disable_env_var.set_new_value("1");
1510         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1511 
1512         enable_env_var.set_new_value("1");
1513         disable_env_var.set_new_value("1");
1514         check_log_for_insert_instance_layer_string(env, implicit_layer_name, false);
1515     }
1516 }
1517 
1518 // Settings can say which filters to use - make sure those are propagated & treated correctly
TEST(SettingsFile, StderrLogFilters)1519 TEST(SettingsFile, StderrLogFilters) {
1520     FrameworkEnvironment env{};
1521     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1522     const char* explicit_layer_name = "Regular_TestLayer1";
1523     env.add_explicit_layer(TestLayerDetails{
1524         ManifestLayer{}.add_layer(
1525             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1526         "explicit_test_layer1.json"});
1527     env.update_loader_settings(env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
1528         AppSpecificSettings{}
1529             .add_layer_configuration(LoaderSettingsLayerConfiguration{}
1530                                          .set_name(explicit_layer_name)
1531                                          .set_path(env.get_shimmed_layer_manifest_path().str())
1532                                          .set_control("on"))
1533             .add_layer_configuration(
1534                 LoaderSettingsLayerConfiguration{}.set_name("VK_LAYER_missing").set_path("/road/to/nowhere").set_control("on"))));
1535 
1536     std::string expected_output_verbose;
1537     expected_output_verbose += "Layer Configurations count = 2\n";
1538     expected_output_verbose += "---- Layer Configuration [0] ----\n";
1539     expected_output_verbose += std::string("Name: ") + explicit_layer_name + "\n";
1540     expected_output_verbose += "Path: " + env.get_shimmed_layer_manifest_path().str() + "\n";
1541     expected_output_verbose += "Control: on\n";
1542     expected_output_verbose += "---- Layer Configuration [1] ----\n";
1543     expected_output_verbose += "Name: VK_LAYER_missing\n";
1544     expected_output_verbose += "Path: /road/to/nowhere\n";
1545     expected_output_verbose += "Control: on\n";
1546     expected_output_verbose += "---------------------------------\n";
1547 
1548     std::string expected_output_info = get_settings_location_log_message(env) + "\n";
1549 
1550     std::string expected_output_warning =
1551         "Layer name Regular_TestLayer1 does not conform to naming standard (Policy #LLP_LAYER_3)\n";
1552 
1553     std::string expected_output_error = "loader_get_json: Failed to open JSON file /road/to/nowhere\n";
1554 
1555     env.loader_settings.app_specific_settings.at(0).stderr_log = {"all"};
1556     env.update_loader_settings(env.loader_settings);
1557     {
1558         InstWrapper inst{env.vulkan_functions};
1559         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1560         inst.CheckCreate();
1561 
1562         ASSERT_TRUE(env.debug_log.find(expected_output_verbose));
1563         ASSERT_TRUE(env.debug_log.find(expected_output_info));
1564         ASSERT_TRUE(env.debug_log.find(expected_output_warning));
1565         ASSERT_TRUE(env.debug_log.find(expected_output_error));
1566         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1567         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
1568     }
1569     env.debug_log.clear();
1570     env.debug_log.create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
1571     env.loader_settings.app_specific_settings.at(0).stderr_log = {"info"};
1572     env.update_loader_settings(env.loader_settings);
1573     {
1574         InstWrapper inst{env.vulkan_functions};
1575         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1576         inst.CheckCreate();
1577 
1578         ASSERT_TRUE(env.debug_log.find(expected_output_verbose));
1579         ASSERT_FALSE(env.debug_log.find(expected_output_info));
1580         ASSERT_FALSE(env.debug_log.find(expected_output_warning));
1581         ASSERT_FALSE(env.debug_log.find(expected_output_error));
1582         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1583         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
1584     }
1585     env.debug_log.clear();
1586     env.debug_log.create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
1587     env.loader_settings.app_specific_settings.at(0).stderr_log = {"debug"};
1588     env.update_loader_settings(env.loader_settings);
1589     {
1590         InstWrapper inst{env.vulkan_functions};
1591         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1592         inst.CheckCreate();
1593 
1594         ASSERT_FALSE(env.debug_log.find(expected_output_verbose));
1595         ASSERT_TRUE(env.debug_log.find(expected_output_info));
1596         ASSERT_FALSE(env.debug_log.find(expected_output_warning));
1597         ASSERT_FALSE(env.debug_log.find(expected_output_error));
1598         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1599         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
1600     }
1601     env.debug_log.clear();
1602     env.debug_log.create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
1603     env.loader_settings.app_specific_settings.at(0).stderr_log = {"warn"};
1604     env.update_loader_settings(env.loader_settings);
1605     {
1606         InstWrapper inst{env.vulkan_functions};
1607         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1608         inst.CheckCreate();
1609 
1610         ASSERT_FALSE(env.debug_log.find(expected_output_verbose));
1611         ASSERT_FALSE(env.debug_log.find(expected_output_info));
1612         ASSERT_TRUE(env.debug_log.find(expected_output_warning));
1613         ASSERT_FALSE(env.debug_log.find(expected_output_error));
1614         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1615         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
1616     }
1617     env.debug_log.clear();
1618     env.debug_log.create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
1619     env.loader_settings.app_specific_settings.at(0).stderr_log = {"error"};
1620     env.update_loader_settings(env.loader_settings);
1621     {
1622         InstWrapper inst{env.vulkan_functions};
1623         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1624         inst.CheckCreate();
1625 
1626         ASSERT_FALSE(env.debug_log.find(expected_output_verbose));
1627         ASSERT_FALSE(env.debug_log.find(expected_output_info));
1628         ASSERT_FALSE(env.debug_log.find(expected_output_warning));
1629         ASSERT_TRUE(env.debug_log.find(expected_output_error));
1630         auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1);
1631         EXPECT_TRUE(string_eq(active_layer_props.at(0).layerName, explicit_layer_name));
1632     }
1633 }
1634 
1635 // Enough layers exist that arrays need to be resized - make sure that works
TEST(SettingsFile, TooManyLayers)1636 TEST(SettingsFile, TooManyLayers) {
1637     FrameworkEnvironment env{};
1638     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({});
1639     env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
1640         AppSpecificSettings{}.add_stderr_log_filter("all"));
1641     std::string layer_name = "VK_LAYER_regular_layer_name_";
1642     uint32_t layer_count = 40;
1643     for (uint32_t i = 0; i < layer_count; i++) {
1644         env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1645                                                                               .set_name(layer_name + std::to_string(i))
1646                                                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1647                                                 layer_name + std::to_string(i) + ".json"}
1648                                    .set_discovery_type(ManifestDiscoveryType::override_folder));
1649         env.loader_settings.app_specific_settings.at(0).add_layer_configuration(LoaderSettingsLayerConfiguration{}
1650                                                                                     .set_name(layer_name + std::to_string(i))
1651                                                                                     .set_path(env.get_layer_manifest_path(i).str())
1652                                                                                     .set_control("on"));
1653     }
1654     env.update_loader_settings(env.loader_settings);
1655 
1656     {
1657         auto layer_props = env.GetLayerProperties(40);
1658         for (uint32_t i = 0; i < layer_count; i++) {
1659             std::string expected_layer_name = layer_name + std::to_string(i);
1660             EXPECT_TRUE(string_eq(layer_props.at(i).layerName, expected_layer_name.c_str()));
1661         }
1662         InstWrapper inst{env.vulkan_functions};
1663         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1664         inst.CheckCreate();
1665 
1666         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1667         env.debug_log.clear();
1668         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 40);
1669         for (uint32_t i = 0; i < layer_count; i++) {
1670             std::string expected_layer_name = layer_name + std::to_string(i);
1671             EXPECT_TRUE(string_eq(layers.at(i).layerName, expected_layer_name.c_str()));
1672         }
1673     }
1674     env.loader_settings.app_specific_settings.at(0).layer_configurations.clear();
1675 
1676     // Now reverse the order to make sure adding the 'last' layer first works
1677     for (uint32_t i = 0; i < layer_count; i++) {
1678         env.loader_settings.app_specific_settings.at(0).add_layer_configuration(
1679             LoaderSettingsLayerConfiguration{}
1680                 .set_name(layer_name + std::to_string(layer_count - i - 1))
1681                 .set_path(env.get_layer_manifest_path(layer_count - i - 1).str())
1682                 .set_control("on"));
1683     }
1684     env.update_loader_settings(env.loader_settings);
1685 
1686     {
1687         auto layer_props = env.GetLayerProperties(40);
1688         for (uint32_t i = 0; i < layer_count; i++) {
1689             std::string expected_layer_name = layer_name + std::to_string(layer_count - i - 1);
1690             EXPECT_TRUE(string_eq(layer_props.at(i).layerName, expected_layer_name.c_str()));
1691         }
1692         InstWrapper inst{env.vulkan_functions};
1693         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1694         inst.CheckCreate();
1695 
1696         ASSERT_TRUE(env.debug_log.find(get_settings_location_log_message(env)));
1697         env.debug_log.clear();
1698         auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 40);
1699         for (uint32_t i = 0; i < layer_count; i++) {
1700             std::string expected_layer_name = layer_name + std::to_string(layer_count - i - 1);
1701             EXPECT_TRUE(string_eq(layers.at(i).layerName, expected_layer_name.c_str()));
1702         }
1703     }
1704 }
1705