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 30TEST(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 43TEST(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 69TEST(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 76TEST(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} 81TEST(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} 86TEST(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} 92TEST(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 101TEST(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 128TEST(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 181TEST(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 206TEST(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 250TEST(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) 307TEST(ICDInterfaceVersion7, SingleDriver) { 308 FrameworkEnvironment env{}; 309 auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7_WITH_ADDITIONAL_EXPORTS)).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 317TEST(ICDInterfaceVersion7, SingleDriverWithoutExportedFunctions) { 318 FrameworkEnvironment env{}; 319 auto& driver = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_7)).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 327TEST(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 357TEST(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 381TEST(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 415TEST(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 471TEST(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. 548void test_vkCmdBeginRendering(VkCommandBuffer, const VkRenderingInfo*) {} 549void test_vkCmdBindVertexBuffers2(VkCommandBuffer, uint32_t, uint32_t, const VkBuffer*, const VkDeviceSize*, const VkDeviceSize*, 550 const VkDeviceSize*) {} 551void test_vkCmdBlitImage2(VkCommandBuffer, const VkBlitImageInfo2*) {} 552void test_vkCmdCopyBuffer2(VkCommandBuffer, const VkCopyBufferInfo2*) {} 553void test_vkCmdCopyBufferToImage2(VkCommandBuffer, const VkCopyBufferToImageInfo2*) {} 554void test_vkCmdCopyImage2(VkCommandBuffer, const VkCopyImageInfo2*) {} 555void test_vkCmdCopyImageToBuffer2(VkCommandBuffer, const VkCopyImageToBufferInfo2*) {} 556void test_vkCmdEndRendering(VkCommandBuffer) {} 557void test_vkCmdPipelineBarrier2(VkCommandBuffer, const VkDependencyInfo*) {} 558void test_vkCmdResetEvent2(VkCommandBuffer, VkEvent, VkPipelineStageFlags2) {} 559void test_vkCmdResolveImage2(VkCommandBuffer, const VkResolveImageInfo2*) {} 560void test_vkCmdSetCullMode(VkCommandBuffer, VkCullModeFlags) {} 561void test_vkCmdSetDepthBiasEnable(VkCommandBuffer, VkBool32) {} 562void test_vkCmdSetDepthBoundsTestEnable(VkCommandBuffer, VkBool32) {} 563void test_vkCmdSetDepthCompareOp(VkCommandBuffer, VkCompareOp) {} 564void test_vkCmdSetDepthTestEnable(VkCommandBuffer, VkBool32) {} 565void test_vkCmdSetDepthWriteEnable(VkCommandBuffer, VkBool32) {} 566void test_vkCmdSetEvent2(VkCommandBuffer, VkEvent, const VkDependencyInfo*) {} 567void test_vkCmdSetFrontFace(VkCommandBuffer, VkFrontFace) {} 568void test_vkCmdSetPrimitiveRestartEnable(VkCommandBuffer, VkBool32) {} 569void test_vkCmdSetPrimitiveTopology(VkCommandBuffer, VkPrimitiveTopology) {} 570void test_vkCmdSetRasterizerDiscardEnable(VkCommandBuffer, VkBool32) {} 571void test_vkCmdSetScissorWithCount(VkCommandBuffer, uint32_t, const VkRect2D*) {} 572void test_vkCmdSetStencilOp(VkCommandBuffer, VkStencilFaceFlags, VkStencilOp, VkStencilOp, VkStencilOp, VkCompareOp) {} 573void test_vkCmdSetStencilTestEnable(VkCommandBuffer, VkBool32) {} 574void test_vkCmdSetViewportWithCount(VkCommandBuffer, uint32_t, const VkViewport*) {} 575void test_vkCmdWaitEvents2(VkCommandBuffer, uint32_t, const VkEvent*, const VkDependencyInfo*) {} 576void test_vkCmdWriteTimestamp2(VkCommandBuffer, VkPipelineStageFlags2, VkQueryPool, uint32_t) {} 577VkResult test_vkCreatePrivateDataSlot(VkDevice, const VkPrivateDataSlotCreateInfo*, const VkAllocationCallbacks*, 578 VkPrivateDataSlot*) { 579 return VK_SUCCESS; 580} 581void test_vkDestroyPrivateDataSlot(VkDevice, VkPrivateDataSlot, const VkAllocationCallbacks*) {} 582void test_vkGetDeviceBufferMemoryRequirements(VkDevice, const VkDeviceBufferMemoryRequirements*, VkMemoryRequirements2*) {} 583void test_vkGetDeviceImageMemoryRequirements(VkDevice, const VkDeviceImageMemoryRequirements*, VkMemoryRequirements2*) {} 584void test_vkGetDeviceImageSparseMemoryRequirements(VkDevice, const VkDeviceImageMemoryRequirements*, uint32_t*, 585 VkSparseImageMemoryRequirements2*) {} 586void test_vkGetPrivateData(VkDevice, VkObjectType, uint64_t, VkPrivateDataSlot, uint64_t*) {} 587VkResult test_vkQueueSubmit2(VkQueue, uint32_t, const VkSubmitInfo2*, VkFence) { return VK_SUCCESS; } 588VkResult test_vkSetPrivateData(VkDevice, VkObjectType, uint64_t, VkPrivateDataSlot, uint64_t) { return VK_SUCCESS; } 589 590TEST(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, ©_info); 678 679 PFN_vkCmdCopyBufferToImage2 CmdCopyBufferToImage2 = device.load("vkCmdCopyBufferToImage2"); 680 VkCopyBufferToImageInfo2 copy_buf_image{}; 681 CmdCopyBufferToImage2(command_buffer, ©_buf_image); 682 683 PFN_vkCmdCopyImage2 CmdCopyImage2 = device.load("vkCmdCopyImage2"); 684 VkCopyImageInfo2 copy_image_info{}; 685 CmdCopyImage2(command_buffer, ©_image_info); 686 687 PFN_vkCmdCopyImageToBuffer2 CmdCopyImageToBuffer2 = device.load("vkCmdCopyImageToBuffer2"); 688 VkCopyImageToBufferInfo2 copy_image_buf; 689 CmdCopyImageToBuffer2(command_buffer, ©_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 776TEST(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 790TEST(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 804TEST(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 825TEST(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 845TEST(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 861TEST(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 877TEST(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 901TEST(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 925struct DriverInfo { 926 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 933void 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 1018TEST(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 1028TEST(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 1038TEST(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 1049TEST(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 1058TEST(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 1068TEST(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 1078TEST(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 1089TEST(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 1103TEST(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 1118TEST(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 1132TEST(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 1147TEST(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 1177TEST(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 1196TEST(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 1221TEST(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 1251TEST(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 1286TEST(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 1372TEST(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 \"") + env.get_test_icd_path().str() + 1384 "\" contained a 1.1 or greater API version, but " 1385 "vkEnumerateInstanceVersion returned 1.0, treating as a 1.0 ICD")); 1386} 1387 1388TEST(DriverManifest, EnumerateInstanceVersionNotSupported) { 1389 FrameworkEnvironment env{}; 1390 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1)) 1391 .set_icd_api_version(VK_API_VERSION_1_0) 1392 .set_can_query_vkEnumerateInstanceVersion(false) 1393 .add_physical_device({}); 1394 1395 InstWrapper inst{env.vulkan_functions}; 1396 inst.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 1397 FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); 1398 inst.CheckCreate(); 1399 1400 ASSERT_TRUE(env.debug_log.find(std::string("terminator_CreateInstance: Manifest ICD for \"") + env.get_test_icd_path().str() + 1401 "\" contained a 1.1 or greater API version, but does " 1402 "not support vkEnumerateInstanceVersion, treating as a 1.0 ICD")); 1403} 1404