• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 The Khronos Group Inc.
3  * Copyright (c) 2021-2023 Valve Corporation
4  * Copyright (c) 2021-2023 LunarG, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and/or associated documentation files (the "Materials"), to
8  * deal in the Materials without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Materials, and to permit persons to whom the Materials are
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice(s) and this permission notice shall be included in
14  * all copies or substantial portions of the Materials.
15  *
16  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  *
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23  * USE OR OTHER DEALINGS IN THE MATERIALS.
24  *
25  * Author: Charles Giessen <charles@lunarg.com>
26  */
27 
28 #include "test_environment.h"
29 
TEST(ICDInterfaceVersion2Plus,vk_icdNegotiateLoaderICDInterfaceVersion)30 TEST(ICDInterfaceVersion2Plus, vk_icdNegotiateLoaderICDInterfaceVersion) {
31     FrameworkEnvironment env{};
32     auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
33 
34     for (uint32_t i = 0; i <= 6; i++) {
35         for (uint32_t j = i; j <= 6; j++) {
36             driver.set_min_icd_interface_version(i).set_max_icd_interface_version(j);
37             InstWrapper inst{env.vulkan_functions};
38             inst.CheckCreate();
39         }
40     }
41 }
42 
TEST(ICDInterfaceVersion2Plus,version_3)43 TEST(ICDInterfaceVersion2Plus, version_3) {
44     FrameworkEnvironment env{};
45     auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
46     {
47         driver.set_min_icd_interface_version(2).set_enable_icd_wsi(true);
48         InstWrapper inst{env.vulkan_functions};
49         inst.CheckCreate();
50 
51         ASSERT_FALSE(driver.is_using_icd_wsi);
52     }
53     {
54         driver.set_min_icd_interface_version(3).set_enable_icd_wsi(false);
55         InstWrapper inst{env.vulkan_functions};
56         inst.CheckCreate();
57 
58         ASSERT_FALSE(driver.is_using_icd_wsi);
59     }
60     {
61         driver.set_min_icd_interface_version(3).set_enable_icd_wsi(true);
62         InstWrapper inst{env.vulkan_functions};
63         inst.CheckCreate();
64 
65         ASSERT_TRUE(driver.is_using_icd_wsi);
66     }
67 }
68 
TEST(ICDInterfaceVersion2Plus,version_4)69 TEST(ICDInterfaceVersion2Plus, version_4) {
70     FrameworkEnvironment env{};
71     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device("physical_device_0");
72     InstWrapper inst{env.vulkan_functions};
73     inst.CheckCreate();
74 }
75 
TEST(ICDInterfaceVersion2Plus,l4_icd4)76 TEST(ICDInterfaceVersion2Plus, l4_icd4) {
77     // TODO:
78     // ICD must fail with VK_ERROR_INCOMPATIBLE_DRIVER for all vkCreateInstance calls with apiVersion set to > Vulkan 1.0
79     // because both the loader and ICD support interface version <= 4. Otherwise, the ICD should behave as normal.
80 }
TEST(ICDInterfaceVersion2Plus,l4_icd5)81 TEST(ICDInterfaceVersion2Plus, l4_icd5) {
82     // TODO:
83     // ICD must fail with VK_ERROR_INCOMPATIBLE_DRIVER for all vkCreateInstance calls with apiVersion set to > Vulkan 1.0
84     // because the loader is still at interface version <= 4. Otherwise, the ICD should behave as normal.
85 }
TEST(ICDInterfaceVersion2Plus,l5_icd4)86 TEST(ICDInterfaceVersion2Plus, l5_icd4) {
87     // TODO:
88     // Loader will fail with VK_ERROR_INCOMPATIBLE_DRIVER if it can't handle the apiVersion. ICD may pass for all apiVersions,
89     // but since its interface is <= 4, it is best if it assumes it needs to do the work of rejecting anything > Vulkan 1.0 and
90     // fail with VK_ERROR_INCOMPATIBLE_DRIVER. Otherwise, the ICD should behave as normal.
91 }
TEST(ICDInterfaceVersion2Plus,l5_icd5)92 TEST(ICDInterfaceVersion2Plus, l5_icd5) {
93     // TODO:
94     // Loader will fail with VK_ERROR_INCOMPATIBLE_DRIVER if it can't handle the apiVersion, and ICDs should fail with
95     // VK_ERROR_INCOMPATIBLE_DRIVER only if they can not support the specified apiVersion. Otherwise, the ICD should behave as
96     // normal.
97 }
98 
99 #if defined(WIN32)
100 // This test makes sure that EnumerateAdapterPhysicalDevices on drivers found in the Khronos/Vulkan/Drivers registry
TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices,version_6_in_drivers_registry)101 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, version_6_in_drivers_registry) {
102     FrameworkEnvironment env{};
103     auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES));
104     driver.physical_devices.emplace_back("physical_device_1");
105     driver.physical_devices.emplace_back("physical_device_0");
106     uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
107     uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
108     std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
109 
110     driver.min_icd_interface_version = 5;
111 
112     auto& known_driver = known_driver_list.at(2);  // which drive this test pretends to be
113     DXGI_ADAPTER_DESC1 desc1{};
114     desc1.AdapterLuid = _LUID{10, 1000};
115     desc1.VendorId = known_driver.vendor_id;
116     env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
117     driver.set_adapterLUID(desc1.AdapterLuid);
118 
119     InstWrapper inst{env.vulkan_functions};
120     inst.CheckCreate();
121 
122     ASSERT_EQ(VK_SUCCESS,
123               env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
124     ASSERT_EQ(physical_count, returned_physical_count);
125     ASSERT_TRUE(driver.called_enumerate_adapter_physical_devices);
126 }
127 // Make the version_6 driver found through the D3DKMT driver discovery mechanism of the loader
TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices,version_6)128 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, version_6) {
129     FrameworkEnvironment env{};
130     env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_6, VK_API_VERSION_1_3}.set_discovery_type(ManifestDiscoveryType::null_dir));
131     // Version 6 provides a mechanism to allow the loader to sort physical devices.
132     // The loader will only attempt to sort physical devices on an ICD if version 6 of the interface is supported.
133     // This version provides the vk_icdEnumerateAdapterPhysicalDevices function.
134     auto& driver = env.get_test_icd(0);
135     driver.physical_devices.emplace_back("physical_device_1");
136     driver.physical_devices.emplace_back("physical_device_0");
137     uint32_t physical_count = 2;
138     uint32_t returned_physical_count = physical_count;
139     std::vector<VkPhysicalDevice> physical_device_handles{physical_count};
140 
141     driver.min_icd_interface_version = 6;
142 
143     auto& known_driver = known_driver_list.at(2);  // which drive this test pretends to be
144     DXGI_ADAPTER_DESC1 desc1{};
145     desc1.AdapterLuid = _LUID{10, 1000};
146     desc1.VendorId = known_driver.vendor_id;
147     env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
148     driver.set_adapterLUID(desc1.AdapterLuid);
149 
150     env.platform_shim->add_d3dkmt_adapter(
151         D3DKMT_Adapter{0, desc1.AdapterLuid}.add_driver_manifest_path(env.get_icd_manifest_path(0)));
152 
153     InstWrapper inst{env.vulkan_functions};
154     inst.CheckCreate();
155 
156     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
157     ASSERT_EQ(physical_count, returned_physical_count);
158     ASSERT_EQ(VK_SUCCESS,
159               env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
160     ASSERT_EQ(physical_count, returned_physical_count);
161     ASSERT_TRUE(driver.called_enumerate_adapter_physical_devices);
162 
163     // Make sure that the loader doesn't write past the the end of the pointer
164     auto temp_ptr = std::unique_ptr<int>(new int());
165     for (auto& phys_dev : physical_device_handles) {
166         phys_dev = reinterpret_cast<VkPhysicalDevice>(temp_ptr.get());
167     }
168 
169     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
170     returned_physical_count = 0;
171     ASSERT_EQ(VK_INCOMPLETE,
172               env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
173     ASSERT_EQ(0U, returned_physical_count);
174     for (auto& phys_dev : physical_device_handles) {
175         ASSERT_EQ(phys_dev, reinterpret_cast<VkPhysicalDevice>(temp_ptr.get()));
176     }
177 }
178 
179 // Declare drivers using the D3DKMT driver interface and make sure the loader can find them - but don't export
180 // EnumerateAdapterPhysicalDevices
TEST(ICDInterfaceVersion2,EnumAdapters2)181 TEST(ICDInterfaceVersion2, EnumAdapters2) {
182     FrameworkEnvironment env{};
183     auto& driver =
184         env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA}.set_discovery_type(ManifestDiscoveryType::null_dir));
185     InstWrapper inst{env.vulkan_functions};
186     driver.physical_devices.emplace_back("physical_device_1");
187     driver.physical_devices.emplace_back("physical_device_0");
188     uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
189     uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
190     std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
191     driver.adapterLUID = _LUID{10, 1000};
192     env.platform_shim->add_d3dkmt_adapter(D3DKMT_Adapter{0, _LUID{10, 1000}}.add_driver_manifest_path(env.get_icd_manifest_path()));
193 
194     inst.CheckCreate();
195 
196     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
197     ASSERT_EQ(physical_count, returned_physical_count);
198     ASSERT_EQ(VK_SUCCESS,
199               env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
200     ASSERT_EQ(physical_count, returned_physical_count);
201     ASSERT_FALSE(driver.called_enumerate_adapter_physical_devices);
202 }
203 
204 // Make sure that physical devices are found through EnumerateAdapterPhysicalDevices
205 // Verify that the handles are correct by calling vkGetPhysicalDeviceProperties with them
TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices,VerifyPhysDevResults)206 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyPhysDevResults) {
207     FrameworkEnvironment env{};
208     auto& driver =
209         env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES, VK_API_VERSION_1_1}
210                         .set_discovery_type(ManifestDiscoveryType::null_dir))
211             .set_min_icd_interface_version(6)
212             .set_icd_api_version(VK_API_VERSION_1_1);
213     const std::vector<std::string> physical_device_names = {"physical_device_4", "physical_device_3", "physical_device_2",
214                                                             "physical_device_1", "physical_device_0"};
215     for (const auto& dev_name : physical_device_names) driver.physical_devices.push_back(dev_name);
216 
217     auto& known_driver = known_driver_list.at(2);  // which drive this test pretends to be
218     DXGI_ADAPTER_DESC1 desc1{};
219     desc1.VendorId = known_driver.vendor_id;
220     desc1.AdapterLuid = _LUID{10, 1000};
221     env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
222     driver.set_adapterLUID(desc1.AdapterLuid);
223 
224     env.platform_shim->add_d3dkmt_adapter(D3DKMT_Adapter{0, _LUID{10, 1000}}.add_driver_manifest_path(env.get_icd_manifest_path()));
225 
226     InstWrapper inst{env.vulkan_functions};
227     inst.CheckCreate();
228 
229     const size_t phys_dev_count = physical_device_names.size();
230 
231     // The test ICD should completely swap the order of devices.
232     // Since we can't compare VkPhysicalDevice handles because they will be different per VkInstance, we will
233     // compare the property names returned, which should still be equal.
234 
235     std::vector<VkPhysicalDevice> adapter_pds{phys_dev_count};
236     uint32_t count = static_cast<uint32_t>(adapter_pds.size());
237     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &count, adapter_pds.data()));
238     ASSERT_EQ(phys_dev_count, count);
239 
240     for (uint32_t dev = 0; dev < phys_dev_count; ++dev) {
241         VkPhysicalDeviceProperties props;
242         env.vulkan_functions.vkGetPhysicalDeviceProperties(adapter_pds[dev], &props);
243         std::string dev_name = props.deviceName;
244         // index in reverse
245         ASSERT_EQ(dev_name, physical_device_names[physical_device_names.size() - 1 - dev]);
246     }
247 }
248 
249 // Make sure physical device groups enumerated through EnumerateAdapterPhysicalDevices are properly found
TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices,VerifyGroupResults)250 TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults) {
251     FrameworkEnvironment env{};
252     auto& driver =
253         env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES, VK_API_VERSION_1_1}
254                         .set_discovery_type(ManifestDiscoveryType::null_dir))
255             .set_min_icd_interface_version(6)
256             .set_icd_api_version(VK_API_VERSION_1_1);
257     const std::vector<std::string> physical_device_names = {"physical_device_4", "physical_device_3", "physical_device_2",
258                                                             "physical_device_1", "physical_device_0"};
259     for (const auto& dev_name : physical_device_names) {
260         driver.physical_devices.push_back(dev_name);
261     }
262 
263     driver.physical_device_groups.emplace_back(driver.physical_devices[0]).use_physical_device(driver.physical_devices[1]);
264     driver.physical_device_groups.emplace_back(driver.physical_devices[2]);
265     driver.physical_device_groups.emplace_back(driver.physical_devices[3]).use_physical_device(driver.physical_devices[4]);
266 
267     auto& known_driver = known_driver_list.at(2);  // which driver this test pretends to be
268     DXGI_ADAPTER_DESC1 desc1{};
269     desc1.VendorId = known_driver.vendor_id;
270     desc1.AdapterLuid = _LUID{10, 1000};
271     env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
272     driver.set_adapterLUID(desc1.AdapterLuid);
273 
274     env.platform_shim->add_d3dkmt_adapter(D3DKMT_Adapter{0, _LUID{10, 1000}}.add_driver_manifest_path(env.get_icd_manifest_path()));
275 
276     InstWrapper inst{env.vulkan_functions};
277     inst.CheckCreate();
278 
279     // The test ICD should completely swap the order of devices.
280     // Since we can't compare VkPhysicalDevice handles because they will be different per VkInstance, we will
281     // compare the property names returned, which should still be equal.
282     // And, since this is device groups, the groups themselves should also be in reverse order with the devices
283     // inside each group in revers order.
284 
285     const uint32_t actual_group_count = 3;
286     uint32_t count = actual_group_count;
287     std::array<VkPhysicalDeviceGroupProperties, actual_group_count> groups{};
288     for (uint32_t group = 0; group < actual_group_count; ++group) {
289         groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
290     }
291     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &count, groups.data()));
292     ASSERT_EQ(actual_group_count, count);
293 
294     size_t cur_device_name_index = physical_device_names.size() - 1;  // start at last index and reverse through it
295     for (uint32_t group = 0; group < actual_group_count; ++group) {
296         for (uint32_t dev = 0; dev < groups[group].physicalDeviceCount; ++dev) {
297             VkPhysicalDeviceProperties props;
298             env.vulkan_functions.vkGetPhysicalDeviceProperties(groups[group].physicalDevices[dev], &props);
299             std::string dev_name = props.deviceName;
300             ASSERT_EQ(dev_name, physical_device_names[cur_device_name_index]);
301             cur_device_name_index--;
302         }
303     }
304 }
305 
306 #endif  // defined(WIN32)
TEST(ICDInterfaceVersion7,SingleDriver)307 TEST(ICDInterfaceVersion7, SingleDriver) {
308     FrameworkEnvironment env{};
309     auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7)).add_physical_device({});
310     InstWrapper inst{env.vulkan_functions};
311     inst.CheckCreate();
312     DeviceWrapper dev{inst};
313     dev.CheckCreate(inst.GetPhysDev());
314     ASSERT_EQ(driver.interface_version_check, InterfaceVersionCheck::version_is_supported);
315 }
316 
TEST(ICDInterfaceVersion7,SingleDriverWithoutExportedFunctions)317 TEST(ICDInterfaceVersion7, SingleDriverWithoutExportedFunctions) {
318     FrameworkEnvironment env{};
319     auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7_WIHTOUT_EXPORTS)).add_physical_device({});
320     InstWrapper inst{env.vulkan_functions};
321     inst.CheckCreate();
322     DeviceWrapper dev{inst};
323     dev.CheckCreate(inst.GetPhysDev());
324     ASSERT_EQ(driver.interface_version_check, InterfaceVersionCheck::version_is_supported);
325 }
326 
TEST(MultipleICDConfig,Basic)327 TEST(MultipleICDConfig, Basic) {
328     FrameworkEnvironment env{};
329     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
330     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
331     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
332 
333     env.get_test_icd(0).physical_devices.emplace_back("physical_device_0");
334     env.get_test_icd(1).physical_devices.emplace_back("physical_device_1");
335     env.get_test_icd(2).physical_devices.emplace_back("physical_device_2");
336 
337     env.get_test_icd(0).physical_devices.at(0).properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
338     env.get_test_icd(1).physical_devices.at(0).properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
339     env.get_test_icd(2).physical_devices.at(0).properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU;
340 
341     copy_string_to_char_array("dev0", env.get_test_icd(0).physical_devices.at(0).properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
342     copy_string_to_char_array("dev1", env.get_test_icd(1).physical_devices.at(0).properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
343     copy_string_to_char_array("dev2", env.get_test_icd(2).physical_devices.at(0).properties.deviceName, VK_MAX_EXTENSION_NAME_SIZE);
344 
345     InstWrapper inst{env.vulkan_functions};
346     inst.CheckCreate();
347 
348     std::array<VkPhysicalDevice, 3> phys_devs_array;
349     uint32_t phys_dev_count = 3;
350     ASSERT_EQ(env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
351     ASSERT_EQ(phys_dev_count, 3U);
352     ASSERT_EQ(env.get_test_icd(0).physical_devices.at(0).properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
353     ASSERT_EQ(env.get_test_icd(1).physical_devices.at(0).properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);
354     ASSERT_EQ(env.get_test_icd(2).physical_devices.at(0).properties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);
355 }
356 
TEST(MultipleDriverConfig,DifferentICDInterfaceVersions)357 TEST(MultipleDriverConfig, DifferentICDInterfaceVersions) {
358     FrameworkEnvironment env{};
359     env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
360     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
361     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
362 
363     TestICD& icd0 = env.get_test_icd(0);
364     icd0.physical_devices.emplace_back("physical_device_0");
365     icd0.max_icd_interface_version = 1;
366 
367     TestICD& icd1 = env.get_test_icd(1);
368     icd1.physical_devices.emplace_back("physical_device_1");
369     icd1.min_icd_interface_version = 2;
370     icd1.max_icd_interface_version = 5;
371 
372     InstWrapper inst{env.vulkan_functions};
373     inst.CheckCreate();
374 
375     std::array<VkPhysicalDevice, 2> phys_devs_array;
376     uint32_t phys_dev_count = 2;
377     ASSERT_EQ(env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
378     ASSERT_EQ(phys_dev_count, 2U);
379 }
380 
TEST(MultipleDriverConfig,DifferentICDsWithDevices)381 TEST(MultipleDriverConfig, DifferentICDsWithDevices) {
382     FrameworkEnvironment env{};
383     env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
384     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
385     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
386 
387     // Make sure the loader returns all devices from all active ICDs.  Many of the other
388     // tests add multiple devices to a single ICD, this just makes sure the loader combines
389     // device info across multiple drivers properly.
390     TestICD& icd0 = env.get_test_icd(0);
391     icd0.physical_devices.emplace_back("physical_device_0");
392     icd0.min_icd_interface_version = 5;
393     icd0.max_icd_interface_version = 5;
394 
395     TestICD& icd1 = env.get_test_icd(1);
396     icd1.physical_devices.emplace_back("physical_device_1");
397     icd1.physical_devices.emplace_back("physical_device_2");
398     icd1.min_icd_interface_version = 5;
399     icd1.max_icd_interface_version = 5;
400 
401     TestICD& icd2 = env.get_test_icd(2);
402     icd2.physical_devices.emplace_back("physical_device_3");
403     icd2.min_icd_interface_version = 5;
404     icd2.max_icd_interface_version = 5;
405 
406     InstWrapper inst{env.vulkan_functions};
407     inst.CheckCreate();
408 
409     std::array<VkPhysicalDevice, 4> phys_devs_array;
410     uint32_t phys_dev_count = 4;
411     ASSERT_EQ(env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
412     ASSERT_EQ(phys_dev_count, 4U);
413 }
414 
TEST(MultipleDriverConfig,DifferentICDsWithDevicesAndGroups)415 TEST(MultipleDriverConfig, DifferentICDsWithDevicesAndGroups) {
416     FrameworkEnvironment env{};
417     env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
418     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
419     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
420 
421     // The loader has to be able to handle drivers that support device groups in combination
422     // with drivers that don't support device groups.  When this is the case, the loader needs
423     // to take every driver that doesn't support device groups and put each of its devices in
424     // a separate group.  Then it combines that information with the drivers that support
425     // device groups returned info.
426 
427     // ICD 0 :  No 1.1 support (so 1 device will become 1 group in loader)
428     TestICD& icd0 = env.get_test_icd(0);
429     icd0.physical_devices.emplace_back("physical_device_0");
430     icd0.min_icd_interface_version = 5;
431     icd0.max_icd_interface_version = 5;
432     icd0.set_icd_api_version(VK_API_VERSION_1_0);
433 
434     // ICD 1 :  1.1 support (with 1 group with 2 devices)
435     TestICD& icd1 = env.get_test_icd(1);
436     icd1.physical_devices.emplace_back("physical_device_1").set_api_version(VK_API_VERSION_1_1);
437     icd1.physical_devices.emplace_back("physical_device_2").set_api_version(VK_API_VERSION_1_1);
438     icd1.physical_device_groups.emplace_back(icd1.physical_devices[0]);
439     icd1.physical_device_groups.back().use_physical_device(icd1.physical_devices[1]);
440     icd1.min_icd_interface_version = 5;
441     icd1.max_icd_interface_version = 5;
442     icd1.set_icd_api_version(VK_API_VERSION_1_1);
443 
444     // ICD 2 :  No 1.1 support (so 3 devices will become 3 groups in loader)
445     TestICD& icd2 = env.get_test_icd(2);
446     icd2.physical_devices.emplace_back("physical_device_3");
447     icd2.physical_devices.emplace_back("physical_device_4");
448     icd2.physical_devices.emplace_back("physical_device_5");
449     icd2.min_icd_interface_version = 5;
450     icd2.max_icd_interface_version = 5;
451     icd2.set_icd_api_version(VK_API_VERSION_1_0);
452 
453     InstWrapper inst{env.vulkan_functions};
454     inst.create_info.set_api_version(1, 1, 0);
455     inst.CheckCreate();
456 
457     uint32_t group_count = static_cast<uint32_t>(5);
458     uint32_t returned_group_count = 0;
459     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, nullptr));
460     ASSERT_EQ(group_count, returned_group_count);
461 
462     std::vector<VkPhysicalDeviceGroupProperties> group_props{};
463     group_props.resize(group_count, VkPhysicalDeviceGroupProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
464     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, group_props.data()));
465     ASSERT_EQ(group_count, returned_group_count);
466 }
467 
468 #if defined(WIN32)
469 // This is testing when there are drivers that support the Windows device adapter sorting mechanism by exporting
470 // EnumerateAdapterPhysicalDevices and drivers that do not expose that functionality
TEST(MultipleICDConfig,version_5_and_version_6)471 TEST(MultipleICDConfig, version_5_and_version_6) {
472     FrameworkEnvironment env;
473 
474     const char* regular_layer_name = "VK_LAYER_TestLayer1";
475     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
476                                                          .set_name(regular_layer_name)
477                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
478                                                          .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))
479                                                          .set_disable_environment("DisableMeIfYouCan")),
480                            "regular_test_layer.json");
481 
482     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
483 
484     uint32_t physical_count = 0;
485     for (uint32_t i = 0; i < 3; i++) {
486         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES));
487         env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
488         auto& driver_5 = env.get_test_icd(i * 2 + 1);
489         driver_5.set_max_icd_interface_version(5);
490         driver_5.set_min_icd_interface_version(5);
491         driver_5.setup_WSI();
492         driver_5.physical_devices.push_back({});
493         driver_5.physical_devices.back().queue_family_properties.push_back(family_props);
494         driver_5.physical_devices.push_back({});
495         driver_5.physical_devices.back().queue_family_properties.push_back(family_props);
496         driver_5.physical_devices.push_back({});
497         driver_5.physical_devices.back().queue_family_properties.push_back(family_props);
498         physical_count += static_cast<uint32_t>(driver_5.physical_devices.size());
499 
500         auto& driver_6 = env.get_test_icd(i * 2);
501         driver_6.setup_WSI();
502         driver_6.physical_devices.emplace_back("physical_device_0");
503         driver_6.physical_devices.back().queue_family_properties.push_back(family_props);
504         driver_6.physical_devices.emplace_back("physical_device_1");
505         driver_6.physical_devices.back().queue_family_properties.push_back(family_props);
506         physical_count += static_cast<uint32_t>(driver_6.physical_devices.size());
507 
508         driver_6.set_max_icd_interface_version(6);
509         driver_6.set_min_icd_interface_version(5);
510 
511         uint32_t driver_index = i % 4;  // which drive this test pretends to be, must stay below 4
512         auto& known_driver = known_driver_list.at(driver_index);
513         DXGI_ADAPTER_DESC1 desc1{};
514         desc1.VendorId = known_driver.vendor_id;
515         desc1.AdapterLuid = LUID{100 + i, static_cast<LONG>(100 + i)};
516         driver_6.set_adapterLUID(desc1.AdapterLuid);
517         env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
518     }
519     uint32_t returned_physical_count = 0;
520     InstWrapper inst{env.vulkan_functions};
521     inst.create_info.setup_WSI();
522     inst.CheckCreate();
523 
524     ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
525     ASSERT_EQ(physical_count, returned_physical_count);
526     std::vector<VkPhysicalDevice> physical_device_handles{returned_physical_count};
527     ASSERT_EQ(VK_SUCCESS,
528               env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
529     ASSERT_EQ(physical_count, returned_physical_count);
530 
531     VkSurfaceKHR surface{};
532     ASSERT_EQ(VK_SUCCESS, create_surface(inst, surface));
533     for (const auto& handle : physical_device_handles) {
534         handle_assert_has_value(handle);
535 
536         VkBool32 supported = false;
537         EXPECT_EQ(VK_SUCCESS, env.vulkan_functions.vkGetPhysicalDeviceSurfaceSupportKHR(handle, 0, surface, &supported));
538     }
539     for (uint32_t i = 0; i < 3; i++) {
540         auto& driver_6 = env.get_test_icd(i * 2);
541         EXPECT_EQ(driver_6.called_enumerate_adapter_physical_devices, true);
542     }
543 }
544 #endif  // defined(WIN32)
545 
546 // shim function pointers for 1.3
547 // Should use autogen for this - it generates 'shim' functions for validation layers, maybe that could be used here.
test_vkCmdBeginRendering(VkCommandBuffer,const VkRenderingInfo *)548 void test_vkCmdBeginRendering(VkCommandBuffer, const VkRenderingInfo*) {}
test_vkCmdBindVertexBuffers2(VkCommandBuffer,uint32_t,uint32_t,const VkBuffer *,const VkDeviceSize *,const VkDeviceSize *,const VkDeviceSize *)549 void test_vkCmdBindVertexBuffers2(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer*, const VkDeviceSize*, const VkDeviceSize*,
550                                   const VkDeviceSize*) {}
test_vkCmdBlitImage2(VkCommandBuffer,const VkBlitImageInfo2 *)551 void test_vkCmdBlitImage2(VkCommandBuffer, const VkBlitImageInfo2*) {}
test_vkCmdCopyBuffer2(VkCommandBuffer,const VkCopyBufferInfo2 *)552 void test_vkCmdCopyBuffer2(VkCommandBuffer, const VkCopyBufferInfo2*) {}
test_vkCmdCopyBufferToImage2(VkCommandBuffer,const VkCopyBufferToImageInfo2 *)553 void test_vkCmdCopyBufferToImage2(VkCommandBuffer, const VkCopyBufferToImageInfo2*) {}
test_vkCmdCopyImage2(VkCommandBuffer,const VkCopyImageInfo2 *)554 void test_vkCmdCopyImage2(VkCommandBuffer, const VkCopyImageInfo2*) {}
test_vkCmdCopyImageToBuffer2(VkCommandBuffer,const VkCopyImageToBufferInfo2 *)555 void test_vkCmdCopyImageToBuffer2(VkCommandBuffer, const VkCopyImageToBufferInfo2*) {}
test_vkCmdEndRendering(VkCommandBuffer)556 void test_vkCmdEndRendering(VkCommandBuffer) {}
test_vkCmdPipelineBarrier2(VkCommandBuffer,const VkDependencyInfo *)557 void test_vkCmdPipelineBarrier2(VkCommandBuffer, const VkDependencyInfo*) {}
test_vkCmdResetEvent2(VkCommandBuffer,VkEvent,VkPipelineStageFlags2)558 void test_vkCmdResetEvent2(VkCommandBuffer, VkEvent, VkPipelineStageFlags2) {}
test_vkCmdResolveImage2(VkCommandBuffer,const VkResolveImageInfo2 *)559 void test_vkCmdResolveImage2(VkCommandBuffer, const VkResolveImageInfo2*) {}
test_vkCmdSetCullMode(VkCommandBuffer,VkCullModeFlags)560 void test_vkCmdSetCullMode(VkCommandBuffer, VkCullModeFlags) {}
test_vkCmdSetDepthBiasEnable(VkCommandBuffer,VkBool32)561 void test_vkCmdSetDepthBiasEnable(VkCommandBuffer, VkBool32) {}
test_vkCmdSetDepthBoundsTestEnable(VkCommandBuffer,VkBool32)562 void test_vkCmdSetDepthBoundsTestEnable(VkCommandBuffer, VkBool32) {}
test_vkCmdSetDepthCompareOp(VkCommandBuffer,VkCompareOp)563 void test_vkCmdSetDepthCompareOp(VkCommandBuffer, VkCompareOp) {}
test_vkCmdSetDepthTestEnable(VkCommandBuffer,VkBool32)564 void test_vkCmdSetDepthTestEnable(VkCommandBuffer, VkBool32) {}
test_vkCmdSetDepthWriteEnable(VkCommandBuffer,VkBool32)565 void test_vkCmdSetDepthWriteEnable(VkCommandBuffer, VkBool32) {}
test_vkCmdSetEvent2(VkCommandBuffer,VkEvent,const VkDependencyInfo *)566 void test_vkCmdSetEvent2(VkCommandBuffer, VkEvent, const VkDependencyInfo*) {}
test_vkCmdSetFrontFace(VkCommandBuffer,VkFrontFace)567 void test_vkCmdSetFrontFace(VkCommandBuffer, VkFrontFace) {}
test_vkCmdSetPrimitiveRestartEnable(VkCommandBuffer,VkBool32)568 void test_vkCmdSetPrimitiveRestartEnable(VkCommandBuffer, VkBool32) {}
test_vkCmdSetPrimitiveTopology(VkCommandBuffer,VkPrimitiveTopology)569 void test_vkCmdSetPrimitiveTopology(VkCommandBuffer, VkPrimitiveTopology) {}
test_vkCmdSetRasterizerDiscardEnable(VkCommandBuffer,VkBool32)570 void test_vkCmdSetRasterizerDiscardEnable(VkCommandBuffer, VkBool32) {}
test_vkCmdSetScissorWithCount(VkCommandBuffer,uint32_t,const VkRect2D *)571 void test_vkCmdSetScissorWithCount(VkCommandBuffer, uint32_t, const VkRect2D*) {}
test_vkCmdSetStencilOp(VkCommandBuffer,VkStencilFaceFlags,VkStencilOp,VkStencilOp,VkStencilOp,VkCompareOp)572 void test_vkCmdSetStencilOp(VkCommandBuffer, VkStencilFaceFlags, VkStencilOp, VkStencilOp, VkStencilOp, VkCompareOp) {}
test_vkCmdSetStencilTestEnable(VkCommandBuffer,VkBool32)573 void test_vkCmdSetStencilTestEnable(VkCommandBuffer, VkBool32) {}
test_vkCmdSetViewportWithCount(VkCommandBuffer,uint32_t,const VkViewport *)574 void test_vkCmdSetViewportWithCount(VkCommandBuffer, uint32_t, const VkViewport*) {}
test_vkCmdWaitEvents2(VkCommandBuffer,uint32_t,const VkEvent *,const VkDependencyInfo *)575 void test_vkCmdWaitEvents2(VkCommandBuffer, uint32_t, const VkEvent*, const VkDependencyInfo*) {}
test_vkCmdWriteTimestamp2(VkCommandBuffer,VkPipelineStageFlags2,VkQueryPool,uint32_t)576 void test_vkCmdWriteTimestamp2(VkCommandBuffer, VkPipelineStageFlags2, VkQueryPool, uint32_t) {}
test_vkCreatePrivateDataSlot(VkDevice,const VkPrivateDataSlotCreateInfo *,const VkAllocationCallbacks *,VkPrivateDataSlot *)577 VkResult test_vkCreatePrivateDataSlot(VkDevice, const VkPrivateDataSlotCreateInfo*, const VkAllocationCallbacks*,
578                                       VkPrivateDataSlot*) {
579     return VK_SUCCESS;
580 }
test_vkDestroyPrivateDataSlot(VkDevice,VkPrivateDataSlot,const VkAllocationCallbacks *)581 void test_vkDestroyPrivateDataSlot(VkDevice, VkPrivateDataSlot, const VkAllocationCallbacks*) {}
test_vkGetDeviceBufferMemoryRequirements(VkDevice,const VkDeviceBufferMemoryRequirements *,VkMemoryRequirements2 *)582 void test_vkGetDeviceBufferMemoryRequirements(VkDevice, const VkDeviceBufferMemoryRequirements*, VkMemoryRequirements2*) {}
test_vkGetDeviceImageMemoryRequirements(VkDevice,const VkDeviceImageMemoryRequirements *,VkMemoryRequirements2 *)583 void test_vkGetDeviceImageMemoryRequirements(VkDevice, const VkDeviceImageMemoryRequirements*, VkMemoryRequirements2*) {}
test_vkGetDeviceImageSparseMemoryRequirements(VkDevice,const VkDeviceImageMemoryRequirements *,uint32_t *,VkSparseImageMemoryRequirements2 *)584 void test_vkGetDeviceImageSparseMemoryRequirements(VkDevice, const VkDeviceImageMemoryRequirements*, uint32_t*,
585                                                    VkSparseImageMemoryRequirements2*) {}
test_vkGetPrivateData(VkDevice,VkObjectType,uint64_t,VkPrivateDataSlot,uint64_t *)586 void test_vkGetPrivateData(VkDevice, VkObjectType, uint64_t, VkPrivateDataSlot, uint64_t*) {}
test_vkQueueSubmit2(VkQueue,uint32_t,const VkSubmitInfo2 *,VkFence)587 VkResult test_vkQueueSubmit2(VkQueue, uint32_t, const VkSubmitInfo2*, VkFence) { return VK_SUCCESS; }
test_vkSetPrivateData(VkDevice,VkObjectType,uint64_t,VkPrivateDataSlot,uint64_t)588 VkResult test_vkSetPrivateData(VkDevice, VkObjectType, uint64_t, VkPrivateDataSlot, uint64_t) { return VK_SUCCESS; }
589 
TEST(MinorVersionUpdate,Version1_3)590 TEST(MinorVersionUpdate, Version1_3) {
591     FrameworkEnvironment env{};
592     auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
593     driver.physical_devices.back().known_device_functions = {
594         VulkanFunction{"vkCmdBeginRendering", to_vkVoidFunction(test_vkCmdBeginRendering)},
595         VulkanFunction{"vkCmdBindVertexBuffers2", to_vkVoidFunction(test_vkCmdBindVertexBuffers2)},
596         VulkanFunction{"vkCmdBlitImage2", to_vkVoidFunction(test_vkCmdBlitImage2)},
597         VulkanFunction{"vkCmdCopyBuffer2", to_vkVoidFunction(test_vkCmdCopyBuffer2)},
598         VulkanFunction{"vkCmdCopyBufferToImage2", to_vkVoidFunction(test_vkCmdCopyBufferToImage2)},
599         VulkanFunction{"vkCmdCopyImage2", to_vkVoidFunction(test_vkCmdCopyImage2)},
600         VulkanFunction{"vkCmdCopyImageToBuffer2", to_vkVoidFunction(test_vkCmdCopyImageToBuffer2)},
601         VulkanFunction{"vkCmdEndRendering", to_vkVoidFunction(test_vkCmdEndRendering)},
602         VulkanFunction{"vkCmdPipelineBarrier2", to_vkVoidFunction(test_vkCmdPipelineBarrier2)},
603         VulkanFunction{"vkCmdResetEvent2", to_vkVoidFunction(test_vkCmdResetEvent2)},
604         VulkanFunction{"vkCmdResolveImage2", to_vkVoidFunction(test_vkCmdResolveImage2)},
605         VulkanFunction{"vkCmdSetCullMode", to_vkVoidFunction(test_vkCmdSetCullMode)},
606         VulkanFunction{"vkCmdSetDepthBiasEnable", to_vkVoidFunction(test_vkCmdSetDepthBiasEnable)},
607         VulkanFunction{"vkCmdSetDepthBoundsTestEnable", to_vkVoidFunction(test_vkCmdSetDepthBoundsTestEnable)},
608         VulkanFunction{"vkCmdSetDepthCompareOp", to_vkVoidFunction(test_vkCmdSetDepthCompareOp)},
609         VulkanFunction{"vkCmdSetDepthTestEnable", to_vkVoidFunction(test_vkCmdSetDepthTestEnable)},
610         VulkanFunction{"vkCmdSetDepthWriteEnable", to_vkVoidFunction(test_vkCmdSetDepthWriteEnable)},
611         VulkanFunction{"vkCmdSetEvent2", to_vkVoidFunction(test_vkCmdSetEvent2)},
612         VulkanFunction{"vkCmdSetFrontFace", to_vkVoidFunction(test_vkCmdSetFrontFace)},
613         VulkanFunction{"vkCmdSetPrimitiveRestartEnable", to_vkVoidFunction(test_vkCmdSetPrimitiveRestartEnable)},
614         VulkanFunction{"vkCmdSetPrimitiveTopology", to_vkVoidFunction(test_vkCmdSetPrimitiveTopology)},
615         VulkanFunction{"vkCmdSetRasterizerDiscardEnable", to_vkVoidFunction(test_vkCmdSetRasterizerDiscardEnable)},
616         VulkanFunction{"vkCmdSetScissorWithCount", to_vkVoidFunction(test_vkCmdSetScissorWithCount)},
617         VulkanFunction{"vkCmdSetStencilOp", to_vkVoidFunction(test_vkCmdSetStencilOp)},
618         VulkanFunction{"vkCmdSetStencilTestEnable", to_vkVoidFunction(test_vkCmdSetStencilTestEnable)},
619         VulkanFunction{"vkCmdSetViewportWithCount", to_vkVoidFunction(test_vkCmdSetViewportWithCount)},
620         VulkanFunction{"vkCmdWaitEvents2", to_vkVoidFunction(test_vkCmdWaitEvents2)},
621         VulkanFunction{"vkCmdWriteTimestamp2", to_vkVoidFunction(test_vkCmdWriteTimestamp2)},
622         VulkanFunction{"vkCreatePrivateDataSlot", to_vkVoidFunction(test_vkCreatePrivateDataSlot)},
623         VulkanFunction{"vkDestroyPrivateDataSlot", to_vkVoidFunction(test_vkDestroyPrivateDataSlot)},
624         VulkanFunction{"vkGetDeviceBufferMemoryRequirements", to_vkVoidFunction(test_vkGetDeviceBufferMemoryRequirements)},
625         VulkanFunction{"vkGetDeviceImageMemoryRequirements", to_vkVoidFunction(test_vkGetDeviceImageMemoryRequirements)},
626         VulkanFunction{"vkGetDeviceImageSparseMemoryRequirements",
627                        to_vkVoidFunction(test_vkGetDeviceImageSparseMemoryRequirements)},
628         VulkanFunction{"vkGetPrivateData", to_vkVoidFunction(test_vkGetPrivateData)},
629         VulkanFunction{"vkQueueSubmit2", to_vkVoidFunction(test_vkQueueSubmit2)},
630         VulkanFunction{"vkSetPrivateData", to_vkVoidFunction(test_vkSetPrivateData)},
631     };
632     driver.physical_devices.back().add_extension({"VK_SOME_EXT_haha"});
633     InstWrapper inst{env.vulkan_functions};
634     inst.create_info.set_api_version(1, 3, 0);
635     inst.CheckCreate();
636 
637     auto phys_dev = inst.GetPhysDev();
638 
639     PFN_vkGetPhysicalDeviceToolProperties GetPhysicalDeviceToolProperties = inst.load("vkGetPhysicalDeviceToolProperties");
640     uint32_t tool_count = 0;
641     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceToolProperties(phys_dev, &tool_count, nullptr));
642     ASSERT_EQ(tool_count, 0U);
643     VkPhysicalDeviceToolProperties props;
644     ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceToolProperties(phys_dev, &tool_count, &props));
645 
646     DeviceWrapper device{inst};
647     device.CheckCreate(phys_dev);
648 
649     PFN_vkCreateCommandPool CreateCommandPool = device.load("vkCreateCommandPool");
650     PFN_vkAllocateCommandBuffers AllocateCommandBuffers = device.load("vkAllocateCommandBuffers");
651     PFN_vkDestroyCommandPool DestroyCommandPool = device.load("vkDestroyCommandPool");
652     VkCommandPool command_pool{};
653     VkCommandPoolCreateInfo pool_create_info{};
654     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
655     ASSERT_EQ(VK_SUCCESS, CreateCommandPool(device, &pool_create_info, nullptr, &command_pool));
656     VkCommandBufferAllocateInfo buffer_allocate_info{};
657     buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
658     buffer_allocate_info.commandPool = command_pool;
659     buffer_allocate_info.commandBufferCount = 1;
660     VkCommandBuffer command_buffer{};
661     ASSERT_EQ(VK_SUCCESS, AllocateCommandBuffers(device, &buffer_allocate_info, &command_buffer));
662     DestroyCommandPool(device, command_pool, nullptr);
663 
664     PFN_vkCmdBeginRendering CmdBeginRendering = device.load("vkCmdBeginRendering");
665     VkRenderingInfoKHR rendering_info{};
666     CmdBeginRendering(command_buffer, &rendering_info);
667 
668     PFN_vkCmdBindVertexBuffers2 CmdBindVertexBuffers2 = device.load("vkCmdBindVertexBuffers2");
669     CmdBindVertexBuffers2(command_buffer, 0, 0, nullptr, nullptr, nullptr, nullptr);
670 
671     PFN_vkCmdBlitImage2 CmdBlitImage2 = device.load("vkCmdBlitImage2");
672     VkBlitImageInfo2 image_info{};
673     CmdBlitImage2(command_buffer, &image_info);
674 
675     PFN_vkCmdCopyBuffer2 CmdCopyBuffer2 = device.load("vkCmdCopyBuffer2");
676     VkCopyBufferInfo2 copy_info{};
677     CmdCopyBuffer2(command_buffer, &copy_info);
678 
679     PFN_vkCmdCopyBufferToImage2 CmdCopyBufferToImage2 = device.load("vkCmdCopyBufferToImage2");
680     VkCopyBufferToImageInfo2 copy_buf_image{};
681     CmdCopyBufferToImage2(command_buffer, &copy_buf_image);
682 
683     PFN_vkCmdCopyImage2 CmdCopyImage2 = device.load("vkCmdCopyImage2");
684     VkCopyImageInfo2 copy_image_info{};
685     CmdCopyImage2(command_buffer, &copy_image_info);
686 
687     PFN_vkCmdCopyImageToBuffer2 CmdCopyImageToBuffer2 = device.load("vkCmdCopyImageToBuffer2");
688     VkCopyImageToBufferInfo2 copy_image_buf;
689     CmdCopyImageToBuffer2(command_buffer, &copy_image_buf);
690 
691     PFN_vkCmdEndRendering CmdEndRendering = device.load("vkCmdEndRendering");
692     CmdEndRendering(command_buffer);
693 
694     PFN_vkCmdPipelineBarrier2 CmdPipelineBarrier2 = device.load("vkCmdPipelineBarrier2");
695     VkDependencyInfo deps_info;
696     CmdPipelineBarrier2(command_buffer, &deps_info);
697 
698     PFN_vkCmdResetEvent2 CmdResetEvent2 = device.load("vkCmdResetEvent2");
699     CmdResetEvent2(command_buffer, {}, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
700 
701     PFN_vkCmdResolveImage2 CmdResolveImage2 = device.load("vkCmdResolveImage2");
702     VkResolveImageInfo2 resolve_image{};
703     CmdResolveImage2(command_buffer, &resolve_image);
704 
705     PFN_vkCmdSetCullMode CmdSetCullMode = device.load("vkCmdSetCullMode");
706     CmdSetCullMode(command_buffer, VK_CULL_MODE_BACK_BIT);
707 
708     PFN_vkCmdSetDepthBiasEnable CmdSetDepthBiasEnable = device.load("vkCmdSetDepthBiasEnable");
709     CmdSetDepthBiasEnable(command_buffer, true);
710 
711     PFN_vkCmdSetDepthBoundsTestEnable CmdSetDepthBoundsTestEnable = device.load("vkCmdSetDepthBoundsTestEnable");
712     CmdSetDepthBoundsTestEnable(command_buffer, true);
713 
714     PFN_vkCmdSetDepthCompareOp CmdSetDepthCompareOp = device.load("vkCmdSetDepthCompareOp");
715     CmdSetDepthCompareOp(command_buffer, VK_COMPARE_OP_ALWAYS);
716 
717     PFN_vkCmdSetDepthTestEnable CmdSetDepthTestEnable = device.load("vkCmdSetDepthTestEnable");
718     CmdSetDepthTestEnable(command_buffer, true);
719 
720     PFN_vkCmdSetDepthWriteEnable CmdSetDepthWriteEnable = device.load("vkCmdSetDepthWriteEnable");
721     CmdSetDepthWriteEnable(command_buffer, true);
722 
723     PFN_vkCmdSetEvent2 CmdSetEvent2 = device.load("vkCmdSetEvent2");
724     CmdSetEvent2(command_buffer, {}, &deps_info);
725 
726     PFN_vkCmdSetFrontFace CmdSetFrontFace = device.load("vkCmdSetFrontFace");
727     CmdSetFrontFace(command_buffer, VK_FRONT_FACE_CLOCKWISE);
728 
729     PFN_vkCmdSetPrimitiveRestartEnable CmdSetPrimitiveRestartEnable = device.load("vkCmdSetPrimitiveRestartEnable");
730     CmdSetPrimitiveRestartEnable(command_buffer, true);
731 
732     PFN_vkCmdSetPrimitiveTopology CmdSetPrimitiveTopology = device.load("vkCmdSetPrimitiveTopology");
733     CmdSetPrimitiveTopology(command_buffer, VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
734 
735     PFN_vkCmdSetRasterizerDiscardEnable CmdSetRasterizerDiscardEnable = device.load("vkCmdSetRasterizerDiscardEnable");
736     CmdSetRasterizerDiscardEnable(command_buffer, true);
737 
738     PFN_vkCmdSetScissorWithCount CmdSetScissorWithCount = device.load("vkCmdSetScissorWithCount");
739     CmdSetScissorWithCount(command_buffer, 0, nullptr);
740 
741     PFN_vkCmdSetStencilOp CmdSetStencilOp = device.load("vkCmdSetStencilOp");
742     CmdSetStencilOp(command_buffer, VK_STENCIL_FACE_BACK_BIT, VK_STENCIL_OP_DECREMENT_AND_WRAP, VK_STENCIL_OP_DECREMENT_AND_CLAMP,
743                     VK_STENCIL_OP_DECREMENT_AND_WRAP, VK_COMPARE_OP_ALWAYS);
744 
745     PFN_vkCmdSetStencilTestEnable CmdSetStencilTestEnable = device.load("vkCmdSetStencilTestEnable");
746     CmdSetStencilTestEnable(command_buffer, true);
747 
748     PFN_vkCmdSetViewportWithCount CmdSetViewportWithCount = device.load("vkCmdSetViewportWithCount");
749     CmdSetViewportWithCount(command_buffer, 0, nullptr);
750 
751     PFN_vkCmdWaitEvents2 CmdWaitEvents2 = device.load("vkCmdWaitEvents2");
752     CmdWaitEvents2(command_buffer, 0, nullptr, &deps_info);
753 
754     PFN_vkCmdWriteTimestamp2 CmdWriteTimestamp2 = device.load("vkCmdWriteTimestamp2");
755     CmdWriteTimestamp2(command_buffer, VK_PIPELINE_STAGE_2_BLIT_BIT, {}, 0);
756 
757     PFN_vkCreatePrivateDataSlot CreatePrivateDataSlot = device.load("vkCreatePrivateDataSlot");
758     CreatePrivateDataSlot(device, nullptr, nullptr, nullptr);
759     PFN_vkDestroyPrivateDataSlot DestroyPrivateDataSlot = device.load("vkDestroyPrivateDataSlot");
760     DestroyPrivateDataSlot(device, VK_NULL_HANDLE, nullptr);
761     PFN_vkGetDeviceBufferMemoryRequirements GetDeviceBufferMemoryRequirements = device.load("vkGetDeviceBufferMemoryRequirements");
762     GetDeviceBufferMemoryRequirements(device, nullptr, nullptr);
763     PFN_vkGetDeviceImageMemoryRequirements GetDeviceImageMemoryRequirements = device.load("vkGetDeviceImageMemoryRequirements");
764     GetDeviceImageMemoryRequirements(device, nullptr, nullptr);
765     PFN_vkGetDeviceImageSparseMemoryRequirements GetDeviceImageSparseMemoryRequirements =
766         device.load("vkGetDeviceImageSparseMemoryRequirements");
767     GetDeviceImageSparseMemoryRequirements(device, nullptr, nullptr, nullptr);
768     PFN_vkGetPrivateData GetPrivateData = device.load("vkGetPrivateData");
769     GetPrivateData(device, VK_OBJECT_TYPE_UNKNOWN, 0, {}, nullptr);
770     PFN_vkQueueSubmit2 QueueSubmit2 = device.load("vkQueueSubmit2");
771     QueueSubmit2(nullptr, 0, nullptr, VK_NULL_HANDLE);
772     PFN_vkSetPrivateData SetPrivateData = device.load("vkSetPrivateData");
773     SetPrivateData(device, VK_OBJECT_TYPE_UNKNOWN, 0, {}, 0);
774 }
775 
TEST(ApplicationInfoVersion,NonVulkanVariant)776 TEST(ApplicationInfoVersion, NonVulkanVariant) {
777     FrameworkEnvironment env{};
778     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
779 
780     DebugUtilsLogger log;
781     InstWrapper inst{env.vulkan_functions};
782     inst.create_info.set_api_version(VK_MAKE_API_VERSION(1, 0, 0, 0));
783     FillDebugUtilsCreateDetails(inst.create_info, log);
784     inst.CheckCreate();
785     ASSERT_TRUE(log.find(
786         std::string("vkCreateInstance: The API Variant specified in pCreateInfo->pApplicationInfo.apiVersion is 1 instead of "
787                     "the expected value of 0.")));
788 }
789 
TEST(DriverManifest,NonVulkanVariant)790 TEST(DriverManifest, NonVulkanVariant) {
791     FrameworkEnvironment env{};
792     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(1, 1, 0, 0))).add_physical_device({});
793 
794     DebugUtilsLogger log;
795     InstWrapper inst{env.vulkan_functions};
796     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
797     FillDebugUtilsCreateDetails(inst.create_info, log);
798     inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER);
799     ASSERT_TRUE(log.find("loader_parse_icd_manifest: Driver's ICD JSON "));
800     // log prints the path to the file, don't look for it since it is hard to determine inside the test what the path should be.
801     ASSERT_TRUE(log.find("\'api_version\' field contains a non-zero variant value of 1.  Skipping ICD JSON."));
802 }
803 
TEST(LayerManifest,ImplicitNonVulkanVariant)804 TEST(LayerManifest, ImplicitNonVulkanVariant) {
805     FrameworkEnvironment env{};
806     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 0, 0))).add_physical_device({});
807 
808     const char* implicit_layer_name = "ImplicitTestLayer";
809     env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
810                                                          .set_name(implicit_layer_name)
811                                                          .set_api_version(VK_MAKE_API_VERSION(1, 1, 0, 0))
812                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
813                                                          .set_disable_environment("DISABLE_ME")),
814                            "implicit_test_layer.json");
815 
816     DebugUtilsLogger log;
817     InstWrapper inst{env.vulkan_functions};
818     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
819     FillDebugUtilsCreateDetails(inst.create_info, log);
820     inst.CheckCreate();
821     ASSERT_TRUE(log.find(std::string("Layer \"") + implicit_layer_name +
822                          "\" has an \'api_version\' field which contains a non-zero variant value of 1.  Skipping Layer."));
823 }
824 
TEST(LayerManifest,ExplicitNonVulkanVariant)825 TEST(LayerManifest, ExplicitNonVulkanVariant) {
826     FrameworkEnvironment env{};
827     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_MAKE_API_VERSION(0, 1, 0, 0))).add_physical_device({});
828 
829     const char* explicit_layer_name = "ExplicitTestLayer";
830     env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
831                                                          .set_name(explicit_layer_name)
832                                                          .set_api_version(VK_MAKE_API_VERSION(1, 1, 0, 0))
833                                                          .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)),
834                            "explicit_test_layer.json");
835 
836     DebugUtilsLogger log;
837     InstWrapper inst{env.vulkan_functions};
838     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0)).add_layer(explicit_layer_name);
839     FillDebugUtilsCreateDetails(inst.create_info, log);
840     inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
841     ASSERT_TRUE(log.find(std::string("Layer \"") + explicit_layer_name +
842                          "\" has an \'api_version\' field which contains a non-zero variant value of 1.  Skipping Layer."));
843 }
844 
TEST(DriverManifest,UnknownManifestVersion)845 TEST(DriverManifest, UnknownManifestVersion) {
846     FrameworkEnvironment env{};
847     env.add_icd(
848            TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_file_format_version({3, 2, 1})))
849         .add_physical_device({});
850 
851     DebugUtilsLogger log;
852     InstWrapper inst{env.vulkan_functions};
853     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
854     FillDebugUtilsCreateDetails(inst.create_info, log);
855     inst.CheckCreate();
856     ASSERT_TRUE(log.find("loader_parse_icd_manifest: "));
857     // log prints the path to the file, don't look for it since it is hard to determine inside the test what the path should be.
858     ASSERT_TRUE(log.find("has unknown icd manifest file version 3.2.1. May cause errors."));
859 }
860 
TEST(DriverManifest,LargeUnknownManifestVersion)861 TEST(DriverManifest, LargeUnknownManifestVersion) {
862     FrameworkEnvironment env{};
863     env.add_icd(TestICDDetails(
864                     ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_file_format_version({100, 222, 111})))
865         .add_physical_device({});
866 
867     DebugUtilsLogger log;
868     InstWrapper inst{env.vulkan_functions};
869     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
870     FillDebugUtilsCreateDetails(inst.create_info, log);
871     inst.CheckCreate();
872     ASSERT_TRUE(log.find("loader_parse_icd_manifest: "));
873     // log prints the path to the file, don't look for it since it is hard to determine inside the test what the path should be.
874     ASSERT_TRUE(log.find("has unknown icd manifest file version 100.222.111. May cause errors."));
875 }
876 
TEST(LayerManifest,UnknownManifestVersion)877 TEST(LayerManifest, UnknownManifestVersion) {
878     FrameworkEnvironment env{};
879     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
880 
881     const char* implicit_layer_name = "ImplicitTestLayer";
882     env.add_implicit_layer(ManifestLayer{}
883                                .add_layer(ManifestLayer::LayerDescription{}
884                                               .set_name(implicit_layer_name)
885                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
886                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
887                                               .set_disable_environment("DISABLE_ME"))
888                                .set_file_format_version({3, 2, 1}),
889                            "implicit_test_layer.json");
890 
891     DebugUtilsLogger log;
892     InstWrapper inst{env.vulkan_functions};
893     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
894     FillDebugUtilsCreateDetails(inst.create_info, log);
895     inst.CheckCreate();
896     ASSERT_TRUE(log.find("loader_add_layer_properties: "));
897     // log prints the path to the file, don't look for it since it is hard to determine inside the test what the path should be.
898     ASSERT_TRUE(log.find("has unknown layer manifest file version 3.2.1.  May cause errors."));
899 }
900 
TEST(LayerManifest,LargeUnknownManifestVersion)901 TEST(LayerManifest, LargeUnknownManifestVersion) {
902     FrameworkEnvironment env{};
903     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({});
904 
905     const char* implicit_layer_name = "ImplicitTestLayer";
906     env.add_implicit_layer(ManifestLayer{}
907                                .add_layer(ManifestLayer::LayerDescription{}
908                                               .set_name(implicit_layer_name)
909                                               .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
910                                               .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)
911                                               .set_disable_environment("DISABLE_ME"))
912                                .set_file_format_version({100, 222, 111}),
913                            "implicit_test_layer.json");
914 
915     DebugUtilsLogger log;
916     InstWrapper inst{env.vulkan_functions};
917     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
918     FillDebugUtilsCreateDetails(inst.create_info, log);
919     inst.CheckCreate();
920     ASSERT_TRUE(log.find("loader_add_layer_properties: "));
921     // log prints the path to the file, don't look for it since it is hard to determine inside the test what the path should be.
922     ASSERT_TRUE(log.find("has unknown layer manifest file version 100.222.111.  May cause errors."));
923 }
924 
925 struct DriverInfo {
DriverInfoDriverInfo926     DriverInfo(TestICDDetails icd_details, uint32_t driver_version, bool expect_to_find) noexcept
927         : icd_details(icd_details), driver_version(driver_version), expect_to_find(expect_to_find) {}
928     TestICDDetails icd_details;
929     uint32_t driver_version = 0;
930     bool expect_to_find = false;
931 };
932 
CheckDirectDriverLoading(FrameworkEnvironment & env,std::vector<DriverInfo> const & normal_drivers,std::vector<DriverInfo> const & direct_drivers,bool exclusive)933 void CheckDirectDriverLoading(FrameworkEnvironment& env, std::vector<DriverInfo> const& normal_drivers,
934                               std::vector<DriverInfo> const& direct_drivers, bool exclusive) {
935     std::vector<VkDirectDriverLoadingInfoLUNARG> ddl_infos;
936     uint32_t expected_driver_count = 0;
937 
938     for (auto const& driver : direct_drivers) {
939         auto& direct_driver_icd = env.add_icd(driver.icd_details);
940         direct_driver_icd.physical_devices.push_back({});
941         direct_driver_icd.physical_devices.at(0).properties.driverVersion = driver.driver_version;
942         VkDirectDriverLoadingInfoLUNARG ddl_info{};
943         ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
944         ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
945         ddl_infos.push_back(ddl_info);
946         if (driver.expect_to_find) {
947             expected_driver_count++;
948         }
949     }
950 
951     for (auto const& driver : normal_drivers) {
952         auto& direct_driver_icd = env.add_icd(driver.icd_details);
953         direct_driver_icd.physical_devices.push_back({});
954         direct_driver_icd.physical_devices.at(0).properties.driverVersion = driver.driver_version;
955         if (!exclusive && driver.expect_to_find) {
956             expected_driver_count++;
957         }
958     }
959 
960     VkDirectDriverLoadingListLUNARG ddl_list{};
961     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
962     ddl_list.mode = exclusive ? VK_DIRECT_DRIVER_LOADING_MODE_EXCLUSIVE_LUNARG : VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG;
963     ddl_list.driverCount = static_cast<uint32_t>(ddl_infos.size());
964     ddl_list.pDrivers = ddl_infos.data();
965 
966     DebugUtilsLogger log;
967     InstWrapper inst{env.vulkan_functions};
968     FillDebugUtilsCreateDetails(inst.create_info, log);
969     log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
970     inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
971     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
972     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
973 
974     if (exclusive) {
975         ASSERT_TRUE(
976             log.find("loader_scan_for_direct_drivers: The VK_LUNARG_direct_driver_loading extension is active and specified "
977                      "VK_DIRECT_DRIVER_LOADING_MODE_EXCLUSIVE_LUNARG, skipping system and environment "
978                      "variable driver search mechanisms."));
979     }
980 
981     // Make sure all drivers we expect to load were found - including checking that the pfn matches exactly.
982     for (uint32_t i = 0; i < direct_drivers.size(); i++) {
983         if (direct_drivers.at(i).expect_to_find) {
984             std::stringstream ss;
985             ss << "loader_add_direct_driver: Adding driver found in index " << i
986                << " of VkDirectDriverLoadingListLUNARG::pDrivers structure. pfnGetInstanceProcAddr was set to "
987                << reinterpret_cast<const void*>(ddl_infos.at(i).pfnGetInstanceProcAddr);
988             std::string log_message = ss.str();
989             ASSERT_TRUE(log.find(log_message));
990         }
991     }
992 
993     auto phys_devs = inst.GetPhysDevs();
994     ASSERT_EQ(phys_devs.size(), expected_driver_count);
995 
996     // We have to iterate through the driver lists backwards because the loader *prepends* icd's, so the last found ICD is found
997     // first in the driver list
998     uint32_t driver_index = 0;
999     for (size_t i = normal_drivers.size() - 1; i == 0; i--) {
1000         if (normal_drivers.at(i).expect_to_find) {
1001             VkPhysicalDeviceProperties props{};
1002             inst.functions->vkGetPhysicalDeviceProperties(phys_devs.at(driver_index), &props);
1003             ASSERT_EQ(props.driverVersion, normal_drivers.at(i).driver_version);
1004             driver_index++;
1005         }
1006     }
1007     for (size_t i = direct_drivers.size() - 1; i == 0; i--) {
1008         if (direct_drivers.at(i).expect_to_find) {
1009             VkPhysicalDeviceProperties props{};
1010             inst.functions->vkGetPhysicalDeviceProperties(phys_devs.at(driver_index), &props);
1011             ASSERT_EQ(props.driverVersion, direct_drivers.at(i).driver_version);
1012             driver_index++;
1013         }
1014     }
1015 }
1016 
1017 // Only 1 direct driver
TEST(DirectDriverLoading,Individual)1018 TEST(DirectDriverLoading, Individual) {
1019     FrameworkEnvironment env{};
1020     std::vector<DriverInfo> normal_drivers;
1021     std::vector<DriverInfo> direct_drivers;
1022     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 10, true);
1023 
1024     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
1025 }
1026 
1027 // 2 direct drivers
TEST(DirectDriverLoading,MultipleDirectDrivers)1028 TEST(DirectDriverLoading, MultipleDirectDrivers) {
1029     FrameworkEnvironment env{};
1030     std::vector<DriverInfo> normal_drivers;
1031     std::vector<DriverInfo> direct_drivers;
1032     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 13, true);
1033     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 7, true);
1034     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
1035 }
1036 
1037 // Multiple direct drivers with a normal driver in the middle
TEST(DirectDriverLoading,MultipleDirectDriversAndNormalDrivers)1038 TEST(DirectDriverLoading, MultipleDirectDriversAndNormalDrivers) {
1039     FrameworkEnvironment env{};
1040     std::vector<DriverInfo> normal_drivers;
1041     std::vector<DriverInfo> direct_drivers;
1042     normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA), 90, true);
1043     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 80, true);
1044     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 70, true);
1045     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
1046 }
1047 
1048 // Normal driver and direct driver with direct driver exclusivity
TEST(DirectDriverLoading,ExclusiveWithNormalDriver)1049 TEST(DirectDriverLoading, ExclusiveWithNormalDriver) {
1050     FrameworkEnvironment env{};
1051     std::vector<DriverInfo> normal_drivers;
1052     std::vector<DriverInfo> direct_drivers;
1053     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 33, true);
1054     normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2), 44, false);
1055     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
1056 }
1057 
TEST(DirectDriverLoading,ExclusiveWithMultipleNormalDriver)1058 TEST(DirectDriverLoading, ExclusiveWithMultipleNormalDriver) {
1059     FrameworkEnvironment env{};
1060     std::vector<DriverInfo> normal_drivers;
1061     std::vector<DriverInfo> direct_drivers;
1062     normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2), 55, true);
1063     normal_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_2), 66, true);
1064     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 77, true);
1065     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
1066 }
1067 
TEST(DirectDriverLoading,ExclusiveWithDriverEnvVar)1068 TEST(DirectDriverLoading, ExclusiveWithDriverEnvVar) {
1069     FrameworkEnvironment env{};
1070     std::vector<DriverInfo> normal_drivers;
1071     std::vector<DriverInfo> direct_drivers;
1072     normal_drivers.emplace_back(
1073         TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::env_var), 4, false);
1074     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 5, true);
1075     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
1076 }
1077 
TEST(DirectDriverLoading,ExclusiveWithAddDriverEnvVar)1078 TEST(DirectDriverLoading, ExclusiveWithAddDriverEnvVar) {
1079     FrameworkEnvironment env{};
1080     std::vector<DriverInfo> normal_drivers;
1081     std::vector<DriverInfo> direct_drivers;
1082 
1083     normal_drivers.emplace_back(
1084         TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_discovery_type(ManifestDiscoveryType::add_env_var), 6, false);
1085     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 7, true);
1086     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
1087 }
1088 
TEST(DirectDriverLoading,InclusiveWithFilterSelect)1089 TEST(DirectDriverLoading, InclusiveWithFilterSelect) {
1090     FrameworkEnvironment env{};
1091     std::vector<DriverInfo> normal_drivers;
1092     std::vector<DriverInfo> direct_drivers;
1093 
1094     EnvVarWrapper driver_filter_select_env_var{"VK_LOADER_DRIVERS_SELECT", "normal_driver.json"};
1095 
1096     normal_drivers.emplace_back(
1097         TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 8, true);
1098     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 9, true);
1099 
1100     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
1101 }
1102 
TEST(DirectDriverLoading,ExclusiveWithFilterSelect)1103 TEST(DirectDriverLoading, ExclusiveWithFilterSelect) {
1104     FrameworkEnvironment env{};
1105     std::vector<DriverInfo> normal_drivers;
1106     std::vector<DriverInfo> direct_drivers;
1107 
1108     EnvVarWrapper driver_filter_select_env_var{"VK_LOADER_DRIVERS_SELECT", "normal_driver.json"};
1109 
1110     normal_drivers.emplace_back(
1111         TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 10,
1112         false);
1113     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 11, true);
1114 
1115     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
1116 }
1117 
TEST(DirectDriverLoading,InclusiveWithFilterDisable)1118 TEST(DirectDriverLoading, InclusiveWithFilterDisable) {
1119     FrameworkEnvironment env{};
1120     std::vector<DriverInfo> normal_drivers;
1121     std::vector<DriverInfo> direct_drivers;
1122 
1123     EnvVarWrapper driver_filter_disable_env_var{"VK_LOADER_DRIVERS_DISABLE", "normal_driver.json"};
1124 
1125     normal_drivers.emplace_back(
1126         TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 12,
1127         false);
1128     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 13, true);
1129     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, false));
1130 }
1131 
TEST(DirectDriverLoading,ExclusiveWithFilterDisable)1132 TEST(DirectDriverLoading, ExclusiveWithFilterDisable) {
1133     FrameworkEnvironment env{};
1134     std::vector<DriverInfo> normal_drivers;
1135     std::vector<DriverInfo> direct_drivers;
1136 
1137     EnvVarWrapper driver_filter_disable_env_var{"VK_LOADER_DRIVERS_DISABLE", "normal_driver.json"};
1138 
1139     normal_drivers.emplace_back(
1140         TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA).set_disable_icd_inc(true).set_json_name("normal_driver"), 14,
1141         false);
1142     direct_drivers.emplace_back(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none), 15, true);
1143     ASSERT_NO_FATAL_FAILURE(CheckDirectDriverLoading(env, normal_drivers, direct_drivers, true));
1144 }
1145 
1146 // The VK_LUNARG_direct_driver_loading extension is not enabled
TEST(DirectDriverLoading,ExtensionNotEnabled)1147 TEST(DirectDriverLoading, ExtensionNotEnabled) {
1148     FrameworkEnvironment env{};
1149 
1150     auto& direct_driver_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none));
1151     direct_driver_icd.physical_devices.push_back({});
1152 
1153     VkDirectDriverLoadingInfoLUNARG ddl_info{};
1154     ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
1155     ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
1156 
1157     VkDirectDriverLoadingListLUNARG ddl_list{};
1158     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
1159     ddl_list.mode = VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG;
1160     ddl_list.driverCount = 1U;
1161     ddl_list.pDrivers = &ddl_info;
1162 
1163     DebugUtilsLogger log;
1164     InstWrapper inst{env.vulkan_functions};
1165     FillDebugUtilsCreateDetails(inst.create_info, log);
1166     log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1167     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1168     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1169 
1170     ASSERT_TRUE(
1171         log.find("loader_scan_for_direct_drivers: The pNext chain of VkInstanceCreateInfo contained the "
1172                  "VkDirectDriverLoadingListLUNARG structure, but the VK_LUNARG_direct_driver_loading extension was "
1173                  "not enabled."));
1174 }
1175 
1176 // VkDirectDriverLoadingListLUNARG is not in the pNext chain of VkInstanceCreateInfo
TEST(DirectDriverLoading,DriverListNotInPnextChain)1177 TEST(DirectDriverLoading, DriverListNotInPnextChain) {
1178     FrameworkEnvironment env{};
1179 
1180     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
1181 
1182     DebugUtilsLogger log;
1183     InstWrapper inst{env.vulkan_functions};
1184     FillDebugUtilsCreateDetails(inst.create_info, log);
1185     inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1186     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1187     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1188 
1189     ASSERT_TRUE(
1190         log.find("loader_scan_for_direct_drivers: The VK_LUNARG_direct_driver_loading extension was enabled but the pNext chain of "
1191                  "VkInstanceCreateInfo did not contain the "
1192                  "VkDirectDriverLoadingListLUNARG structure."));
1193 }
1194 
1195 // User sets the pDrivers pointer in VkDirectDriverLoadingListLUNARG to nullptr
TEST(DirectDriverLoading,DriverListHasNullDriverPointer)1196 TEST(DirectDriverLoading, DriverListHasNullDriverPointer) {
1197     FrameworkEnvironment env{};
1198 
1199     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
1200 
1201     VkDirectDriverLoadingListLUNARG ddl_list{};
1202     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
1203     ddl_list.mode = VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG;
1204     ddl_list.driverCount = 1U;
1205     ddl_list.pDrivers = nullptr;  // user forgot to set the pDrivers
1206 
1207     DebugUtilsLogger log;
1208     InstWrapper inst{env.vulkan_functions};
1209     FillDebugUtilsCreateDetails(inst.create_info, log);
1210     log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1211     inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1212     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1213     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1214 
1215     ASSERT_TRUE(
1216         log.find("loader_scan_for_direct_drivers: The VkDirectDriverLoadingListLUNARG structure in the pNext chain of "
1217                  "VkInstanceCreateInfo has a NULL pDrivers member."));
1218 }
1219 
1220 // User sets the driverCount in VkDirectDriverLoadingListLUNARG to zero
TEST(DirectDriverLoading,DriverListHasZeroInfoCount)1221 TEST(DirectDriverLoading, DriverListHasZeroInfoCount) {
1222     FrameworkEnvironment env{};
1223 
1224     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
1225 
1226     VkDirectDriverLoadingInfoLUNARG ddl_info{};
1227     ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
1228     ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
1229 
1230     VkDirectDriverLoadingListLUNARG ddl_list{};
1231     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
1232     ddl_list.mode = VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG;
1233     ddl_list.driverCount = 0;  // user set 0 for the info list
1234     ddl_list.pDrivers = &ddl_info;
1235 
1236     DebugUtilsLogger log;
1237     InstWrapper inst{env.vulkan_functions};
1238     FillDebugUtilsCreateDetails(inst.create_info, log);
1239     log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1240     inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1241     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1242     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1243 
1244     ASSERT_TRUE(
1245         log.find("loader_scan_for_direct_drivers: The VkDirectDriverLoadingListLUNARG structure in the pNext chain of "
1246                  "VkInstanceCreateInfo has a non-null pDrivers member but a driverCount member with a value "
1247                  "of zero."));
1248 }
1249 
1250 // pfnGetInstanceProcAddr in VkDirectDriverLoadingInfoLUNARG is nullptr
TEST(DirectDriverLoading,DriverInfoMissingGetInstanceProcAddr)1251 TEST(DirectDriverLoading, DriverInfoMissingGetInstanceProcAddr) {
1252     FrameworkEnvironment env{};
1253 
1254     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none)).add_physical_device({});
1255 
1256     std::array<VkDirectDriverLoadingInfoLUNARG, 2> ddl_infos{};
1257     ddl_infos[0].sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
1258     ddl_infos[0].pfnGetInstanceProcAddr = nullptr;  // user didn't set the pfnGetInstanceProcAddr to the driver's handle
1259 
1260     ddl_infos[1].sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
1261     ddl_infos[1].pfnGetInstanceProcAddr = nullptr;  // user didn't set the pfnGetInstanceProcAddr to the driver's handle
1262 
1263     VkDirectDriverLoadingListLUNARG ddl_list{};
1264     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
1265     ddl_list.mode = VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG;
1266     ddl_list.driverCount = static_cast<uint32_t>(ddl_infos.size());
1267     ddl_list.pDrivers = ddl_infos.data();
1268 
1269     DebugUtilsLogger log;
1270     InstWrapper inst{env.vulkan_functions};
1271     FillDebugUtilsCreateDetails(inst.create_info, log);
1272     log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1273     inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1274     inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1275     ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1276 
1277     ASSERT_TRUE(
1278         log.find("loader_add_direct_driver: VkDirectDriverLoadingInfoLUNARG structure at index 0 contains a NULL pointer for the "
1279                  "pfnGetInstanceProcAddr member, skipping."));
1280     ASSERT_TRUE(
1281         log.find("loader_add_direct_driver: VkDirectDriverLoadingInfoLUNARG structure at index 1 contains a NULL pointer for the "
1282                  "pfnGetInstanceProcAddr member, skipping."));
1283 }
1284 
1285 // test the various error paths in loader_add_direct_driver
TEST(DirectDriverLoading,DriverDoesNotExportNegotiateFunction)1286 TEST(DirectDriverLoading, DriverDoesNotExportNegotiateFunction) {
1287     FrameworkEnvironment env{};
1288 
1289     auto& direct_driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7).set_discovery_type(ManifestDiscoveryType::none))
1290                               .add_physical_device({})
1291                               .set_exposes_vk_icdNegotiateLoaderICDInterfaceVersion(false)
1292                               .set_exposes_vkCreateInstance(false)
1293                               .set_exposes_vkEnumerateInstanceExtensionProperties(false);
1294 
1295     VkDirectDriverLoadingInfoLUNARG ddl_info{};
1296     ddl_info.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG;
1297     ddl_info.pfnGetInstanceProcAddr = env.icds.back().icd_library.get_symbol("vk_icdGetInstanceProcAddr");
1298 
1299     VkDirectDriverLoadingListLUNARG ddl_list{};
1300     ddl_list.sType = VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG;
1301     ddl_list.mode = VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG;
1302     ddl_list.driverCount = 1;
1303     ddl_list.pDrivers = &ddl_info;
1304 
1305     {
1306         DebugUtilsLogger log;
1307         InstWrapper inst{env.vulkan_functions};
1308         FillDebugUtilsCreateDetails(inst.create_info, log);
1309         log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1310         inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1311         inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1312         ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1313 
1314         ASSERT_TRUE(
1315             log.find("loader_add_direct_driver: Could not get 'vk_icdNegotiateLoaderICDInterfaceVersion' from "
1316                      "VkDirectDriverLoadingInfoLUNARG structure at "
1317                      "index 0, skipping."));
1318     }
1319 
1320     // Allow the negotiate function to be found, now it should fail to find instance creation function
1321     direct_driver.set_exposes_vk_icdNegotiateLoaderICDInterfaceVersion(true);
1322     direct_driver.set_max_icd_interface_version(4);
1323 
1324     {
1325         DebugUtilsLogger log;
1326         InstWrapper inst{env.vulkan_functions};
1327         FillDebugUtilsCreateDetails(inst.create_info, log);
1328         log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1329         inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1330         inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1331         ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1332 
1333         ASSERT_TRUE(log.find(
1334             "loader_add_direct_driver: VkDirectDriverLoadingInfoLUNARG structure at index 0 supports interface version 4, "
1335             "which is incompatible with the Loader Driver Interface version that supports the VK_LUNARG_direct_driver_loading "
1336             "extension, skipping."));
1337     }
1338     direct_driver.set_max_icd_interface_version(7);
1339 
1340     {
1341         DebugUtilsLogger log;
1342         InstWrapper inst{env.vulkan_functions};
1343         FillDebugUtilsCreateDetails(inst.create_info, log);
1344         log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1345         inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1346         inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1347         ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1348 
1349         ASSERT_TRUE(
1350             log.find("loader_add_direct_driver: Could not get 'vkEnumerateInstanceExtensionProperties' from "
1351                      "VkDirectDriverLoadingInfoLUNARG structure at index 0, skipping."));
1352     }
1353 
1354     // Allow the instance creation function to be found, now it should fail to find EnumInstExtProps
1355     direct_driver.set_exposes_vkCreateInstance(true);
1356 
1357     {
1358         DebugUtilsLogger log;
1359         InstWrapper inst{env.vulkan_functions};
1360         FillDebugUtilsCreateDetails(inst.create_info, log);
1361         log.get()->pNext = reinterpret_cast<const void*>(&ddl_list);
1362         inst.create_info.add_extension(VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME);
1363         inst.create_info.set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0));
1364         ASSERT_NO_FATAL_FAILURE(inst.CheckCreate(VK_ERROR_INCOMPATIBLE_DRIVER));
1365 
1366         ASSERT_TRUE(
1367             log.find("loader_add_direct_driver: Could not get 'vkEnumerateInstanceExtensionProperties' from "
1368                      "VkDirectDriverLoadingInfoLUNARG structure at index 0, skipping."));
1369     }
1370 }
1371 
TEST(DriverManifest,VersionMismatchWithEnumerateInstanceVersion)1372 TEST(DriverManifest, VersionMismatchWithEnumerateInstanceVersion) {
1373     FrameworkEnvironment env{};
1374     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
1375         .set_icd_api_version(VK_API_VERSION_1_0)
1376         .add_physical_device({});
1377 
1378     InstWrapper inst{env.vulkan_functions};
1379     inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
1380     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1381     inst.CheckCreate();
1382 
1383     ASSERT_TRUE(env.debug_log.find(std::string("terminator_CreateInstance: Manifest ICD for \"") +
1384                                    env.get_test_icd_path().string() +
1385                                    "\" contained a 1.1 or greater API version, but "
1386                                    "vkEnumerateInstanceVersion returned 1.0, treating as a 1.0 ICD"));
1387 }
1388 
TEST(DriverManifest,EnumerateInstanceVersionNotSupported)1389 TEST(DriverManifest, EnumerateInstanceVersionNotSupported) {
1390     FrameworkEnvironment env{};
1391     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1))
1392         .set_icd_api_version(VK_API_VERSION_1_0)
1393         .set_can_query_vkEnumerateInstanceVersion(false)
1394         .add_physical_device({});
1395 
1396     InstWrapper inst{env.vulkan_functions};
1397     inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
1398     FillDebugUtilsCreateDetails(inst.create_info, env.debug_log);
1399     inst.CheckCreate();
1400 
1401     ASSERT_TRUE(env.debug_log.find(std::string("terminator_CreateInstance: Manifest ICD for \"") +
1402                                    env.get_test_icd_path().string() +
1403                                    "\" contained a 1.1 or greater API version, but does "
1404                                    "not support vkEnumerateInstanceVersion, treating as a 1.0 ICD"));
1405 }
1406