• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 The Khronos Group Inc.
3  * Copyright (c) 2021-2022 Valve Corporation
4  * Copyright (c) 2021-2022 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 
CheckLogForLayerString(FrameworkEnvironment & env,const char * implicit_layer_name,bool check_for_enable)30 void CheckLogForLayerString(FrameworkEnvironment& env, const char* implicit_layer_name, bool check_for_enable) {
31     {
32         InstWrapper inst{env.vulkan_functions};
33         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
34         inst.CheckCreate(VK_SUCCESS);
35         if (check_for_enable) {
36             ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + implicit_layer_name));
37         } else {
38             ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer ") + implicit_layer_name));
39         }
40     }
41     env.debug_log.clear();
42 }
43 
44 const char* lunarg_meta_layer_name = "VK_LAYER_LUNARG_override";
45 
TEST(ImplicitLayers,WithEnableAndDisableEnvVar)46 TEST(ImplicitLayers, WithEnableAndDisableEnvVar) {
47     FrameworkEnvironment env;
48     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
49     const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer";
50     const char* enable_env_var = "ENABLE_ME";
51     const char* disable_env_var = "DISABLE_ME";
52 
53     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
54                                                          .set_name(implicit_layer_name)
55                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
56                                                          .set_disable_environment(disable_env_var)
57                                                          .set_enable_environment(enable_env_var)),
58                            "implicit_test_layer.json");
59 
60     uint32_t count = 0;
61     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
62     ASSERT_EQ(count, 1U);
63 
64     // didn't set enable env-var, layer should not load
65     CheckLogForLayerString(env, implicit_layer_name, false);
66 
67     // set enable env-var to 0, no layer should be found
68     set_env_var(enable_env_var, "0");
69     CheckLogForLayerString(env, implicit_layer_name, false);
70 
71     // // set enable env-var, layer should load
72     set_env_var(enable_env_var, "1");
73     CheckLogForLayerString(env, implicit_layer_name, true);
74 
75     remove_env_var(enable_env_var);
76 
77     // set disable env-var to 0, layer should not load
78     set_env_var(disable_env_var, "0");
79     CheckLogForLayerString(env, implicit_layer_name, false);
80 
81     // set disable env-var to 1, layer should not load
82     set_env_var(disable_env_var, "1");
83     CheckLogForLayerString(env, implicit_layer_name, false);
84 
85     // set both enable and disable env-var, layer should not load
86     set_env_var(enable_env_var, "1");
87     set_env_var(disable_env_var, "1");
88     CheckLogForLayerString(env, implicit_layer_name, false);
89 
90     remove_env_var(enable_env_var);
91     remove_env_var(disable_env_var);
92 }
93 
TEST(ImplicitLayers,OnlyDisableEnvVar)94 TEST(ImplicitLayers, OnlyDisableEnvVar) {
95     FrameworkEnvironment env;
96     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
97     const char* implicit_layer_name = "ImplicitTestLayer";
98     const char* disable_env_var = "DISABLE_ME";
99 
100     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
101                                                          .set_name(implicit_layer_name)
102                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
103                                                          .set_disable_environment(disable_env_var)),
104                            "implicit_test_layer.json");
105 
106     uint32_t count = 0;
107     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
108     ASSERT_EQ(count, 1U);
109 
110     // don't set disable env-var, layer should load
111     CheckLogForLayerString(env, implicit_layer_name, true);
112 
113     // set disable env-var to 0, layer should load
114     set_env_var(disable_env_var, "0");
115     CheckLogForLayerString(env, implicit_layer_name, false);
116 
117     // set disable env-var to 1, layer should not load
118     set_env_var(disable_env_var, "1");
119     CheckLogForLayerString(env, implicit_layer_name, false);
120 
121     {
122         InstWrapper inst{env.vulkan_functions};
123         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
124         inst.create_info.add_layer(implicit_layer_name);
125         inst.CheckCreate(VK_SUCCESS);
126         ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + implicit_layer_name));
127     }
128     remove_env_var(disable_env_var);
129 }
130 
TEST(ImplicitLayers,PreInstanceEnumInstLayerProps)131 TEST(ImplicitLayers, PreInstanceEnumInstLayerProps) {
132     FrameworkEnvironment env;
133     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
134     const char* implicit_layer_name = "ImplicitTestLayer";
135     const char* disable_env_var = "DISABLE_ME";
136 
137     env.add_implicit_layer(
138         ManifestLayer{}
139             .set_file_format_version(ManifestVersion(1, 1, 2))
140             .add_layer(ManifestLayer::LayerDescription{}
141                            .set_name(implicit_layer_name)
142                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
143                            .set_disable_environment(disable_env_var)
144                            .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
145                                                           .set_vk_func("vkEnumerateInstanceLayerProperties")
146                                                           .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))),
147         "implicit_test_layer.json");
148 
149     uint32_t layer_props = 43;
150     auto& layer = env.get_test_layer(0);
151     layer.set_reported_layer_props(layer_props);
152 
153     uint32_t count = 0;
154     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
155     ASSERT_EQ(count, layer_props);
156 
157     // set disable env-var to 1, layer should not load
158     set_env_var(disable_env_var, "1");
159 
160     count = 0;
161     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
162     ASSERT_NE(count, 0U);
163     ASSERT_NE(count, layer_props);
164 
165     remove_env_var(disable_env_var);
166 }
167 
TEST(ImplicitLayers,PreInstanceEnumInstExtProps)168 TEST(ImplicitLayers, PreInstanceEnumInstExtProps) {
169     FrameworkEnvironment env;
170     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
171     const char* implicit_layer_name = "ImplicitTestLayer";
172     const char* disable_env_var = "DISABLE_ME";
173 
174     env.add_implicit_layer(ManifestLayer{}
175                                .set_file_format_version(ManifestVersion(1, 1, 2))
176                                .add_layer(ManifestLayer::LayerDescription{}
177                                               .set_name(implicit_layer_name)
178                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
179                                               .set_disable_environment(disable_env_var)
180                                               .add_pre_instance_function(
181                                                   ManifestLayer::LayerDescription::FunctionOverride{}
182                                                       .set_vk_func("vkEnumerateInstanceExtensionProperties")
183                                                       .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))),
184                            "implicit_test_layer.json");
185 
186     uint32_t ext_props = 52;
187     auto& layer = env.get_test_layer(0);
188     layer.set_reported_extension_props(ext_props);
189 
190     uint32_t count = 0;
191     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
192     ASSERT_EQ(count, ext_props);
193 
194     // set disable env-var to 1, layer should not load
195     set_env_var(disable_env_var, "1");
196 
197     count = 0;
198     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
199     ASSERT_NE(count, 0U);
200     ASSERT_NE(count, ext_props);
201 
202     remove_env_var(disable_env_var);
203 }
204 
TEST(ImplicitLayers,PreInstanceVersion)205 TEST(ImplicitLayers, PreInstanceVersion) {
206     FrameworkEnvironment env;
207     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
208     env.get_test_icd().physical_devices.push_back({});
209     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 3);
210 
211     const char* implicit_layer_name = "ImplicitTestLayer";
212     const char* disable_env_var = "DISABLE_ME";
213 
214     env.add_implicit_layer(
215         ManifestLayer{}
216             .set_file_format_version(ManifestVersion(1, 1, 2))
217             .add_layer(ManifestLayer::LayerDescription{}
218                            .set_name(implicit_layer_name)
219                            .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
220                            .set_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3))
221                            .set_disable_environment(disable_env_var)
222                            .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{}
223                                                           .set_vk_func("vkEnumerateInstanceVersion")
224                                                           .set_override_name("test_preinst_vkEnumerateInstanceVersion"))),
225         "implicit_test_layer.json");
226 
227     uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4);
228     auto& layer = env.get_test_layer(0);
229     layer.set_reported_instance_version(layer_version);
230 
231     uint32_t version = 0;
232     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
233     ASSERT_EQ(version, layer_version);
234 
235     // set disable env-var to 1, layer should not load
236     set_env_var(disable_env_var, "1");
237 
238     version = 0;
239     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version));
240     ASSERT_NE(version, 0U);
241     ASSERT_NE(version, layer_version);
242 
243     remove_env_var(disable_env_var);
244 }
245 
246 // Run with a pre-Negotiate function version of the layer so that it has to query vkCreateInstance using the
247 // renamed vkGetInstanceProcAddr function which returns one that intentionally fails.  Then disable the
248 // layer and verify it works.  The non-override version of vkCreateInstance in the layer also works (and is
249 // tested through behavior above).
TEST(ImplicitLayers,OverrideGetInstanceProcAddr)250 TEST(ImplicitLayers, OverrideGetInstanceProcAddr) {
251     FrameworkEnvironment env;
252     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
253     env.get_test_icd().physical_devices.push_back({});
254 
255     const char* implicit_layer_name = "ImplicitTestLayer";
256     const char* disable_env_var = "DISABLE_ME";
257 
258     env.add_implicit_layer(ManifestLayer{}
259                                .set_file_format_version(ManifestVersion(1, 0, 0))
260                                .add_layer(ManifestLayer::LayerDescription{}
261                                               .set_name(implicit_layer_name)
262                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_1)
263                                               .set_disable_environment(disable_env_var)
264                                               .add_function(ManifestLayer::LayerDescription::FunctionOverride{}
265                                                                 .set_vk_func("vkGetInstanceProcAddr")
266                                                                 .set_override_name("test_override_vkGetInstanceProcAddr"))),
267                            "implicit_test_layer.json");
268 
269     {
270         InstWrapper inst1{env.vulkan_functions};
271         inst1.CheckCreate(VK_ERROR_INVALID_SHADER_NV);
272     }
273 
274     {
275         // set disable env-var to 1, layer should not load
276         set_env_var(disable_env_var, "1");
277         InstWrapper inst2{env.vulkan_functions};
278         inst2.CheckCreate();
279     }
280 
281     remove_env_var(disable_env_var);
282 }
283 
284 // Meta layer which contains component layers that do not exist.
TEST(MetaLayers,InvalidComponentLayer)285 TEST(MetaLayers, InvalidComponentLayer) {
286     FrameworkEnvironment env;
287     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
288     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
289     const char* invalid_layer_name_1 = "VK_LAYER_InvalidLayer1";
290     const char* invalid_layer_name_2 = "VK_LAYER_InvalidLayer2";
291     env.add_implicit_layer(ManifestLayer{}
292                                .set_file_format_version(ManifestVersion(1, 1, 2))
293                                .add_layer(ManifestLayer::LayerDescription{}
294                                               .set_name(meta_layer_name)
295                                               .add_component_layers({invalid_layer_name_1, invalid_layer_name_2})
296                                               .set_disable_environment("NotGonnaWork")
297                                               .add_instance_extension({"NeverGonnaGiveYouUp"})
298                                               .add_device_extension({"NeverGonnaLetYouDown"})),
299                            "meta_test_layer.json");
300 
301     const char* regular_layer_name = "TestLayer";
302     env.add_explicit_layer(
303         ManifestLayer{}.add_layer(
304             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
305         "regular_test_layer.json");
306 
307     // should find 1, the 'regular' layer
308     uint32_t layer_count = 1;
309     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
310     EXPECT_EQ(layer_count, 1U);
311 
312     VkLayerProperties layer_props;
313     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, &layer_props));
314     EXPECT_EQ(layer_count, 1U);
315     EXPECT_TRUE(string_eq(layer_props.layerName, regular_layer_name));
316 
317     uint32_t extension_count = 0;
318     std::array<VkExtensionProperties, 3> extensions;
319     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
320     EXPECT_EQ(extension_count, 3U);  // return debug report & debug utils & portability enumeration
321 
322     EXPECT_EQ(VK_SUCCESS,
323               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()));
324     EXPECT_EQ(extension_count, 3U);
325 
326     InstWrapper inst{env.vulkan_functions};
327     inst.create_info.add_layer(meta_layer_name);
328     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
329     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
330     ASSERT_TRUE(env.debug_log.find(std::string("verify_meta_layer_component_layers: Meta-layer ") + meta_layer_name +
331                                    " can't find component layer " + invalid_layer_name_1 + " at index 0.  Skipping this layer."));
332 }
333 
334 // Meta layer that is an explicit layer
TEST(MetaLayers,ExplicitMetaLayer)335 TEST(MetaLayers, ExplicitMetaLayer) {
336     FrameworkEnvironment env;
337     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
338     env.get_test_icd().add_physical_device({});
339     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
340     const char* regular_layer_name = "VK_LAYER_TestLayer";
341     env.add_explicit_layer(
342         ManifestLayer{}
343             .set_file_format_version(ManifestVersion(1, 1, 2))
344             .add_layer(ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
345         "meta_test_layer.json");
346 
347     env.add_explicit_layer(
348         ManifestLayer{}.add_layer(
349             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
350         "regular_test_layer.json");
351     {  // global functions
352         // should find 1, the 'regular' layer
353         uint32_t layer_count = 0;
354         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
355         EXPECT_EQ(layer_count, 2U);
356 
357         std::array<VkLayerProperties, 2> layer_props;
358         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
359         EXPECT_EQ(layer_count, 2U);
360         EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name}, layer_props));
361 
362         uint32_t extension_count = 0;
363         std::array<VkExtensionProperties, 3> extensions;
364         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
365         EXPECT_EQ(extension_count, 3U);  // return debug report & debug utils & portability enumeration
366 
367         EXPECT_EQ(VK_SUCCESS,
368                   env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()));
369         EXPECT_EQ(extension_count, 3U);
370     }
371     {  // don't enable the layer, shouldn't find any layers when calling vkEnumerateDeviceLayerProperties
372         InstWrapper inst{env.vulkan_functions};
373         inst.CheckCreate(VK_SUCCESS);
374         auto phys_dev = inst.GetPhysDev();
375         uint32_t count = 0;
376         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
377         ASSERT_EQ(count, 0U);
378     }
379     {
380         InstWrapper inst{env.vulkan_functions};
381         inst.create_info.add_layer(meta_layer_name);
382         inst.CheckCreate(VK_SUCCESS);
383         auto phys_dev = inst.GetPhysDev();
384         uint32_t count = 0;
385         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
386         ASSERT_EQ(count, 2U);
387         std::array<VkLayerProperties, 2> layer_props;
388         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
389         ASSERT_EQ(count, 2U);
390         EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name}, layer_props));
391     }
392 }
393 
394 // Meta layer which adds itself in its list of component layers
TEST(MetaLayers,MetaLayerNameInComponentLayers)395 TEST(MetaLayers, MetaLayerNameInComponentLayers) {
396     FrameworkEnvironment env;
397     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
398     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
399     const char* regular_layer_name = "VK_LAYER_TestLayer";
400     env.add_implicit_layer(ManifestLayer{}
401                                .set_file_format_version(ManifestVersion(1, 1, 2))
402                                .add_layer(ManifestLayer::LayerDescription{}
403                                               .set_name(meta_layer_name)
404                                               .add_component_layers({meta_layer_name, regular_layer_name})
405                                               .set_disable_environment("NotGonnaWork")
406                                               .add_instance_extension({"NeverGonnaGiveYouUp"})
407                                               .add_device_extension({"NeverGonnaLetYouDown"})),
408                            "meta_test_layer.json");
409 
410     env.add_explicit_layer(
411         ManifestLayer{}.add_layer(
412             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
413         "regular_test_layer.json");
414 
415     // should find 1, the 'regular' layer
416     uint32_t layer_count = 1;
417     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
418     EXPECT_EQ(layer_count, 1U);
419 
420     VkLayerProperties layer_props;
421     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, &layer_props));
422     EXPECT_EQ(layer_count, 1U);
423     EXPECT_TRUE(string_eq(layer_props.layerName, regular_layer_name));
424 
425     uint32_t extension_count = 0;
426     std::array<VkExtensionProperties, 3> extensions;
427     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
428     EXPECT_EQ(extension_count, 3U);  // return debug report & debug utils & portability enumeration
429 
430     EXPECT_EQ(VK_SUCCESS,
431               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()));
432     EXPECT_EQ(extension_count, 3U);
433 
434     InstWrapper inst{env.vulkan_functions};
435     inst.create_info.add_layer(meta_layer_name);
436     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
437     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
438     ASSERT_TRUE(env.debug_log.find(std::string("verify_meta_layer_component_layers: Meta-layer ") + meta_layer_name +
439                                    " lists itself in its component layer " + "list at index 0.  Skipping this layer."));
440 }
441 
442 // Meta layer which adds another meta layer as a component layer
TEST(MetaLayers,MetaLayerWhichAddsMetaLayer)443 TEST(MetaLayers, MetaLayerWhichAddsMetaLayer) {
444     FrameworkEnvironment env;
445     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
446     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
447     const char* meta_meta_layer_name = "VK_LAYER_MetaMetaTestLayer";
448     const char* regular_layer_name = "VK_LAYER_TestLayer";
449     env.add_explicit_layer(
450         ManifestLayer{}.add_layer(
451             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
452         "regular_test_layer.json");
453     env.add_explicit_layer(
454         ManifestLayer{}
455             .set_file_format_version(ManifestVersion(1, 1, 2))
456             .add_layer(ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
457         "meta_test_layer.json");
458     env.add_explicit_layer(ManifestLayer{}
459                                .set_file_format_version(ManifestVersion(1, 1, 2))
460                                .add_layer(ManifestLayer::LayerDescription{}
461                                               .set_name(meta_meta_layer_name)
462                                               .add_component_layers({meta_layer_name, regular_layer_name})),
463                            "meta_meta_test_layer.json");
464 
465     uint32_t layer_count = 3;
466     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
467     EXPECT_EQ(layer_count, 3U);
468 
469     std::array<VkLayerProperties, 3> layer_props;
470     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
471     EXPECT_EQ(layer_count, 3U);
472     EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name, meta_meta_layer_name}, layer_props));
473 
474     uint32_t extension_count = 0;
475     std::array<VkExtensionProperties, 3> extensions;
476     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
477     EXPECT_EQ(extension_count, 3U);  // return debug report & debug utils & portability enumeration
478 
479     EXPECT_EQ(VK_SUCCESS,
480               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()));
481     EXPECT_EQ(extension_count, 3U);
482 
483     InstWrapper inst{env.vulkan_functions};
484     inst.create_info.add_layer(meta_layer_name);
485     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
486     inst.CheckCreate();
487     ASSERT_TRUE(env.debug_log.find(std::string("verify_meta_layer_component_layers: Adding meta-layer ") + meta_meta_layer_name +
488                                    " which also contains meta-layer " + meta_layer_name));
489 }
490 
TEST(MetaLayers,InstanceExtensionInComponentLayer)491 TEST(MetaLayers, InstanceExtensionInComponentLayer) {
492     FrameworkEnvironment env;
493     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
494     env.get_test_icd().add_physical_device({});
495     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
496     const char* regular_layer_name = "VK_LAYER_TestLayer";
497     const char* instance_ext_name = "VK_EXT_headless_surface";
498     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
499                                                          .set_name(regular_layer_name)
500                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
501                                                          .add_instance_extension({instance_ext_name})),
502                            "regular_test_layer.json");
503     env.add_explicit_layer(
504         ManifestLayer{}
505             .set_file_format_version(ManifestVersion(1, 1, 2))
506             .add_layer(ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
507         "meta_test_layer.json");
508 
509     uint32_t extension_count = 0;
510     std::array<VkExtensionProperties, 1> extensions;
511     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(meta_layer_name, &extension_count, nullptr));
512     EXPECT_EQ(extension_count, 1U);  // return instance_ext_name
513 
514     EXPECT_EQ(VK_SUCCESS,
515               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(meta_layer_name, &extension_count, extensions.data()));
516     EXPECT_EQ(extension_count, 1U);
517     EXPECT_TRUE(string_eq(extensions[0].extensionName, instance_ext_name));
518 }
519 
TEST(MetaLayers,DeviceExtensionInComponentLayer)520 TEST(MetaLayers, DeviceExtensionInComponentLayer) {
521     FrameworkEnvironment env;
522     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
523     env.get_test_icd().add_physical_device({});
524     const char* meta_layer_name = "VK_LAYER_MetaTestLayer";
525     const char* regular_layer_name = "VK_LAYER_TestLayer";
526     const char* device_ext_name = "VK_EXT_fake_dev_ext";
527     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
528                                                          .set_name(regular_layer_name)
529                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
530                                                          .add_device_extension({device_ext_name})),
531                            "regular_test_layer.json");
532     env.add_explicit_layer(
533         ManifestLayer{}
534             .set_file_format_version(ManifestVersion(1, 1, 2))
535             .add_layer(ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})),
536         "meta_test_layer.json");
537     {
538         uint32_t extension_count = 0;
539         EXPECT_EQ(VK_SUCCESS,
540                   env.vulkan_functions.vkEnumerateInstanceExtensionProperties(meta_layer_name, &extension_count, nullptr));
541         EXPECT_EQ(extension_count, 0U);
542     }
543     {  // layer is not enabled
544         InstWrapper inst{env.vulkan_functions};
545         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
546         inst.CheckCreate();
547         ASSERT_TRUE(env.debug_log.find(std::string("Meta-layer ") + meta_layer_name + " component layer " + regular_layer_name +
548                                        " adding device extension " + device_ext_name));
549 
550         auto phys_dev = inst.GetPhysDev();
551         uint32_t extension_count = 0;
552         std::array<VkExtensionProperties, 1> extensions;
553         EXPECT_EQ(VK_SUCCESS,
554                   env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, meta_layer_name, &extension_count, nullptr));
555         EXPECT_EQ(extension_count, 1U);  // return device_ext_name
556 
557         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, meta_layer_name, &extension_count,
558                                                                                         extensions.data()));
559         EXPECT_EQ(extension_count, 1U);
560         EXPECT_TRUE(string_eq(extensions[0].extensionName, device_ext_name));
561     }
562     {  // layer is enabled
563         InstWrapper inst{env.vulkan_functions};
564         inst.create_info.add_layer(meta_layer_name);
565         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
566         inst.CheckCreate();
567         ASSERT_TRUE(env.debug_log.find(std::string("Meta-layer ") + meta_layer_name + " component layer " + regular_layer_name +
568                                        " adding device extension " + device_ext_name));
569         auto phys_dev = inst.GetPhysDev();
570 
571         uint32_t extension_count = 0;
572         std::array<VkExtensionProperties, 1> extensions;
573         EXPECT_EQ(VK_SUCCESS,
574                   env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, meta_layer_name, &extension_count, nullptr));
575         EXPECT_EQ(extension_count, 1U);  // return device_ext_name
576 
577         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, meta_layer_name, &extension_count,
578                                                                                         extensions.data()));
579         EXPECT_EQ(extension_count, 1U);
580         EXPECT_TRUE(string_eq(extensions[0].extensionName, device_ext_name));
581     }
582 }
583 // Override meta layer missing disable environment variable still enables the layer
TEST(OverrideMetaLayer,InvalidDisableEnvironment)584 TEST(OverrideMetaLayer, InvalidDisableEnvironment) {
585     FrameworkEnvironment env;
586     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
587     env.get_test_icd().add_physical_device({});
588     const char* regular_layer_name = "VK_LAYER_TestLayer";
589     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
590                                                          .set_name(regular_layer_name)
591                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
592                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
593                                                          .add_device_extension({"NeverGonnaLetYouDown"})),
594                            "regular_test_layer.json");
595 
596     env.add_implicit_layer(ManifestLayer{}
597                                .set_file_format_version(ManifestVersion(1, 1, 2))
598                                .add_layer(ManifestLayer::LayerDescription{}
599                                               .set_name(lunarg_meta_layer_name)
600                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
601                                               .add_component_layers({regular_layer_name})),
602                            "meta_test_layer.json");
603 
604     uint32_t layer_count = 0;
605     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
606     EXPECT_EQ(layer_count, 1U);
607 
608     std::array<VkLayerProperties, 1> layer_props;
609     EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
610     EXPECT_EQ(layer_count, 1U);
611     EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
612 
613     InstWrapper inst{env.vulkan_functions};
614     inst.CheckCreate();
615 }
616 
617 // Override meta layer whose version is less than the api version of the instance
TEST(OverrideMetaLayer,OlderVersionThanInstance)618 TEST(OverrideMetaLayer, OlderVersionThanInstance) {
619     FrameworkEnvironment env;
620     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
621     env.get_test_icd().add_physical_device({});
622     const char* regular_layer_name = "VK_LAYER_TestLayer";
623     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
624                                                          .set_name(regular_layer_name)
625                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
626                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
627                                                          .add_device_extension({"NeverGonnaLetYouDown"})),
628                            "regular_test_layer.json");
629 
630     env.add_implicit_layer(ManifestLayer{}
631                                .set_file_format_version(ManifestVersion(1, 1, 2))
632                                .add_layer(ManifestLayer::LayerDescription{}
633                                               .set_name(lunarg_meta_layer_name)
634                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
635                                               .set_disable_environment("DisableMeIfYouCan")
636                                               .add_component_layers({regular_layer_name})),
637                            "meta_test_layer.json");
638     {  // global functions
639         uint32_t layer_count = 0;
640         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
641         EXPECT_EQ(layer_count, 2U);
642 
643         std::array<VkLayerProperties, 2> layer_props;
644         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
645         EXPECT_EQ(layer_count, 2U);
646         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
647     }
648     {  // 1.1 instance
649         InstWrapper inst{env.vulkan_functions};
650         inst.create_info.api_version = VK_API_VERSION_1_1;
651         inst.CheckCreate();
652         VkPhysicalDevice phys_dev = inst.GetPhysDev();
653 
654         uint32_t count = 0;
655         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
656         ASSERT_EQ(2U, count);
657         std::array<VkLayerProperties, 2> layer_props;
658 
659         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
660         ASSERT_EQ(2U, count);
661         ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
662         ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name));
663     }
664     {  // 1.3 instance
665 
666         InstWrapper inst{env.vulkan_functions};
667         inst.create_info.api_version = VK_API_VERSION_1_3;
668         inst.CheckCreate();
669         VkPhysicalDevice phys_dev = inst.GetPhysDev();
670 
671         uint32_t count = 0;
672         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
673         ASSERT_EQ(2U, count);
674         std::array<VkLayerProperties, 2> layer_props;
675 
676         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
677         ASSERT_EQ(2U, count);
678         ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
679         ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name));
680     }
681 }
682 
TEST(OverrideMetaLayer,OlderMetaLayerWithNewerInstanceVersion)683 TEST(OverrideMetaLayer, OlderMetaLayerWithNewerInstanceVersion) {
684     FrameworkEnvironment env;
685     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
686     env.get_test_icd().add_physical_device({});
687 
688     const char* regular_layer_name = "VK_LAYER_TestLayer";
689     env.add_explicit_layer(ManifestLayer{}
690                                .set_file_format_version(ManifestVersion(1, 2, 0))
691                                .add_layer(ManifestLayer::LayerDescription{}
692                                               .set_name(regular_layer_name)
693                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
694                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
695                            "regular_test_layer.json");
696 
697     env.add_implicit_layer(ManifestLayer{}
698                                .set_file_format_version(ManifestVersion(1, 2, 0))
699                                .add_layer(ManifestLayer::LayerDescription{}
700                                               .set_name(lunarg_meta_layer_name)
701                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
702                                               .add_component_layers({regular_layer_name})
703                                               .set_disable_environment("DisableMeIfYouCan")),
704                            "meta_test_layer.json");
705     {  // global functions
706         uint32_t layer_count = 2;
707         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
708         EXPECT_EQ(layer_count, 2U);
709 
710         std::array<VkLayerProperties, 2> layer_props;
711         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
712         EXPECT_EQ(layer_count, 2U);
713         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
714     }
715     {
716         // 1.1 instance
717         InstWrapper inst{env.vulkan_functions};
718         inst.create_info.set_api_version(1, 1, 0);
719         inst.CheckCreate();
720         VkPhysicalDevice phys_dev = inst.GetPhysDev();
721 
722         uint32_t count = 0;
723         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
724         ASSERT_EQ(2U, count);
725         std::array<VkLayerProperties, 2> layer_props;
726 
727         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
728         ASSERT_EQ(2U, count);
729         ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
730         ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name));
731     }
732 
733     {
734         // 1.3 instance
735         InstWrapper inst{env.vulkan_functions};
736         inst.create_info.set_api_version(1, 3, 0);
737         inst.CheckCreate();
738         VkPhysicalDevice phys_dev = inst.GetPhysDev();
739 
740         uint32_t count = 0;
741         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
742         ASSERT_EQ(2U, count);
743         std::array<VkLayerProperties, 2> layer_props;
744 
745         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
746         ASSERT_EQ(2U, count);
747         ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
748         ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name));
749     }
750 }
751 
TEST(OverrideMetaLayer,NewerComponentLayerInMetaLayer)752 TEST(OverrideMetaLayer, NewerComponentLayerInMetaLayer) {
753     FrameworkEnvironment env;
754     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
755     env.get_test_icd().add_physical_device({});
756 
757     const char* regular_layer_name = "VK_LAYER_TestLayer";
758     env.add_explicit_layer(ManifestLayer{}
759                                .set_file_format_version(ManifestVersion(1, 2, 0))
760                                .add_layer(ManifestLayer::LayerDescription{}
761                                               .set_name(regular_layer_name)
762                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
763                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 2, 0))),
764                            "regular_test_layer.json");
765 
766     env.add_implicit_layer(ManifestLayer{}
767                                .set_file_format_version(ManifestVersion(1, 2, 0))
768                                .add_layer(ManifestLayer::LayerDescription{}
769                                               .set_name(lunarg_meta_layer_name)
770                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
771                                               .add_component_layers({regular_layer_name})
772                                               .set_disable_environment("DisableMeIfYouCan")),
773                            "meta_test_layer.json");
774     {  // global functions
775         uint32_t layer_count = 0;
776         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
777         EXPECT_EQ(layer_count, 2U);
778 
779         std::array<VkLayerProperties, 2> layer_props;
780         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
781         EXPECT_EQ(layer_count, 2U);
782         // Expect the explicit layer to still be found
783         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
784     }
785     {
786         // 1.1 instance
787         InstWrapper inst{env.vulkan_functions};
788         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
789         inst.create_info.set_api_version(1, 1, 0);
790         inst.CheckCreate();
791         VkPhysicalDevice phys_dev = inst.GetPhysDev();
792         // Newer component is allowed now
793         EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
794         env.debug_log.clear();
795         uint32_t count = 0;
796         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
797         EXPECT_EQ(2U, count);
798         std::array<VkLayerProperties, 2> layer_props;
799 
800         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
801         EXPECT_EQ(2U, count);
802         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
803     }
804 
805     {
806         // 1.3 instance
807         InstWrapper inst{env.vulkan_functions};
808         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
809         inst.create_info.set_api_version(1, 3, 0);
810         inst.CheckCreate();
811         VkPhysicalDevice phys_dev = inst.GetPhysDev();
812         // Newer component is allowed now
813         EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
814         env.debug_log.clear();
815         uint32_t count = 0;
816         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
817         EXPECT_EQ(2U, count);
818         std::array<VkLayerProperties, 2> layer_props;
819 
820         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
821         EXPECT_EQ(2U, count);
822         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
823     }
824 }
825 
TEST(OverrideMetaLayer,OlderComponentLayerInMetaLayer)826 TEST(OverrideMetaLayer, OlderComponentLayerInMetaLayer) {
827     FrameworkEnvironment env;
828     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
829     env.get_test_icd().add_physical_device({});
830 
831     const char* regular_layer_name = "VK_LAYER_TestLayer";
832     env.add_explicit_layer(ManifestLayer{}
833                                .set_file_format_version(ManifestVersion(1, 2, 0))
834                                .add_layer(ManifestLayer::LayerDescription{}
835                                               .set_name(regular_layer_name)
836                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
837                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
838                            "regular_test_layer.json");
839 
840     env.add_implicit_layer(ManifestLayer{}
841                                .set_file_format_version(ManifestVersion(1, 2, 0))
842                                .add_layer(ManifestLayer::LayerDescription{}
843                                               .set_name(lunarg_meta_layer_name)
844                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
845                                               .add_component_layers({regular_layer_name})
846                                               .set_disable_environment("DisableMeIfYouCan")),
847                            "meta_test_layer.json");
848     {  // global functions
849         uint32_t layer_count = 0;
850         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
851         EXPECT_EQ(layer_count, 1U);
852 
853         std::array<VkLayerProperties, 1> layer_props;
854         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
855         EXPECT_EQ(layer_count, 1U);
856         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
857     }
858     {
859         // 1.1 instance
860         InstWrapper inst{env.vulkan_functions};
861         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
862         inst.create_info.set_api_version(1, 1, 0);
863         inst.CheckCreate();
864         VkPhysicalDevice phys_dev = inst.GetPhysDev();
865         EXPECT_TRUE(
866             env.debug_log.find("verify_meta_layer_component_layers: Meta-layer uses API version 1.1, but component layer 0 has API "
867                                "version 1.0 that is lower.  Skipping this layer."));
868         env.debug_log.clear();
869         uint32_t count = 0;
870         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
871         ASSERT_EQ(0U, count);
872         std::array<VkLayerProperties, 2> layer_props;
873         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
874         ASSERT_EQ(0U, count);
875     }
876 
877     {
878         // 1.2 instance
879         InstWrapper inst{env.vulkan_functions};
880         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
881         inst.create_info.set_api_version(1, 2, 0);
882         inst.CheckCreate();
883         VkPhysicalDevice phys_dev = inst.GetPhysDev();
884         ASSERT_TRUE(
885             env.debug_log.find("verify_meta_layer_component_layers: Meta-layer uses API version 1.1, but component layer 0 has API "
886                                "version 1.0 that is lower.  Skipping this layer."));
887         env.debug_log.clear();
888         uint32_t count = 0;
889         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
890         ASSERT_EQ(0U, count);
891         std::array<VkLayerProperties, 2> layer_props;
892         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
893         ASSERT_EQ(0U, count);
894     }
895 }
896 
TEST(OverrideMetaLayer,ApplicationEnabledLayerInBlacklist)897 TEST(OverrideMetaLayer, ApplicationEnabledLayerInBlacklist) {
898     FrameworkEnvironment env;
899     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
900     env.get_test_icd().add_physical_device({});
901 
902     const char* automatic_regular_layer_name = "VK_LAYER_TestLayer_1";
903     const char* manual_regular_layer_name = "VK_LAYER_TestLayer_2";
904     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
905                                                          .set_name(automatic_regular_layer_name)
906                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
907                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
908                            "regular_test_layer_1.json");
909     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
910                                                          .set_name(manual_regular_layer_name)
911                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
912                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
913                            "regular_test_layer_2.json");
914     env.add_implicit_layer(ManifestLayer{}
915                                .set_file_format_version(ManifestVersion(1, 2, 0))
916                                .add_layer(ManifestLayer::LayerDescription{}
917                                               .set_name(lunarg_meta_layer_name)
918                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
919                                               .add_component_layer(automatic_regular_layer_name)
920                                               .add_blacklisted_layer(manual_regular_layer_name)
921                                               .set_disable_environment("DisableMeIfYouCan")),
922                            "meta_test_layer.json");
923 
924     {  // enable the layer in the blacklist
925         InstWrapper inst{env.vulkan_functions};
926         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
927         inst.create_info.add_layer(manual_regular_layer_name);
928         inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
929         ASSERT_TRUE(env.debug_log.find(std::string("loader_remove_layers_in_blacklist: Override layer is active and layer ") +
930                                        manual_regular_layer_name +
931                                        " is in the blacklist inside of it. Removing that layer from current layer list."));
932         env.debug_log.clear();
933     }
934     {  // dont enable the layer in the blacklist
935         InstWrapper inst{env.vulkan_functions};
936         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
937         inst.CheckCreate();
938         VkPhysicalDevice phys_dev = inst.GetPhysDev();
939         ASSERT_TRUE(env.debug_log.find(std::string("loader_remove_layers_in_blacklist: Override layer is active and layer ") +
940                                        manual_regular_layer_name +
941                                        " is in the blacklist inside of it. Removing that layer from current layer list."));
942         env.debug_log.clear();
943         uint32_t count = 0;
944         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
945         ASSERT_EQ(2U, count);
946         std::array<VkLayerProperties, 2> layer_props;
947         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
948         ASSERT_EQ(2U, count);
949         ASSERT_TRUE(check_permutation({automatic_regular_layer_name, lunarg_meta_layer_name}, layer_props));
950     }
951 }
952 
TEST(OverrideMetaLayer,BasicOverridePaths)953 TEST(OverrideMetaLayer, BasicOverridePaths) {
954     FrameworkEnvironment env;
955     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
956     env.get_test_icd().add_physical_device({});
957     fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
958 
959     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
960     override_layer_folder.write_manifest("regular_test_layer.json",
961                                          ManifestLayer{}
962                                              .add_layer(ManifestLayer::LayerDescription{}
963                                                             .set_name(regular_layer_name)
964                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
965                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
966                                              .get_manifest_str());
967     auto override_folder_location = fs::make_native(override_layer_folder.location().str());
968     env.add_implicit_layer(ManifestLayer{}
969                                .set_file_format_version(ManifestVersion(1, 2, 0))
970                                .add_layer(ManifestLayer::LayerDescription{}
971                                               .set_name(lunarg_meta_layer_name)
972                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
973                                               .add_component_layer(regular_layer_name)
974                                               .set_disable_environment("DisableMeIfYouCan")
975                                               .add_override_path(override_folder_location)),
976                            "meta_test_layer.json");
977 
978     InstWrapper inst{env.vulkan_functions};
979     inst.create_info.set_api_version(1, 1, 0);
980     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
981     inst.CheckCreate();
982     ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
983     env.layers.clear();
984 }
985 
TEST(OverrideMetaLayer,BasicOverridePathsIgnoreOtherLayers)986 TEST(OverrideMetaLayer, BasicOverridePathsIgnoreOtherLayers) {
987     FrameworkEnvironment env;
988     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
989     env.get_test_icd().add_physical_device({});
990     fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
991 
992     const char* regular_layer_name = "VK_LAYER_TestLayer";
993     env.add_explicit_layer(ManifestLayer{}
994                                .set_file_format_version(ManifestVersion(1, 2, 0))
995                                .add_layer(ManifestLayer::LayerDescription{}
996                                               .set_name(regular_layer_name)
997                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
998                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
999                            "regular_test_layer.json");
1000 
1001     const char* special_layer_name = "VK_LAYER_TestLayer_1";
1002     override_layer_folder.write_manifest("regular_test_layer.json",
1003                                          ManifestLayer{}
1004                                              .add_layer(ManifestLayer::LayerDescription{}
1005                                                             .set_name(special_layer_name)
1006                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1007                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
1008                                              .get_manifest_str());
1009     auto override_folder_location = fs::make_native(override_layer_folder.location().str());
1010     env.add_implicit_layer(ManifestLayer{}
1011                                .set_file_format_version(ManifestVersion(1, 2, 0))
1012                                .add_layer(ManifestLayer::LayerDescription{}
1013                                               .set_name(lunarg_meta_layer_name)
1014                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
1015                                               .add_component_layer(special_layer_name)
1016                                               .set_disable_environment("DisableMeIfYouCan")
1017                                               .add_override_path(override_folder_location)),
1018                            "meta_test_layer.json");
1019 
1020     InstWrapper inst{env.vulkan_functions};
1021     inst.create_info.set_api_version(1, 1, 0);
1022     inst.create_info.add_layer(regular_layer_name);
1023     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1024     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
1025     ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
1026     env.layers.clear();
1027 }
1028 
TEST(OverrideMetaLayer,OverridePathsInteractionWithVK_LAYER_PATH)1029 TEST(OverrideMetaLayer, OverridePathsInteractionWithVK_LAYER_PATH) {
1030     FrameworkEnvironment env;
1031     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1032     env.get_test_icd().add_physical_device({});
1033 
1034     // add explicit layer to VK_LAYER_PATH folder
1035     const char* env_var_layer_name = "VK_LAYER_env_var_set_path";
1036     env.add_explicit_layer(TestLayerDetails{ManifestLayer{}
1037                                                 .set_file_format_version(ManifestVersion(1, 2, 0))
1038                                                 .add_layer(ManifestLayer::LayerDescription{}
1039                                                                .set_name(env_var_layer_name)
1040                                                                .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1041                                                                .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
1042                                             "regular_test_layer.json"}
1043                                .set_discovery_type(ManifestDiscoveryType::env_var));
1044 
1045     // add layer to regular explicit layer folder
1046     const char* regular_layer_name = "VK_LAYER_regular_layer_path";
1047     env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1048                                                                           .set_name(regular_layer_name)
1049                                                                           .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1050                                                                           .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))),
1051                                             "regular_test_layer.json"}
1052                                .set_discovery_type(ManifestDiscoveryType::override_folder));
1053 
1054     env.add_implicit_layer(
1055         ManifestLayer{}
1056             .set_file_format_version(ManifestVersion(1, 2, 0))
1057             .add_layer(ManifestLayer::LayerDescription{}
1058                            .set_name(lunarg_meta_layer_name)
1059                            .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
1060                            .add_component_layer(regular_layer_name)
1061                            .set_disable_environment("DisableMeIfYouCan")
1062                            .add_override_path(env.get_folder(ManifestLocation::override_layer).location().str())),
1063         "meta_test_layer.json");
1064 
1065     InstWrapper inst{env.vulkan_functions};
1066     inst.create_info.set_api_version(1, 1, 0);
1067     inst.create_info.add_layer(env_var_layer_name);
1068     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1069     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
1070     ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer ") + env_var_layer_name));
1071 
1072     env.layers.clear();
1073     remove_env_var("VK_LAYER_PATH");
1074 }
1075 
1076 // Make sure that implicit layers not in the override paths aren't found by mistake
TEST(OverrideMetaLayer,OverridePathsEnableImplicitLayerInDefaultPaths)1077 TEST(OverrideMetaLayer, OverridePathsEnableImplicitLayerInDefaultPaths) {
1078     FrameworkEnvironment env;
1079     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1080     env.get_test_icd().add_physical_device({});
1081     fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
1082 
1083     const char* implicit_layer_name = "VK_LAYER_ImplicitLayer";
1084     env.add_implicit_layer(ManifestLayer{}
1085                                .set_file_format_version(ManifestVersion(1, 2, 0))
1086                                .add_layer(ManifestLayer::LayerDescription{}
1087                                               .set_name(implicit_layer_name)
1088                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1089                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))),
1090                            "implicit_test_layer.json");
1091 
1092     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
1093     override_layer_folder.write_manifest("regular_test_layer.json",
1094                                          ManifestLayer{}
1095                                              .add_layer(ManifestLayer::LayerDescription{}
1096                                                             .set_name(regular_layer_name)
1097                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1098                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
1099                                              .get_manifest_str());
1100     auto override_folder_location = fs::make_native(override_layer_folder.location().str());
1101     env.add_implicit_layer(ManifestLayer{}
1102                                .set_file_format_version(ManifestVersion(1, 2, 0))
1103                                .add_layer(ManifestLayer::LayerDescription{}
1104                                               .set_name(lunarg_meta_layer_name)
1105                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
1106                                               .add_component_layers({regular_layer_name, implicit_layer_name})
1107                                               .set_disable_environment("DisableMeIfYouCan")
1108                                               .add_override_path(override_folder_location)),
1109                            "meta_test_layer.json");
1110 
1111     InstWrapper inst{env.vulkan_functions};
1112     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1113     inst.create_info.set_api_version(1, 1, 0);
1114     inst.CheckCreate();
1115     ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer ") + implicit_layer_name));
1116     ASSERT_TRUE(
1117         env.debug_log.find("Removing meta-layer VK_LAYER_LUNARG_override from instance layer list since it appears invalid."));
1118     env.layers.clear();
1119 }
1120 
TEST(OverrideMetaLayer,ManifestFileFormatVersionTooOld)1121 TEST(OverrideMetaLayer, ManifestFileFormatVersionTooOld) {
1122     FrameworkEnvironment env;
1123     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1124     env.get_test_icd().add_physical_device({});
1125     fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"};
1126 
1127     const char* regular_layer_name = "VK_LAYER_TestLayer_1";
1128     override_layer_folder.write_manifest("regular_test_layer.json",
1129                                          ManifestLayer{}
1130                                              .add_layer(ManifestLayer::LayerDescription{}
1131                                                             .set_name(regular_layer_name)
1132                                                             .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
1133                                                             .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)))
1134                                              .get_manifest_str());
1135     auto override_folder_location = fs::make_native(override_layer_folder.location().str());
1136     env.add_implicit_layer(ManifestLayer{}
1137                                .set_file_format_version(ManifestVersion(1, 0, 0))
1138                                .add_layer(ManifestLayer::LayerDescription{}
1139                                               .set_name(lunarg_meta_layer_name)
1140                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
1141                                               .add_component_layer(regular_layer_name)
1142                                               .set_disable_environment("DisableMeIfYouCan")
1143                                               .add_override_path(override_folder_location)),
1144                            "meta_test_layer.json");
1145 
1146     InstWrapper inst{env.vulkan_functions};
1147     inst.create_info.set_api_version(1, 1, 0);
1148     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1149     inst.CheckCreate();
1150     ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
1151     ASSERT_TRUE(env.debug_log.find("Indicating meta-layer-specific override paths, but using older JSON file version."));
1152     env.layers.clear();
1153 }
1154 
1155 // app_key contains test executable name, should activate the override layer
TEST(OverrideMetaLayer,AppKeysDoesContainCurrentApplication)1156 TEST(OverrideMetaLayer, AppKeysDoesContainCurrentApplication) {
1157     FrameworkEnvironment env;
1158     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1159     env.get_test_icd().add_physical_device({});
1160 
1161     const char* regular_layer_name = "VK_LAYER_TestLayer";
1162     env.add_explicit_layer(
1163         ManifestLayer{}
1164             .set_file_format_version(ManifestVersion(1, 2, 0))
1165             .add_layer(
1166                 ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1167         "regular_test_layer.json");
1168 
1169     std::string cur_path = test_platform_executable_path();
1170 
1171     env.add_implicit_layer(ManifestLayer{}
1172                                .set_file_format_version(ManifestVersion(1, 2, 0))
1173                                .add_layer(ManifestLayer::LayerDescription{}
1174                                               .set_name(lunarg_meta_layer_name)
1175                                               .add_component_layers({regular_layer_name})
1176                                               .set_disable_environment("DisableMeIfYouCan")
1177                                               .add_app_key(cur_path)),
1178                            "meta_test_layer.json");
1179     {  // global functions
1180         uint32_t layer_count = 0;
1181         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
1182         EXPECT_EQ(layer_count, 2U);
1183 
1184         std::array<VkLayerProperties, 2> layer_props;
1185         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
1186         EXPECT_EQ(layer_count, 2U);
1187         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
1188     }
1189     {
1190         // instance
1191         InstWrapper inst{env.vulkan_functions};
1192         inst.CheckCreate();
1193         VkPhysicalDevice phys_dev = inst.GetPhysDev();
1194 
1195         uint32_t count = 0;
1196         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
1197         EXPECT_EQ(2U, count);
1198         std::array<VkLayerProperties, 2> layer_props;
1199         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
1200         EXPECT_EQ(2U, count);
1201         EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props));
1202     }
1203 }
1204 
1205 // app_key contains random strings, should not activate the override layer
TEST(OverrideMetaLayer,AppKeysDoesNotContainCurrentApplication)1206 TEST(OverrideMetaLayer, AppKeysDoesNotContainCurrentApplication) {
1207     FrameworkEnvironment env;
1208     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1209     env.get_test_icd().add_physical_device({});
1210 
1211     const char* regular_layer_name = "VK_LAYER_TestLayer";
1212     env.add_explicit_layer(
1213         ManifestLayer{}
1214             .set_file_format_version(ManifestVersion(1, 2, 0))
1215             .add_layer(
1216                 ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1217         "regular_test_layer.json");
1218 
1219     env.add_implicit_layer(ManifestLayer{}
1220                                .set_file_format_version(ManifestVersion(1, 2, 0))
1221                                .add_layer(ManifestLayer::LayerDescription{}
1222                                               .set_name(lunarg_meta_layer_name)
1223                                               .add_component_layers({regular_layer_name})
1224                                               .set_disable_environment("DisableMeIfYouCan")
1225                                               .add_app_keys({"/Hello", "Hi", "./../Uh-oh", "C:/Windows/Only"})),
1226                            "meta_test_layer.json");
1227     {  // global functions
1228         uint32_t layer_count = 0;
1229         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
1230         EXPECT_EQ(layer_count, 1U);
1231 
1232         std::array<VkLayerProperties, 2> layer_props;
1233         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
1234         EXPECT_EQ(layer_count, 1U);
1235         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
1236     }
1237     {
1238         // instance
1239         InstWrapper inst{env.vulkan_functions};
1240         inst.CheckCreate();
1241         VkPhysicalDevice phys_dev = inst.GetPhysDev();
1242 
1243         uint32_t count = 0;
1244         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
1245         EXPECT_EQ(0U, count);
1246         std::array<VkLayerProperties, 2> layer_props;
1247         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, layer_props.data());
1248         EXPECT_EQ(0U, count);
1249     }
1250 }
1251 
1252 // This test makes sure that any layer calling GetPhysicalDeviceProperties2 inside of CreateInstance
1253 // succeeds and doesn't crash.
TEST(LayerCreateInstance,GetPhysicalDeviceProperties2)1254 TEST(LayerCreateInstance, GetPhysicalDeviceProperties2) {
1255     FrameworkEnvironment env;
1256     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1257     env.get_test_icd().physical_devices.push_back({});
1258     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 1, 0);
1259 
1260     const char* regular_layer_name = "TestLayer";
1261     env.add_explicit_layer(
1262         ManifestLayer{}
1263             .set_file_format_version(ManifestVersion(1, 1, 2))
1264             .add_layer(
1265                 ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1266         "regular_test_layer.json");
1267 
1268     auto& layer = env.get_test_layer(0);
1269     layer.set_create_instance_callback([](TestLayer& layer) -> VkResult {
1270         uint32_t phys_dev_count = 0;
1271         VkResult res = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, nullptr);
1272         if (res != VK_SUCCESS || phys_dev_count > 1) {
1273             return VK_ERROR_INITIALIZATION_FAILED;  // expecting only a single physical device.
1274         }
1275         VkPhysicalDevice phys_dev{};
1276         res = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, &phys_dev);
1277         if (res != VK_SUCCESS) {
1278             return VK_ERROR_INITIALIZATION_FAILED;
1279         }
1280         VkPhysicalDeviceProperties2 props2{};
1281         props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1282         layer.instance_dispatch_table.GetPhysicalDeviceProperties2(phys_dev, &props2);
1283 
1284         VkPhysicalDeviceFeatures2 features2{};
1285         features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1286         layer.instance_dispatch_table.GetPhysicalDeviceFeatures2(phys_dev, &features2);
1287         return VK_SUCCESS;
1288     });
1289 
1290     InstWrapper inst{env.vulkan_functions};
1291     inst.create_info.add_layer(regular_layer_name).set_api_version(1, 1, 0);
1292     inst.CheckCreate();
1293 }
1294 
TEST(LayerCreateInstance,GetPhysicalDeviceProperties2KHR)1295 TEST(LayerCreateInstance, GetPhysicalDeviceProperties2KHR) {
1296     FrameworkEnvironment env;
1297     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1298     env.get_test_icd().physical_devices.push_back({});
1299     env.get_test_icd().add_instance_extension({"VK_KHR_get_physical_device_properties2", 0});
1300 
1301     const char* regular_layer_name = "VK_LAYER_TestLayer";
1302     env.add_explicit_layer(
1303         ManifestLayer{}.add_layer(
1304             ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1305         "regular_test_layer.json");
1306 
1307     auto& layer = env.get_test_layer(0);
1308     layer.set_create_instance_callback([](TestLayer& layer) -> VkResult {
1309         uint32_t phys_dev_count = 1;
1310         VkPhysicalDevice phys_dev{};
1311         layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, &phys_dev);
1312 
1313         VkPhysicalDeviceProperties2KHR props2{};
1314         props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
1315         layer.instance_dispatch_table.GetPhysicalDeviceProperties2KHR(phys_dev, &props2);
1316 
1317         VkPhysicalDeviceFeatures2KHR features2{};
1318         features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
1319         layer.instance_dispatch_table.GetPhysicalDeviceFeatures2KHR(phys_dev, &features2);
1320         return VK_SUCCESS;
1321     });
1322 
1323     InstWrapper inst{env.vulkan_functions};
1324     inst.create_info.add_layer(regular_layer_name).add_extension("VK_KHR_get_physical_device_properties2");
1325     inst.CheckCreate();
1326 }
1327 
TEST(ExplicitLayers,WrapObjects)1328 TEST(ExplicitLayers, WrapObjects) {
1329     FrameworkEnvironment env;
1330     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1331     auto& driver = env.get_test_icd();
1332 
1333     const char* wrap_objects_name = "VK_LAYER_LUNARG_wrap_objects";
1334     env.add_explicit_layer(ManifestLayer{}.add_layer(
1335                                ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
1336                            "wrap_objects_layer.json");
1337 
1338     const char* regular_layer_name_1 = "RegularLayer1";
1339     env.add_explicit_layer(
1340         ManifestLayer{}.add_layer(
1341             ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1342         "regular_layer_1.json");
1343 
1344     const char* regular_layer_name_2 = "RegularLayer2";
1345     env.add_explicit_layer(
1346         ManifestLayer{}.add_layer(
1347             ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
1348         "regular_layer_2.json");
1349 
1350     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1351 
1352     driver.physical_devices.emplace_back("physical_device_0");
1353     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1354     {  // just the wrap layer
1355         InstWrapper inst{env.vulkan_functions};
1356         inst.create_info.add_layer(wrap_objects_name);
1357         inst.CheckCreate();
1358         VkPhysicalDevice phys_dev = inst.GetPhysDev();
1359 
1360         DeviceWrapper dev{inst};
1361         dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
1362         dev.CheckCreate(phys_dev);
1363     }
1364     {  // wrap layer first
1365         InstWrapper inst{env.vulkan_functions};
1366         inst.create_info.add_layer(wrap_objects_name).add_layer(regular_layer_name_1);
1367         inst.CheckCreate();
1368         VkPhysicalDevice phys_dev = inst.GetPhysDev();
1369 
1370         DeviceWrapper dev{inst};
1371         dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
1372         dev.CheckCreate(phys_dev);
1373     }
1374     {  // wrap layer last
1375         InstWrapper inst{env.vulkan_functions};
1376         inst.create_info.add_layer(regular_layer_name_1).add_layer(wrap_objects_name);
1377         inst.CheckCreate();
1378         VkPhysicalDevice phys_dev = inst.GetPhysDev();
1379 
1380         DeviceWrapper dev{inst};
1381         dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
1382         dev.CheckCreate(phys_dev);
1383     }
1384     {  // wrap layer last
1385         InstWrapper inst{env.vulkan_functions};
1386         inst.create_info.add_layer(regular_layer_name_1).add_layer(wrap_objects_name).add_layer(regular_layer_name_2);
1387         inst.CheckCreate();
1388         VkPhysicalDevice phys_dev = inst.GetPhysDev();
1389 
1390         DeviceWrapper dev{inst};
1391         dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
1392         dev.CheckCreate(phys_dev);
1393     }
1394 }
1395 
TEST(LayerExtensions,ImplicitNoAdditionalInstanceExtension)1396 TEST(LayerExtensions, ImplicitNoAdditionalInstanceExtension) {
1397     FrameworkEnvironment env;
1398     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1399     auto& driver = env.get_test_icd();
1400     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1401 
1402     driver.physical_devices.emplace_back("physical_device_0");
1403     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1404 
1405     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1406     const char* enable_env_var = "ENABLE_ME";
1407     const char* disable_env_var = "DISABLE_ME";
1408 
1409     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1410                                                          .set_name(implicit_layer_name)
1411                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
1412                                                          .set_disable_environment(disable_env_var)
1413                                                          .set_enable_environment(enable_env_var)),
1414                            "implicit_wrap_layer_no_ext.json");
1415 
1416     uint32_t count = 0;
1417     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1418     ASSERT_EQ(count, 1U);
1419 
1420     // set enable env-var, layer should load
1421     set_env_var(enable_env_var, "1");
1422     CheckLogForLayerString(env, implicit_layer_name, true);
1423 
1424     uint32_t extension_count = 0;
1425     std::vector<VkExtensionProperties> extension_props;
1426     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1427 
1428     extension_props.resize(extension_count);
1429     ASSERT_EQ(VK_SUCCESS,
1430               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1431     ASSERT_EQ(extension_count, 3U);  // debug_utils, debug_report, and portability enumeration
1432 
1433     // Make sure the extensions that are implemented only in the test layers is not present.
1434     ASSERT_FALSE(contains(extension_props, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1435     ASSERT_FALSE(contains(extension_props, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1436 
1437     InstWrapper inst{env.vulkan_functions};
1438     inst.CheckCreate();
1439 
1440     // Make sure all the function pointers are NULL as well
1441     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
1442     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1443 
1444     remove_env_var(enable_env_var);
1445 }
1446 
TEST(LayerExtensions,ImplicitDirDispModeInstanceExtension)1447 TEST(LayerExtensions, ImplicitDirDispModeInstanceExtension) {
1448     FrameworkEnvironment env;
1449     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1450     auto& driver = env.get_test_icd();
1451     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1452 
1453     driver.physical_devices.emplace_back("physical_device_0");
1454     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1455 
1456     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1457     const char* enable_env_var = "ENABLE_ME";
1458     const char* disable_env_var = "DISABLE_ME";
1459 
1460     env.add_implicit_layer(
1461         ManifestLayer{}.add_layer(
1462             ManifestLayer::LayerDescription{}
1463                 .set_name(implicit_layer_name)
1464                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
1465                 .set_disable_environment(disable_env_var)
1466                 .set_enable_environment(enable_env_var)
1467                 .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})),
1468         "implicit_wrap_layer_dir_disp_mode.json");
1469 
1470     uint32_t count = 0;
1471     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1472     ASSERT_EQ(count, 1U);
1473 
1474     // // set enable env-var, layer should load
1475     set_env_var(enable_env_var, "1");
1476     CheckLogForLayerString(env, implicit_layer_name, true);
1477 
1478     uint32_t extension_count = 0;
1479     std::vector<VkExtensionProperties> extension_props;
1480     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1481     ASSERT_EQ(extension_count, 4U);  // the instance extension, debug_utils, debug_report, and portability enumeration
1482     extension_props.resize(extension_count);
1483     ASSERT_EQ(VK_SUCCESS,
1484               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1485     ASSERT_EQ(extension_count, 4U);
1486 
1487     // Make sure the extensions that are implemented only in the test layers is not present.
1488     ASSERT_TRUE(contains(extension_props, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1489     ASSERT_FALSE(contains(extension_props, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1490 
1491     InstWrapper inst{env.vulkan_functions};
1492     inst.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME);
1493     inst.CheckCreate();
1494 
1495     // Make sure only the appropriate function pointers are NULL as well
1496     handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
1497     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1498 
1499     remove_env_var(enable_env_var);
1500 }
1501 
TEST(LayerExtensions,ImplicitDispSurfCountInstanceExtension)1502 TEST(LayerExtensions, ImplicitDispSurfCountInstanceExtension) {
1503     FrameworkEnvironment env;
1504     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1505     auto& driver = env.get_test_icd();
1506     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1507 
1508     driver.physical_devices.emplace_back("physical_device_0");
1509     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1510 
1511     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1512     const char* enable_env_var = "ENABLE_ME";
1513     const char* disable_env_var = "DISABLE_ME";
1514 
1515     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1516                                                          .set_name(implicit_layer_name)
1517                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
1518                                                          .set_disable_environment(disable_env_var)
1519                                                          .set_enable_environment(enable_env_var)
1520                                                          .add_instance_extension({VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME,
1521                                                                                   1,
1522                                                                                   {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
1523                            "implicit_wrap_layer_disp_surf_count.json");
1524 
1525     uint32_t count = 0;
1526     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1527     ASSERT_EQ(count, 1U);
1528 
1529     // // set enable env-var, layer should load
1530     set_env_var(enable_env_var, "1");
1531     CheckLogForLayerString(env, implicit_layer_name, true);
1532 
1533     uint32_t extension_count = 0;
1534     std::vector<VkExtensionProperties> extension_props;
1535     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1536     ASSERT_EQ(extension_count, 4U);  // the instance extension, debug_utils, debug_report, and portability enumeration
1537     extension_props.resize(extension_count);
1538     ASSERT_EQ(VK_SUCCESS,
1539               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1540     ASSERT_EQ(extension_count, 4U);
1541 
1542     // Make sure the extensions that are implemented only in the test layers is not present.
1543     ASSERT_FALSE(contains(extension_props, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1544     ASSERT_TRUE(contains(extension_props, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1545 
1546     InstWrapper inst{env.vulkan_functions};
1547     inst.create_info.add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
1548     inst.CheckCreate();
1549 
1550     // Make sure only the appropriate function pointers are NULL as well
1551     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
1552     handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1553 
1554     remove_env_var(enable_env_var);
1555 }
1556 
TEST(LayerExtensions,ImplicitBothInstanceExtensions)1557 TEST(LayerExtensions, ImplicitBothInstanceExtensions) {
1558     FrameworkEnvironment env;
1559     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1560     auto& driver = env.get_test_icd();
1561     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1562 
1563     driver.physical_devices.emplace_back("physical_device_0");
1564     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1565 
1566     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1567     const char* enable_env_var = "ENABLE_ME";
1568     const char* disable_env_var = "DISABLE_ME";
1569 
1570     env.add_implicit_layer(
1571         ManifestLayer{}.add_layer(
1572             ManifestLayer::LayerDescription{}
1573                 .set_name(implicit_layer_name)
1574                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
1575                 .set_disable_environment(disable_env_var)
1576                 .set_enable_environment(enable_env_var)
1577                 .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
1578                 .add_instance_extension(
1579                     {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
1580         "implicit_wrap_layer_both_inst.json");
1581 
1582     uint32_t count = 0;
1583     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1584     ASSERT_EQ(count, 1U);
1585 
1586     // // set enable env-var, layer should load
1587     set_env_var(enable_env_var, "1");
1588     CheckLogForLayerString(env, implicit_layer_name, true);
1589 
1590     uint32_t extension_count = 0;
1591     std::vector<VkExtensionProperties> extension_props;
1592     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1593     ASSERT_EQ(extension_count, 5U);  // the two instance extension plus debug_utils, debug_report, portability enumeration
1594     extension_props.resize(extension_count);
1595     ASSERT_EQ(VK_SUCCESS,
1596               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1597     ASSERT_EQ(extension_count, 5U);
1598 
1599     // Make sure the extensions that are implemented only in the test layers is not present.
1600     ASSERT_TRUE(contains(extension_props, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1601     ASSERT_TRUE(contains(extension_props, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1602 
1603     InstWrapper inst{env.vulkan_functions};
1604     inst.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)
1605         .add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
1606     inst.CheckCreate();
1607 
1608     // Make sure only the appropriate function pointers are NULL as well
1609     handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
1610     handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1611 
1612     remove_env_var(enable_env_var);
1613 }
1614 
TEST(LayerExtensions,ExplicitNoAdditionalInstanceExtension)1615 TEST(LayerExtensions, ExplicitNoAdditionalInstanceExtension) {
1616     FrameworkEnvironment env;
1617     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1618     auto& driver = env.get_test_icd();
1619     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1620 
1621     driver.physical_devices.emplace_back("physical_device_0");
1622     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1623 
1624     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1625     env.add_explicit_layer(
1626         ManifestLayer{}.add_layer(
1627             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
1628         "explicit_wrap_layer_no_ext.json");
1629 
1630     uint32_t count = 0;
1631     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1632     ASSERT_EQ(count, 1U);
1633 
1634     uint32_t extension_count = 0;
1635     std::vector<VkExtensionProperties> extension_props;
1636     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1637     ASSERT_EQ(extension_count, 3U);  // debug utils, debug report, portability enumeration
1638     extension_props.resize(extension_count);
1639     ASSERT_EQ(VK_SUCCESS,
1640               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1641     ASSERT_EQ(extension_count, 3U);
1642 
1643     // Make sure the extensions are not present
1644     for (const auto& ext : extension_props) {
1645         ASSERT_FALSE(string_eq(ext.extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1646         ASSERT_FALSE(string_eq(ext.extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1647     }
1648 
1649     // Now query by layer name.
1650     extension_count = 0;
1651     extension_props.clear();
1652     ASSERT_EQ(VK_SUCCESS,
1653               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
1654     ASSERT_EQ(extension_count, 0U);
1655 
1656     InstWrapper inst{env.vulkan_functions};
1657     inst.CheckCreate();
1658 
1659     // Make sure all the function pointers are NULL as well
1660     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
1661     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1662 }
1663 
TEST(LayerExtensions,ExplicitDirDispModeInstanceExtension)1664 TEST(LayerExtensions, ExplicitDirDispModeInstanceExtension) {
1665     FrameworkEnvironment env;
1666     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1667     auto& driver = env.get_test_icd();
1668     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1669 
1670     driver.physical_devices.emplace_back("physical_device_0");
1671     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1672 
1673     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1674     env.add_explicit_layer(
1675         ManifestLayer{}.add_layer(
1676             ManifestLayer::LayerDescription{}
1677                 .set_name(explicit_layer_name)
1678                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
1679                 .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})),
1680         "explicit_wrap_layer_dir_disp_mode.json");
1681 
1682     uint32_t count = 0;
1683     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1684     ASSERT_EQ(count, 1U);
1685 
1686     uint32_t extension_count = 0;
1687     std::vector<VkExtensionProperties> extension_props;
1688     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1689     ASSERT_EQ(extension_count, 3U);  // debug utils, debug report, portability enumeration
1690     extension_props.resize(extension_count);
1691     ASSERT_EQ(VK_SUCCESS,
1692               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1693     ASSERT_EQ(extension_count, 3U);
1694     // Make sure the extensions are not present
1695     for (const auto& ext : extension_props) {
1696         ASSERT_FALSE(string_eq(ext.extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1697         ASSERT_FALSE(string_eq(ext.extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1698     }
1699 
1700     // Now query by layer name.
1701     extension_count = 0;
1702     extension_props.clear();
1703     ASSERT_EQ(VK_SUCCESS,
1704               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
1705     ASSERT_EQ(extension_count, 1U);
1706     extension_props.resize(extension_count);
1707     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count,
1708                                                                                       extension_props.data()));
1709 
1710     // Make sure the extensions still aren't present in this layer
1711     bool found = false;
1712     for (uint32_t ext = 0; ext < extension_count; ++ext) {
1713         if (!strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
1714             found = true;
1715         }
1716         ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1717     }
1718     ASSERT_EQ(true, found);
1719 
1720     InstWrapper inst1{env.vulkan_functions};
1721     inst1.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME);
1722     inst1.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
1723 
1724     // Make sure only the appropriate function pointers are NULL as well
1725     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT"));
1726     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1727 
1728     InstWrapper inst2{env.vulkan_functions};
1729     inst2.create_info.add_layer(explicit_layer_name).add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME);
1730     inst2.CheckCreate();
1731 
1732     // Make sure only the appropriate function pointers are NULL as well
1733     handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT"));
1734     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1735 }
1736 
TEST(LayerExtensions,ExplicitDispSurfCountInstanceExtension)1737 TEST(LayerExtensions, ExplicitDispSurfCountInstanceExtension) {
1738     FrameworkEnvironment env;
1739     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1740     auto& driver = env.get_test_icd();
1741     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1742 
1743     driver.physical_devices.emplace_back("physical_device_0");
1744     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1745 
1746     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1747     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1748                                                          .set_name(explicit_layer_name)
1749                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
1750                                                          .add_instance_extension({VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME,
1751                                                                                   1,
1752                                                                                   {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
1753                            "explicit_wrap_layer_disp_surf_count.json");
1754 
1755     uint32_t count = 0;
1756     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1757     ASSERT_EQ(count, 1U);
1758 
1759     uint32_t extension_count = 0;
1760     std::vector<VkExtensionProperties> extension_props;
1761     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1762     if (extension_count > 0) {
1763         extension_props.resize(extension_count);
1764         ASSERT_EQ(VK_SUCCESS,
1765                   env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1766 
1767         // Make sure the extensions are not present
1768         for (uint32_t ext = 0; ext < extension_count; ++ext) {
1769             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1770             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1771         }
1772     }
1773 
1774     // Now query by layer name.
1775     extension_count = 0;
1776     extension_props.clear();
1777     ASSERT_EQ(VK_SUCCESS,
1778               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
1779     ASSERT_EQ(extension_count, 1U);
1780     extension_props.resize(extension_count);
1781     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count,
1782                                                                                       extension_props.data()));
1783 
1784     // Make sure the extensions still aren't present in this layer
1785     bool found = false;
1786     for (uint32_t ext = 0; ext < extension_count; ++ext) {
1787         if (!strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
1788             found = true;
1789         }
1790         ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1791     }
1792     ASSERT_EQ(true, found);
1793 
1794     InstWrapper inst1{env.vulkan_functions};
1795     inst1.create_info.add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
1796     inst1.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
1797 
1798     // Make sure only the appropriate function pointers are NULL as well
1799     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT"));
1800     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1801 
1802     InstWrapper inst2{env.vulkan_functions};
1803     inst2.create_info.add_layer(explicit_layer_name).add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
1804     inst2.CheckCreate();
1805 
1806     // Make sure only the appropriate function pointers are NULL as well
1807     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT"));
1808     handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1809 }
1810 
TEST(LayerExtensions,ExplicitBothInstanceExtensions)1811 TEST(LayerExtensions, ExplicitBothInstanceExtensions) {
1812     FrameworkEnvironment env;
1813     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1814     auto& driver = env.get_test_icd();
1815     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1816 
1817     driver.physical_devices.emplace_back("physical_device_0");
1818     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1819 
1820     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1821     env.add_explicit_layer(
1822         ManifestLayer{}.add_layer(
1823             ManifestLayer::LayerDescription{}
1824                 .set_name(explicit_layer_name)
1825                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
1826                 .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
1827                 .add_instance_extension(
1828                     {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
1829         "explicit_wrap_layer_both_inst.json");
1830 
1831     uint32_t count = 0;
1832     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1833     ASSERT_EQ(count, 1U);
1834 
1835     uint32_t extension_count = 0;
1836     std::vector<VkExtensionProperties> extension_props;
1837     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
1838     if (extension_count > 0) {
1839         extension_props.resize(extension_count);
1840         ASSERT_EQ(VK_SUCCESS,
1841                   env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
1842 
1843         // Make sure the extensions are not present
1844         for (uint32_t ext = 0; ext < extension_count; ++ext) {
1845             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
1846             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
1847         }
1848     }
1849 
1850     // Now query by layer name.
1851     extension_count = 0;
1852     extension_props.clear();
1853     ASSERT_EQ(VK_SUCCESS,
1854               env.vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
1855     ASSERT_EQ(extension_count, 2U);
1856     extension_props.resize(extension_count);
1857     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count,
1858                                                                                       extension_props.data()));
1859 
1860     // Make sure the extensions still aren't present in this layer
1861     bool found[2] = {false, false};
1862     for (uint32_t ext = 0; ext < extension_count; ++ext) {
1863         if (!strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
1864             found[0] = true;
1865         }
1866         if (!strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
1867             found[1] = true;
1868         }
1869     }
1870     for (uint32_t ext = 0; ext < 2; ++ext) {
1871         ASSERT_EQ(true, found[ext]);
1872     }
1873 
1874     InstWrapper inst1{env.vulkan_functions};
1875     inst1.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)
1876         .add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
1877     inst1.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
1878 
1879     // Make sure only the appropriate function pointers are NULL as well
1880     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT"));
1881     handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1882 
1883     InstWrapper inst2{env.vulkan_functions};
1884     inst2.create_info.add_layer(explicit_layer_name)
1885         .add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)
1886         .add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
1887     inst2.CheckCreate();
1888     VkPhysicalDevice phys_dev = inst2.GetPhysDev();
1889 
1890     // Make sure only the appropriate function pointers are NULL as well
1891     handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT"));
1892     PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT pfnGetPhysicalDeviceSurfaceCapabilities2EXT =
1893         reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT>(
1894             env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
1895     handle_assert_has_value(pfnGetPhysicalDeviceSurfaceCapabilities2EXT);
1896 
1897     VkSurfaceCapabilities2EXT surf_caps{VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT};
1898 
1899     // Call and then check a few things
1900     ASSERT_EQ(VK_SUCCESS, pfnGetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev, VK_NULL_HANDLE, &surf_caps));
1901     ASSERT_EQ(7U, surf_caps.minImageCount);
1902     ASSERT_EQ(12U, surf_caps.maxImageCount);
1903     ASSERT_EQ(365U, surf_caps.maxImageArrayLayers);
1904 }
1905 
TEST(LayerExtensions,ImplicitNoAdditionalDeviceExtension)1906 TEST(LayerExtensions, ImplicitNoAdditionalDeviceExtension) {
1907     FrameworkEnvironment env;
1908     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1909     auto& driver = env.get_test_icd();
1910     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1911 
1912     driver.physical_devices.emplace_back("physical_device_0");
1913     driver.physical_devices.back().queue_family_properties.push_back(family_props);
1914 
1915     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
1916     const char* enable_env_var = "ENABLE_ME";
1917     const char* disable_env_var = "DISABLE_ME";
1918 
1919     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
1920                                                          .set_name(implicit_layer_name)
1921                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
1922                                                          .set_disable_environment(disable_env_var)
1923                                                          .set_enable_environment(enable_env_var)),
1924                            "implicit_wrap_layer_no_ext.json");
1925 
1926     uint32_t count = 0;
1927     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
1928     ASSERT_EQ(count, 1U);
1929 
1930     // // set enable env-var, layer should load
1931     set_env_var(enable_env_var, "1");
1932     CheckLogForLayerString(env, implicit_layer_name, true);
1933 
1934     InstWrapper inst{env.vulkan_functions};
1935     inst.CheckCreate();
1936     VkPhysicalDevice phys_dev = inst.GetPhysDev();
1937 
1938     uint32_t extension_count = 0;
1939     std::vector<VkExtensionProperties> extension_props;
1940     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
1941     if (extension_count > 0) {
1942         extension_props.resize(extension_count);
1943         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
1944                                                                                         extension_props.data()));
1945 
1946         // Make sure the extensions that are implemented only in the test layers is not present.
1947         for (uint32_t ext = 0; ext < extension_count; ++ext) {
1948             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
1949             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
1950         }
1951     }
1952 
1953     // Device functions queried using vkGetInstanceProcAddr should be non-NULL since this could be available for any attached
1954     // physical device.
1955     PFN_vkTrimCommandPoolKHR pfn_vkTrimCommandPool =
1956         reinterpret_cast<PFN_vkTrimCommandPoolKHR>(inst->vkGetInstanceProcAddr(inst.inst, "vkTrimCommandPoolKHR"));
1957     PFN_vkGetSwapchainStatusKHR pfn_vkGetSwapchainStatus =
1958         reinterpret_cast<PFN_vkGetSwapchainStatusKHR>(inst->vkGetInstanceProcAddr(inst.inst, "vkGetSwapchainStatusKHR"));
1959     PFN_vkSetDeviceMemoryPriorityEXT pfn_vkSetDeviceMemoryPriority =
1960         reinterpret_cast<PFN_vkSetDeviceMemoryPriorityEXT>(inst->vkGetInstanceProcAddr(inst.inst, "vkSetDeviceMemoryPriorityEXT"));
1961     handle_assert_has_value(pfn_vkTrimCommandPool);
1962     handle_assert_has_value(pfn_vkGetSwapchainStatus);
1963     handle_assert_has_value(pfn_vkSetDeviceMemoryPriority);
1964 
1965     DeviceWrapper dev{inst};
1966     dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
1967     dev.CheckCreate(phys_dev);
1968 
1969     // Query again after create device to make sure the value returned by vkGetInstanceProcAddr did not change
1970     PFN_vkTrimCommandPoolKHR pfn_vkTrimCommandPool2 =
1971         reinterpret_cast<PFN_vkTrimCommandPoolKHR>(inst->vkGetInstanceProcAddr(inst.inst, "vkTrimCommandPoolKHR"));
1972     PFN_vkGetSwapchainStatusKHR pfn_vkGetSwapchainStatus2 =
1973         reinterpret_cast<PFN_vkGetSwapchainStatusKHR>(inst->vkGetInstanceProcAddr(inst.inst, "vkGetSwapchainStatusKHR"));
1974     PFN_vkSetDeviceMemoryPriorityEXT pfn_vkSetDeviceMemoryPriority2 =
1975         reinterpret_cast<PFN_vkSetDeviceMemoryPriorityEXT>(inst->vkGetInstanceProcAddr(inst.inst, "vkSetDeviceMemoryPriorityEXT"));
1976     ASSERT_EQ(pfn_vkTrimCommandPool, pfn_vkTrimCommandPool2);
1977     ASSERT_EQ(pfn_vkGetSwapchainStatus, pfn_vkGetSwapchainStatus2);
1978     ASSERT_EQ(pfn_vkSetDeviceMemoryPriority, pfn_vkSetDeviceMemoryPriority2);
1979 
1980     // Make sure all the function pointers returned by vkGetDeviceProcAddr for non-enabled extensions are NULL
1981     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
1982     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
1983     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkSetDeviceMemoryPriorityEXT"));
1984 
1985     // Even though the instance functions returned are non-NULL.  They should not work if we haven't enabled the extensions.
1986     ASSERT_DEATH(pfn_vkTrimCommandPool(dev.dev, VK_NULL_HANDLE, 0), "");
1987     ASSERT_DEATH(pfn_vkGetSwapchainStatus(dev.dev, VK_NULL_HANDLE), "");
1988     ASSERT_DEATH(pfn_vkSetDeviceMemoryPriority(dev.dev, VK_NULL_HANDLE, 0.f), "");
1989 
1990     remove_env_var(enable_env_var);
1991 }
1992 
TEST(LayerExtensions,ImplicitMaintenanceDeviceExtension)1993 TEST(LayerExtensions, ImplicitMaintenanceDeviceExtension) {
1994     FrameworkEnvironment env;
1995     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
1996     auto& driver = env.get_test_icd();
1997     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
1998 
1999     driver.physical_devices.emplace_back("physical_device_0");
2000     driver.physical_devices.back().queue_family_properties.push_back(family_props);
2001 
2002     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2003     const char* enable_env_var = "ENABLE_ME";
2004     const char* disable_env_var = "DISABLE_ME";
2005 
2006     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2007                                                          .set_name(implicit_layer_name)
2008                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
2009                                                          .set_disable_environment(disable_env_var)
2010                                                          .set_enable_environment(enable_env_var)),
2011                            "implicit_wrap_layer_maint.json");
2012 
2013     uint32_t count = 0;
2014     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2015     ASSERT_EQ(count, 1U);
2016 
2017     // // set enable env-var, layer should load
2018     set_env_var(enable_env_var, "1");
2019     CheckLogForLayerString(env, implicit_layer_name, true);
2020 
2021     InstWrapper inst{env.vulkan_functions};
2022     inst.CheckCreate();
2023     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2024 
2025     uint32_t extension_count = 0;
2026     std::vector<VkExtensionProperties> extension_props;
2027     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
2028     ASSERT_EQ(extension_count, 1U);
2029     extension_props.resize(extension_count);
2030     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
2031                                                                                     extension_props.data()));
2032 
2033     // Make sure only the one extension implemented by the enabled implicit layer is present.
2034     bool found = false;
2035     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2036         if (!strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2037             found = true;
2038         }
2039         ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
2040     }
2041     ASSERT_EQ(true, found);
2042 
2043     DeviceWrapper dev{inst};
2044     dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME).add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2045     dev.CheckCreate(phys_dev);
2046 
2047     // Make sure only the appropriate function pointers are NULL as well
2048     handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
2049     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
2050 
2051     remove_env_var(enable_env_var);
2052 }
2053 
TEST(LayerExtensions,ImplicitPresentImageDeviceExtension)2054 TEST(LayerExtensions, ImplicitPresentImageDeviceExtension) {
2055     FrameworkEnvironment env;
2056     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2057     auto& driver = env.get_test_icd();
2058     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
2059 
2060     driver.physical_devices.emplace_back("physical_device_0");
2061     driver.physical_devices.back().queue_family_properties.push_back(family_props);
2062 
2063     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2064     const char* enable_env_var = "ENABLE_ME";
2065     const char* disable_env_var = "DISABLE_ME";
2066 
2067     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2068                                                          .set_name(implicit_layer_name)
2069                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
2070                                                          .set_disable_environment(disable_env_var)
2071                                                          .set_enable_environment(enable_env_var)),
2072                            "implicit_wrap_layer_pres.json");
2073 
2074     uint32_t count = 0;
2075     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2076     ASSERT_EQ(count, 1U);
2077 
2078     // // set enable env-var, layer should load
2079     set_env_var(enable_env_var, "1");
2080     CheckLogForLayerString(env, implicit_layer_name, true);
2081 
2082     InstWrapper inst{env.vulkan_functions};
2083     inst.CheckCreate();
2084     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2085 
2086     uint32_t extension_count = 0;
2087     std::vector<VkExtensionProperties> extension_props;
2088     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
2089     ASSERT_EQ(extension_count, 1U);
2090     extension_props.resize(extension_count);
2091     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
2092                                                                                     extension_props.data()));
2093 
2094     // Make sure only the one extension implemented by the enabled implicit layer is present.
2095     bool found = false;
2096     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2097         ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
2098         if (!strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2099             found = true;
2100         }
2101     }
2102     ASSERT_EQ(true, found);
2103 
2104     DeviceWrapper dev{inst};
2105     dev.create_info.add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
2106         .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2107     dev.CheckCreate(phys_dev);
2108 
2109     // Make sure only the appropriate function pointers are NULL as well
2110     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
2111     handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
2112 
2113     remove_env_var(enable_env_var);
2114 }
2115 
TEST(LayerExtensions,ImplicitBothDeviceExtensions)2116 TEST(LayerExtensions, ImplicitBothDeviceExtensions) {
2117     FrameworkEnvironment env;
2118     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2119     auto& driver = env.get_test_icd();
2120     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
2121 
2122     driver.physical_devices.emplace_back("physical_device_0");
2123     driver.physical_devices.back().queue_family_properties.push_back(family_props);
2124 
2125     const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2126     const char* enable_env_var = "ENABLE_ME";
2127     const char* disable_env_var = "DISABLE_ME";
2128 
2129     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2130                                                          .set_name(implicit_layer_name)
2131                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
2132                                                          .set_disable_environment(disable_env_var)
2133                                                          .set_enable_environment(enable_env_var)),
2134                            "implicit_wrap_layer_both_dev.json");
2135 
2136     uint32_t count = 0;
2137     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2138     ASSERT_EQ(count, 1U);
2139 
2140     // // set enable env-var, layer should load
2141     set_env_var(enable_env_var, "1");
2142     CheckLogForLayerString(env, implicit_layer_name, true);
2143 
2144     InstWrapper inst{env.vulkan_functions};
2145     inst.CheckCreate();
2146     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2147 
2148     uint32_t extension_count = 0;
2149     std::vector<VkExtensionProperties> extension_props;
2150     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
2151     ASSERT_EQ(extension_count, 2U);
2152     extension_props.resize(extension_count);
2153     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
2154                                                                                     extension_props.data()));
2155 
2156     // Make sure only the one extension implemented by the enabled implicit layer is present.
2157     bool found[2] = {false, false};
2158     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2159         if (!strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2160             found[0] = true;
2161         }
2162         if (!strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2163             found[1] = true;
2164         }
2165     }
2166     for (uint32_t ext = 0; ext < 2; ++ext) {
2167         ASSERT_EQ(true, found[ext]);
2168     }
2169 
2170     DeviceWrapper dev{inst};
2171     dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME)
2172         .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
2173         .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2174     dev.CheckCreate(phys_dev);
2175 
2176     // Make sure only the appropriate function pointers are NULL as well
2177     handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
2178     handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
2179 
2180     remove_env_var(enable_env_var);
2181 }
2182 
TEST(LayerExtensions,ExplicitNoAdditionalDeviceExtension)2183 TEST(LayerExtensions, ExplicitNoAdditionalDeviceExtension) {
2184     FrameworkEnvironment env;
2185     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2186     auto& driver = env.get_test_icd();
2187     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
2188 
2189     driver.physical_devices.emplace_back("physical_device_0");
2190     driver.physical_devices.back().queue_family_properties.push_back(family_props);
2191 
2192     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2193     env.add_explicit_layer(
2194         ManifestLayer{}.add_layer(
2195             ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)),
2196         "explicit_wrap_layer_no_ext.json");
2197 
2198     uint32_t count = 0;
2199     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2200     ASSERT_EQ(count, 1U);
2201 
2202     InstWrapper inst{env.vulkan_functions};
2203     inst.create_info.add_layer(explicit_layer_name);
2204     inst.CheckCreate();
2205     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2206 
2207     uint32_t extension_count = 0;
2208     std::vector<VkExtensionProperties> extension_props;
2209     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
2210     if (extension_count > 0) {
2211         extension_props.resize(extension_count);
2212         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
2213                                                                                         extension_props.data()));
2214 
2215         // Make sure the extensions are not present
2216         for (uint32_t ext = 0; ext < extension_count; ++ext) {
2217             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
2218             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
2219         }
2220     }
2221 
2222     // Now query by layer name.
2223     extension_count = 0;
2224     extension_props.clear();
2225     ASSERT_EQ(VK_SUCCESS,
2226               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name, &extension_count, nullptr));
2227     if (extension_count > 0) {
2228         extension_props.resize(extension_count);
2229         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name,
2230                                                                                         &extension_count, extension_props.data()));
2231 
2232         // Make sure the extensions still aren't present in this layer
2233         for (uint32_t ext = 0; ext < extension_count; ++ext) {
2234             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
2235             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
2236         }
2237     }
2238 
2239     DeviceWrapper dev{inst};
2240     dev.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2241     dev.CheckCreate(phys_dev);
2242 
2243     // Make sure all the function pointers are NULL as well
2244     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
2245     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
2246     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkSetDeviceMemoryPriorityEXT"));
2247 }
2248 
TEST(LayerExtensions,ExplicitMaintenanceDeviceExtension)2249 TEST(LayerExtensions, ExplicitMaintenanceDeviceExtension) {
2250     FrameworkEnvironment env;
2251     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2252     auto& driver = env.get_test_icd();
2253     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
2254 
2255     driver.physical_devices.emplace_back("physical_device_0");
2256     driver.physical_devices.back().queue_family_properties.push_back(family_props);
2257 
2258     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2259     env.add_explicit_layer(
2260         ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2261                                       .set_name(explicit_layer_name)
2262                                       .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
2263                                       .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
2264                                       .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})),
2265         "explicit_wrap_layer_maint.json");
2266 
2267     uint32_t count = 0;
2268     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2269     ASSERT_EQ(count, 1U);
2270 
2271     InstWrapper inst{env.vulkan_functions};
2272     inst.create_info.add_layer(explicit_layer_name);
2273     inst.CheckCreate();
2274     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2275 
2276     uint32_t extension_count = 0;
2277     std::vector<VkExtensionProperties> extension_props;
2278     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
2279     if (extension_count > 0) {
2280         extension_props.resize(extension_count);
2281         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
2282                                                                                         extension_props.data()));
2283 
2284         // Make sure the extensions are not present
2285         for (uint32_t ext = 0; ext < extension_count; ++ext) {
2286             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
2287             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
2288         }
2289     }
2290 
2291     // Now query by layer name.
2292     extension_count = 0;
2293     extension_props.clear();
2294     ASSERT_EQ(VK_SUCCESS,
2295               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name, &extension_count, nullptr));
2296     ASSERT_EQ(extension_count, 1U);
2297     extension_props.resize(extension_count);
2298     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name, &extension_count,
2299                                                                                     extension_props.data()));
2300 
2301     // Make sure only the one extension implemented by the enabled implicit layer is present.
2302     bool found = true;
2303     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2304         if (!strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2305             found = true;
2306         }
2307         ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
2308     }
2309     ASSERT_EQ(true, found);
2310 
2311     DeviceWrapper dev{inst};
2312     dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME).add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2313     dev.CheckCreate(phys_dev);
2314 
2315     // Make sure only the appropriate function pointers are NULL as well
2316     handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
2317     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
2318 }
2319 
TEST(LayerExtensions,ExplicitPresentImageDeviceExtension)2320 TEST(LayerExtensions, ExplicitPresentImageDeviceExtension) {
2321     FrameworkEnvironment env;
2322     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2323     auto& driver = env.get_test_icd();
2324     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
2325 
2326     driver.physical_devices.emplace_back("physical_device_0");
2327     driver.physical_devices.back().queue_family_properties.push_back(family_props);
2328 
2329     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2330     env.add_explicit_layer(
2331         ManifestLayer{}.add_layer(
2332             ManifestLayer::LayerDescription{}
2333                 .set_name(explicit_layer_name)
2334                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
2335                 .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
2336                 .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
2337         "explicit_wrap_layer_pres.json");
2338 
2339     uint32_t count = 0;
2340     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2341     ASSERT_EQ(count, 1U);
2342 
2343     InstWrapper inst{env.vulkan_functions};
2344     inst.create_info.add_layer(explicit_layer_name);
2345     inst.CheckCreate();
2346     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2347 
2348     uint32_t extension_count = 0;
2349     std::vector<VkExtensionProperties> extension_props;
2350     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
2351     if (extension_count > 0) {
2352         extension_props.resize(extension_count);
2353         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
2354                                                                                         extension_props.data()));
2355 
2356         // Make sure the extensions are not present
2357         for (uint32_t ext = 0; ext < extension_count; ++ext) {
2358             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
2359             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
2360         }
2361     }
2362 
2363     // Now query by layer name.
2364     extension_count = 0;
2365     extension_props.clear();
2366     ASSERT_EQ(VK_SUCCESS,
2367               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name, &extension_count, nullptr));
2368     ASSERT_EQ(extension_count, 1U);
2369     extension_props.resize(extension_count);
2370     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name, &extension_count,
2371                                                                                     extension_props.data()));
2372 
2373     // Make sure only the one extension implemented by the enabled implicit layer is present.
2374     bool found = false;
2375     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2376         ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
2377         if (!strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2378             found = true;
2379         }
2380     }
2381     ASSERT_EQ(true, found);
2382 
2383     DeviceWrapper dev{inst};
2384     dev.create_info.add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
2385         .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2386     dev.CheckCreate(phys_dev);
2387 
2388     // Make sure only the appropriate function pointers are NULL as well
2389     handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
2390     handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
2391 }
2392 
TEST(LayerExtensions,ExplicitBothDeviceExtensions)2393 TEST(LayerExtensions, ExplicitBothDeviceExtensions) {
2394     FrameworkEnvironment env;
2395     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2396     auto& driver = env.get_test_icd();
2397     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
2398 
2399     driver.physical_devices.emplace_back("physical_device_0");
2400     driver.physical_devices.back().queue_family_properties.push_back(family_props);
2401 
2402     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2403     env.add_explicit_layer(
2404         ManifestLayer{}.add_layer(
2405             ManifestLayer::LayerDescription{}
2406                 .set_name(explicit_layer_name)
2407                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
2408                 .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
2409                 .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
2410                 .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
2411         "explicit_wrap_layer_both_dev.json");
2412 
2413     uint32_t count = 0;
2414     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
2415     ASSERT_EQ(count, 1U);
2416 
2417     InstWrapper inst{env.vulkan_functions};
2418     inst.create_info.add_layer(explicit_layer_name);
2419     inst.CheckCreate();
2420     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2421     handle_assert_has_value(phys_dev);
2422 
2423     uint32_t extension_count = 0;
2424     std::vector<VkExtensionProperties> extension_props;
2425     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count, nullptr));
2426     if (extension_count > 0) {
2427         extension_props.resize(extension_count);
2428         ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, nullptr, &extension_count,
2429                                                                                         extension_props.data()));
2430 
2431         // Make sure the extensions are not present
2432         for (uint32_t ext = 0; ext < extension_count; ++ext) {
2433             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME));
2434             ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME));
2435         }
2436     }
2437 
2438     // Now query by layer name.
2439     extension_count = 0;
2440     extension_props.clear();
2441     ASSERT_EQ(VK_SUCCESS,
2442               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name, &extension_count, nullptr));
2443     ASSERT_EQ(extension_count, 2U);  // debug_utils, and debug_report
2444     extension_props.resize(extension_count);
2445     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev, explicit_layer_name, &extension_count,
2446                                                                                     extension_props.data()));
2447 
2448     // Make sure only the one extension implemented by the enabled implicit layer is present.
2449     bool found[2] = {false, false};
2450     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2451         if (!strcmp(extension_props[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2452             found[0] = true;
2453         }
2454         if (!strcmp(extension_props[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2455             found[1] = true;
2456         }
2457     }
2458     for (uint32_t ext = 0; ext < 2; ++ext) {
2459         ASSERT_EQ(true, found[ext]);
2460     }
2461 
2462     DeviceWrapper dev{inst};
2463     dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME)
2464         .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
2465         .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2466     dev.CheckCreate(phys_dev);
2467 
2468     // Make sure only the appropriate function pointers are NULL as well
2469     handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR"));
2470 
2471     PFN_vkGetSwapchainStatusKHR gipa_pfnGetSwapchainStatusKHR =
2472         reinterpret_cast<PFN_vkGetSwapchainStatusKHR>(inst->vkGetInstanceProcAddr(inst.inst, "vkGetSwapchainStatusKHR"));
2473     PFN_vkGetSwapchainStatusKHR gdpa_pfnGetSwapchainStatusKHR =
2474         reinterpret_cast<PFN_vkGetSwapchainStatusKHR>(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR"));
2475     handle_assert_has_value(gipa_pfnGetSwapchainStatusKHR);
2476     handle_assert_has_value(gdpa_pfnGetSwapchainStatusKHR);
2477 
2478     // Make sure both versions (from vkGetInstanceProcAddr and vkGetDeviceProcAddr) return the same value.
2479     ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, gipa_pfnGetSwapchainStatusKHR(dev.dev, VK_NULL_HANDLE));
2480     ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, gdpa_pfnGetSwapchainStatusKHR(dev.dev, VK_NULL_HANDLE));
2481 }
2482 
TEST(TestLayers,ExplicitlyEnableImplicitLayer)2483 TEST(TestLayers, ExplicitlyEnableImplicitLayer) {
2484     FrameworkEnvironment env;
2485     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));
2486     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
2487     VkPhysicalDeviceProperties properties{};
2488     properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
2489     env.get_test_icd().add_physical_device({});
2490     env.get_test_icd().physical_devices.back().set_properties(properties);
2491 
2492     const char* regular_layer_name = "VK_LAYER_TestLayer1";
2493     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2494                                                          .set_name(regular_layer_name)
2495                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2496                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
2497                                                          .set_disable_environment("DisableMeIfYouCan")),
2498                            "regular_test_layer.json");
2499     {  // 1.1 instance
2500         InstWrapper inst{env.vulkan_functions};
2501         inst.create_info.add_layer(regular_layer_name);
2502         inst.create_info.set_api_version(1, 1, 0);
2503         inst.CheckCreate();
2504         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2505 
2506         uint32_t count = 0;
2507         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2508         EXPECT_EQ(1U, count);
2509         VkLayerProperties layer_props{};
2510         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2511         EXPECT_EQ(1U, count);
2512         ASSERT_TRUE(string_eq(regular_layer_name, layer_props.layerName));
2513     }
2514     {  // 1.2 instance
2515         InstWrapper inst{env.vulkan_functions};
2516         inst.create_info.add_layer(regular_layer_name);
2517         inst.create_info.set_api_version(1, 2, 0);
2518         inst.CheckCreate();
2519         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2520 
2521         uint32_t count = 0;
2522         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2523         ASSERT_EQ(1U, count);
2524         VkLayerProperties layer_props{};
2525         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2526         ASSERT_EQ(1U, count);
2527     }
2528 }
2529 
TEST(TestLayers,NewerInstanceVersionThanImplicitLayer)2530 TEST(TestLayers, NewerInstanceVersionThanImplicitLayer) {
2531     FrameworkEnvironment env;
2532     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));
2533     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
2534     VkPhysicalDeviceProperties properties{};
2535     properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
2536     env.get_test_icd().add_physical_device({});
2537     env.get_test_icd().physical_devices.back().set_properties(properties);
2538 
2539     const char* regular_layer_name = "VK_LAYER_TestLayer1";
2540     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2541                                                          .set_name(regular_layer_name)
2542                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2543                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
2544                                                          .set_disable_environment("DisableMeIfYouCan")),
2545                            "regular_test_layer.json");
2546     {  // global functions
2547         uint32_t layer_count = 0;
2548         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
2549         EXPECT_EQ(layer_count, 1U);
2550 
2551         std::array<VkLayerProperties, 1> layer_props;
2552         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
2553         EXPECT_EQ(layer_count, 1U);
2554         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
2555     }
2556     {  // 1.1 instance - should find the implicit layer
2557         InstWrapper inst{env.vulkan_functions};
2558         inst.create_info.set_api_version(1, 1, 0);
2559         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
2560         inst.CheckCreate();
2561         EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
2562         env.debug_log.clear();
2563         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2564 
2565         uint32_t count = 0;
2566         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2567         EXPECT_EQ(1U, count);
2568         VkLayerProperties layer_props{};
2569         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2570         EXPECT_EQ(1U, count);
2571         ASSERT_TRUE(string_eq(regular_layer_name, layer_props.layerName));
2572     }
2573     {  // 1.2 instance -- instance layer should be found
2574         InstWrapper inst{env.vulkan_functions};
2575         inst.create_info.set_api_version(1, 2, 0);
2576         FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
2577         inst.CheckCreate();
2578         EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer ") + regular_layer_name));
2579         env.debug_log.clear();
2580 
2581         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2582         uint32_t count = 0;
2583         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2584         EXPECT_EQ(1U, count);
2585         VkLayerProperties layer_props{};
2586         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2587         EXPECT_EQ(1U, count);
2588         ASSERT_TRUE(string_eq(regular_layer_name, layer_props.layerName));
2589     }
2590 }
2591 
TEST(TestLayers,ImplicitLayerPre10APIVersion)2592 TEST(TestLayers, ImplicitLayerPre10APIVersion) {
2593     FrameworkEnvironment env;
2594     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));
2595     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
2596     VkPhysicalDeviceProperties properties{};
2597     properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
2598     env.get_test_icd().add_physical_device({});
2599     env.get_test_icd().physical_devices.back().set_properties(properties);
2600 
2601     const char* regular_layer_name = "VK_LAYER_TestLayer1";
2602     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2603                                                          .set_name(regular_layer_name)
2604                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2605                                                          .set_api_version(VK_MAKE_API_VERSION(0, 0, 1, 0))
2606                                                          .set_disable_environment("DisableMeIfYouCan")),
2607                            "regular_test_layer.json");
2608     {  // global functions
2609 
2610         uint32_t layer_count = 0;
2611         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, nullptr));
2612         EXPECT_EQ(layer_count, 1U);
2613 
2614         std::array<VkLayerProperties, 1> layer_props;
2615         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, layer_props.data()));
2616         EXPECT_EQ(layer_count, 1U);
2617         EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name));
2618     }
2619     {  // 1.0 instance
2620         DebugUtilsLogger log;
2621         InstWrapper inst{env.vulkan_functions};
2622         inst.create_info.set_api_version(1, 0, 0);
2623         FillDebugUtilsCreateDetails(inst.create_info, log);
2624         inst.CheckCreate();
2625         EXPECT_TRUE(log.find(std::string("Insert instance layer ") + regular_layer_name));
2626         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2627 
2628         uint32_t count = 0;
2629         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2630         EXPECT_EQ(1U, count);
2631         VkLayerProperties layer_props{};
2632         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2633         EXPECT_EQ(1U, count);
2634         ASSERT_TRUE(string_eq(regular_layer_name, layer_props.layerName));
2635     }
2636     {  // 1.1 instance
2637         DebugUtilsLogger log;
2638         InstWrapper inst{env.vulkan_functions};
2639         inst.create_info.set_api_version(1, 1, 0);
2640         FillDebugUtilsCreateDetails(inst.create_info, log);
2641         inst.CheckCreate();
2642         EXPECT_TRUE(log.find(std::string("Insert instance layer ") + regular_layer_name));
2643         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2644         uint32_t count = 0;
2645         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2646         EXPECT_EQ(1U, count);
2647         VkLayerProperties layer_props{};
2648         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2649         EXPECT_EQ(1U, count);
2650         ASSERT_TRUE(string_eq(regular_layer_name, layer_props.layerName));
2651     }
2652     {  // 1.2 instance
2653         DebugUtilsLogger log;
2654         InstWrapper inst{env.vulkan_functions};
2655         inst.create_info.set_api_version(1, 2, 0);
2656         FillDebugUtilsCreateDetails(inst.create_info, log);
2657         inst.CheckCreate();
2658         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2659         EXPECT_TRUE(log.find(std::string("Insert instance layer ") + regular_layer_name));
2660         uint32_t count = 0;
2661         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2662         EXPECT_EQ(1U, count);
2663         VkLayerProperties layer_props{};
2664         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2665         EXPECT_EQ(1U, count);
2666         ASSERT_TRUE(string_eq(regular_layer_name, layer_props.layerName));
2667     }
2668     {  // application doesn't state its API version
2669         DebugUtilsLogger log;
2670         InstWrapper inst{env.vulkan_functions};
2671         inst.create_info.set_fill_in_application_info(false);
2672         FillDebugUtilsCreateDetails(inst.create_info, log);
2673         inst.CheckCreate();
2674         EXPECT_TRUE(log.find(std::string("Insert instance layer ") + regular_layer_name));
2675         VkPhysicalDevice phys_dev = inst.GetPhysDev();
2676 
2677         uint32_t count = 0;
2678         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, nullptr);
2679         EXPECT_EQ(1U, count);
2680         VkLayerProperties layer_props{};
2681         env.vulkan_functions.vkEnumerateDeviceLayerProperties(phys_dev, &count, &layer_props);
2682         EXPECT_EQ(1U, count);
2683         ASSERT_TRUE(string_eq(regular_layer_name, layer_props.layerName));
2684     }
2685 }
2686 
2687 // Verify that VK_INSTANCE_LAYERS work.  To test this, make sure that an explicit layer does not affect an instance until
2688 // it is set with VK_INSTANCE_LAYERS
TEST(TestLayers,EnvironEnableExplicitLayer)2689 TEST(TestLayers, EnvironEnableExplicitLayer) {
2690     FrameworkEnvironment env;
2691     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));
2692     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
2693     VkPhysicalDeviceProperties properties{};
2694     properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
2695     env.get_test_icd().add_physical_device({});
2696     env.get_test_icd().physical_devices.back().set_properties(properties);
2697 
2698     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2699     env.add_explicit_layer(
2700         ManifestLayer{}.add_layer(
2701             ManifestLayer::LayerDescription{}
2702                 .set_name(explicit_layer_name)
2703                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
2704                 .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
2705                 .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
2706                 .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
2707         "explicit_wrap_layer_both_dev.json");
2708 
2709     // First, test an instance/device without the layer forced on.  The extensions shouldn't be present and
2710     // the function pointers should be NULL.
2711     InstWrapper inst1{env.vulkan_functions};
2712     inst1.CheckCreate();
2713     VkPhysicalDevice phys_dev1 = inst1.GetPhysDev();
2714 
2715     // Make sure the extensions in the layer aren't present
2716     uint32_t extension_count = 40;
2717     std::array<VkExtensionProperties, 40> extensions;
2718     EXPECT_EQ(VK_SUCCESS,
2719               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev1, nullptr, &extension_count, extensions.data()));
2720     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2721         if (string_eq(extensions[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME) ||
2722             string_eq(extensions[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2723             FAIL() << "Extension should not be present";
2724         }
2725     }
2726 
2727     // Create a device and query the function pointers
2728     DeviceWrapper dev1{inst1};
2729     dev1.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2730     dev1.CheckCreate(phys_dev1);
2731     PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolBefore = dev1.load("vkTrimCommandPoolKHR");
2732     PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusBefore = dev1.load("vkGetSwapchainStatusKHR");
2733     handle_assert_null(pfn_TrimCommandPoolBefore);
2734     handle_assert_null(pfn_GetSwapchainStatusBefore);
2735 
2736     // Now setup the instance layer
2737     set_env_var("VK_INSTANCE_LAYERS", explicit_layer_name);
2738 
2739     // Now, test an instance/device with the layer forced on.  The extensions should be present and
2740     // the function pointers should be valid.
2741     InstWrapper inst2{env.vulkan_functions};
2742     inst2.CheckCreate();
2743     VkPhysicalDevice phys_dev2 = inst2.GetPhysDev();
2744 
2745     // Make sure the extensions in the layer are present
2746     extension_count = 40;
2747     EXPECT_EQ(VK_SUCCESS,
2748               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev2, nullptr, &extension_count, extensions.data()));
2749     bool maint_found = false;
2750     bool pres_found = false;
2751     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2752         if (string_eq(extensions[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2753             maint_found = true;
2754         }
2755         if (string_eq(extensions[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2756             pres_found = true;
2757         }
2758     }
2759     ASSERT_EQ(true, maint_found);
2760     ASSERT_EQ(true, pres_found);
2761 
2762     DeviceWrapper dev2{inst2};
2763     dev2.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME)
2764         .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
2765         .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2766     dev2.CheckCreate(phys_dev2);
2767 
2768     PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolAfter = dev2.load("vkTrimCommandPoolKHR");
2769     PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusAfter = dev2.load("vkGetSwapchainStatusKHR");
2770     handle_assert_has_value(pfn_TrimCommandPoolAfter);
2771     handle_assert_has_value(pfn_GetSwapchainStatusAfter);
2772 
2773     ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, pfn_GetSwapchainStatusAfter(dev2.dev, VK_NULL_HANDLE));
2774 
2775     remove_env_var("VK_INSTANCE_LAYERS");
2776 }
2777 
2778 // Add a device layer, should not work
TEST(TestLayers,DoNotUseDeviceLayer)2779 TEST(TestLayers, DoNotUseDeviceLayer) {
2780     FrameworkEnvironment env;
2781     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));
2782     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
2783     VkPhysicalDeviceProperties properties{};
2784     properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
2785     env.get_test_icd().add_physical_device({});
2786     env.get_test_icd().physical_devices.back().set_properties(properties);
2787 
2788     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2789     env.add_explicit_layer(
2790         ManifestLayer{}.add_layer(
2791             ManifestLayer::LayerDescription{}
2792                 .set_name(explicit_layer_name)
2793                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
2794                 .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
2795                 .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
2796                 .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
2797         "explicit_wrap_layer_both_dev.json");
2798 
2799     // First, test an instance/device without the layer forced on.  The extensions shouldn't be present and
2800     // the function pointers should be NULL.
2801     InstWrapper inst1{env.vulkan_functions};
2802     inst1.CheckCreate();
2803     VkPhysicalDevice phys_dev1 = inst1.GetPhysDev();
2804 
2805     // Make sure the extensions in the layer aren't present
2806     uint32_t extension_count = 40;
2807     std::array<VkExtensionProperties, 40> extensions;
2808     EXPECT_EQ(VK_SUCCESS,
2809               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev1, nullptr, &extension_count, extensions.data()));
2810     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2811         if (string_eq(extensions[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME) ||
2812             string_eq(extensions[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2813             FAIL() << "Extension should not be present";
2814         }
2815     }
2816 
2817     // Create a device and query the function pointers
2818     DeviceWrapper dev1{inst1};
2819     dev1.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
2820     dev1.CheckCreate(phys_dev1);
2821     PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolBefore = dev1.load("vkTrimCommandPoolKHR");
2822     PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusBefore = dev1.load("vkGetSwapchainStatusKHR");
2823     handle_assert_null(pfn_TrimCommandPoolBefore);
2824     handle_assert_null(pfn_GetSwapchainStatusBefore);
2825 
2826     // Now, test an instance/device with the layer forced on.  The extensions should be present and
2827     // the function pointers should be valid.
2828     InstWrapper inst2{env.vulkan_functions};
2829     inst2.CheckCreate();
2830     VkPhysicalDevice phys_dev2 = inst2.GetPhysDev();
2831 
2832     // Make sure the extensions in the layer aren't present
2833     extension_count = 40;
2834     EXPECT_EQ(VK_SUCCESS,
2835               env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev1, nullptr, &extension_count, extensions.data()));
2836     for (uint32_t ext = 0; ext < extension_count; ++ext) {
2837         if (string_eq(extensions[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME) ||
2838             string_eq(extensions[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
2839             FAIL() << "Extension should not be present";
2840         }
2841     }
2842 
2843     DeviceWrapper dev2{inst2};
2844     dev2.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME)
2845         .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
2846         .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f))
2847         .add_layer(explicit_layer_name);
2848     dev2.CheckCreate(phys_dev2, VK_ERROR_EXTENSION_NOT_PRESENT);
2849 
2850     DeviceWrapper dev3{inst2};
2851     dev3.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f)).add_layer(explicit_layer_name);
2852     dev3.CheckCreate(phys_dev2);
2853 
2854     PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolAfter = dev3.load("vkTrimCommandPoolKHR");
2855     PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusAfter = dev3.load("vkGetSwapchainStatusKHR");
2856     handle_assert_null(pfn_TrimCommandPoolAfter);
2857     handle_assert_null(pfn_GetSwapchainStatusAfter);
2858 }
2859 
2860 // Make sure that a layer enabled as both an instance and device layer works properly.
TEST(TestLayers,InstanceAndDeviceLayer)2861 TEST(TestLayers, InstanceAndDeviceLayer) {
2862     FrameworkEnvironment env;
2863     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));
2864     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
2865     VkPhysicalDeviceProperties properties{};
2866     properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
2867     env.get_test_icd().add_physical_device({});
2868     env.get_test_icd().physical_devices.back().set_properties(properties);
2869 
2870     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2871     env.add_explicit_layer(
2872         ManifestLayer{}.add_layer(
2873             ManifestLayer::LayerDescription{}
2874                 .set_name(explicit_layer_name)
2875                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
2876                 .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
2877                 .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
2878                 .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
2879         "explicit_wrap_layer_both_dev.json");
2880 
2881     InstWrapper inst{env.vulkan_functions};
2882     inst.create_info.add_layer(explicit_layer_name);
2883     inst.CheckCreate();
2884     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2885 
2886     DeviceWrapper dev{inst};
2887     dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME)
2888         .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
2889         .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f))
2890         .add_layer(explicit_layer_name);
2891     dev.CheckCreate(phys_dev);
2892 
2893     PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolAfter = dev.load("vkTrimCommandPoolKHR");
2894     PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusAfter = dev.load("vkGetSwapchainStatusKHR");
2895     handle_assert_has_value(pfn_TrimCommandPoolAfter);
2896     handle_assert_has_value(pfn_GetSwapchainStatusAfter);
2897 
2898     ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, pfn_GetSwapchainStatusAfter(dev.dev, VK_NULL_HANDLE));
2899 }
2900 
2901 // Make sure loader does not throw an error for a device layer  that is not present
TEST(TestLayers,DeviceLayerNotPresent)2902 TEST(TestLayers, DeviceLayerNotPresent) {
2903     FrameworkEnvironment env;
2904     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 2, 0)));
2905     env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
2906     VkPhysicalDeviceProperties properties{};
2907     properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
2908     env.get_test_icd().add_physical_device({});
2909     env.get_test_icd().physical_devices.back().set_properties(properties);
2910 
2911     const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
2912 
2913     InstWrapper inst{env.vulkan_functions};
2914     inst.CheckCreate();
2915     VkPhysicalDevice phys_dev = inst.GetPhysDev();
2916 
2917     DeviceWrapper dev{inst};
2918     dev.create_info.add_layer(explicit_layer_name);
2919     dev.CheckCreate(phys_dev);
2920 }
2921 
TEST(LayerPhysDeviceMod,AddPhysicalDevices)2922 TEST(LayerPhysDeviceMod, AddPhysicalDevices) {
2923     FrameworkEnvironment env;
2924     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
2925     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
2926                                                          .set_name("VkLayer_LunarG_add_phys_dev")
2927                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
2928                                                          .set_api_version(VK_API_VERSION_1_1)
2929                                                          .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")),
2930                            "test_layer_add.json");
2931 
2932     auto& layer = env.get_test_layer(0);
2933     layer.set_add_phys_devs(true);
2934 
2935     for (uint32_t icd = 0; icd < 2; ++icd) {
2936         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
2937         auto& cur_icd = env.get_test_icd(icd);
2938         cur_icd.icd_api_version = VK_API_VERSION_1_2;
2939         VkPhysicalDeviceProperties properties{};
2940         properties.apiVersion = VK_API_VERSION_1_2;
2941         properties.vendorID = 0x11000000 + (icd << 6);
2942         for (uint32_t dev = 0; dev < 3; ++dev) {
2943             properties.deviceID = properties.vendorID + dev;
2944             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
2945             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
2946 #if defined(_WIN32)
2947             strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
2948 #else
2949             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
2950 #endif
2951             cur_icd.add_physical_device({});
2952             cur_icd.physical_devices.back().set_properties(properties);
2953         }
2954         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
2955         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
2956         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
2957     }
2958     const uint32_t icd_devices = 6;
2959 
2960     InstWrapper inst{env.vulkan_functions};
2961     inst.create_info.set_api_version(VK_API_VERSION_1_1);
2962     inst.CheckCreate();
2963 
2964     uint32_t dev_count = 0;
2965     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
2966     ASSERT_GT(dev_count, icd_devices);
2967 
2968     auto not_exp_physical_devices = std::vector<VkPhysicalDevice>(icd_devices);
2969     uint32_t returned_phys_dev_count = icd_devices;
2970     ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, not_exp_physical_devices.data()));
2971     ASSERT_EQ(icd_devices, returned_phys_dev_count);
2972 
2973     auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
2974     returned_phys_dev_count = dev_count;
2975     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
2976     ASSERT_EQ(dev_count, returned_phys_dev_count);
2977 
2978     uint32_t diff_count = dev_count - icd_devices;
2979     uint32_t found_incomplete = 0;
2980     uint32_t found_added_count = 0;
2981     for (uint32_t dev = 0; dev < dev_count; ++dev) {
2982         VkPhysicalDeviceProperties props{};
2983         inst->vkGetPhysicalDeviceProperties(physical_devices[dev], &props);
2984         if (string_eq(props.deviceName, "physdev_added_xx")) {
2985             found_added_count++;
2986         }
2987         for (uint32_t incomp = 0; incomp < icd_devices; ++incomp) {
2988             if (not_exp_physical_devices[incomp] == physical_devices[dev]) {
2989                 found_incomplete++;
2990                 break;
2991             }
2992         }
2993     }
2994 
2995     // We should have added the number of diff items, and the incomplete count should match the number of
2996     // original physical devices.
2997     ASSERT_EQ(found_added_count, diff_count);
2998     ASSERT_EQ(found_incomplete, icd_devices);
2999 }
3000 
TEST(LayerPhysDeviceMod,RemovePhysicalDevices)3001 TEST(LayerPhysDeviceMod, RemovePhysicalDevices) {
3002     FrameworkEnvironment env;
3003     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
3004     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
3005                                                          .set_name("VkLayer_LunarG_remove_phys_dev")
3006                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
3007                                                          .set_api_version(VK_API_VERSION_1_1)
3008                                                          .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")),
3009                            "test_layer_remove.json");
3010 
3011     auto& layer = env.get_test_layer(0);
3012     layer.set_remove_phys_devs(true);
3013 
3014     for (uint32_t icd = 0; icd < 2; ++icd) {
3015         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
3016         auto& cur_icd = env.get_test_icd(icd);
3017         cur_icd.icd_api_version = VK_API_VERSION_1_2;
3018         VkPhysicalDeviceProperties properties{};
3019         properties.apiVersion = VK_API_VERSION_1_2;
3020         properties.vendorID = 0x11000000 + (icd << 6);
3021         for (uint32_t dev = 0; dev < 3; ++dev) {
3022             properties.deviceID = properties.vendorID + dev;
3023             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
3024             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
3025 #if defined(_WIN32)
3026             strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
3027 #else
3028             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3029 #endif
3030             cur_icd.add_physical_device({});
3031             cur_icd.physical_devices.back().set_properties(properties);
3032         }
3033         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
3034         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
3035         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
3036     }
3037     const uint32_t icd_devices = 6;
3038 
3039     InstWrapper inst{env.vulkan_functions};
3040     inst.create_info.set_api_version(VK_API_VERSION_1_1);
3041     inst.CheckCreate();
3042 
3043     uint32_t dev_count = 0;
3044     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
3045     ASSERT_LT(dev_count, icd_devices);
3046 
3047     auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
3048     uint32_t returned_phys_dev_count = dev_count;
3049     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
3050     ASSERT_EQ(dev_count, returned_phys_dev_count);
3051 }
3052 
TEST(LayerPhysDeviceMod,ReorderPhysicalDevices)3053 TEST(LayerPhysDeviceMod, ReorderPhysicalDevices) {
3054     FrameworkEnvironment env;
3055     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
3056     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
3057                                                          .set_name("VkLayer_LunarG_reorder_phys_dev")
3058                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
3059                                                          .set_api_version(VK_API_VERSION_1_1)
3060                                                          .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")),
3061                            "test_layer_reorder.json");
3062 
3063     auto& layer = env.get_test_layer(0);
3064     layer.set_reorder_phys_devs(true);
3065 
3066     for (uint32_t icd = 0; icd < 2; ++icd) {
3067         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
3068         auto& cur_icd = env.get_test_icd(icd);
3069         cur_icd.icd_api_version = VK_API_VERSION_1_2;
3070         VkPhysicalDeviceProperties properties{};
3071         properties.apiVersion = VK_API_VERSION_1_2;
3072         properties.vendorID = 0x11000000 + (icd << 6);
3073         for (uint32_t dev = 0; dev < 3; ++dev) {
3074             properties.deviceID = properties.vendorID + dev;
3075             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
3076             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
3077 #if defined(_WIN32)
3078             strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
3079 #else
3080             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3081 #endif
3082             cur_icd.add_physical_device({});
3083             cur_icd.physical_devices.back().set_properties(properties);
3084         }
3085         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
3086         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
3087         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
3088     }
3089     const uint32_t icd_devices = 6;
3090 
3091     InstWrapper inst{env.vulkan_functions};
3092     inst.create_info.set_api_version(VK_API_VERSION_1_1);
3093     inst.CheckCreate();
3094 
3095     uint32_t dev_count = 0;
3096     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
3097     ASSERT_EQ(dev_count, icd_devices);
3098 
3099     auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
3100     uint32_t returned_phys_dev_count = dev_count;
3101     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
3102     ASSERT_EQ(dev_count, returned_phys_dev_count);
3103 }
3104 
TEST(LayerPhysDeviceMod,AddRemoveAndReorderPhysicalDevices)3105 TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDevices) {
3106     FrameworkEnvironment env;
3107     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
3108     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
3109                                                          .set_name("VkLayer_LunarG_all_phys_dev")
3110                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
3111                                                          .set_api_version(VK_API_VERSION_1_1)
3112                                                          .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")),
3113                            "test_layer_all.json");
3114 
3115     auto& layer = env.get_test_layer(0);
3116     layer.set_add_phys_devs(true).set_remove_phys_devs(true).set_reorder_phys_devs(true);
3117 
3118     for (uint32_t icd = 0; icd < 2; ++icd) {
3119         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
3120         auto& cur_icd = env.get_test_icd(icd);
3121         cur_icd.icd_api_version = VK_API_VERSION_1_2;
3122         VkPhysicalDeviceProperties properties{};
3123         properties.apiVersion = VK_API_VERSION_1_2;
3124         properties.vendorID = 0x11000000 + (icd << 6);
3125         for (uint32_t dev = 0; dev < 3; ++dev) {
3126             properties.deviceID = properties.vendorID + dev;
3127             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
3128             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
3129 #if defined(_WIN32)
3130             strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
3131 #else
3132             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3133 #endif
3134             cur_icd.add_physical_device({});
3135             cur_icd.physical_devices.back().set_properties(properties);
3136         }
3137         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
3138         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
3139         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
3140     }
3141     const uint32_t icd_devices = 6;
3142 
3143     InstWrapper inst{env.vulkan_functions};
3144     inst.create_info.set_api_version(VK_API_VERSION_1_1);
3145     inst.CheckCreate();
3146 
3147     uint32_t dev_count = 0;
3148     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
3149     ASSERT_GT(dev_count, icd_devices);
3150 
3151     auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
3152     uint32_t returned_phys_dev_count = dev_count;
3153     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
3154     ASSERT_EQ(dev_count, returned_phys_dev_count);
3155 
3156     uint32_t found_added_count = 0;
3157     for (uint32_t dev = 0; dev < dev_count; ++dev) {
3158         VkPhysicalDeviceProperties props{};
3159         inst->vkGetPhysicalDeviceProperties(physical_devices[dev], &props);
3160         if (string_eq(props.deviceName, "physdev_added_xx")) {
3161             found_added_count++;
3162         }
3163     }
3164 
3165     // Should see 2 removed, but 3 added so a diff count of 1
3166     uint32_t diff_count = dev_count - icd_devices;
3167     ASSERT_EQ(1U, diff_count);
3168     ASSERT_EQ(found_added_count, 3U);
3169 }
3170 
GroupsAreTheSame(VkPhysicalDeviceGroupProperties a,VkPhysicalDeviceGroupProperties b)3171 static bool GroupsAreTheSame(VkPhysicalDeviceGroupProperties a, VkPhysicalDeviceGroupProperties b) {
3172     if (a.physicalDeviceCount != b.physicalDeviceCount) {
3173         return false;
3174     }
3175     for (uint32_t dev = 0; dev < a.physicalDeviceCount; ++dev) {
3176         if (a.physicalDevices[dev] != b.physicalDevices[dev]) {
3177             return false;
3178         }
3179     }
3180     return true;
3181 }
3182 
TEST(LayerPhysDeviceMod,AddPhysicalDeviceGroups)3183 TEST(LayerPhysDeviceMod, AddPhysicalDeviceGroups) {
3184     FrameworkEnvironment env;
3185     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
3186     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
3187                                                          .set_name("VkLayer_LunarG_add_phys_dev")
3188                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
3189                                                          .set_api_version(VK_API_VERSION_1_1)
3190                                                          .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")),
3191                            "test_layer_remove.json");
3192 
3193     auto& layer = env.get_test_layer(0);
3194     layer.set_add_phys_devs(true);
3195 
3196     for (uint32_t icd = 0; icd < 2; ++icd) {
3197         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
3198         auto& cur_icd = env.get_test_icd(icd);
3199         cur_icd.icd_api_version = VK_API_VERSION_1_2;
3200         VkPhysicalDeviceProperties properties{};
3201         properties.apiVersion = VK_API_VERSION_1_2;
3202         properties.vendorID = 0x11000000 + (icd << 6);
3203         for (uint32_t dev = 0; dev < 3; ++dev) {
3204             properties.deviceID = properties.vendorID + dev;
3205             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
3206             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
3207 #if defined(_WIN32)
3208             strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
3209 #else
3210             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3211 #endif
3212             cur_icd.add_physical_device({});
3213             cur_icd.physical_devices.back().set_properties(properties);
3214         }
3215         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
3216         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
3217         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
3218     }
3219     const uint32_t icd_groups = 4;
3220 
3221     InstWrapper inst{env.vulkan_functions};
3222     inst.create_info.set_api_version(VK_API_VERSION_1_1);
3223     inst.CheckCreate();
3224 
3225     uint32_t grp_count = 0;
3226     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
3227     ASSERT_GT(grp_count, icd_groups);
3228 
3229     auto not_exp_phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(icd_groups);
3230     for (uint32_t group = 0; group < icd_groups; ++group) {
3231         not_exp_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
3232     }
3233     uint32_t returned_group_count = icd_groups;
3234     ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, not_exp_phys_dev_groups.data()));
3235     ASSERT_EQ(icd_groups, returned_group_count);
3236 
3237     auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
3238     for (uint32_t group = 0; group < grp_count; ++group) {
3239         phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
3240     }
3241     returned_group_count = grp_count;
3242     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
3243     ASSERT_EQ(grp_count, returned_group_count);
3244 
3245     uint32_t diff_count = grp_count - icd_groups;
3246     uint32_t found_incomplete = 0;
3247     uint32_t found_added_count = 0;
3248     for (uint32_t grp = 0; grp < grp_count; ++grp) {
3249         // Shortcut, only groups with 1 device could be added in the newly added count
3250         if (1 == phys_dev_groups[grp].physicalDeviceCount) {
3251             for (uint32_t dev = 0; dev < phys_dev_groups[grp].physicalDeviceCount; ++dev) {
3252                 VkPhysicalDeviceProperties props{};
3253                 inst->vkGetPhysicalDeviceProperties(phys_dev_groups[grp].physicalDevices[dev], &props);
3254                 if (string_eq(props.deviceName, "physdev_added_xx")) {
3255                     found_added_count++;
3256                 }
3257             }
3258         }
3259         for (uint32_t incomp = 0; incomp < icd_groups; ++incomp) {
3260             if (GroupsAreTheSame(not_exp_phys_dev_groups[incomp], phys_dev_groups[grp])) {
3261                 found_incomplete++;
3262                 break;
3263             }
3264         }
3265     }
3266 
3267     // We should have added the number of diff items, and the incomplete count should match the number of
3268     // original physical devices.
3269     ASSERT_EQ(found_added_count, diff_count);
3270     ASSERT_EQ(found_incomplete, icd_groups);
3271 }
3272 
TEST(LayerPhysDeviceMod,RemovePhysicalDeviceGroups)3273 TEST(LayerPhysDeviceMod, RemovePhysicalDeviceGroups) {
3274     FrameworkEnvironment env;
3275     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
3276     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
3277                                                          .set_name("VkLayer_LunarG_remove_phys_dev")
3278                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
3279                                                          .set_api_version(VK_API_VERSION_1_1)
3280                                                          .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")),
3281                            "test_layer_remove.json");
3282 
3283     auto& layer = env.get_test_layer(0);
3284     layer.set_remove_phys_devs(true);
3285 
3286     for (uint32_t icd = 0; icd < 2; ++icd) {
3287         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
3288         auto& cur_icd = env.get_test_icd(icd);
3289         cur_icd.icd_api_version = VK_API_VERSION_1_2;
3290         VkPhysicalDeviceProperties properties{};
3291         properties.apiVersion = VK_API_VERSION_1_2;
3292         properties.vendorID = 0x11000000 + (icd << 6);
3293         for (uint32_t dev = 0; dev < 3; ++dev) {
3294             properties.deviceID = properties.vendorID + dev;
3295             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
3296             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
3297 #if defined(_WIN32)
3298             strncpy_s(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3299 #else
3300             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3301 #endif
3302             cur_icd.add_physical_device({});
3303             cur_icd.physical_devices.back().set_properties(properties);
3304         }
3305         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
3306         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
3307         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
3308     }
3309     const uint32_t icd_groups = 4;
3310 
3311     InstWrapper inst{env.vulkan_functions};
3312     inst.create_info.set_api_version(VK_API_VERSION_1_1);
3313     inst.CheckCreate();
3314 
3315     uint32_t grp_count = 0;
3316     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
3317     ASSERT_LT(grp_count, icd_groups);
3318 
3319     auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
3320     for (uint32_t group = 0; group < grp_count; ++group) {
3321         phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
3322     }
3323     uint32_t returned_group_count = grp_count;
3324     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
3325     ASSERT_EQ(grp_count, returned_group_count);
3326 }
3327 
TEST(LayerPhysDeviceMod,ReorderPhysicalDeviceGroups)3328 TEST(LayerPhysDeviceMod, ReorderPhysicalDeviceGroups) {
3329     FrameworkEnvironment env;
3330     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
3331     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
3332                                                          .set_name("VkLayer_LunarG_reorder_phys_dev")
3333                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
3334                                                          .set_api_version(VK_API_VERSION_1_1)
3335                                                          .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")),
3336                            "test_layer_reorder.json");
3337 
3338     auto& layer = env.get_test_layer(0);
3339     layer.set_reorder_phys_devs(true);
3340 
3341     for (uint32_t icd = 0; icd < 2; ++icd) {
3342         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
3343         auto& cur_icd = env.get_test_icd(icd);
3344         cur_icd.icd_api_version = VK_API_VERSION_1_2;
3345         VkPhysicalDeviceProperties properties{};
3346         properties.apiVersion = VK_API_VERSION_1_2;
3347         properties.vendorID = 0x11000000 + (icd << 6);
3348         for (uint32_t dev = 0; dev < 3; ++dev) {
3349             properties.deviceID = properties.vendorID + dev;
3350             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
3351             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
3352 #if defined(_WIN32)
3353             strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
3354 #else
3355             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3356 #endif
3357             cur_icd.add_physical_device({});
3358             cur_icd.physical_devices.back().set_properties(properties);
3359         }
3360         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
3361         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
3362         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
3363     }
3364     const uint32_t icd_groups = 4;
3365 
3366     InstWrapper inst{env.vulkan_functions};
3367     inst.create_info.set_api_version(VK_API_VERSION_1_1);
3368     inst.CheckCreate();
3369 
3370     uint32_t grp_count = 0;
3371     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
3372     ASSERT_EQ(grp_count, icd_groups);
3373 
3374     auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
3375     for (uint32_t group = 0; group < grp_count; ++group) {
3376         phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
3377     }
3378     uint32_t returned_group_count = grp_count;
3379     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
3380     ASSERT_EQ(grp_count, returned_group_count);
3381 }
3382 
TEST(LayerPhysDeviceMod,AddRemoveAndReorderPhysicalDeviceGroups)3383 TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDeviceGroups) {
3384     FrameworkEnvironment env;
3385     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
3386     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
3387                                                          .set_name("VkLayer_LunarG_all_phys_dev")
3388                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
3389                                                          .set_api_version(VK_API_VERSION_1_1)
3390                                                          .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")),
3391                            "test_layer_all.json");
3392 
3393     auto& layer = env.get_test_layer(0);
3394     layer.set_add_phys_devs(true).set_remove_phys_devs(true).set_reorder_phys_devs(true);
3395 
3396     for (uint32_t icd = 0; icd < 2; ++icd) {
3397         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
3398         auto& cur_icd = env.get_test_icd(icd);
3399         cur_icd.icd_api_version = VK_API_VERSION_1_2;
3400         VkPhysicalDeviceProperties properties{};
3401         properties.apiVersion = VK_API_VERSION_1_2;
3402         properties.vendorID = 0x11000000 + (icd << 6);
3403         for (uint32_t dev = 0; dev < 3; ++dev) {
3404             properties.deviceID = properties.vendorID + dev;
3405             properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
3406             auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev);
3407 #if defined(_WIN32)
3408             strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
3409 #else
3410             strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
3411 #endif
3412             cur_icd.add_physical_device({});
3413             cur_icd.physical_devices.back().set_properties(properties);
3414         }
3415         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
3416         cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
3417         cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
3418     }
3419     const uint32_t icd_groups = 4;
3420 
3421     InstWrapper inst{env.vulkan_functions};
3422     inst.create_info.set_api_version(VK_API_VERSION_1_1);
3423     inst.CheckCreate();
3424 
3425     uint32_t grp_count = 0;
3426     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
3427     ASSERT_GT(grp_count, icd_groups);
3428 
3429     auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
3430     for (uint32_t group = 0; group < grp_count; ++group) {
3431         phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
3432     }
3433     uint32_t returned_group_count = grp_count;
3434     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
3435     ASSERT_EQ(grp_count, returned_group_count);
3436 
3437     uint32_t diff_count = grp_count - icd_groups;
3438     uint32_t found_added_count = 0;
3439     for (uint32_t grp = 0; grp < grp_count; ++grp) {
3440         // Shortcut, only groups with 1 device could be added in the newly added count
3441         if (1 == phys_dev_groups[grp].physicalDeviceCount) {
3442             for (uint32_t dev = 0; dev < phys_dev_groups[grp].physicalDeviceCount; ++dev) {
3443                 VkPhysicalDeviceProperties props{};
3444                 inst->vkGetPhysicalDeviceProperties(phys_dev_groups[grp].physicalDevices[dev], &props);
3445                 if (string_eq(props.deviceName, "physdev_added_xx")) {
3446                     found_added_count++;
3447                 }
3448             }
3449         }
3450     }
3451 
3452     // Should see 2 devices removed which should result in 1 group removed and since 3
3453     // devices were added we should have 3 new groups.  So we should have a diff of 2
3454     // groups and 3 new groups
3455     ASSERT_EQ(2U, diff_count);
3456     ASSERT_EQ(found_added_count, 3U);
3457 }
3458