1/* 2 * Copyright (c) 2021-2022 The Khronos Group Inc. 3 * Copyright (c) 2021-2022 Valve Corporation 4 * Copyright (c) 2021-2022 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and/or associated documentation files (the "Materials"), to 8 * deal in the Materials without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Materials, and to permit persons to whom the Materials are 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice(s) and this permission notice shall be included in 14 * all copies or substantial portions of the Materials. 15 * 16 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * 20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 23 * USE OR OTHER DEALINGS IN THE MATERIALS. 24 * 25 * Author: Charles Giessen <charles@lunarg.com> 26 * Author: Mark Young <marky@lunarg.com> 27 */ 28 29#include "test_environment.h" 30 31// These tests are all instance extension tests that touch physical devices. This was 32// before the idea that physical device extensions were more appropriately found in the 33// list of device extensions. Because of that, all these tests need to support devices 34// that don't support the extension and have a fallback path in the loader that needs 35// validation. 36 37// Fill in random but valid data into the device properties struct for the current physical device 38void FillInRandomICDInfo(uint32_t& vendor_id, uint32_t& driver_vers) { 39 vendor_id = VK_MAKE_API_VERSION(0, rand() % 64, rand() % 255, rand() % 255); 40 driver_vers = VK_MAKE_API_VERSION(0, rand() % 64, rand() % 255, rand() % 255); 41} 42 43// Fill in random but valid data into the device properties struct for the current physical device 44void FillInRandomDeviceProps(VkPhysicalDeviceProperties& props, uint32_t api_vers, uint32_t vendor, uint32_t driver_vers) { 45 props.apiVersion = api_vers; 46 props.driverVersion = driver_vers; 47 props.vendorID = vendor; 48 props.deviceID = (static_cast<uint32_t>(rand()) >> 4) + (static_cast<uint32_t>(rand()) << 2); 49 props.deviceType = static_cast<VkPhysicalDeviceType>(rand() % 5); 50 for (uint8_t idx = 0; idx < VK_UUID_SIZE; ++idx) { 51 props.pipelineCacheUUID[idx] = static_cast<uint8_t>(rand() % 255); 52 } 53} 54 55// 56// VK_KHR_get_physical_device_properties2 57// 58 59// Test vkGetPhysicalDeviceProperties2KHR where nothing supports it. 60TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoSupport) { 61 FrameworkEnvironment env{}; 62 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 63 env.get_test_icd(0).physical_devices.push_back({}); 64 65 InstWrapper instance(env.vulkan_functions); 66 instance.CheckCreate(); 67 68 PFN_vkGetPhysicalDeviceProperties2KHR GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2KHR"); 69 ASSERT_EQ(GetPhysDevProps2, nullptr); 70} 71 72// Test vkGetPhysicalDeviceProperties2KHR where instance supports it, but nothing else. 73TEST(LoaderInstPhysDevExts, PhysDevProps2KHRNoICDSupport) { 74 FrameworkEnvironment env{}; 75 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 76 env.get_test_icd(0).physical_devices.push_back({}); 77 78 InstWrapper instance(env.vulkan_functions); 79 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 80 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 81 82 PFN_vkGetPhysicalDeviceProperties2KHR GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2KHR"); 83 ASSERT_EQ(GetPhysDevProps2, nullptr); 84} 85 86// Test vkGetPhysicalDeviceProperties2KHR where instance and ICD supports it, but device does not support it. 87TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceAndICDSupport) { 88 FrameworkEnvironment env{}; 89 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 90 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 91 env.get_test_icd(0).physical_devices.push_back({}); 92 FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_0, 5, 123); 93 94 InstWrapper instance(env.vulkan_functions); 95 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 96 instance.CheckCreate(); 97 98 PFN_vkGetPhysicalDeviceProperties2KHR GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2KHR"); 99 ASSERT_NE(GetPhysDevProps2, nullptr); 100 101 uint32_t driver_count = 1; 102 VkPhysicalDevice physical_device; 103 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 104 ASSERT_EQ(driver_count, 1U); 105 106 VkPhysicalDeviceProperties props{}; 107 instance->vkGetPhysicalDeviceProperties(physical_device, &props); 108 VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; 109 GetPhysDevProps2(physical_device, &props2); 110 111 // Both properties should match 112 ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); 113 ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); 114 ASSERT_EQ(props.vendorID, props2.properties.vendorID); 115 ASSERT_EQ(props.deviceID, props2.properties.deviceID); 116 ASSERT_EQ(props.deviceType, props2.properties.deviceType); 117 ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); 118} 119 120// Test vkGetPhysicalDeviceProperties2 where instance supports, an ICD, and a device under that ICD 121// also support, so everything should work and return properly. 122// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 123TEST(LoaderInstPhysDevExts, PhysDevProps2Simple) { 124 FrameworkEnvironment env{}; 125 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1)); 126 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 127 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 128 env.get_test_icd(0).physical_devices.push_back({}); 129 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 130 FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_1, 5, 123); 131 { 132 InstWrapper instance(env.vulkan_functions); 133 instance.create_info.set_api_version(VK_API_VERSION_1_1); 134 instance.CheckCreate(); 135 136 PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2"); 137 ASSERT_NE(GetPhysDevProps2, nullptr); 138 139 uint32_t driver_count = 1; 140 VkPhysicalDevice physical_device; 141 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 142 ASSERT_EQ(driver_count, 1U); 143 144 VkPhysicalDeviceProperties props{}; 145 instance->vkGetPhysicalDeviceProperties(physical_device, &props); 146 VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; 147 GetPhysDevProps2(physical_device, &props2); 148 149 // Both properties should match 150 ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); 151 ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); 152 ASSERT_EQ(props.vendorID, props2.properties.vendorID); 153 ASSERT_EQ(props.deviceID, props2.properties.deviceID); 154 ASSERT_EQ(props.deviceType, props2.properties.deviceType); 155 ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); 156 } 157 158 { // Do the same logic but have the application forget to use 1.1 and doesn't enable the extension - should emulate the call 159 InstWrapper instance(env.vulkan_functions); 160 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 161 instance.CheckCreate(); 162 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 163 CreateDebugUtilsMessenger(log); 164 165 PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2"); 166 ASSERT_NE(GetPhysDevProps2, nullptr); 167 168 uint32_t driver_count = 1; 169 VkPhysicalDevice physical_device; 170 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 171 ASSERT_EQ(driver_count, 1U); 172 173 VkPhysicalDeviceProperties props{}; 174 instance->vkGetPhysicalDeviceProperties(physical_device, &props); 175 VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; 176 GetPhysDevProps2(physical_device, &props2); 177 178 // Both properties should match 179 ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); 180 ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); 181 ASSERT_EQ(props.vendorID, props2.properties.vendorID); 182 ASSERT_EQ(props.deviceID, props2.properties.deviceID); 183 ASSERT_EQ(props.deviceType, props2.properties.deviceType); 184 ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); 185 ASSERT_TRUE(log.find("Emulating call in ICD")); 186 } 187 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 188 .set_name("modify_api_version_layer") 189 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 190 .set_disable_environment("DisableEnvVar")), 191 "modify_api_version_layer.json"); 192 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 193 { // Now do the same as above but with a layer that updates the version to 1.1 194 InstWrapper instance(env.vulkan_functions); 195 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 196 instance.CheckCreate(); 197 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 198 CreateDebugUtilsMessenger(log); 199 200 PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2"); 201 ASSERT_NE(GetPhysDevProps2, nullptr); 202 203 uint32_t driver_count = 1; 204 VkPhysicalDevice physical_device; 205 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 206 ASSERT_EQ(driver_count, 1U); 207 208 VkPhysicalDeviceProperties props{}; 209 instance->vkGetPhysicalDeviceProperties(physical_device, &props); 210 VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; 211 GetPhysDevProps2(physical_device, &props2); 212 213 // Both properties should match 214 ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); 215 ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); 216 ASSERT_EQ(props.vendorID, props2.properties.vendorID); 217 ASSERT_EQ(props.deviceID, props2.properties.deviceID); 218 ASSERT_EQ(props.deviceType, props2.properties.deviceType); 219 ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); 220 ASSERT_FALSE(log.find("Emulating call in ICD")); 221 } 222} 223 224// Test vkGetPhysicalDeviceProperties2 and vkGetPhysicalDeviceProperties2KHR where ICD is 1.0 and supports 225// extension but the instance supports 1.1 and the extension 226TEST(LoaderInstPhysDevExts, PhysDevProps2KHRInstanceSupports11) { 227 FrameworkEnvironment env{}; 228 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0)); 229 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 230 env.get_test_icd(0).physical_devices.push_back({}); 231 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 232 FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_API_VERSION_1_0, 5, 123); 233 234 InstWrapper instance(env.vulkan_functions); 235 instance.create_info.set_api_version(VK_API_VERSION_1_1); 236 instance.create_info.add_extensions( 237 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 238 instance.CheckCreate(); 239 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 240 CreateDebugUtilsMessenger(log); 241 242 PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2"); 243 ASSERT_NE(GetPhysDevProps2, nullptr); 244 245 PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2KHR = instance.load("vkGetPhysicalDeviceProperties2KHR"); 246 ASSERT_NE(GetPhysDevProps2KHR, nullptr); 247 248 uint32_t driver_count = 1; 249 VkPhysicalDevice physical_device; 250 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 251 ASSERT_EQ(driver_count, 1U); 252 253 VkPhysicalDeviceProperties props{}; 254 instance->vkGetPhysicalDeviceProperties(physical_device, &props); 255 VkPhysicalDeviceProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; 256 GetPhysDevProps2(physical_device, &props2); 257 258 // Both VkPhysicalDeviceProperties2 properties should match 259 ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); 260 ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); 261 ASSERT_EQ(props.vendorID, props2.properties.vendorID); 262 ASSERT_EQ(props.deviceID, props2.properties.deviceID); 263 ASSERT_EQ(props.deviceType, props2.properties.deviceType); 264 ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); 265 266 VkPhysicalDeviceProperties2KHR props2KHR{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR}; 267 GetPhysDevProps2(physical_device, &props2KHR); 268 269 // Both VkPhysicalDeviceProperties2KHR properties should match 270 ASSERT_EQ(props.apiVersion, props2KHR.properties.apiVersion); 271 ASSERT_EQ(props.driverVersion, props2KHR.properties.driverVersion); 272 ASSERT_EQ(props.vendorID, props2KHR.properties.vendorID); 273 ASSERT_EQ(props.deviceID, props2KHR.properties.deviceID); 274 ASSERT_EQ(props.deviceType, props2KHR.properties.deviceType); 275 ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2KHR.properties.pipelineCacheUUID, VK_UUID_SIZE)); 276 277 ASSERT_FALSE(log.find("Emulating call in ICD")); 278} 279 280// Test vkGetPhysicalDeviceProperties2 where instance supports it with some ICDs that both support 281// and don't support it: 282// ICD 0 supports 283// Physical device 0 does not 284// Physical device 1 does 285// Physical device 2 does not 286// ICD 1 doesn't support 287// Physical device 3 does not 288// ICD 2 supports 289// Physical device 4 does not 290// Physical device 5 does not 291// ICD 3 supports 292// Physical device 6 does 293TEST(LoaderInstPhysDevExts, PhysDevProps2Mixed) { 294 FrameworkEnvironment env{}; 295 const uint32_t max_icd_count = 4; 296 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 297 const uint32_t max_phys_devs = 7; 298 299 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 300 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 301 auto& cur_icd = env.get_test_icd(icd); 302 303 // ICD 1 should not have 1.1 304 if (icd != 1) { 305 cur_icd.icd_api_version = VK_API_VERSION_1_1; 306 cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 307 } 308 309 uint32_t rand_vendor_id; 310 uint32_t rand_driver_vers; 311 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 312 313 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 314 uint32_t device_version = VK_API_VERSION_1_0; 315 cur_icd.physical_devices.push_back({}); 316 auto& cur_dev = cur_icd.physical_devices.back(); 317 318 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 319 if ((icd == 0 && dev == 1) || icd == 3) { 320 cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 321 device_version = VK_API_VERSION_1_1; 322 } 323 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 324 } 325 } 326 327 InstWrapper instance(env.vulkan_functions); 328 instance.create_info.set_api_version(VK_API_VERSION_1_1); 329 instance.CheckCreate(); 330 331 PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = instance.load("vkGetPhysicalDeviceProperties2"); 332 ASSERT_NE(GetPhysDevProps2, nullptr); 333 334 uint32_t device_count = max_phys_devs; 335 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 336 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 337 ASSERT_EQ(device_count, max_phys_devs); 338 339 for (uint32_t dev = 0; dev < device_count; ++dev) { 340 VkPhysicalDeviceProperties props{}; 341 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &props); 342 VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; 343 GetPhysDevProps2(physical_devices[dev], &props2); 344 345 // Both properties should match 346 ASSERT_EQ(props.apiVersion, props2.properties.apiVersion); 347 ASSERT_EQ(props.driverVersion, props2.properties.driverVersion); 348 ASSERT_EQ(props.vendorID, props2.properties.vendorID); 349 ASSERT_EQ(props.deviceID, props2.properties.deviceID); 350 ASSERT_EQ(props.deviceType, props2.properties.deviceType); 351 ASSERT_EQ(0, memcmp(props.pipelineCacheUUID, props2.properties.pipelineCacheUUID, VK_UUID_SIZE)); 352 } 353} 354 355// Fill in random but valid data into the features struct for the current physical device 356void FillInRandomFeatures(VkPhysicalDeviceFeatures& feats) { 357 feats.robustBufferAccess = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 358 feats.fullDrawIndexUint32 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 359 feats.imageCubeArray = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 360 feats.independentBlend = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 361 feats.geometryShader = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 362 feats.tessellationShader = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 363 feats.sampleRateShading = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 364 feats.dualSrcBlend = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 365 feats.logicOp = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 366 feats.multiDrawIndirect = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 367 feats.drawIndirectFirstInstance = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 368 feats.depthClamp = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 369 feats.depthBiasClamp = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 370 feats.fillModeNonSolid = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 371 feats.depthBounds = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 372 feats.wideLines = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 373 feats.largePoints = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 374 feats.alphaToOne = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 375 feats.multiViewport = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 376 feats.samplerAnisotropy = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 377 feats.textureCompressionETC2 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 378 feats.textureCompressionASTC_LDR = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 379 feats.textureCompressionBC = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 380 feats.occlusionQueryPrecise = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 381 feats.pipelineStatisticsQuery = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 382 feats.vertexPipelineStoresAndAtomics = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 383 feats.fragmentStoresAndAtomics = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 384 feats.shaderTessellationAndGeometryPointSize = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 385 feats.shaderImageGatherExtended = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 386 feats.shaderStorageImageExtendedFormats = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 387 feats.shaderStorageImageMultisample = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 388 feats.shaderStorageImageReadWithoutFormat = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 389 feats.shaderStorageImageWriteWithoutFormat = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 390 feats.shaderUniformBufferArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 391 feats.shaderSampledImageArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 392 feats.shaderStorageBufferArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 393 feats.shaderStorageImageArrayDynamicIndexing = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 394 feats.shaderClipDistance = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 395 feats.shaderCullDistance = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 396 feats.shaderFloat64 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 397 feats.shaderInt64 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 398 feats.shaderInt16 = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 399 feats.shaderResourceResidency = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 400 feats.shaderResourceMinLod = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 401 feats.sparseBinding = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 402 feats.sparseResidencyBuffer = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 403 feats.sparseResidencyImage2D = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 404 feats.sparseResidencyImage3D = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 405 feats.sparseResidency2Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 406 feats.sparseResidency4Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 407 feats.sparseResidency8Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 408 feats.sparseResidency16Samples = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 409 feats.sparseResidencyAliased = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 410 feats.variableMultisampleRate = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 411 feats.inheritedQueries = (rand() % 2) == 0 ? VK_FALSE : VK_TRUE; 412} 413 414// Compare the contents of the feature structs 415bool CompareFeatures(const VkPhysicalDeviceFeatures& feats1, const VkPhysicalDeviceFeatures2& feats2) { 416 return feats1.robustBufferAccess == feats2.features.robustBufferAccess && 417 feats1.fullDrawIndexUint32 == feats2.features.fullDrawIndexUint32 && 418 feats1.imageCubeArray == feats2.features.imageCubeArray && feats1.independentBlend == feats2.features.independentBlend && 419 feats1.geometryShader == feats2.features.geometryShader && 420 feats1.tessellationShader == feats2.features.tessellationShader && 421 feats1.sampleRateShading == feats2.features.sampleRateShading && feats1.dualSrcBlend == feats2.features.dualSrcBlend && 422 feats1.logicOp == feats2.features.logicOp && feats1.multiDrawIndirect == feats2.features.multiDrawIndirect && 423 feats1.drawIndirectFirstInstance == feats2.features.drawIndirectFirstInstance && 424 feats1.depthClamp == feats2.features.depthClamp && feats1.depthBiasClamp == feats2.features.depthBiasClamp && 425 feats1.fillModeNonSolid == feats2.features.fillModeNonSolid && feats1.depthBounds == feats2.features.depthBounds && 426 feats1.wideLines == feats2.features.wideLines && feats1.largePoints == feats2.features.largePoints && 427 feats1.alphaToOne == feats2.features.alphaToOne && feats1.multiViewport == feats2.features.multiViewport && 428 feats1.samplerAnisotropy == feats2.features.samplerAnisotropy && 429 feats1.textureCompressionETC2 == feats2.features.textureCompressionETC2 && 430 feats1.textureCompressionASTC_LDR == feats2.features.textureCompressionASTC_LDR && 431 feats1.textureCompressionBC == feats2.features.textureCompressionBC && 432 feats1.occlusionQueryPrecise == feats2.features.occlusionQueryPrecise && 433 feats1.pipelineStatisticsQuery == feats2.features.pipelineStatisticsQuery && 434 feats1.vertexPipelineStoresAndAtomics == feats2.features.vertexPipelineStoresAndAtomics && 435 feats1.fragmentStoresAndAtomics == feats2.features.fragmentStoresAndAtomics && 436 feats1.shaderTessellationAndGeometryPointSize == feats2.features.shaderTessellationAndGeometryPointSize && 437 feats1.shaderImageGatherExtended == feats2.features.shaderImageGatherExtended && 438 feats1.shaderStorageImageExtendedFormats == feats2.features.shaderStorageImageExtendedFormats && 439 feats1.shaderStorageImageMultisample == feats2.features.shaderStorageImageMultisample && 440 feats1.shaderStorageImageReadWithoutFormat == feats2.features.shaderStorageImageReadWithoutFormat && 441 feats1.shaderStorageImageWriteWithoutFormat == feats2.features.shaderStorageImageWriteWithoutFormat && 442 feats1.shaderUniformBufferArrayDynamicIndexing == feats2.features.shaderUniformBufferArrayDynamicIndexing && 443 feats1.shaderSampledImageArrayDynamicIndexing == feats2.features.shaderSampledImageArrayDynamicIndexing && 444 feats1.shaderStorageBufferArrayDynamicIndexing == feats2.features.shaderStorageBufferArrayDynamicIndexing && 445 feats1.shaderStorageImageArrayDynamicIndexing == feats2.features.shaderStorageImageArrayDynamicIndexing && 446 feats1.shaderClipDistance == feats2.features.shaderClipDistance && 447 feats1.shaderCullDistance == feats2.features.shaderCullDistance && 448 feats1.shaderFloat64 == feats2.features.shaderFloat64 && feats1.shaderInt64 == feats2.features.shaderInt64 && 449 feats1.shaderInt16 == feats2.features.shaderInt16 && 450 feats1.shaderResourceResidency == feats2.features.shaderResourceResidency && 451 feats1.shaderResourceMinLod == feats2.features.shaderResourceMinLod && 452 feats1.sparseBinding == feats2.features.sparseBinding && 453 feats1.sparseResidencyBuffer == feats2.features.sparseResidencyBuffer && 454 feats1.sparseResidencyImage2D == feats2.features.sparseResidencyImage2D && 455 feats1.sparseResidencyImage3D == feats2.features.sparseResidencyImage3D && 456 feats1.sparseResidency2Samples == feats2.features.sparseResidency2Samples && 457 feats1.sparseResidency4Samples == feats2.features.sparseResidency4Samples && 458 feats1.sparseResidency8Samples == feats2.features.sparseResidency8Samples && 459 feats1.sparseResidency16Samples == feats2.features.sparseResidency16Samples && 460 feats1.sparseResidencyAliased == feats2.features.sparseResidencyAliased && 461 feats1.variableMultisampleRate == feats2.features.variableMultisampleRate && 462 feats1.inheritedQueries == feats2.features.inheritedQueries; 463} 464 465// Test vkGetPhysicalDeviceFeatures2KHR where nothing supports it. 466TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRNoSupport) { 467 FrameworkEnvironment env{}; 468 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 469 env.get_test_icd(0).physical_devices.push_back({}); 470 471 InstWrapper instance(env.vulkan_functions); 472 instance.CheckCreate(); 473 474 PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysDevFeats2KHR = instance.load("vkGetPhysicalDeviceFeatures2KHR"); 475 ASSERT_EQ(GetPhysDevFeats2KHR, nullptr); 476} 477 478// Test vkGetPhysicalDeviceFeatures2KHR where instance supports it, but nothing else. 479TEST(LoaderInstPhysDevExts, PhysDevFeatsKHRNoICDSupport) { 480 FrameworkEnvironment env{}; 481 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 482 env.get_test_icd(0).physical_devices.push_back({}); 483 484 InstWrapper instance(env.vulkan_functions); 485 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 486 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 487 488 PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysDevFeats2KHR = instance.load("vkGetPhysicalDeviceFeatures2KHR"); 489 ASSERT_EQ(GetPhysDevFeats2KHR, nullptr); 490} 491 492// Test vkGetPhysicalDeviceFeatures2KHR where instance and ICD supports it, but device does not support it. 493TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceAndICDSupport) { 494 FrameworkEnvironment env{}; 495 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 496 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 497 env.get_test_icd(0).physical_devices.push_back({}); 498 FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features); 499 500 InstWrapper instance(env.vulkan_functions); 501 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 502 instance.CheckCreate(); 503 504 PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysDevFeats2KHR = instance.load("vkGetPhysicalDeviceFeatures2KHR"); 505 ASSERT_NE(GetPhysDevFeats2KHR, nullptr); 506 507 uint32_t driver_count = 1; 508 VkPhysicalDevice physical_device; 509 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 510 ASSERT_EQ(driver_count, 1U); 511 512 VkPhysicalDeviceFeatures feats{}; 513 instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); 514 VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR}; 515 GetPhysDevFeats2KHR(physical_device, &feats2); 516 ASSERT_TRUE(CompareFeatures(feats, feats2)); 517} 518 519// Test vkGetPhysicalDeviceFeatures2 where instance supports, an ICD, and a device under that ICD 520// also support, so everything should work and return properly. 521// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 522TEST(LoaderInstPhysDevExts, PhysDevFeats2Simple) { 523 FrameworkEnvironment env{}; 524 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1)); 525 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 526 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 527 env.get_test_icd(0).physical_devices.push_back({}); 528 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 529 env.get_test_icd(0).physical_devices.back().set_api_version(VK_API_VERSION_1_1); 530 FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features); 531 { 532 InstWrapper instance(env.vulkan_functions); 533 instance.create_info.set_api_version(VK_API_VERSION_1_1); 534 instance.CheckCreate(); 535 536 PFN_vkGetPhysicalDeviceFeatures2 GetPhysDevFeats2 = instance.load("vkGetPhysicalDeviceFeatures2"); 537 ASSERT_NE(GetPhysDevFeats2, nullptr); 538 539 uint32_t driver_count = 1; 540 VkPhysicalDevice physical_device; 541 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 542 ASSERT_EQ(driver_count, 1U); 543 544 VkPhysicalDeviceFeatures feats{}; 545 instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); 546 VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; 547 GetPhysDevFeats2(physical_device, &feats2); 548 ASSERT_TRUE(CompareFeatures(feats, feats2)); 549 } 550 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 551 InstWrapper instance(env.vulkan_functions); 552 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 553 instance.CheckCreate(); 554 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 555 CreateDebugUtilsMessenger(log); 556 557 PFN_vkGetPhysicalDeviceFeatures2 GetPhysDevFeats2 = instance.load("vkGetPhysicalDeviceFeatures2"); 558 ASSERT_NE(GetPhysDevFeats2, nullptr); 559 560 uint32_t driver_count = 1; 561 VkPhysicalDevice physical_device; 562 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 563 ASSERT_EQ(driver_count, 1U); 564 565 VkPhysicalDeviceFeatures feats{}; 566 instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); 567 VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; 568 GetPhysDevFeats2(physical_device, &feats2); 569 ASSERT_TRUE(CompareFeatures(feats, feats2)); 570 571 ASSERT_TRUE(log.find("Emulating call in ICD")); 572 } 573 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 574 .set_name("modify_api_version_layer") 575 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 576 .set_disable_environment("DisableEnvVar")), 577 "modify_api_version_layer.json"); 578 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 579 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 580 InstWrapper instance(env.vulkan_functions); 581 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 582 instance.CheckCreate(); 583 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 584 CreateDebugUtilsMessenger(log); 585 586 PFN_vkGetPhysicalDeviceFeatures2 GetPhysDevFeats2 = instance.load("vkGetPhysicalDeviceFeatures2"); 587 ASSERT_NE(GetPhysDevFeats2, nullptr); 588 589 uint32_t driver_count = 1; 590 VkPhysicalDevice physical_device; 591 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 592 ASSERT_EQ(driver_count, 1U); 593 594 VkPhysicalDeviceFeatures feats{}; 595 instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); 596 VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; 597 GetPhysDevFeats2(physical_device, &feats2); 598 ASSERT_TRUE(CompareFeatures(feats, feats2)); 599 600 ASSERT_FALSE(log.find("Emulating call in ICD")); 601 } 602} 603 604// Test vkGetPhysicalDeviceFeatures2 and vkGetPhysicalDeviceFeatures2KHR where ICD is 1.0 and supports 605// extension but the instance supports 1.1 and the extension 606TEST(LoaderInstPhysDevExts, PhysDevFeats2KHRInstanceSupports11) { 607 FrameworkEnvironment env{}; 608 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_0)); 609 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 610 env.get_test_icd(0).physical_devices.push_back({}); 611 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 612 FillInRandomFeatures(env.get_test_icd(0).physical_devices.back().features); 613 614 InstWrapper instance(env.vulkan_functions); 615 instance.create_info.set_api_version(VK_API_VERSION_1_1); 616 instance.create_info.add_extensions( 617 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 618 instance.CheckCreate(); 619 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 620 CreateDebugUtilsMessenger(log); 621 622 PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysDevFeats2KHR = instance.load("vkGetPhysicalDeviceFeatures2KHR"); 623 ASSERT_NE(GetPhysDevFeats2KHR, nullptr); 624 625 PFN_vkGetPhysicalDeviceFeatures2 GetPhysDevFeats2 = instance.load("vkGetPhysicalDeviceFeatures2"); 626 ASSERT_NE(GetPhysDevFeats2, nullptr); 627 628 uint32_t driver_count = 1; 629 VkPhysicalDevice physical_device; 630 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 631 ASSERT_EQ(driver_count, 1U); 632 633 VkPhysicalDeviceFeatures feats{}; 634 instance->vkGetPhysicalDeviceFeatures(physical_device, &feats); 635 636 VkPhysicalDeviceFeatures2KHR feats2KHR{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR}; 637 GetPhysDevFeats2KHR(physical_device, &feats2KHR); 638 ASSERT_TRUE(CompareFeatures(feats, feats2KHR)); 639 640 VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; 641 GetPhysDevFeats2(physical_device, &feats2); 642 ASSERT_TRUE(CompareFeatures(feats, feats2)); 643 644 ASSERT_FALSE(log.find("Emulating call in ICD")); 645} 646 647// Test vkGetPhysicalDeviceFeatures2 where instance supports it with some ICDs that both support 648// and don't support it: 649// ICD 0 supports 650// Physical device 0 does not 651// Physical device 1 does 652// Physical device 2 does not 653// ICD 1 doesn't support 654// Physical device 3 does not 655// ICD 2 supports 656// Physical device 4 does not 657// Physical device 5 does not 658// ICD 3 supports 659// Physical device 6 does 660TEST(LoaderInstPhysDevExts, PhysDevFeatsMixed) { 661 FrameworkEnvironment env{}; 662 const uint32_t max_icd_count = 4; 663 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 664 const uint32_t max_phys_devs = 7; 665 666 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 667 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 668 auto& cur_icd = env.get_test_icd(icd); 669 670 // ICD 1 should not have 1.1 671 if (icd != 1) { 672 cur_icd.icd_api_version = VK_API_VERSION_1_1; 673 cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 674 } 675 676 uint32_t rand_vendor_id; 677 uint32_t rand_driver_vers; 678 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 679 680 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 681 uint32_t device_version = VK_API_VERSION_1_0; 682 cur_icd.physical_devices.push_back({}); 683 auto& cur_dev = cur_icd.physical_devices.back(); 684 685 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 686 if ((icd == 0 && dev == 1) || icd == 3) { 687 cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 688 device_version = VK_API_VERSION_1_1; 689 } 690 691 // Still set physical device properties (so we can determine if device is correct API version) 692 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 693 FillInRandomFeatures(cur_dev.features); 694 } 695 } 696 697 InstWrapper instance(env.vulkan_functions); 698 instance.create_info.set_api_version(VK_API_VERSION_1_1); 699 instance.CheckCreate(); 700 701 PFN_vkGetPhysicalDeviceFeatures2 GetPhysDevFeats2 = instance.load("vkGetPhysicalDeviceFeatures2"); 702 ASSERT_NE(GetPhysDevFeats2, nullptr); 703 704 uint32_t device_count = max_phys_devs; 705 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 706 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 707 ASSERT_EQ(device_count, max_phys_devs); 708 709 for (uint32_t dev = 0; dev < device_count; ++dev) { 710 VkPhysicalDeviceFeatures feats{}; 711 instance->vkGetPhysicalDeviceFeatures(physical_devices[dev], &feats); 712 VkPhysicalDeviceFeatures2 feats2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; 713 GetPhysDevFeats2(physical_devices[dev], &feats2); 714 ASSERT_TRUE(CompareFeatures(feats, feats2)); 715 } 716} 717 718// Fill in random but valid data into the format properties struct for the current physical device 719void FillInRandomFormatProperties(std::vector<VkFormatProperties>& props) { 720 props.resize(5); 721 for (uint8_t form = 0; form < 5; ++form) { 722 props[form].bufferFeatures = static_cast<VkFormatFeatureFlags>(rand()); 723 props[form].linearTilingFeatures = static_cast<VkFormatFeatureFlags>(rand()); 724 props[form].optimalTilingFeatures = static_cast<VkFormatFeatureFlags>(rand()); 725 } 726} 727 728// Test vkGetPhysicalDeviceFormatProperties2KHR where nothing supports it. 729TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRNoSupport) { 730 FrameworkEnvironment env{}; 731 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 732 env.get_test_icd(0).physical_devices.push_back({}); 733 734 InstWrapper instance(env.vulkan_functions); 735 instance.CheckCreate(); 736 737 PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysDevFormatProps2KHR = 738 instance.load("vkGetPhysicalDeviceFormatProperties2KHR"); 739 ASSERT_EQ(GetPhysDevFormatProps2KHR, nullptr); 740} 741 742// Test vkGetPhysicalDeviceFormatProperties2KHR where instance supports it, but nothing else. 743TEST(LoaderInstPhysDevExts, PhysDevFormatPropsKHRNoICDSupport) { 744 FrameworkEnvironment env{}; 745 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 746 env.get_test_icd(0).physical_devices.push_back({}); 747 748 InstWrapper instance(env.vulkan_functions); 749 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 750 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 751 752 PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysDevFormatProps2KHR = 753 instance.load("vkGetPhysicalDeviceFormatProperties2KHR"); 754 ASSERT_EQ(GetPhysDevFormatProps2KHR, nullptr); 755} 756 757// Test vkGetPhysicalDeviceFormatProperties2KHR where instance and ICD supports it, but device does not support it. 758TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceAndICDSupport) { 759 FrameworkEnvironment env{}; 760 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 761 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 762 env.get_test_icd(0).physical_devices.push_back({}); 763 FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties); 764 765 InstWrapper instance(env.vulkan_functions); 766 instance.create_info.add_extensions( 767 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 768 instance.CheckCreate(); 769 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 770 CreateDebugUtilsMessenger(log); 771 772 PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysDevFormatProps2KHR = 773 instance.load("vkGetPhysicalDeviceFormatProperties2KHR"); 774 ASSERT_NE(GetPhysDevFormatProps2KHR, nullptr); 775 776 uint32_t driver_count = 1; 777 VkPhysicalDevice physical_device; 778 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 779 ASSERT_EQ(driver_count, 1U); 780 781 VkFormatProperties props{}; 782 instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); 783 VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 784 GetPhysDevFormatProps2KHR(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); 785 786 ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); 787 ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); 788 ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); 789} 790 791// Test vkGetPhysicalDeviceFormatProperties2 where instance supports, an ICD, and a device under that ICD 792// also support, so everything should work and return properly. 793// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 794TEST(LoaderInstPhysDevExts, PhysDevFormatProps2Simple) { 795 FrameworkEnvironment env{}; 796 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_1)); 797 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 798 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 799 env.get_test_icd(0).physical_devices.push_back({}); 800 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 801 env.get_test_icd(0).physical_devices.back().set_api_version(VK_API_VERSION_1_1); 802 FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties); 803 { 804 InstWrapper instance(env.vulkan_functions); 805 instance.create_info.set_api_version(VK_API_VERSION_1_1); 806 instance.CheckCreate(); 807 808 PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysDevFormatProps2 = instance.load("vkGetPhysicalDeviceFormatProperties2"); 809 ASSERT_NE(GetPhysDevFormatProps2, nullptr); 810 811 uint32_t driver_count = 1; 812 VkPhysicalDevice physical_device; 813 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 814 ASSERT_EQ(driver_count, 1U); 815 816 VkFormatProperties props{}; 817 instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); 818 VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 819 GetPhysDevFormatProps2(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); 820 821 ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); 822 ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); 823 ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); 824 } 825 { // Do the same logic but have the application forget to enable 1.1 and doesn't enable the extension 826 InstWrapper instance(env.vulkan_functions); 827 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 828 instance.CheckCreate(); 829 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 830 CreateDebugUtilsMessenger(log); 831 832 PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysDevFormatProps2 = instance.load("vkGetPhysicalDeviceFormatProperties2"); 833 ASSERT_NE(GetPhysDevFormatProps2, nullptr); 834 835 uint32_t driver_count = 1; 836 VkPhysicalDevice physical_device; 837 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 838 ASSERT_EQ(driver_count, 1U); 839 840 VkFormatProperties props{}; 841 instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); 842 VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 843 GetPhysDevFormatProps2(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); 844 845 ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); 846 ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); 847 ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); 848 ASSERT_TRUE(log.find("Emulating call in ICD")); 849 } 850 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 851 .set_name("modify_api_version_layer") 852 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 853 .set_disable_environment("DisableEnvVar")), 854 "modify_api_version_layer.json"); 855 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 856 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 857 InstWrapper instance(env.vulkan_functions); 858 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 859 instance.CheckCreate(); 860 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 861 CreateDebugUtilsMessenger(log); 862 863 PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysDevFormatProps2 = instance.load("vkGetPhysicalDeviceFormatProperties2"); 864 ASSERT_NE(GetPhysDevFormatProps2, nullptr); 865 866 uint32_t driver_count = 1; 867 VkPhysicalDevice physical_device; 868 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 869 ASSERT_EQ(driver_count, 1U); 870 871 VkFormatProperties props{}; 872 instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); 873 VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 874 GetPhysDevFormatProps2(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); 875 876 ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); 877 ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); 878 ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); 879 ASSERT_FALSE(log.find("Emulating call in ICD")); 880 } 881} 882// Test vkGetPhysicalDeviceFormatProperties2 and vkGetPhysicalDeviceFormatProperties2KHR where ICD is 1.0 and supports 883// extension but the instance supports 1.1 and the extension 884TEST(LoaderInstPhysDevExts, PhysDevFormatProps2KHRInstanceSupports11) { 885 FrameworkEnvironment env{}; 886 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 887 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 888 env.get_test_icd(0).physical_devices.push_back({}); 889 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 890 FillInRandomFormatProperties(env.get_test_icd(0).physical_devices.back().format_properties); 891 892 InstWrapper instance(env.vulkan_functions); 893 instance.create_info.set_api_version(VK_API_VERSION_1_1); 894 instance.create_info.add_extensions( 895 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 896 instance.CheckCreate(); 897 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 898 CreateDebugUtilsMessenger(log); 899 900 PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysDevFormatProps2 = instance.load("vkGetPhysicalDeviceFormatProperties2"); 901 ASSERT_NE(GetPhysDevFormatProps2, nullptr); 902 903 PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysDevFormatProps2KHR = 904 instance.load("vkGetPhysicalDeviceFormatProperties2KHR"); 905 ASSERT_NE(GetPhysDevFormatProps2KHR, nullptr); 906 907 uint32_t driver_count = 1; 908 VkPhysicalDevice physical_device; 909 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 910 ASSERT_EQ(driver_count, 1U); 911 912 VkFormatProperties props{}; 913 instance->vkGetPhysicalDeviceFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props); 914 VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 915 GetPhysDevFormatProps2(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2); 916 917 ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); 918 ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); 919 ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); 920 921 VkFormatProperties2KHR props2KHR{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 922 GetPhysDevFormatProps2KHR(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, &props2KHR); 923 924 ASSERT_EQ(props.bufferFeatures, props2KHR.formatProperties.bufferFeatures); 925 ASSERT_EQ(props.linearTilingFeatures, props2KHR.formatProperties.linearTilingFeatures); 926 ASSERT_EQ(props.optimalTilingFeatures, props2KHR.formatProperties.optimalTilingFeatures); 927 928 ASSERT_FALSE(log.find("Emulating call in ICD")); 929} 930 931// Test vkGetPhysicalDeviceFormatProperties2 where instance supports it with some ICDs that both support 932// and don't support it: 933// ICD 0 supports 934// Physical device 0 does not 935// Physical device 1 does 936// Physical device 2 does not 937// ICD 1 doesn't support 938// Physical device 3 does not 939// ICD 2 supports 940// Physical device 4 does not 941// Physical device 5 does not 942// ICD 3 supports 943// Physical device 6 does 944TEST(LoaderInstPhysDevExts, PhysDevFormatPropsMixed) { 945 FrameworkEnvironment env{}; 946 const uint32_t max_icd_count = 4; 947 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 948 const uint32_t max_phys_devs = 7; 949 950 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 951 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 952 auto& cur_icd = env.get_test_icd(icd); 953 954 // ICD 1 should not have 1.1 955 if (icd != 1) { 956 cur_icd.icd_api_version = VK_API_VERSION_1_1; 957 cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 958 } 959 960 uint32_t rand_vendor_id; 961 uint32_t rand_driver_vers; 962 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 963 964 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 965 uint32_t device_version = VK_API_VERSION_1_0; 966 cur_icd.physical_devices.push_back({}); 967 auto& cur_dev = cur_icd.physical_devices.back(); 968 969 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 970 if ((icd == 0 && dev == 1) || icd == 3) { 971 cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 972 device_version = VK_API_VERSION_1_1; 973 } 974 975 // Still set physical device properties (so we can determine if device is correct API version) 976 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 977 FillInRandomFormatProperties(cur_dev.format_properties); 978 } 979 } 980 981 InstWrapper instance(env.vulkan_functions); 982 instance.create_info.set_api_version(VK_API_VERSION_1_1); 983 instance.CheckCreate(); 984 985 PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysDevFormatProps2 = instance.load("vkGetPhysicalDeviceFormatProperties2"); 986 ASSERT_NE(GetPhysDevFormatProps2, nullptr); 987 988 uint32_t device_count = max_phys_devs; 989 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 990 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 991 ASSERT_EQ(device_count, max_phys_devs); 992 993 for (uint32_t dev = 0; dev < device_count; ++dev) { 994 VkFormat format = static_cast<VkFormat>((dev + 1) % 5); 995 VkFormatProperties props{}; 996 instance->vkGetPhysicalDeviceFormatProperties(physical_devices[dev], format, &props); 997 VkFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 998 GetPhysDevFormatProps2(physical_devices[dev], format, &props2); 999 1000 ASSERT_EQ(props.bufferFeatures, props2.formatProperties.bufferFeatures); 1001 ASSERT_EQ(props.linearTilingFeatures, props2.formatProperties.linearTilingFeatures); 1002 ASSERT_EQ(props.optimalTilingFeatures, props2.formatProperties.optimalTilingFeatures); 1003 } 1004} 1005 1006// Fill in random but valid data into the image format data struct for the current physical device 1007void FillInRandomImageFormatData(VkImageFormatProperties& props) { 1008 props.maxExtent = {static_cast<uint32_t>(rand() % 512), static_cast<uint32_t>(rand() % 512), 1009 static_cast<uint32_t>(rand() % 512)}; 1010 props.maxMipLevels = static_cast<uint32_t>(1 << (rand() % 16)); 1011 props.maxArrayLayers = static_cast<uint32_t>(1 << (rand() % 16)); 1012 props.sampleCounts = static_cast<VkSampleCountFlags>(1 << (rand() % 7)); 1013 props.maxResourceSize = static_cast<uint64_t>(rand()); 1014} 1015 1016// Test vkGetPhysicalDeviceImageFormatProperties2KHR where nothing supports it. 1017TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRNoSupport) { 1018 FrameworkEnvironment env{}; 1019 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1020 env.get_test_icd(0).physical_devices.push_back({}); 1021 1022 InstWrapper instance(env.vulkan_functions); 1023 instance.CheckCreate(); 1024 1025 PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysDevImageFormatProps2 = 1026 instance.load("vkGetPhysicalDeviceImageFormatProperties2KHR"); 1027 ASSERT_EQ(GetPhysDevImageFormatProps2, nullptr); 1028} 1029 1030// Test vkGetPhysicalDeviceImageFormatProperties2KHR where instance supports it, but nothing else. 1031TEST(LoaderInstPhysDevExts, PhysDevImageFormatPropsKHRNoICDSupport) { 1032 FrameworkEnvironment env{}; 1033 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1034 env.get_test_icd(0).physical_devices.push_back({}); 1035 1036 InstWrapper instance(env.vulkan_functions); 1037 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 1038 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 1039 1040 PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysDevImageFormatProps2KHR = 1041 instance.load("vkGetPhysicalDeviceImageFormatProperties2KHR"); 1042 ASSERT_EQ(GetPhysDevImageFormatProps2KHR, nullptr); 1043} 1044 1045// Test vkGetPhysicalDeviceImageFormatProperties2KHR where instance and ICD supports it, but device does not support it. 1046TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceAndICDSupport) { 1047 FrameworkEnvironment env{}; 1048 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1049 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1050 env.get_test_icd(0).physical_devices.push_back({}); 1051 FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties); 1052 1053 InstWrapper instance(env.vulkan_functions); 1054 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 1055 instance.CheckCreate(); 1056 1057 PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysDevImageFormatProps2KHR = 1058 instance.load("vkGetPhysicalDeviceImageFormatProperties2KHR"); 1059 ASSERT_NE(GetPhysDevImageFormatProps2KHR, nullptr); 1060 1061 uint32_t driver_count = 1; 1062 VkPhysicalDevice physical_device; 1063 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1064 ASSERT_EQ(driver_count, 1U); 1065 1066 VkImageFormatProperties props{}; 1067 ASSERT_EQ(VK_SUCCESS, 1068 instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 1069 VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); 1070 1071 VkPhysicalDeviceImageFormatInfo2 info2{ 1072 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType 1073 nullptr, // pNext 1074 VK_FORMAT_R4G4_UNORM_PACK8, // format 1075 VK_IMAGE_TYPE_2D, // type 1076 VK_IMAGE_TILING_OPTIMAL, // tiling 1077 0, // usage 1078 0, // flags 1079 }; 1080 VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 1081 ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2KHR(physical_device, &info2, &props2)); 1082 1083 ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); 1084 ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); 1085 ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); 1086 ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); 1087 ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); 1088 ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); 1089 ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); 1090} 1091 1092// Test vkGetPhysicalDeviceImageFormatProperties2 where instance supports, an ICD, and a device under that ICD 1093// also support, so everything should work and return properly. 1094// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 1095TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2Simple) { 1096 FrameworkEnvironment env{}; 1097 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1098 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 1099 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1100 env.get_test_icd(0).physical_devices.push_back({}); 1101 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1102 FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties); 1103 { 1104 InstWrapper instance(env.vulkan_functions); 1105 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1106 instance.CheckCreate(); 1107 1108 PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysDevImageFormatProps2 = 1109 instance.load("vkGetPhysicalDeviceImageFormatProperties2"); 1110 ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); 1111 1112 uint32_t driver_count = 1; 1113 VkPhysicalDevice physical_device; 1114 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1115 ASSERT_EQ(driver_count, 1U); 1116 1117 VkImageFormatProperties props{}; 1118 ASSERT_EQ(VK_SUCCESS, 1119 instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 1120 VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); 1121 1122 VkPhysicalDeviceImageFormatInfo2 info2{ 1123 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType 1124 nullptr, // pNext 1125 VK_FORMAT_R4G4_UNORM_PACK8, // format 1126 VK_IMAGE_TYPE_2D, // type 1127 VK_IMAGE_TILING_OPTIMAL, // tiling 1128 0, // usage 1129 0, // flags 1130 }; 1131 1132 VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 1133 ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_device, &info2, &props2)); 1134 1135 ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); 1136 ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); 1137 ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); 1138 ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); 1139 ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); 1140 ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); 1141 ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); 1142 } 1143 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 1144 InstWrapper instance(env.vulkan_functions); 1145 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 1146 instance.CheckCreate(); 1147 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1148 CreateDebugUtilsMessenger(log); 1149 1150 PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysDevImageFormatProps2 = 1151 instance.load("vkGetPhysicalDeviceImageFormatProperties2"); 1152 ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); 1153 1154 uint32_t driver_count = 1; 1155 VkPhysicalDevice physical_device; 1156 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1157 ASSERT_EQ(driver_count, 1U); 1158 1159 VkImageFormatProperties props{}; 1160 ASSERT_EQ(VK_SUCCESS, 1161 instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 1162 VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); 1163 1164 VkPhysicalDeviceImageFormatInfo2 info2{ 1165 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType 1166 nullptr, // pNext 1167 VK_FORMAT_R4G4_UNORM_PACK8, // format 1168 VK_IMAGE_TYPE_2D, // type 1169 VK_IMAGE_TILING_OPTIMAL, // tiling 1170 0, // usage 1171 0, // flags 1172 }; 1173 1174 VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 1175 ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_device, &info2, &props2)); 1176 1177 ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); 1178 ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); 1179 ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); 1180 ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); 1181 ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); 1182 ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); 1183 ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); 1184 ASSERT_TRUE(log.find("Emulating call in ICD")); 1185 } 1186 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 1187 .set_name("modify_api_version_layer") 1188 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 1189 .set_disable_environment("DisableEnvVar")), 1190 "modify_api_version_layer.json"); 1191 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 1192 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 1193 InstWrapper instance(env.vulkan_functions); 1194 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 1195 instance.CheckCreate(); 1196 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1197 CreateDebugUtilsMessenger(log); 1198 1199 PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysDevImageFormatProps2 = 1200 instance.load("vkGetPhysicalDeviceImageFormatProperties2"); 1201 ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); 1202 1203 uint32_t driver_count = 1; 1204 VkPhysicalDevice physical_device; 1205 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1206 ASSERT_EQ(driver_count, 1U); 1207 1208 VkImageFormatProperties props{}; 1209 ASSERT_EQ(VK_SUCCESS, 1210 instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 1211 VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); 1212 1213 VkPhysicalDeviceImageFormatInfo2 info2{ 1214 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType 1215 nullptr, // pNext 1216 VK_FORMAT_R4G4_UNORM_PACK8, // format 1217 VK_IMAGE_TYPE_2D, // type 1218 VK_IMAGE_TILING_OPTIMAL, // tiling 1219 0, // usage 1220 0, // flags 1221 }; 1222 1223 VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 1224 ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_device, &info2, &props2)); 1225 1226 ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); 1227 ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); 1228 ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); 1229 ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); 1230 ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); 1231 ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); 1232 ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); 1233 ASSERT_FALSE(log.find("Emulating call in ICD")); 1234 } 1235} 1236 1237// Test vkGetPhysicalDeviceImageFormatProperties2 and vkGetPhysicalDeviceImageFormatProperties2KHR where instance supports, an ICD, 1238// and a device under that ICD also support, so everything should work and return properly. 1239TEST(LoaderInstPhysDevExts, PhysDevImageFormatProps2KHRInstanceSupports11) { 1240 FrameworkEnvironment env{}; 1241 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1242 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1243 env.get_test_icd(0).physical_devices.push_back({}); 1244 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1245 FillInRandomImageFormatData(env.get_test_icd(0).physical_devices.back().image_format_properties); 1246 1247 InstWrapper instance(env.vulkan_functions); 1248 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1249 instance.create_info.add_extensions( 1250 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 1251 instance.CheckCreate(); 1252 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1253 CreateDebugUtilsMessenger(log); 1254 1255 PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysDevImageFormatProps2 = 1256 instance.load("vkGetPhysicalDeviceImageFormatProperties2"); 1257 ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); 1258 1259 PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysDevImageFormatProps2KHR = 1260 instance.load("vkGetPhysicalDeviceImageFormatProperties2KHR"); 1261 ASSERT_NE(GetPhysDevImageFormatProps2KHR, nullptr); 1262 1263 uint32_t driver_count = 1; 1264 VkPhysicalDevice physical_device; 1265 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1266 ASSERT_EQ(driver_count, 1U); 1267 1268 VkImageFormatProperties props{}; 1269 ASSERT_EQ(VK_SUCCESS, 1270 instance->vkGetPhysicalDeviceImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 1271 VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); 1272 1273 VkPhysicalDeviceImageFormatInfo2 info2{ 1274 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType 1275 nullptr, // pNext 1276 VK_FORMAT_R4G4_UNORM_PACK8, // format 1277 VK_IMAGE_TYPE_2D, // type 1278 VK_IMAGE_TILING_OPTIMAL, // tiling 1279 0, // usage 1280 0, // flags 1281 }; 1282 1283 VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 1284 ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_device, &info2, &props2)); 1285 1286 ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); 1287 ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); 1288 ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); 1289 ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); 1290 ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); 1291 ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); 1292 ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); 1293 1294 VkImageFormatProperties2KHR props2KHR{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR}; 1295 ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2KHR(physical_device, &info2, &props2KHR)); 1296 1297 ASSERT_EQ(props.maxExtent.width, props2KHR.imageFormatProperties.maxExtent.width); 1298 ASSERT_EQ(props.maxExtent.height, props2KHR.imageFormatProperties.maxExtent.height); 1299 ASSERT_EQ(props.maxExtent.depth, props2KHR.imageFormatProperties.maxExtent.depth); 1300 ASSERT_EQ(props.maxMipLevels, props2KHR.imageFormatProperties.maxMipLevels); 1301 ASSERT_EQ(props.maxArrayLayers, props2KHR.imageFormatProperties.maxArrayLayers); 1302 ASSERT_EQ(props.sampleCounts, props2KHR.imageFormatProperties.sampleCounts); 1303 ASSERT_EQ(props.maxResourceSize, props2KHR.imageFormatProperties.maxResourceSize); 1304 1305 ASSERT_FALSE(log.find("Emulating call in ICD")); 1306} 1307 1308// Test vkGetPhysicalDeviceImageFormatProperties2 where instance supports it with some ICDs that both support 1309// and don't support it: 1310// ICD 0 supports 1311// Physical device 0 does not 1312// Physical device 1 does 1313// Physical device 2 does not 1314// ICD 1 doesn't support 1315// Physical device 3 does not 1316// ICD 2 supports 1317// Physical device 4 does not 1318// Physical device 5 does not 1319// ICD 3 supports 1320// Physical device 6 does 1321TEST(LoaderInstPhysDevExts, PhysDevImageFormatPropsMixed) { 1322 FrameworkEnvironment env{}; 1323 const uint32_t max_icd_count = 4; 1324 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 1325 const uint32_t max_phys_devs = 7; 1326 1327 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 1328 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 1329 auto& cur_icd = env.get_test_icd(icd); 1330 1331 // ICD 1 should not have 1.1 1332 if (icd != 1) { 1333 cur_icd.icd_api_version = VK_API_VERSION_1_1; 1334 cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1335 } 1336 1337 uint32_t rand_vendor_id; 1338 uint32_t rand_driver_vers; 1339 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 1340 1341 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 1342 uint32_t device_version = VK_API_VERSION_1_0; 1343 cur_icd.physical_devices.push_back({}); 1344 auto& cur_dev = cur_icd.physical_devices.back(); 1345 1346 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 1347 if ((icd == 0 && dev == 1) || icd == 3) { 1348 cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1349 device_version = VK_API_VERSION_1_1; 1350 } 1351 1352 // Still set physical device properties (so we can determine if device is correct API version) 1353 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 1354 FillInRandomImageFormatData(cur_dev.image_format_properties); 1355 } 1356 } 1357 1358 InstWrapper instance(env.vulkan_functions); 1359 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1360 instance.CheckCreate(); 1361 1362 PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysDevImageFormatProps2 = 1363 instance.load("vkGetPhysicalDeviceImageFormatProperties2"); 1364 ASSERT_NE(GetPhysDevImageFormatProps2, nullptr); 1365 1366 uint32_t device_count = max_phys_devs; 1367 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 1368 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 1369 ASSERT_EQ(device_count, max_phys_devs); 1370 1371 for (uint32_t dev = 0; dev < device_count; ++dev) { 1372 VkImageFormatProperties props{}; 1373 ASSERT_EQ(VK_SUCCESS, 1374 instance->vkGetPhysicalDeviceImageFormatProperties(physical_devices[dev], VK_FORMAT_R4G4_UNORM_PACK8, 1375 VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, 0, 0, &props)); 1376 1377 VkPhysicalDeviceImageFormatInfo2 info2{ 1378 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType 1379 nullptr, // pNext 1380 VK_FORMAT_R4G4_UNORM_PACK8, // format 1381 VK_IMAGE_TYPE_2D, // type 1382 VK_IMAGE_TILING_OPTIMAL, // tiling 1383 0, // usage 1384 0, // flags 1385 }; 1386 VkImageFormatProperties2 props2{VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2}; 1387 ASSERT_EQ(VK_SUCCESS, GetPhysDevImageFormatProps2(physical_devices[dev], &info2, &props2)); 1388 1389 ASSERT_EQ(props.maxExtent.width, props2.imageFormatProperties.maxExtent.width); 1390 ASSERT_EQ(props.maxExtent.height, props2.imageFormatProperties.maxExtent.height); 1391 ASSERT_EQ(props.maxExtent.depth, props2.imageFormatProperties.maxExtent.depth); 1392 ASSERT_EQ(props.maxMipLevels, props2.imageFormatProperties.maxMipLevels); 1393 ASSERT_EQ(props.maxArrayLayers, props2.imageFormatProperties.maxArrayLayers); 1394 ASSERT_EQ(props.sampleCounts, props2.imageFormatProperties.sampleCounts); 1395 ASSERT_EQ(props.maxResourceSize, props2.imageFormatProperties.maxResourceSize); 1396 } 1397} 1398 1399// Test vkGetPhysicalDeviceMemoryProperties2KHR where nothing supports it. 1400TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRNoSupport) { 1401 FrameworkEnvironment env{}; 1402 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1403 env.get_test_icd(0).physical_devices.push_back({}); 1404 1405 InstWrapper instance(env.vulkan_functions); 1406 instance.CheckCreate(); 1407 1408 PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysDevMemoryProps2KHR = 1409 instance.load("vkGetPhysicalDeviceMemoryProperties2KHR"); 1410 ASSERT_EQ(GetPhysDevMemoryProps2KHR, nullptr); 1411} 1412 1413// Test vkGetPhysicalDeviceMemoryProperties2KHR where instance supports it, but nothing else. 1414TEST(LoaderInstPhysDevExts, PhysDevMemoryPropsKHRNoICDSupport) { 1415 FrameworkEnvironment env{}; 1416 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1417 env.get_test_icd(0).physical_devices.push_back({}); 1418 1419 InstWrapper instance(env.vulkan_functions); 1420 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 1421 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 1422 1423 PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysDevMemoryProps2KHR = 1424 instance.load("vkGetPhysicalDeviceMemoryProperties2KHR"); 1425 ASSERT_EQ(GetPhysDevMemoryProps2KHR, nullptr); 1426} 1427 1428// Fill in random but valid data into the memory data struct for the current physical device 1429void FillInRandomMemoryData(VkPhysicalDeviceMemoryProperties& props) { 1430 props.memoryTypeCount = (rand() % 7) + 1; 1431 props.memoryHeapCount = (rand() % 7) + 1; 1432 for (uint32_t i = 0; i < props.memoryHeapCount; ++i) { 1433 props.memoryHeaps[i].size = (rand() % 728) + (rand() % 728) + 1; 1434 props.memoryHeaps[i].flags = (rand() % 2) + 1; 1435 } 1436 for (uint32_t i = 0; i < props.memoryTypeCount; ++i) { 1437 props.memoryTypes[i].propertyFlags = static_cast<VkMemoryPropertyFlags>((rand() % 2) + 1); 1438 props.memoryTypes[i].heapIndex = rand() % props.memoryHeapCount; 1439 } 1440} 1441 1442// Compare the memory structs 1443bool CompareMemoryData(const VkPhysicalDeviceMemoryProperties& props1, const VkPhysicalDeviceMemoryProperties2& props2) { 1444 bool equal = true; 1445 equal = equal && props1.memoryTypeCount == props2.memoryProperties.memoryTypeCount; 1446 equal = equal && props1.memoryHeapCount == props2.memoryProperties.memoryHeapCount; 1447 for (uint32_t i = 0; i < props1.memoryHeapCount; ++i) { 1448 equal = equal && props1.memoryHeaps[i].size == props2.memoryProperties.memoryHeaps[i].size; 1449 equal = equal && props1.memoryHeaps[i].flags == props2.memoryProperties.memoryHeaps[i].flags; 1450 } 1451 for (uint32_t i = 0; i < props1.memoryTypeCount; ++i) { 1452 equal = equal && props1.memoryTypes[i].propertyFlags == props2.memoryProperties.memoryTypes[i].propertyFlags; 1453 equal = equal && props1.memoryTypes[i].heapIndex == props2.memoryProperties.memoryTypes[i].heapIndex; 1454 } 1455 return equal; 1456} 1457 1458// Test vkGetPhysicalDeviceMemoryProperties2KHR where instance and ICD supports it, but device does not support it. 1459TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceAndICDSupport) { 1460 FrameworkEnvironment env{}; 1461 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1462 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1463 env.get_test_icd(0).physical_devices.push_back({}); 1464 FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties); 1465 1466 InstWrapper instance(env.vulkan_functions); 1467 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 1468 instance.CheckCreate(); 1469 1470 PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysDevMemoryProps2KHR = 1471 instance.load("vkGetPhysicalDeviceMemoryProperties2KHR"); 1472 ASSERT_NE(GetPhysDevMemoryProps2KHR, nullptr); 1473 1474 uint32_t driver_count = 1; 1475 VkPhysicalDevice physical_device; 1476 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1477 ASSERT_EQ(driver_count, 1U); 1478 1479 VkPhysicalDeviceMemoryProperties props{}; 1480 instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); 1481 1482 VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; 1483 GetPhysDevMemoryProps2KHR(physical_device, &props2); 1484 ASSERT_TRUE(CompareMemoryData(props, props2)); 1485} 1486 1487// Test vkGetPhysicalDeviceMemoryProperties2 where instance supports, an ICD, and a device under that ICD 1488// also support, so everything should work and return properly. 1489// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 1490TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2Simple) { 1491 FrameworkEnvironment env{}; 1492 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1493 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 1494 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1495 env.get_test_icd(0).physical_devices.push_back({}); 1496 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1497 FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties); 1498 { 1499 InstWrapper instance(env.vulkan_functions); 1500 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1501 instance.CheckCreate(); 1502 1503 PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysDevMemoryProps2 = instance.load("vkGetPhysicalDeviceMemoryProperties2"); 1504 ASSERT_NE(GetPhysDevMemoryProps2, nullptr); 1505 1506 uint32_t driver_count = 1; 1507 VkPhysicalDevice physical_device; 1508 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1509 ASSERT_EQ(driver_count, 1U); 1510 1511 VkPhysicalDeviceMemoryProperties props{}; 1512 instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); 1513 1514 VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; 1515 GetPhysDevMemoryProps2(physical_device, &props2); 1516 ASSERT_TRUE(CompareMemoryData(props, props2)); 1517 } 1518 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 1519 InstWrapper instance(env.vulkan_functions); 1520 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 1521 instance.CheckCreate(); 1522 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1523 CreateDebugUtilsMessenger(log); 1524 1525 PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysDevMemoryProps2 = instance.load("vkGetPhysicalDeviceMemoryProperties2"); 1526 ASSERT_NE(GetPhysDevMemoryProps2, nullptr); 1527 1528 uint32_t driver_count = 1; 1529 VkPhysicalDevice physical_device; 1530 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1531 ASSERT_EQ(driver_count, 1U); 1532 1533 VkPhysicalDeviceMemoryProperties props{}; 1534 instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); 1535 1536 VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; 1537 GetPhysDevMemoryProps2(physical_device, &props2); 1538 ASSERT_TRUE(CompareMemoryData(props, props2)); 1539 ASSERT_TRUE(log.find("Emulating call in ICD")); 1540 } 1541 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 1542 .set_name("modify_api_version_layer") 1543 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 1544 .set_disable_environment("DisableEnvVar")), 1545 "modify_api_version_layer.json"); 1546 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 1547 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 1548 InstWrapper instance(env.vulkan_functions); 1549 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 1550 instance.CheckCreate(); 1551 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1552 CreateDebugUtilsMessenger(log); 1553 1554 PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysDevMemoryProps2 = instance.load("vkGetPhysicalDeviceMemoryProperties2"); 1555 ASSERT_NE(GetPhysDevMemoryProps2, nullptr); 1556 1557 uint32_t driver_count = 1; 1558 VkPhysicalDevice physical_device; 1559 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1560 ASSERT_EQ(driver_count, 1U); 1561 1562 VkPhysicalDeviceMemoryProperties props{}; 1563 instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); 1564 1565 VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; 1566 GetPhysDevMemoryProps2(physical_device, &props2); 1567 ASSERT_TRUE(CompareMemoryData(props, props2)); 1568 ASSERT_FALSE(log.find("Emulating call in ICD")); 1569 } 1570} 1571 1572// Test vkGetPhysicalDeviceMemoryProperties2 and vkGetPhysicalDeviceMemoryProperties2KHR where ICD is 1.0 and supports 1573// extension but the instance supports 1.1 and the extension 1574TEST(LoaderInstPhysDevExts, PhysDevMemoryProps2KHRInstanceSupports11) { 1575 FrameworkEnvironment env{}; 1576 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1577 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1578 env.get_test_icd(0).physical_devices.push_back({}); 1579 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1580 FillInRandomMemoryData(env.get_test_icd(0).physical_devices.back().memory_properties); 1581 1582 InstWrapper instance(env.vulkan_functions); 1583 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1584 instance.create_info.add_extensions( 1585 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 1586 instance.CheckCreate(); 1587 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1588 CreateDebugUtilsMessenger(log); 1589 1590 PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysDevMemoryProps2 = instance.load("vkGetPhysicalDeviceMemoryProperties2"); 1591 ASSERT_NE(GetPhysDevMemoryProps2, nullptr); 1592 1593 PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysDevMemoryProps2KHR = 1594 instance.load("vkGetPhysicalDeviceMemoryProperties2KHR"); 1595 ASSERT_NE(GetPhysDevMemoryProps2KHR, nullptr); 1596 1597 uint32_t driver_count = 1; 1598 VkPhysicalDevice physical_device; 1599 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1600 ASSERT_EQ(driver_count, 1U); 1601 1602 VkPhysicalDeviceMemoryProperties props{}; 1603 instance->vkGetPhysicalDeviceMemoryProperties(physical_device, &props); 1604 1605 VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; 1606 GetPhysDevMemoryProps2(physical_device, &props2); 1607 ASSERT_TRUE(CompareMemoryData(props, props2)); 1608 1609 VkPhysicalDeviceMemoryProperties2KHR props2KHR{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR}; 1610 GetPhysDevMemoryProps2KHR(physical_device, &props2KHR); 1611 ASSERT_TRUE(CompareMemoryData(props, props2KHR)); 1612 1613 ASSERT_FALSE(log.find("Emulating call in ICD")); 1614} 1615// Test vkGetPhysicalDeviceMemoryProperties2 where instance supports it with some ICDs that both support 1616// and don't support it: 1617// ICD 0 supports 1618// Physical device 0 does not 1619// Physical device 1 does 1620// Physical device 2 does not 1621// ICD 1 doesn't support 1622// Physical device 3 does not 1623// ICD 2 supports 1624// Physical device 4 does not 1625// Physical device 5 does not 1626// ICD 3 supports 1627// Physical device 6 does 1628TEST(LoaderInstPhysDevExts, PhysDevMemoryPropsMixed) { 1629 FrameworkEnvironment env{}; 1630 const uint32_t max_icd_count = 4; 1631 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 1632 const uint32_t max_phys_devs = 7; 1633 1634 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 1635 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 1636 auto& cur_icd = env.get_test_icd(icd); 1637 1638 // ICD 1 should not have 1.1 1639 if (icd != 1) { 1640 cur_icd.icd_api_version = VK_API_VERSION_1_1; 1641 cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1642 } 1643 1644 uint32_t rand_vendor_id; 1645 uint32_t rand_driver_vers; 1646 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 1647 1648 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 1649 uint32_t device_version = VK_API_VERSION_1_0; 1650 cur_icd.physical_devices.push_back({}); 1651 auto& cur_dev = cur_icd.physical_devices.back(); 1652 1653 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 1654 if ((icd == 0 && dev == 1) || icd == 3) { 1655 cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1656 device_version = VK_API_VERSION_1_1; 1657 } 1658 1659 // Still set physical device properties (so we can determine if device is correct API version) 1660 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 1661 FillInRandomMemoryData(cur_dev.memory_properties); 1662 } 1663 } 1664 1665 InstWrapper instance(env.vulkan_functions); 1666 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1667 instance.CheckCreate(); 1668 1669 PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysDevMemoryProps2 = instance.load("vkGetPhysicalDeviceMemoryProperties2"); 1670 ASSERT_NE(GetPhysDevMemoryProps2, nullptr); 1671 1672 uint32_t device_count = max_phys_devs; 1673 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 1674 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 1675 ASSERT_EQ(device_count, max_phys_devs); 1676 1677 for (uint32_t dev = 0; dev < device_count; ++dev) { 1678 VkPhysicalDeviceMemoryProperties props{}; 1679 instance->vkGetPhysicalDeviceMemoryProperties(physical_devices[dev], &props); 1680 1681 VkPhysicalDeviceMemoryProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2}; 1682 GetPhysDevMemoryProps2(physical_devices[dev], &props2); 1683 ASSERT_TRUE(CompareMemoryData(props, props2)); 1684 } 1685} 1686 1687// Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where nothing supports it. 1688TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRNoSupport) { 1689 FrameworkEnvironment env{}; 1690 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1691 env.get_test_icd(0).physical_devices.push_back({}); 1692 1693 InstWrapper instance(env.vulkan_functions); 1694 instance.CheckCreate(); 1695 1696 PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysDevQueueFamilyProps2KHR = 1697 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2KHR"); 1698 ASSERT_EQ(GetPhysDevQueueFamilyProps2KHR, nullptr); 1699} 1700 1701// Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where instance supports it, but nothing else. 1702TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyPropsKHRNoICDSupport) { 1703 FrameworkEnvironment env{}; 1704 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1705 env.get_test_icd(0).physical_devices.push_back({}); 1706 1707 InstWrapper instance(env.vulkan_functions); 1708 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 1709 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 1710 1711 PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysDevQueueFamilyProps2KHR = 1712 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2KHR"); 1713 ASSERT_EQ(GetPhysDevQueueFamilyProps2KHR, nullptr); 1714} 1715 1716// Fill in random but valid data into the queue family data struct for the current physical device 1717uint32_t FillInRandomQueueFamilyData(std::vector<MockQueueFamilyProperties>& props) { 1718 props.resize((rand() % 4) + 1); 1719 for (uint32_t i = 0; i < props.size(); ++i) { 1720 props[i].properties.queueFlags = (rand() % 30) + 1; 1721 props[i].properties.queueCount = (rand() % 7) + 1; 1722 props[i].properties.timestampValidBits = (rand() % 30) + 7; 1723 props[i].properties.minImageTransferGranularity.width = (rand() % 30) + 1; 1724 props[i].properties.minImageTransferGranularity.height = (rand() % 30) + 1; 1725 props[i].properties.minImageTransferGranularity.depth = (rand() % 30) + 1; 1726 props[i].support_present = rand() % 2 == 0; 1727 } 1728 return static_cast<uint32_t>(props.size()); 1729} 1730 1731// Compare the queue family structs 1732bool CompareQueueFamilyData(const std::vector<VkQueueFamilyProperties>& props1, 1733 const std::vector<VkQueueFamilyProperties2>& props2) { 1734 if (props1.size() != props2.size()) return false; 1735 bool equal = true; 1736 for (uint32_t i = 0; i < props1.size(); ++i) { 1737 equal = equal && props1[i].queueFlags == props2[i].queueFamilyProperties.queueFlags; 1738 equal = equal && props1[i].queueCount == props2[i].queueFamilyProperties.queueCount; 1739 equal = equal && props1[i].timestampValidBits == props2[i].queueFamilyProperties.timestampValidBits; 1740 equal = equal && 1741 props1[i].minImageTransferGranularity.width == props2[i].queueFamilyProperties.minImageTransferGranularity.width; 1742 equal = equal && 1743 props1[i].minImageTransferGranularity.height == props2[i].queueFamilyProperties.minImageTransferGranularity.height; 1744 equal = equal && 1745 props1[i].minImageTransferGranularity.depth == props2[i].queueFamilyProperties.minImageTransferGranularity.depth; 1746 } 1747 return equal; 1748} 1749 1750// Test vkGetPhysicalDeviceQueueFamilyProperties2KHR where instance and ICD supports it, but device does not support it. 1751TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceAndICDSupport) { 1752 FrameworkEnvironment env{}; 1753 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1754 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1755 env.get_test_icd(0).physical_devices.push_back({}); 1756 uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties); 1757 1758 InstWrapper instance(env.vulkan_functions); 1759 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 1760 instance.CheckCreate(); 1761 1762 PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysDevQueueFamilyProps2KHR = 1763 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2KHR"); 1764 ASSERT_NE(GetPhysDevQueueFamilyProps2KHR, nullptr); 1765 1766 uint32_t driver_count = 1; 1767 VkPhysicalDevice physical_device; 1768 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1769 ASSERT_EQ(driver_count, 1U); 1770 1771 uint32_t ret_fam_1 = 0; 1772 std::vector<VkQueueFamilyProperties> props{}; 1773 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); 1774 ASSERT_EQ(num_fam, ret_fam_1); 1775 props.resize(ret_fam_1); 1776 1777 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); 1778 1779 std::vector<VkQueueFamilyProperties2> props2{}; 1780 uint32_t ret_fam_2 = 0; 1781 GetPhysDevQueueFamilyProps2KHR(physical_device, &ret_fam_2, nullptr); 1782 ASSERT_EQ(ret_fam_1, ret_fam_2); 1783 props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); 1784 GetPhysDevQueueFamilyProps2KHR(physical_device, &ret_fam_2, props2.data()); 1785 ASSERT_TRUE(CompareQueueFamilyData(props, props2)); 1786} 1787 1788// Test vkGetPhysicalDeviceQueueFamilyProperties2 where instance supports, an ICD, and a device under that ICD 1789// also support, so everything should work and return properly. 1790// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 1791TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2Simple) { 1792 FrameworkEnvironment env{}; 1793 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1794 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 1795 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1796 env.get_test_icd(0).physical_devices.push_back({}); 1797 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1798 uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties); 1799 { 1800 InstWrapper instance(env.vulkan_functions); 1801 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1802 instance.CheckCreate(); 1803 1804 PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysDevQueueFamilyProps2 = 1805 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2"); 1806 ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); 1807 1808 uint32_t driver_count = 1; 1809 VkPhysicalDevice physical_device; 1810 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1811 ASSERT_EQ(driver_count, 1U); 1812 1813 uint32_t ret_fam_1 = 0; 1814 std::vector<VkQueueFamilyProperties> props{}; 1815 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); 1816 ASSERT_EQ(num_fam, ret_fam_1); 1817 props.resize(ret_fam_1); 1818 1819 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); 1820 1821 std::vector<VkQueueFamilyProperties2> props2{}; 1822 uint32_t ret_fam_2 = 0; 1823 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, nullptr); 1824 ASSERT_EQ(ret_fam_1, ret_fam_2); 1825 props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); 1826 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, props2.data()); 1827 ASSERT_TRUE(CompareQueueFamilyData(props, props2)); 1828 } 1829 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 1830 InstWrapper instance(env.vulkan_functions); 1831 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 1832 instance.CheckCreate(); 1833 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1834 CreateDebugUtilsMessenger(log); 1835 1836 PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysDevQueueFamilyProps2 = 1837 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2"); 1838 ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); 1839 1840 uint32_t driver_count = 1; 1841 VkPhysicalDevice physical_device; 1842 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1843 ASSERT_EQ(driver_count, 1U); 1844 1845 uint32_t ret_fam_1 = 0; 1846 std::vector<VkQueueFamilyProperties> props{}; 1847 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); 1848 ASSERT_EQ(num_fam, ret_fam_1); 1849 props.resize(ret_fam_1); 1850 1851 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); 1852 1853 std::vector<VkQueueFamilyProperties2> props2{}; 1854 uint32_t ret_fam_2 = 0; 1855 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, nullptr); 1856 ASSERT_EQ(ret_fam_1, ret_fam_2); 1857 props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); 1858 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, props2.data()); 1859 ASSERT_TRUE(CompareQueueFamilyData(props, props2)); 1860 ASSERT_TRUE(log.find("Emulating call in ICD")); 1861 } 1862 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 1863 .set_name("modify_api_version_layer") 1864 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 1865 .set_disable_environment("DisableEnvVar")), 1866 "modify_api_version_layer.json"); 1867 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 1868 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 1869 InstWrapper instance(env.vulkan_functions); 1870 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 1871 instance.CheckCreate(); 1872 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1873 CreateDebugUtilsMessenger(log); 1874 1875 PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysDevQueueFamilyProps2 = 1876 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2"); 1877 ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); 1878 1879 uint32_t driver_count = 1; 1880 VkPhysicalDevice physical_device; 1881 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1882 ASSERT_EQ(driver_count, 1U); 1883 1884 uint32_t ret_fam_1 = 0; 1885 std::vector<VkQueueFamilyProperties> props{}; 1886 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); 1887 ASSERT_EQ(num_fam, ret_fam_1); 1888 props.resize(ret_fam_1); 1889 1890 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); 1891 1892 std::vector<VkQueueFamilyProperties2> props2{}; 1893 uint32_t ret_fam_2 = 0; 1894 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, nullptr); 1895 ASSERT_EQ(ret_fam_1, ret_fam_2); 1896 props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); 1897 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, props2.data()); 1898 ASSERT_TRUE(CompareQueueFamilyData(props, props2)); 1899 ASSERT_FALSE(log.find("Emulating call in ICD")); 1900 } 1901} 1902 1903// Test vkGetPhysicalDeviceQueueFamilyProperties2 and vkGetPhysicalDeviceQueueFamilyProperties2KHR where ICD is 1.0 and supports 1904// extension but the instance supports 1.1 and the extension 1905TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyProps2KHRInstanceSupports11) { 1906 FrameworkEnvironment env{}; 1907 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 1908 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1909 env.get_test_icd(0).physical_devices.push_back({}); 1910 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 1911 uint32_t num_fam = FillInRandomQueueFamilyData(env.get_test_icd(0).physical_devices.back().queue_family_properties); 1912 1913 InstWrapper instance(env.vulkan_functions); 1914 instance.create_info.set_api_version(VK_API_VERSION_1_1); 1915 instance.create_info.add_extensions( 1916 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 1917 instance.CheckCreate(); 1918 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 1919 CreateDebugUtilsMessenger(log); 1920 1921 PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysDevQueueFamilyProps2 = 1922 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2"); 1923 ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); 1924 1925 PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysDevQueueFamilyProps2KHR = 1926 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2KHR"); 1927 ASSERT_NE(GetPhysDevQueueFamilyProps2KHR, nullptr); 1928 1929 uint32_t driver_count = 1; 1930 VkPhysicalDevice physical_device; 1931 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 1932 ASSERT_EQ(driver_count, 1U); 1933 1934 uint32_t ret_fam_1 = 0; 1935 std::vector<VkQueueFamilyProperties> props{}; 1936 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, nullptr); 1937 ASSERT_EQ(num_fam, ret_fam_1); 1938 props.resize(ret_fam_1); 1939 1940 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &ret_fam_1, props.data()); 1941 1942 std::vector<VkQueueFamilyProperties2> props2{}; 1943 uint32_t ret_fam_2 = 0; 1944 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, nullptr); 1945 ASSERT_EQ(ret_fam_1, ret_fam_2); 1946 props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); 1947 GetPhysDevQueueFamilyProps2(physical_device, &ret_fam_2, props2.data()); 1948 ASSERT_TRUE(CompareQueueFamilyData(props, props2)); 1949 1950 std::vector<VkQueueFamilyProperties2KHR> props2KHR{}; 1951 uint32_t ret_fam_2_khr = 0; 1952 GetPhysDevQueueFamilyProps2KHR(physical_device, &ret_fam_2_khr, nullptr); 1953 ASSERT_EQ(ret_fam_1, ret_fam_2_khr); 1954 props2KHR.resize(ret_fam_2_khr, VkQueueFamilyProperties2KHR{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR}); 1955 GetPhysDevQueueFamilyProps2KHR(physical_device, &ret_fam_2_khr, props2KHR.data()); 1956 ASSERT_TRUE(CompareQueueFamilyData(props, props2KHR)); 1957 1958 ASSERT_FALSE(log.find("Emulating call in ICD")); 1959} 1960 1961// Test vkGetPhysicalDeviceQueueFamilyProperties2 where instance supports it with some ICDs that both support 1962// and don't support it: 1963// ICD 0 supports 1964// Physical device 0 does not 1965// Physical device 1 does 1966// Physical device 2 does not 1967// ICD 1 doesn't support 1968// Physical device 3 does not 1969// ICD 2 supports 1970// Physical device 4 does not 1971// Physical device 5 does not 1972// ICD 3 supports 1973// Physical device 6 does 1974TEST(LoaderInstPhysDevExts, PhysDevQueueFamilyPropsMixed) { 1975 FrameworkEnvironment env{}; 1976 const uint32_t max_icd_count = 4; 1977 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 1978 const uint32_t max_phys_devs = 7; 1979 1980 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 1981 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 1982 auto& cur_icd = env.get_test_icd(icd); 1983 1984 // ICD 1 should not have 1.1 1985 if (icd != 1) { 1986 cur_icd.icd_api_version = VK_API_VERSION_1_1; 1987 cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 1988 } 1989 1990 uint32_t rand_vendor_id; 1991 uint32_t rand_driver_vers; 1992 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 1993 1994 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 1995 uint32_t device_version = VK_API_VERSION_1_0; 1996 cur_icd.physical_devices.push_back({}); 1997 auto& cur_dev = cur_icd.physical_devices.back(); 1998 1999 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 2000 if ((icd == 0 && dev == 1) || icd == 3) { 2001 cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 2002 device_version = VK_API_VERSION_1_1; 2003 } 2004 2005 // Still set physical device properties (so we can determine if device is correct API version) 2006 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 2007 FillInRandomQueueFamilyData(cur_dev.queue_family_properties); 2008 } 2009 } 2010 2011 InstWrapper instance(env.vulkan_functions); 2012 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2013 instance.CheckCreate(); 2014 2015 PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysDevQueueFamilyProps2 = 2016 instance.load("vkGetPhysicalDeviceQueueFamilyProperties2"); 2017 ASSERT_NE(GetPhysDevQueueFamilyProps2, nullptr); 2018 2019 uint32_t device_count = max_phys_devs; 2020 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 2021 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 2022 ASSERT_EQ(device_count, max_phys_devs); 2023 2024 for (uint32_t dev = 0; dev < device_count; ++dev) { 2025 uint32_t ret_fam_1 = 0; 2026 std::vector<VkQueueFamilyProperties> props{}; 2027 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[dev], &ret_fam_1, nullptr); 2028 props.resize(ret_fam_1); 2029 instance->vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[dev], &ret_fam_1, props.data()); 2030 2031 std::vector<VkQueueFamilyProperties2> props2{}; 2032 uint32_t ret_fam_2 = 0; 2033 GetPhysDevQueueFamilyProps2(physical_devices[dev], &ret_fam_2, nullptr); 2034 ASSERT_EQ(ret_fam_1, ret_fam_2); 2035 props2.resize(ret_fam_2, VkQueueFamilyProperties2{VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2}); 2036 GetPhysDevQueueFamilyProps2(physical_devices[dev], &ret_fam_2, props2.data()); 2037 ASSERT_TRUE(CompareQueueFamilyData(props, props2)); 2038 } 2039} 2040 2041// Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where nothing supports it. 2042TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRNoSupport) { 2043 FrameworkEnvironment env{}; 2044 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2045 env.get_test_icd(0).physical_devices.push_back({}); 2046 2047 InstWrapper instance(env.vulkan_functions); 2048 instance.CheckCreate(); 2049 2050 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysDevSparseImageFormatProps2KHR = 2051 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2KHR"); 2052 ASSERT_EQ(GetPhysDevSparseImageFormatProps2KHR, nullptr); 2053} 2054 2055// Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where instance supports it, but nothing else. 2056TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatPropsKHRNoICDSupport) { 2057 FrameworkEnvironment env{}; 2058 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2059 env.get_test_icd(0).physical_devices.push_back({}); 2060 2061 InstWrapper instance(env.vulkan_functions); 2062 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 2063 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 2064 2065 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysDevSparseImageFormatProps2KHR = 2066 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2KHR"); 2067 ASSERT_EQ(GetPhysDevSparseImageFormatProps2KHR, nullptr); 2068} 2069 2070// Fill in random but valid data into the sparse image format data struct for the current physical device 2071void FillInRandomSparseImageFormatData(std::vector<VkSparseImageFormatProperties>& props) { 2072 props.resize((rand() % 4) + 1); 2073 for (uint32_t i = 0; i < props.size(); ++i) { 2074 props[i].aspectMask = static_cast<VkImageAspectFlags>((rand() % 0x7FE) + 1); 2075 props[i].imageGranularity = {static_cast<uint32_t>(rand() % 512), static_cast<uint32_t>(rand() % 512), 2076 static_cast<uint32_t>(rand() % 512)}; 2077 props[i].flags = static_cast<VkSparseImageFormatFlags>((rand() % 6) + 1); 2078 } 2079} 2080 2081// Compare the sparse image format structs 2082bool CompareSparseImageFormatData(const std::vector<VkSparseImageFormatProperties>& props1, 2083 const std::vector<VkSparseImageFormatProperties2>& props2) { 2084 if (props1.size() != props2.size()) return false; 2085 bool equal = true; 2086 for (uint32_t i = 0; i < props1.size(); ++i) { 2087 equal = equal && props1[i].aspectMask == props2[i].properties.aspectMask; 2088 equal = equal && props1[i].imageGranularity.width == props2[i].properties.imageGranularity.width; 2089 equal = equal && props1[i].imageGranularity.height == props2[i].properties.imageGranularity.height; 2090 equal = equal && props1[i].imageGranularity.depth == props2[i].properties.imageGranularity.depth; 2091 equal = equal && props1[i].flags == props2[i].properties.flags; 2092 } 2093 return equal; 2094} 2095 2096// Test vkGetPhysicalDeviceSparseImageFormatProperties2KHR where instance and ICD supports it, but device does not support it. 2097TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceAndICDSupport) { 2098 FrameworkEnvironment env{}; 2099 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2100 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 2101 env.get_test_icd(0).physical_devices.push_back({}); 2102 FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties); 2103 2104 InstWrapper instance(env.vulkan_functions); 2105 instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); 2106 instance.CheckCreate(); 2107 2108 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysDevSparseImageFormatProps2KHR = 2109 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2KHR"); 2110 ASSERT_NE(GetPhysDevSparseImageFormatProps2KHR, nullptr); 2111 2112 uint32_t driver_count = 1; 2113 VkPhysicalDevice physical_device; 2114 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2115 ASSERT_EQ(driver_count, 1U); 2116 2117 std::vector<VkSparseImageFormatProperties> props{}; 2118 uint32_t sparse_count_1 = 0; 2119 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2120 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2121 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); 2122 ASSERT_NE(sparse_count_1, 0U); 2123 props.resize(sparse_count_1); 2124 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2125 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2126 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); 2127 ASSERT_NE(sparse_count_1, 0U); 2128 2129 VkPhysicalDeviceSparseImageFormatInfo2 info2{ 2130 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType 2131 nullptr, // pNext 2132 VK_FORMAT_R4G4_UNORM_PACK8, // format 2133 VK_IMAGE_TYPE_2D, // type 2134 VK_SAMPLE_COUNT_4_BIT, // samples 2135 VK_IMAGE_USAGE_STORAGE_BIT, // usage 2136 VK_IMAGE_TILING_OPTIMAL, // tiling 2137 }; 2138 std::vector<VkSparseImageFormatProperties2> props2{}; 2139 uint32_t sparse_count_2 = 0; 2140 GetPhysDevSparseImageFormatProps2KHR(physical_device, &info2, &sparse_count_2, nullptr); 2141 ASSERT_EQ(sparse_count_1, sparse_count_2); 2142 props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); 2143 GetPhysDevSparseImageFormatProps2KHR(physical_device, &info2, &sparse_count_2, props2.data()); 2144 ASSERT_EQ(sparse_count_1, sparse_count_2); 2145 ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); 2146} 2147 2148// Test vkGetPhysicalDeviceSparseImageFormatProperties2 where instance supports, an ICD, and a device under that ICD 2149// also support, so everything should work and return properly. 2150// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 2151TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2Simple) { 2152 FrameworkEnvironment env{}; 2153 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2154 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 2155 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 2156 env.get_test_icd(0).physical_devices.push_back({}); 2157 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 2158 FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties); 2159 { 2160 InstWrapper instance(env.vulkan_functions); 2161 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2162 instance.CheckCreate(); 2163 2164 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysDevSparseImageFormatProps2 = 2165 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2"); 2166 ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); 2167 2168 uint32_t driver_count = 1; 2169 VkPhysicalDevice physical_device; 2170 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2171 ASSERT_EQ(driver_count, 1U); 2172 2173 std::vector<VkSparseImageFormatProperties> props{}; 2174 uint32_t sparse_count_1 = 0; 2175 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2176 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2177 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); 2178 ASSERT_NE(sparse_count_1, 0U); 2179 props.resize(sparse_count_1); 2180 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2181 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2182 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); 2183 ASSERT_NE(sparse_count_1, 0U); 2184 2185 VkPhysicalDeviceSparseImageFormatInfo2 info2{ 2186 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType 2187 nullptr, // pNext 2188 VK_FORMAT_R4G4_UNORM_PACK8, // format 2189 VK_IMAGE_TYPE_2D, // type 2190 VK_SAMPLE_COUNT_4_BIT, // samples 2191 VK_IMAGE_USAGE_STORAGE_BIT, // usage 2192 VK_IMAGE_TILING_OPTIMAL, // tiling 2193 }; 2194 std::vector<VkSparseImageFormatProperties2> props2{}; 2195 uint32_t sparse_count_2 = 0; 2196 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, nullptr); 2197 ASSERT_EQ(sparse_count_1, sparse_count_2); 2198 props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); 2199 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, props2.data()); 2200 ASSERT_EQ(sparse_count_1, sparse_count_2); 2201 ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); 2202 } 2203 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 2204 InstWrapper instance(env.vulkan_functions); 2205 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 2206 instance.CheckCreate(); 2207 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 2208 CreateDebugUtilsMessenger(log); 2209 2210 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysDevSparseImageFormatProps2 = 2211 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2"); 2212 ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); 2213 2214 uint32_t driver_count = 1; 2215 VkPhysicalDevice physical_device; 2216 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2217 ASSERT_EQ(driver_count, 1U); 2218 2219 std::vector<VkSparseImageFormatProperties> props{}; 2220 uint32_t sparse_count_1 = 0; 2221 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2222 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2223 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); 2224 ASSERT_NE(sparse_count_1, 0U); 2225 props.resize(sparse_count_1); 2226 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2227 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2228 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); 2229 ASSERT_NE(sparse_count_1, 0U); 2230 2231 VkPhysicalDeviceSparseImageFormatInfo2 info2{ 2232 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType 2233 nullptr, // pNext 2234 VK_FORMAT_R4G4_UNORM_PACK8, // format 2235 VK_IMAGE_TYPE_2D, // type 2236 VK_SAMPLE_COUNT_4_BIT, // samples 2237 VK_IMAGE_USAGE_STORAGE_BIT, // usage 2238 VK_IMAGE_TILING_OPTIMAL, // tiling 2239 }; 2240 std::vector<VkSparseImageFormatProperties2> props2{}; 2241 uint32_t sparse_count_2 = 0; 2242 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, nullptr); 2243 ASSERT_EQ(sparse_count_1, sparse_count_2); 2244 props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); 2245 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, props2.data()); 2246 ASSERT_EQ(sparse_count_1, sparse_count_2); 2247 ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); 2248 ASSERT_TRUE(log.find("Emulating call in ICD")); 2249 } 2250 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 2251 .set_name("modify_api_version_layer") 2252 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 2253 .set_disable_environment("DisableEnvVar")), 2254 "modify_api_version_layer.json"); 2255 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 2256 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 2257 InstWrapper instance(env.vulkan_functions); 2258 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 2259 instance.CheckCreate(); 2260 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 2261 CreateDebugUtilsMessenger(log); 2262 2263 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysDevSparseImageFormatProps2 = 2264 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2"); 2265 ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); 2266 2267 uint32_t driver_count = 1; 2268 VkPhysicalDevice physical_device; 2269 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2270 ASSERT_EQ(driver_count, 1U); 2271 2272 std::vector<VkSparseImageFormatProperties> props{}; 2273 uint32_t sparse_count_1 = 0; 2274 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2275 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2276 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); 2277 ASSERT_NE(sparse_count_1, 0U); 2278 props.resize(sparse_count_1); 2279 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2280 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2281 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); 2282 ASSERT_NE(sparse_count_1, 0U); 2283 2284 VkPhysicalDeviceSparseImageFormatInfo2 info2{ 2285 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType 2286 nullptr, // pNext 2287 VK_FORMAT_R4G4_UNORM_PACK8, // format 2288 VK_IMAGE_TYPE_2D, // type 2289 VK_SAMPLE_COUNT_4_BIT, // samples 2290 VK_IMAGE_USAGE_STORAGE_BIT, // usage 2291 VK_IMAGE_TILING_OPTIMAL, // tiling 2292 }; 2293 std::vector<VkSparseImageFormatProperties2> props2{}; 2294 uint32_t sparse_count_2 = 0; 2295 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, nullptr); 2296 ASSERT_EQ(sparse_count_1, sparse_count_2); 2297 props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); 2298 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, props2.data()); 2299 ASSERT_EQ(sparse_count_1, sparse_count_2); 2300 ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); 2301 ASSERT_FALSE(log.find("Emulating call in ICD")); 2302 } 2303} 2304 2305// Test vkGetPhysicalDeviceSparseImageFormatProperties2 and vkGetPhysicalDeviceSparseImageFormatProperties2KHR where ICD is 1.0 and 2306// supports extension but the instance supports 1.1 and the extension 2307TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatProps2KHRInstanceSupports11) { 2308 FrameworkEnvironment env{}; 2309 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2310 env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 2311 env.get_test_icd(0).physical_devices.push_back({}); 2312 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 2313 FillInRandomSparseImageFormatData(env.get_test_icd(0).physical_devices.back().sparse_image_format_properties); 2314 2315 InstWrapper instance(env.vulkan_functions); 2316 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2317 instance.create_info.add_extensions( 2318 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME}); 2319 instance.CheckCreate(); 2320 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 2321 CreateDebugUtilsMessenger(log); 2322 2323 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysDevSparseImageFormatProps2 = 2324 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2"); 2325 ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); 2326 2327 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysDevSparseImageFormatProps2KHR = 2328 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2KHR"); 2329 ASSERT_NE(GetPhysDevSparseImageFormatProps2KHR, nullptr); 2330 2331 uint32_t driver_count = 1; 2332 VkPhysicalDevice physical_device; 2333 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2334 ASSERT_EQ(driver_count, 1U); 2335 2336 std::vector<VkSparseImageFormatProperties> props{}; 2337 uint32_t sparse_count_1 = 0; 2338 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2339 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2340 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); 2341 ASSERT_NE(sparse_count_1, 0U); 2342 props.resize(sparse_count_1); 2343 instance->vkGetPhysicalDeviceSparseImageFormatProperties(physical_device, VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, 2344 VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2345 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); 2346 ASSERT_NE(sparse_count_1, 0U); 2347 2348 VkPhysicalDeviceSparseImageFormatInfo2 info2{ 2349 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType 2350 nullptr, // pNext 2351 VK_FORMAT_R4G4_UNORM_PACK8, // format 2352 VK_IMAGE_TYPE_2D, // type 2353 VK_SAMPLE_COUNT_4_BIT, // samples 2354 VK_IMAGE_USAGE_STORAGE_BIT, // usage 2355 VK_IMAGE_TILING_OPTIMAL, // tiling 2356 }; 2357 std::vector<VkSparseImageFormatProperties2> props2{}; 2358 uint32_t sparse_count_2 = 0; 2359 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, nullptr); 2360 ASSERT_EQ(sparse_count_1, sparse_count_2); 2361 props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); 2362 GetPhysDevSparseImageFormatProps2(physical_device, &info2, &sparse_count_2, props2.data()); 2363 ASSERT_EQ(sparse_count_1, sparse_count_2); 2364 ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); 2365 2366 std::vector<VkSparseImageFormatProperties2KHR> props2KHR{}; 2367 uint32_t sparse_count_2_khr = 0; 2368 GetPhysDevSparseImageFormatProps2KHR(physical_device, &info2, &sparse_count_2_khr, nullptr); 2369 ASSERT_EQ(sparse_count_1, sparse_count_2_khr); 2370 props2KHR.resize(sparse_count_2, VkSparseImageFormatProperties2KHR{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR}); 2371 GetPhysDevSparseImageFormatProps2KHR(physical_device, &info2, &sparse_count_2_khr, props2KHR.data()); 2372 ASSERT_EQ(sparse_count_1, sparse_count_2_khr); 2373 ASSERT_TRUE(CompareSparseImageFormatData(props, props2KHR)); 2374 2375 ASSERT_FALSE(log.find("Emulating call in ICD")); 2376} 2377 2378// Test vkGetPhysicalDeviceSparseImageFormatProperties2 where instance supports it with some ICDs that both support 2379// and don't support it: 2380// ICD 0 supports 2381// Physical device 0 does not 2382// Physical device 1 does 2383// Physical device 2 does not 2384// ICD 1 doesn't support 2385// Physical device 3 does not 2386// ICD 2 supports 2387// Physical device 4 does not 2388// Physical device 5 does not 2389// ICD 3 supports 2390// Physical device 6 does 2391TEST(LoaderInstPhysDevExts, PhysDevSparseImageFormatPropsMixed) { 2392 FrameworkEnvironment env{}; 2393 const uint32_t max_icd_count = 4; 2394 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 2395 const uint32_t max_phys_devs = 7; 2396 2397 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 2398 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 2399 auto& cur_icd = env.get_test_icd(icd); 2400 2401 // ICD 1 should not have 1.1 2402 if (icd != 1) { 2403 cur_icd.icd_api_version = VK_API_VERSION_1_1; 2404 cur_icd.add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}); 2405 } 2406 2407 uint32_t rand_vendor_id; 2408 uint32_t rand_driver_vers; 2409 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 2410 2411 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 2412 uint32_t device_version = VK_API_VERSION_1_0; 2413 cur_icd.physical_devices.push_back({}); 2414 auto& cur_dev = cur_icd.physical_devices.back(); 2415 2416 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 2417 if ((icd == 0 && dev == 1) || icd == 3) { 2418 cur_dev.extensions.push_back({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 0}); 2419 device_version = VK_API_VERSION_1_1; 2420 } 2421 2422 // Still set physical device properties (so we can determine if device is correct API version) 2423 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 2424 FillInRandomSparseImageFormatData(cur_dev.sparse_image_format_properties); 2425 } 2426 } 2427 2428 InstWrapper instance(env.vulkan_functions); 2429 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2430 instance.CheckCreate(); 2431 2432 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysDevSparseImageFormatProps2 = 2433 instance.load("vkGetPhysicalDeviceSparseImageFormatProperties2"); 2434 ASSERT_NE(GetPhysDevSparseImageFormatProps2, nullptr); 2435 2436 uint32_t device_count = max_phys_devs; 2437 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 2438 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 2439 ASSERT_EQ(device_count, max_phys_devs); 2440 2441 for (uint32_t dev = 0; dev < device_count; ++dev) { 2442 std::vector<VkSparseImageFormatProperties> props{}; 2443 uint32_t sparse_count_1 = 0; 2444 instance->vkGetPhysicalDeviceSparseImageFormatProperties( 2445 physical_devices[dev], VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2446 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, nullptr); 2447 ASSERT_NE(sparse_count_1, 0U); 2448 props.resize(sparse_count_1); 2449 instance->vkGetPhysicalDeviceSparseImageFormatProperties( 2450 physical_devices[dev], VK_FORMAT_R4G4_UNORM_PACK8, VK_IMAGE_TYPE_2D, VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_USAGE_STORAGE_BIT, 2451 VK_IMAGE_TILING_OPTIMAL, &sparse_count_1, props.data()); 2452 ASSERT_NE(sparse_count_1, 0U); 2453 2454 VkPhysicalDeviceSparseImageFormatInfo2 info2{ 2455 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, // sType 2456 nullptr, // pNext 2457 VK_FORMAT_R4G4_UNORM_PACK8, // format 2458 VK_IMAGE_TYPE_2D, // type 2459 VK_SAMPLE_COUNT_4_BIT, // samples 2460 VK_IMAGE_USAGE_STORAGE_BIT, // usage 2461 VK_IMAGE_TILING_OPTIMAL, // tiling 2462 }; 2463 std::vector<VkSparseImageFormatProperties2> props2{}; 2464 uint32_t sparse_count_2 = 0; 2465 GetPhysDevSparseImageFormatProps2(physical_devices[dev], &info2, &sparse_count_2, nullptr); 2466 ASSERT_EQ(sparse_count_1, sparse_count_2); 2467 props2.resize(sparse_count_2, VkSparseImageFormatProperties2{VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2}); 2468 GetPhysDevSparseImageFormatProps2(physical_devices[dev], &info2, &sparse_count_2, props2.data()); 2469 ASSERT_EQ(sparse_count_1, sparse_count_2); 2470 ASSERT_TRUE(CompareSparseImageFormatData(props, props2)); 2471 } 2472} 2473 2474// 2475// VK_KHR_external_memory_capabilities 2476// 2477 2478// Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where nothing supports it. 2479TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsKHRNoSupport) { 2480 FrameworkEnvironment env{}; 2481 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2482 env.get_test_icd(0).physical_devices.push_back({}); 2483 2484 InstWrapper instance(env.vulkan_functions); 2485 instance.CheckCreate(); 2486 2487 PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR = 2488 instance.load("vkGetPhysicalDeviceExternalBufferPropertiesKHR"); 2489 ASSERT_EQ(GetPhysicalDeviceExternalBufferPropertiesKHR, nullptr); 2490} 2491 2492// Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where instance supports it, but nothing else. 2493TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsKHRNoICDSupport) { 2494 FrameworkEnvironment env{}; 2495 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2496 env.get_test_icd(0).physical_devices.push_back({}); 2497 2498 InstWrapper instance(env.vulkan_functions); 2499 instance.create_info.add_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); 2500 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 2501 2502 PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR = 2503 instance.load("vkGetPhysicalDeviceExternalBufferPropertiesKHR"); 2504 ASSERT_EQ(GetPhysicalDeviceExternalBufferPropertiesKHR, nullptr); 2505} 2506 2507// Fill in random but valid data into the external memorydata struct for the current physical device 2508void FillInRandomExtMemoryData(VkExternalMemoryProperties& props) { 2509 props.externalMemoryFeatures = static_cast<VkExternalMemoryFeatureFlags>((rand() % 6) + 1); 2510 props.exportFromImportedHandleTypes = static_cast<VkExternalMemoryHandleTypeFlags>((rand() % 0x1FFE) + 1); 2511 props.compatibleHandleTypes = static_cast<VkExternalMemoryHandleTypeFlags>((rand() % 0x1FFE) + 1); 2512} 2513 2514// Compare the external memory data structs 2515bool CompareExtMemoryData(const VkExternalMemoryProperties& props1, const VkExternalMemoryProperties& props2, 2516 bool supported = true) { 2517 bool equal = true; 2518 if (supported) { 2519 equal = equal && props1.externalMemoryFeatures == props2.externalMemoryFeatures; 2520 equal = equal && props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes; 2521 equal = equal && props1.compatibleHandleTypes == props2.compatibleHandleTypes; 2522 } else { 2523 equal = equal && 0 == props2.externalMemoryFeatures; 2524 equal = equal && 0 == props2.exportFromImportedHandleTypes; 2525 equal = equal && 0 == props2.compatibleHandleTypes; 2526 } 2527 return equal; 2528} 2529 2530// Test vkGetPhysicalDeviceExternalBufferPropertiesKHR where instance and ICD supports it, but device does not support it. 2531TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2KHRInstanceAndICDSupport) { 2532 FrameworkEnvironment env{}; 2533 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2534 env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); 2535 env.get_test_icd(0).physical_devices.push_back({}); 2536 FillInRandomExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties); 2537 2538 InstWrapper instance(env.vulkan_functions); 2539 instance.create_info.add_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); 2540 instance.CheckCreate(); 2541 2542 PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR = 2543 instance.load("vkGetPhysicalDeviceExternalBufferPropertiesKHR"); 2544 ASSERT_NE(GetPhysicalDeviceExternalBufferPropertiesKHR, nullptr); 2545 2546 uint32_t driver_count = 1; 2547 VkPhysicalDevice physical_device; 2548 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2549 ASSERT_EQ(driver_count, 1U); 2550 2551 VkPhysicalDeviceExternalBufferInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR}; 2552 VkExternalBufferPropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR}; 2553 GetPhysicalDeviceExternalBufferPropertiesKHR(physical_device, &info, &props); 2554 ASSERT_TRUE(CompareExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties, 2555 props.externalMemoryProperties)); 2556} 2557 2558// Test vkGetPhysicalDeviceExternalBufferProperties where instance supports, an ICD, and a device under that ICD 2559// also support, so everything should work and return properly. 2560// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 2561TEST(LoaderInstPhysDevExts, PhysDevExtBufProps2Simple) { 2562 FrameworkEnvironment env{}; 2563 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2564 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 2565 env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); 2566 env.get_test_icd(0).physical_devices.push_back({}); 2567 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0}); 2568 FillInRandomExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties); 2569 { 2570 InstWrapper instance(env.vulkan_functions); 2571 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2572 instance.CheckCreate(); 2573 2574 PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties = 2575 instance.load("vkGetPhysicalDeviceExternalBufferProperties"); 2576 ASSERT_NE(GetPhysicalDeviceExternalBufferProperties, nullptr); 2577 2578 uint32_t driver_count = 1; 2579 VkPhysicalDevice physical_device; 2580 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2581 ASSERT_EQ(driver_count, 1U); 2582 2583 VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO}; 2584 VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES}; 2585 GetPhysicalDeviceExternalBufferProperties(physical_device, &info, &props); 2586 ASSERT_TRUE(CompareExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties, 2587 props.externalMemoryProperties)); 2588 } 2589 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 2590 InstWrapper instance(env.vulkan_functions); 2591 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 2592 instance.CheckCreate(); 2593 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 2594 CreateDebugUtilsMessenger(log); 2595 2596 PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties = 2597 instance.load("vkGetPhysicalDeviceExternalBufferProperties"); 2598 ASSERT_NE(GetPhysicalDeviceExternalBufferProperties, nullptr); 2599 2600 uint32_t driver_count = 1; 2601 VkPhysicalDevice physical_device; 2602 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2603 ASSERT_EQ(driver_count, 1U); 2604 2605 VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO}; 2606 VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES}; 2607 GetPhysicalDeviceExternalBufferProperties(physical_device, &info, &props); 2608 // Compare against 'zeroed' out VkExternalMemoryProperties 2609 ASSERT_TRUE(CompareExtMemoryData(VkExternalMemoryProperties{}, props.externalMemoryProperties)); 2610 ASSERT_TRUE(log.find("Emulating call in ICD")); 2611 } 2612 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 2613 .set_name("modify_api_version_layer") 2614 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 2615 .set_disable_environment("DisableEnvVar")), 2616 "modify_api_version_layer.json"); 2617 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 2618 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 2619 InstWrapper instance(env.vulkan_functions); 2620 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 2621 instance.CheckCreate(); 2622 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 2623 CreateDebugUtilsMessenger(log); 2624 2625 PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties = 2626 instance.load("vkGetPhysicalDeviceExternalBufferProperties"); 2627 ASSERT_NE(GetPhysicalDeviceExternalBufferProperties, nullptr); 2628 2629 uint32_t driver_count = 1; 2630 VkPhysicalDevice physical_device; 2631 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2632 ASSERT_EQ(driver_count, 1U); 2633 2634 VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO}; 2635 VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES}; 2636 GetPhysicalDeviceExternalBufferProperties(physical_device, &info, &props); 2637 ASSERT_TRUE(CompareExtMemoryData(env.get_test_icd(0).physical_devices.back().external_memory_properties, 2638 props.externalMemoryProperties)); 2639 ASSERT_FALSE(log.find("Emulating call in ICD")); 2640 } 2641} 2642 2643// Test vkGetPhysicalDeviceExternalBufferProperties where instance supports it with some ICDs that both support 2644// and don't support it: 2645// ICD 0 supports 2646// Physical device 0 does not 2647// Physical device 1 does 2648// Physical device 2 does not 2649// ICD 1 doesn't support 2650// Physical device 3 does not 2651// ICD 2 supports 2652// Physical device 4 does not 2653// Physical device 5 does not 2654// ICD 3 supports 2655// Physical device 6 does 2656TEST(LoaderInstPhysDevExts, PhysDevExtBufPropsMixed) { 2657 FrameworkEnvironment env{}; 2658 const uint32_t max_icd_count = 4; 2659 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 2660 const uint32_t max_phys_devs = 7; 2661 2662 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 2663 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 2664 auto& cur_icd = env.get_test_icd(icd); 2665 2666 // ICD 1 should not have 1.1 2667 if (icd != 1) { 2668 cur_icd.icd_api_version = VK_API_VERSION_1_1; 2669 cur_icd.add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); 2670 } 2671 2672 uint32_t rand_vendor_id; 2673 uint32_t rand_driver_vers; 2674 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 2675 2676 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 2677 uint32_t device_version = VK_API_VERSION_1_0; 2678 cur_icd.physical_devices.push_back({}); 2679 auto& cur_dev = cur_icd.physical_devices.back(); 2680 2681 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 2682 if ((icd == 0 && dev == 1) || icd == 3) { 2683 cur_dev.extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0}); 2684 device_version = VK_API_VERSION_1_1; 2685 } 2686 2687 // Still set physical device properties (so we can determine if device is correct API version) 2688 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 2689 FillInRandomExtMemoryData(cur_dev.external_memory_properties); 2690 } 2691 } 2692 2693 InstWrapper instance(env.vulkan_functions); 2694 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2695 instance.CheckCreate(); 2696 2697 PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties = 2698 instance.load("vkGetPhysicalDeviceExternalBufferProperties"); 2699 ASSERT_NE(GetPhysicalDeviceExternalBufferProperties, nullptr); 2700 2701 uint32_t device_count = max_phys_devs; 2702 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 2703 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 2704 ASSERT_EQ(device_count, max_phys_devs); 2705 2706 for (uint32_t dev = 0; dev < device_count; ++dev) { 2707 VkPhysicalDeviceProperties pd_props{}; 2708 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 2709 2710 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 2711 auto& cur_icd = env.get_test_icd(icd); 2712 bool found = false; 2713 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 2714 auto& cur_dev = cur_icd.physical_devices[pd]; 2715 // Find the ICD device matching the physical device we're looking at info for so we can compare the 2716 // physical devices info with the returned info. 2717 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 2718 cur_dev.properties.deviceType == pd_props.deviceType && 2719 cur_dev.properties.driverVersion == pd_props.driverVersion && 2720 cur_dev.properties.vendorID == pd_props.vendorID) { 2721 VkPhysicalDeviceExternalBufferInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO}; 2722 VkExternalBufferProperties props{VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES}; 2723 GetPhysicalDeviceExternalBufferProperties(physical_devices[dev], &info, &props); 2724 // No driver support for extension or 1.1 for ICD 1, all others support 2725 ASSERT_TRUE(CompareExtMemoryData(cur_dev.external_memory_properties, props.externalMemoryProperties, icd != 1)); 2726 found = true; 2727 break; 2728 } 2729 } 2730 if (found) { 2731 break; 2732 } 2733 } 2734 } 2735} 2736 2737// 2738// VK_KHR_external_semaphore_capabilities 2739// 2740 2741// Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where nothing supports it. 2742TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsKHRNoSupport) { 2743 FrameworkEnvironment env{}; 2744 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2745 env.get_test_icd(0).physical_devices.push_back({}); 2746 2747 InstWrapper instance(env.vulkan_functions); 2748 instance.CheckCreate(); 2749 2750 PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR = 2751 instance.load("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"); 2752 ASSERT_EQ(GetPhysicalDeviceExternalSemaphorePropertiesKHR, nullptr); 2753} 2754 2755// Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where instance supports it, but nothing else. 2756TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsKHRNoICDSupport) { 2757 FrameworkEnvironment env{}; 2758 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2759 env.get_test_icd(0).physical_devices.push_back({}); 2760 2761 InstWrapper instance(env.vulkan_functions); 2762 instance.create_info.add_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); 2763 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 2764 2765 PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR = 2766 instance.load("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"); 2767 ASSERT_EQ(GetPhysicalDeviceExternalSemaphorePropertiesKHR, nullptr); 2768} 2769 2770// Fill in random but valid data into the external semaphore data struct for the current physical device 2771void FillInRandomExtSemData(VkExternalSemaphoreProperties& props) { 2772 props.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES; 2773 props.pNext = nullptr; 2774 props.exportFromImportedHandleTypes = static_cast<VkExternalSemaphoreHandleTypeFlags>((rand() % 0xFFF) + 1); 2775 props.compatibleHandleTypes = static_cast<VkExternalSemaphoreHandleTypeFlags>((rand() % 0xFFF) + 1); 2776 props.externalSemaphoreFeatures = static_cast<VkExternalSemaphoreFeatureFlags>((rand() % 0xFFF) + 1); 2777} 2778 2779// Compare the external semaphore data structs 2780bool CompareExtSemaphoreData(const VkExternalSemaphoreProperties& props1, const VkExternalSemaphoreProperties& props2, 2781 bool supported = true) { 2782 bool equal = true; 2783 if (supported) { 2784 equal = equal && props1.externalSemaphoreFeatures == props2.externalSemaphoreFeatures; 2785 equal = equal && props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes; 2786 equal = equal && props1.compatibleHandleTypes == props2.compatibleHandleTypes; 2787 } else { 2788 equal = equal && 0 == props2.externalSemaphoreFeatures; 2789 equal = equal && 0 == props2.exportFromImportedHandleTypes; 2790 equal = equal && 0 == props2.compatibleHandleTypes; 2791 } 2792 return equal; 2793} 2794 2795// Test vkGetPhysicalDeviceExternalSemaphorePropertiesKHR where instance and ICD supports it, but device does not support it. 2796TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2KHRInstanceAndICDSupport) { 2797 FrameworkEnvironment env{}; 2798 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2799 env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); 2800 env.get_test_icd(0).physical_devices.push_back({}); 2801 FillInRandomExtSemData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties); 2802 2803 InstWrapper instance(env.vulkan_functions); 2804 instance.create_info.add_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); 2805 instance.CheckCreate(); 2806 2807 PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR = 2808 instance.load("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"); 2809 ASSERT_NE(GetPhysicalDeviceExternalSemaphorePropertiesKHR, nullptr); 2810 2811 uint32_t driver_count = 1; 2812 VkPhysicalDevice physical_device; 2813 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2814 ASSERT_EQ(driver_count, 1U); 2815 2816 VkPhysicalDeviceExternalSemaphoreInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR}; 2817 VkExternalSemaphorePropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR}; 2818 GetPhysicalDeviceExternalSemaphorePropertiesKHR(physical_device, &info, &props); 2819 ASSERT_TRUE(CompareExtSemaphoreData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props)); 2820} 2821 2822// Test vkGetPhysicalDeviceExternalSemaphoreProperties where instance supports, an ICD, and a device under that ICD 2823// also support, so everything should work and return properly. 2824// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 2825TEST(LoaderInstPhysDevExts, PhysDevExtSemProps2Simple) { 2826 FrameworkEnvironment env{}; 2827 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 2828 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 2829 env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); 2830 env.get_test_icd(0).physical_devices.push_back({}); 2831 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0}); 2832 FillInRandomExtSemData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties); 2833 { 2834 InstWrapper instance(env.vulkan_functions); 2835 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2836 instance.CheckCreate(); 2837 2838 PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties = 2839 instance.load("vkGetPhysicalDeviceExternalSemaphoreProperties"); 2840 ASSERT_NE(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); 2841 2842 uint32_t driver_count = 1; 2843 VkPhysicalDevice physical_device; 2844 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2845 ASSERT_EQ(driver_count, 1U); 2846 2847 VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO}; 2848 VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES}; 2849 GetPhysicalDeviceExternalSemaphoreProperties(physical_device, &info, &props); 2850 ASSERT_TRUE(CompareExtSemaphoreData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props)); 2851 } 2852 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 2853 InstWrapper instance(env.vulkan_functions); 2854 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 2855 instance.CheckCreate(); 2856 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 2857 CreateDebugUtilsMessenger(log); 2858 PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties = 2859 instance.load("vkGetPhysicalDeviceExternalSemaphoreProperties"); 2860 ASSERT_NE(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); 2861 2862 uint32_t driver_count = 1; 2863 VkPhysicalDevice physical_device; 2864 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2865 ASSERT_EQ(driver_count, 1U); 2866 2867 VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO}; 2868 VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES}; 2869 GetPhysicalDeviceExternalSemaphoreProperties(physical_device, &info, &props); 2870 // Compare against 'zeroed' out VkExternalSemaphoreProperties 2871 ASSERT_TRUE(CompareExtSemaphoreData(VkExternalSemaphoreProperties{}, props)); 2872 ASSERT_TRUE(log.find("Emulating call in ICD")); 2873 } 2874 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 2875 .set_name("modify_api_version_layer") 2876 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 2877 .set_disable_environment("DisableEnvVar")), 2878 "modify_api_version_layer.json"); 2879 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 2880 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 2881 InstWrapper instance(env.vulkan_functions); 2882 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 2883 instance.CheckCreate(); 2884 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 2885 CreateDebugUtilsMessenger(log); 2886 PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties = 2887 instance.load("vkGetPhysicalDeviceExternalSemaphoreProperties"); 2888 ASSERT_NE(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); 2889 2890 uint32_t driver_count = 1; 2891 VkPhysicalDevice physical_device; 2892 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 2893 ASSERT_EQ(driver_count, 1U); 2894 2895 VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO}; 2896 VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES}; 2897 GetPhysicalDeviceExternalSemaphoreProperties(physical_device, &info, &props); 2898 ASSERT_TRUE(CompareExtSemaphoreData(env.get_test_icd(0).physical_devices.back().external_semaphore_properties, props)); 2899 ASSERT_FALSE(log.find("Emulating call in ICD")); 2900 } 2901} 2902 2903// Test vkGetPhysicalDeviceExternalSemaphoreProperties where instance supports it with some ICDs that both support 2904// and don't support it: 2905// ICD 0 supports 2906// Physical device 0 does not 2907// Physical device 1 does 2908// Physical device 2 does not 2909// ICD 1 doesn't support 2910// Physical device 3 does not 2911// ICD 2 supports 2912// Physical device 4 does not 2913// Physical device 5 does not 2914// ICD 3 supports 2915// Physical device 6 does 2916TEST(LoaderInstPhysDevExts, PhysDevExtSemPropsMixed) { 2917 FrameworkEnvironment env{}; 2918 const uint32_t max_icd_count = 4; 2919 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 2920 const uint32_t max_phys_devs = 7; 2921 2922 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 2923 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 2924 auto& cur_icd = env.get_test_icd(icd); 2925 2926 // ICD 1 should not have 1.1 2927 if (icd != 1) { 2928 cur_icd.icd_api_version = VK_API_VERSION_1_1; 2929 cur_icd.add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); 2930 } 2931 2932 uint32_t rand_vendor_id; 2933 uint32_t rand_driver_vers; 2934 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 2935 2936 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 2937 uint32_t device_version = VK_API_VERSION_1_0; 2938 cur_icd.physical_devices.push_back({}); 2939 auto& cur_dev = cur_icd.physical_devices.back(); 2940 2941 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 2942 if ((icd == 0 && dev == 1) || icd == 3) { 2943 cur_dev.extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0}); 2944 device_version = VK_API_VERSION_1_1; 2945 } 2946 2947 // Still set physical device properties (so we can determine if device is correct API version) 2948 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 2949 FillInRandomExtSemData(cur_dev.external_semaphore_properties); 2950 } 2951 } 2952 2953 InstWrapper instance(env.vulkan_functions); 2954 instance.create_info.set_api_version(VK_API_VERSION_1_1); 2955 instance.CheckCreate(); 2956 2957 PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties = 2958 instance.load("vkGetPhysicalDeviceExternalSemaphoreProperties"); 2959 ASSERT_NE(GetPhysicalDeviceExternalSemaphoreProperties, nullptr); 2960 2961 uint32_t device_count = max_phys_devs; 2962 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 2963 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 2964 ASSERT_EQ(device_count, max_phys_devs); 2965 2966 for (uint32_t dev = 0; dev < device_count; ++dev) { 2967 VkPhysicalDeviceProperties pd_props{}; 2968 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 2969 2970 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 2971 auto& cur_icd = env.get_test_icd(icd); 2972 bool found = false; 2973 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 2974 auto& cur_dev = cur_icd.physical_devices[pd]; 2975 // Find the ICD device matching the physical device we're looking at info for so we can compare the 2976 // physical devices info with the returned info. 2977 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 2978 cur_dev.properties.deviceType == pd_props.deviceType && 2979 cur_dev.properties.driverVersion == pd_props.driverVersion && 2980 cur_dev.properties.vendorID == pd_props.vendorID) { 2981 VkPhysicalDeviceExternalSemaphoreInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO}; 2982 VkExternalSemaphoreProperties props{VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES}; 2983 GetPhysicalDeviceExternalSemaphoreProperties(physical_devices[dev], &info, &props); 2984 // No driver support for extension or 1.1 for ICD 1, all others support 2985 ASSERT_TRUE(CompareExtSemaphoreData(cur_dev.external_semaphore_properties, props, icd != 1)); 2986 found = true; 2987 break; 2988 } 2989 } 2990 if (found) { 2991 break; 2992 } 2993 } 2994 } 2995} 2996 2997// 2998// VK_KHR_external_fence_capabilities 2999// 3000 3001// Test vkGetPhysicalDeviceExternalFencePropertiesKHR where nothing supports it. 3002TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsKHRNoSupport) { 3003 FrameworkEnvironment env{}; 3004 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3005 env.get_test_icd(0).physical_devices.push_back({}); 3006 3007 InstWrapper instance(env.vulkan_functions); 3008 instance.CheckCreate(); 3009 3010 PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR = 3011 instance.load("vkGetPhysicalDeviceExternalFencePropertiesKHR"); 3012 ASSERT_EQ(GetPhysicalDeviceExternalFencePropertiesKHR, nullptr); 3013} 3014 3015// Test vkGetPhysicalDeviceExternalFencePropertiesKHR where instance supports it, but nothing else. 3016TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsKHRNoICDSupport) { 3017 FrameworkEnvironment env{}; 3018 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3019 env.get_test_icd(0).physical_devices.push_back({}); 3020 3021 InstWrapper instance(env.vulkan_functions); 3022 instance.create_info.add_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); 3023 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 3024 3025 PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR = 3026 instance.load("vkGetPhysicalDeviceExternalFencePropertiesKHR"); 3027 ASSERT_EQ(GetPhysicalDeviceExternalFencePropertiesKHR, nullptr); 3028} 3029 3030// Fill in random but valid data into the external fence data struct for the current physical device 3031void FillInRandomExtFenceData(VkExternalFenceProperties& props) { 3032 props.sType = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES; 3033 props.pNext = nullptr; 3034 props.exportFromImportedHandleTypes = static_cast<VkExternalFenceHandleTypeFlags>((rand() % 0xFFF) + 1); 3035 props.compatibleHandleTypes = static_cast<VkExternalFenceHandleTypeFlags>((rand() % 0xFFF) + 1); 3036 props.externalFenceFeatures = static_cast<VkExternalFenceFeatureFlags>((rand() % 0xFFF) + 1); 3037} 3038 3039// Compare the external fence data structs 3040bool CompareExtFenceData(const VkExternalFenceProperties& props1, const VkExternalFenceProperties& props2, bool supported = true) { 3041 bool equal = true; 3042 if (supported) { 3043 equal = equal && props1.externalFenceFeatures == props2.externalFenceFeatures; 3044 equal = equal && props1.exportFromImportedHandleTypes == props2.exportFromImportedHandleTypes; 3045 equal = equal && props1.compatibleHandleTypes == props2.compatibleHandleTypes; 3046 } else { 3047 equal = equal && 0 == props2.externalFenceFeatures; 3048 equal = equal && 0 == props2.exportFromImportedHandleTypes; 3049 equal = equal && 0 == props2.compatibleHandleTypes; 3050 } 3051 return equal; 3052} 3053 3054// Test vkGetPhysicalDeviceExternalFencePropertiesKHR where instance and ICD supports it, but device does not support it. 3055TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2KHRInstanceAndICDSupport) { 3056 FrameworkEnvironment env{}; 3057 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3058 env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); 3059 env.get_test_icd(0).physical_devices.push_back({}); 3060 FillInRandomExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties); 3061 3062 InstWrapper instance(env.vulkan_functions); 3063 instance.create_info.add_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); 3064 instance.CheckCreate(); 3065 3066 PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR = 3067 instance.load("vkGetPhysicalDeviceExternalFencePropertiesKHR"); 3068 ASSERT_NE(GetPhysicalDeviceExternalFencePropertiesKHR, nullptr); 3069 3070 uint32_t driver_count = 1; 3071 VkPhysicalDevice physical_device; 3072 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3073 ASSERT_EQ(driver_count, 1U); 3074 3075 VkPhysicalDeviceExternalFenceInfoKHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR}; 3076 VkExternalFencePropertiesKHR props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR}; 3077 GetPhysicalDeviceExternalFencePropertiesKHR(physical_device, &info, &props); 3078 ASSERT_TRUE(CompareExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties, props)); 3079} 3080 3081// Test vkGetPhysicalDeviceExternalFenceProperties where instance supports, an ICD, and a device under that ICD 3082// also support, so everything should work and return properly. 3083// Also check if the application didn't enable 1.1 and when a layer 'upgrades' the api version to 1.1 3084TEST(LoaderInstPhysDevExts, PhysDevExtFenceProps2Simple) { 3085 FrameworkEnvironment env{}; 3086 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3087 env.get_test_icd(0).icd_api_version = VK_API_VERSION_1_1; 3088 env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); 3089 env.get_test_icd(0).physical_devices.push_back({}); 3090 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0}); 3091 FillInRandomExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties); 3092 { 3093 InstWrapper instance(env.vulkan_functions); 3094 instance.create_info.set_api_version(VK_API_VERSION_1_1); 3095 instance.CheckCreate(); 3096 3097 PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties = 3098 instance.load("vkGetPhysicalDeviceExternalFenceProperties"); 3099 ASSERT_NE(GetPhysicalDeviceExternalFenceProperties, nullptr); 3100 3101 uint32_t driver_count = 1; 3102 VkPhysicalDevice physical_device; 3103 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3104 ASSERT_EQ(driver_count, 1U); 3105 3106 VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO}; 3107 VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES}; 3108 GetPhysicalDeviceExternalFenceProperties(physical_device, &info, &props); 3109 ASSERT_TRUE(CompareExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties, props)); 3110 } 3111 { // Now do the same logic but the application didn't enable 1.0 or the extension so they get the emulated call 3112 InstWrapper instance(env.vulkan_functions); 3113 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 3114 instance.CheckCreate(); 3115 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 3116 CreateDebugUtilsMessenger(log); 3117 3118 PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties = 3119 instance.load("vkGetPhysicalDeviceExternalFenceProperties"); 3120 ASSERT_NE(GetPhysicalDeviceExternalFenceProperties, nullptr); 3121 3122 uint32_t driver_count = 1; 3123 VkPhysicalDevice physical_device; 3124 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3125 ASSERT_EQ(driver_count, 1U); 3126 3127 VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO}; 3128 VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES}; 3129 GetPhysicalDeviceExternalFenceProperties(physical_device, &info, &props); 3130 // Compare against 'zeroed' out VkExternalFenceProperties 3131 ASSERT_TRUE(CompareExtFenceData(VkExternalFenceProperties{}, props)); 3132 ASSERT_TRUE(log.find("Emulating call in ICD")); 3133 } 3134 env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} 3135 .set_name("modify_api_version_layer") 3136 .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) 3137 .set_disable_environment("DisableEnvVar")), 3138 "modify_api_version_layer.json"); 3139 env.get_test_layer().set_alter_api_version(VK_API_VERSION_1_1); 3140 { // Now do the same as above but with a layer that updates the version to 1.1 on behalf of the application 3141 InstWrapper instance(env.vulkan_functions); 3142 instance.create_info.add_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); 3143 instance.CheckCreate(); 3144 DebugUtilsWrapper log{instance, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT}; 3145 CreateDebugUtilsMessenger(log); 3146 PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties = 3147 instance.load("vkGetPhysicalDeviceExternalFenceProperties"); 3148 ASSERT_NE(GetPhysicalDeviceExternalFenceProperties, nullptr); 3149 3150 uint32_t driver_count = 1; 3151 VkPhysicalDevice physical_device; 3152 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3153 ASSERT_EQ(driver_count, 1U); 3154 3155 VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO}; 3156 VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES}; 3157 GetPhysicalDeviceExternalFenceProperties(physical_device, &info, &props); 3158 ASSERT_TRUE(CompareExtFenceData(env.get_test_icd(0).physical_devices.back().external_fence_properties, props)); 3159 ASSERT_FALSE(log.find("Emulating call in ICD")); 3160 } 3161} 3162// Test vkGetPhysicalDeviceExternalFenceProperties where instance supports it with some ICDs that both support 3163// and don't support it: 3164// ICD 0 supports 3165// Physical device 0 does not 3166// Physical device 1 does 3167// Physical device 2 does not 3168// ICD 1 doesn't support 3169// Physical device 3 does not 3170// ICD 2 supports 3171// Physical device 4 does not 3172// Physical device 5 does not 3173// ICD 3 supports 3174// Physical device 6 does 3175TEST(LoaderInstPhysDevExts, PhysDevExtFencePropsMixed) { 3176 FrameworkEnvironment env{}; 3177 const uint32_t max_icd_count = 4; 3178 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 3179 const uint32_t max_phys_devs = 7; 3180 3181 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 3182 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 3183 auto& cur_icd = env.get_test_icd(icd); 3184 3185 // ICD 1 should not have 1.1 3186 if (icd != 1) { 3187 cur_icd.icd_api_version = VK_API_VERSION_1_1; 3188 cur_icd.add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); 3189 } 3190 3191 uint32_t rand_vendor_id; 3192 uint32_t rand_driver_vers; 3193 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 3194 3195 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 3196 uint32_t device_version = VK_API_VERSION_1_0; 3197 cur_icd.physical_devices.push_back({}); 3198 auto& cur_dev = cur_icd.physical_devices.back(); 3199 3200 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 3201 if ((icd == 0 && dev == 1) || icd == 3) { 3202 cur_dev.extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0}); 3203 device_version = VK_API_VERSION_1_1; 3204 } 3205 3206 // Still set physical device properties (so we can determine if device is correct API version) 3207 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 3208 FillInRandomExtFenceData(cur_dev.external_fence_properties); 3209 } 3210 } 3211 3212 InstWrapper instance(env.vulkan_functions); 3213 instance.create_info.set_api_version(VK_API_VERSION_1_1); 3214 instance.CheckCreate(); 3215 3216 PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties = 3217 instance.load("vkGetPhysicalDeviceExternalFenceProperties"); 3218 ASSERT_NE(GetPhysicalDeviceExternalFenceProperties, nullptr); 3219 3220 uint32_t device_count = max_phys_devs; 3221 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 3222 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 3223 ASSERT_EQ(device_count, max_phys_devs); 3224 3225 for (uint32_t dev = 0; dev < device_count; ++dev) { 3226 VkPhysicalDeviceProperties pd_props{}; 3227 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 3228 3229 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 3230 auto& cur_icd = env.get_test_icd(icd); 3231 bool found = false; 3232 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 3233 auto& cur_dev = cur_icd.physical_devices[pd]; 3234 // Find the ICD device matching the physical device we're looking at info for so we can compare the 3235 // physical devices info with the returned info. 3236 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 3237 cur_dev.properties.deviceType == pd_props.deviceType && 3238 cur_dev.properties.driverVersion == pd_props.driverVersion && 3239 cur_dev.properties.vendorID == pd_props.vendorID) { 3240 VkPhysicalDeviceExternalFenceInfo info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO}; 3241 VkExternalFenceProperties props{VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES}; 3242 GetPhysicalDeviceExternalFenceProperties(physical_devices[dev], &info, &props); 3243 // No driver support for extension or 1.1 for ICD 1, all others support 3244 ASSERT_TRUE(CompareExtFenceData(cur_dev.external_fence_properties, props, icd != 1)); 3245 found = true; 3246 break; 3247 } 3248 } 3249 if (found) { 3250 break; 3251 } 3252 } 3253 } 3254} 3255 3256// 3257// VK_KHR_get_surface_capabilities2 3258// 3259 3260// Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where nothing supports it. 3261TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRNoSupport) { 3262 FrameworkEnvironment env{}; 3263 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3264 env.get_test_icd(0).physical_devices.push_back({}); 3265 3266 InstWrapper instance(env.vulkan_functions); 3267 instance.CheckCreate(); 3268 3269 PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR = 3270 instance.load("vkGetPhysicalDeviceSurfaceCapabilities2KHR"); 3271 ASSERT_EQ(GetPhysicalDeviceSurfaceCapabilities2KHR, nullptr); 3272} 3273 3274// Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where instance supports it, but nothing else. 3275TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRNoICDSupport) { 3276 FrameworkEnvironment env{}; 3277 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3278 env.get_test_icd(0).physical_devices.push_back({}); 3279 3280 InstWrapper instance(env.vulkan_functions); 3281 instance.create_info.add_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME); 3282 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 3283 3284 PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR = 3285 instance.load("vkGetPhysicalDeviceSurfaceCapabilities2KHR"); 3286 ASSERT_EQ(GetPhysicalDeviceSurfaceCapabilities2KHR, nullptr); 3287} 3288 3289// Fill in random but valid data into the surface capability data struct for the current physical device 3290void FillInRandomSurfaceCapsData(VkSurfaceCapabilitiesKHR& props) { 3291 props.minImageCount = (rand() % 0xFFF) + 1; 3292 props.maxImageCount = (rand() % 0xFFF) + 1; 3293 props.currentExtent.width = (rand() % 0xFFF) + 1; 3294 props.currentExtent.height = (rand() % 0xFFF) + 1; 3295 props.minImageExtent.width = (rand() % 0xFFF) + 1; 3296 props.minImageExtent.height = (rand() % 0xFFF) + 1; 3297 props.maxImageExtent.width = (rand() % 0xFFF) + 1; 3298 props.maxImageExtent.height = (rand() % 0xFFF) + 1; 3299 props.maxImageArrayLayers = (rand() % 0xFFF) + 1; 3300 props.supportedTransforms = static_cast<VkSurfaceTransformFlagsKHR>((rand() % 0xFFF) + 1); 3301 props.currentTransform = static_cast<VkSurfaceTransformFlagBitsKHR>((rand() % 0xFFF) + 1); 3302 props.supportedCompositeAlpha = static_cast<VkCompositeAlphaFlagsKHR>((rand() % 0xFFF) + 1); 3303 props.supportedUsageFlags = static_cast<VkImageUsageFlags>((rand() % 0xFFF) + 1); 3304} 3305 3306// Compare the surface capability data structs 3307bool CompareSurfaceCapsData(const VkSurfaceCapabilitiesKHR& props1, const VkSurfaceCapabilitiesKHR& props2, bool supported = true) { 3308 bool equal = true; 3309 if (supported) { 3310 equal = equal && props1.minImageCount == props2.minImageCount; 3311 equal = equal && props1.maxImageCount == props2.maxImageCount; 3312 equal = equal && props1.currentExtent.width == props2.currentExtent.width; 3313 equal = equal && props1.currentExtent.height == props2.currentExtent.height; 3314 equal = equal && props1.minImageExtent.width == props2.minImageExtent.width; 3315 equal = equal && props1.minImageExtent.height == props2.minImageExtent.height; 3316 equal = equal && props1.maxImageExtent.width == props2.maxImageExtent.width; 3317 equal = equal && props1.maxImageExtent.height == props2.maxImageExtent.height; 3318 equal = equal && props1.maxImageArrayLayers == props2.maxImageArrayLayers; 3319 equal = equal && props1.supportedTransforms == props2.supportedTransforms; 3320 equal = equal && props1.currentTransform == props2.currentTransform; 3321 equal = equal && props1.supportedCompositeAlpha == props2.supportedCompositeAlpha; 3322 equal = equal && props1.supportedUsageFlags == props2.supportedUsageFlags; 3323 } else { 3324 equal = equal && 0 == props2.minImageCount; 3325 equal = equal && 0 == props2.maxImageCount; 3326 equal = equal && 0 == props2.currentExtent.width; 3327 equal = equal && 0 == props2.currentExtent.height; 3328 equal = equal && 0 == props2.minImageExtent.width; 3329 equal = equal && 0 == props2.minImageExtent.height; 3330 equal = equal && 0 == props2.maxImageExtent.width; 3331 equal = equal && 0 == props2.maxImageExtent.height; 3332 equal = equal && 0 == props2.maxImageArrayLayers; 3333 equal = equal && 0 == props2.supportedTransforms; 3334 equal = equal && 0 == props2.currentTransform; 3335 equal = equal && 0 == props2.supportedCompositeAlpha; 3336 equal = equal && 0 == props2.supportedUsageFlags; 3337 } 3338 return equal; 3339} 3340 3341// Test vkGetPhysicalDeviceSurfaceCapabilities2KHR where instance and ICD supports it, but device does not support it. 3342TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRInstanceAndICDSupport) { 3343 FrameworkEnvironment env{}; 3344 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3345 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; 3346 Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; 3347 Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; 3348 auto& cur_icd = env.get_test_icd(0); 3349 cur_icd.add_instance_extensions({first_ext, second_ext, third_ext}); 3350 cur_icd.physical_devices.push_back({}); 3351 cur_icd.min_icd_interface_version = 3; 3352 cur_icd.enable_icd_wsi = true; 3353 FillInRandomSurfaceCapsData(env.get_test_icd(0).physical_devices.back().surface_capabilities); 3354 3355 InstWrapper instance(env.vulkan_functions); 3356 instance.create_info.add_extensions( 3357 {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); 3358 instance.CheckCreate(); 3359 3360 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR = 3361 instance.load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); 3362 ASSERT_NE(GetPhysicalDeviceSurfaceCapabilitiesKHR, nullptr); 3363 PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT = instance.load("vkCreateHeadlessSurfaceEXT"); 3364 ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); 3365 PFN_vkDestroySurfaceKHR DestroySurfaceKHR = instance.load("vkDestroySurfaceKHR"); 3366 ASSERT_NE(DestroySurfaceKHR, nullptr); 3367 PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR = 3368 instance.load("vkGetPhysicalDeviceSurfaceCapabilities2KHR"); 3369 ASSERT_NE(GetPhysicalDeviceSurfaceCapabilities2KHR, nullptr); 3370 3371 uint32_t driver_count = 1; 3372 VkPhysicalDevice physical_device; 3373 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3374 ASSERT_EQ(driver_count, 1U); 3375 3376 VkSurfaceKHR surface; 3377 VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; 3378 ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); 3379 3380 VkSurfaceCapabilitiesKHR props{}; 3381 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &props)); 3382 3383 VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; 3384 VkSurfaceCapabilities2KHR props2{VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR}; 3385 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilities2KHR(physical_device, &info, &props2)); 3386 ASSERT_TRUE(CompareSurfaceCapsData(props, props2.surfaceCapabilities)); 3387 3388 DestroySurfaceKHR(instance.inst, surface, nullptr); 3389} 3390 3391// Test vkGetPhysicalDeviceSurfaceCapabilities2 where instance supports it with some ICDs that both support 3392// and don't support it: 3393// ICD 0 supports 3394// Physical device 0 does not 3395// Physical device 1 does 3396// Physical device 2 does not 3397// ICD 1 doesn't support 3398// Physical device 3 does not 3399// ICD 2 supports 3400// Physical device 4 does not 3401// Physical device 5 does not 3402// ICD 3 supports 3403// Physical device 6 does 3404TEST(LoaderInstPhysDevExts, PhysDevSurfaceCaps2KHRMixed) { 3405 FrameworkEnvironment env{}; 3406 const uint32_t max_icd_count = 4; 3407 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 3408 const uint32_t max_phys_devs = 7; 3409 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; 3410 Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; 3411 Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; 3412 3413 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 3414 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 3415 auto& cur_icd = env.get_test_icd(icd); 3416 cur_icd.icd_api_version = VK_API_VERSION_1_0; 3417 cur_icd.min_icd_interface_version = 3; 3418 cur_icd.enable_icd_wsi = true; 3419 cur_icd.add_instance_extensions({first_ext, third_ext}); 3420 3421 // ICD 1 should not have 1.1 3422 if (icd != 1) { 3423 cur_icd.icd_api_version = VK_API_VERSION_1_1; 3424 cur_icd.add_instance_extension(second_ext); 3425 } 3426 3427 uint32_t rand_vendor_id; 3428 uint32_t rand_driver_vers; 3429 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 3430 3431 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 3432 uint32_t device_version = VK_API_VERSION_1_0; 3433 cur_icd.physical_devices.push_back({}); 3434 auto& cur_dev = cur_icd.physical_devices.back(); 3435 cur_dev.extensions.push_back({VK_KHR_SURFACE_EXTENSION_NAME, 0}); 3436 cur_dev.extensions.push_back({VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, 0}); 3437 3438 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 3439 if ((icd == 0 && dev == 1) || icd == 3) { 3440 cur_dev.extensions.push_back({VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 0}); 3441 device_version = VK_API_VERSION_1_1; 3442 } 3443 3444 // Still set physical device properties (so we can determine if device is correct API version) 3445 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 3446 FillInRandomSurfaceCapsData(cur_dev.surface_capabilities); 3447 } 3448 } 3449 3450 InstWrapper instance(env.vulkan_functions); 3451 instance.create_info.add_extensions( 3452 {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); 3453 instance.CheckCreate(); 3454 3455 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR = 3456 instance.load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); 3457 ASSERT_NE(GetPhysicalDeviceSurfaceCapabilitiesKHR, nullptr); 3458 PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT = instance.load("vkCreateHeadlessSurfaceEXT"); 3459 ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); 3460 PFN_vkDestroySurfaceKHR DestroySurfaceKHR = instance.load("vkDestroySurfaceKHR"); 3461 ASSERT_NE(DestroySurfaceKHR, nullptr); 3462 PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR = 3463 instance.load("vkGetPhysicalDeviceSurfaceCapabilities2KHR"); 3464 ASSERT_NE(GetPhysicalDeviceSurfaceCapabilities2KHR, nullptr); 3465 3466 uint32_t device_count = max_phys_devs; 3467 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 3468 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 3469 ASSERT_EQ(device_count, max_phys_devs); 3470 3471 VkSurfaceKHR surface; 3472 VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; 3473 ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); 3474 3475 for (uint32_t dev = 0; dev < device_count; ++dev) { 3476 VkSurfaceCapabilitiesKHR props{}; 3477 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices[dev], surface, &props)); 3478 3479 VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; 3480 VkSurfaceCapabilities2KHR props2{VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR}; 3481 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceCapabilities2KHR(physical_devices[dev], &info, &props2)); 3482 ASSERT_TRUE(CompareSurfaceCapsData(props, props2.surfaceCapabilities)); 3483 } 3484 3485 DestroySurfaceKHR(instance.inst, surface, nullptr); 3486} 3487 3488// Test vkGetPhysicalDeviceSurfaceFormats2KHR where nothing supports it. 3489TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRNoSupport) { 3490 FrameworkEnvironment env{}; 3491 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3492 env.get_test_icd(0).physical_devices.push_back({}); 3493 3494 InstWrapper instance(env.vulkan_functions); 3495 instance.CheckCreate(); 3496 3497 PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR = 3498 instance.load("vkGetPhysicalDeviceSurfaceFormats2KHR"); 3499 ASSERT_EQ(GetPhysicalDeviceSurfaceFormats2KHR, nullptr); 3500} 3501 3502// Test vkGetPhysicalDeviceSurfaceFormats2KHR where instance supports it, but nothing else. 3503TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRNoICDSupport) { 3504 FrameworkEnvironment env{}; 3505 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3506 env.get_test_icd(0).physical_devices.push_back({}); 3507 3508 InstWrapper instance(env.vulkan_functions); 3509 instance.create_info.add_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME); 3510 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 3511 3512 PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR = 3513 instance.load("vkGetPhysicalDeviceSurfaceFormats2KHR"); 3514 ASSERT_EQ(GetPhysicalDeviceSurfaceFormats2KHR, nullptr); 3515} 3516 3517// Fill in random but valid data into the surface formats data struct for the current physical device 3518void FillInRandomSurfaceFormatsData(std::vector<VkSurfaceFormatKHR>& props) { 3519 props.resize((rand() % 5) + 1); 3520 for (uint32_t i = 0; i < props.size(); ++i) { 3521 props[i].format = static_cast<VkFormat>((rand() % 0xFFF) + 1); 3522 props[i].colorSpace = static_cast<VkColorSpaceKHR>((rand() % 0xFFF) + 1); 3523 } 3524} 3525 3526// Compare the surface formats data structs 3527bool CompareSurfaceFormatsData(const std::vector<VkSurfaceFormatKHR>& props1, const std::vector<VkSurfaceFormat2KHR>& props2, 3528 bool supported = true) { 3529 if (props1.size() != props2.size()) return false; 3530 bool equal = true; 3531 for (uint32_t i = 0; i < props1.size(); ++i) { 3532 if (supported) { 3533 equal = equal && props1[i].format == props2[i].surfaceFormat.format; 3534 equal = equal && props1[i].colorSpace == props2[i].surfaceFormat.colorSpace; 3535 } else { 3536 equal = equal && 0 == props2[i].surfaceFormat.format; 3537 equal = equal && 0 == props2[i].surfaceFormat.colorSpace; 3538 } 3539 } 3540 return equal; 3541} 3542 3543// Test vkGetPhysicalDeviceSurfaceFormats2KHR where instance and ICD supports it, but device does not support it. 3544TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRInstanceAndICDSupport) { 3545 FrameworkEnvironment env{}; 3546 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3547 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; 3548 Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; 3549 Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; 3550 auto& cur_icd = env.get_test_icd(0); 3551 cur_icd.add_instance_extensions({first_ext, second_ext, third_ext}); 3552 cur_icd.physical_devices.push_back({}); 3553 cur_icd.min_icd_interface_version = 3; 3554 cur_icd.enable_icd_wsi = true; 3555 FillInRandomSurfaceFormatsData(env.get_test_icd(0).physical_devices.back().surface_formats); 3556 3557 InstWrapper instance(env.vulkan_functions); 3558 instance.create_info.add_extensions( 3559 {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); 3560 instance.CheckCreate(); 3561 3562 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR = 3563 instance.load("vkGetPhysicalDeviceSurfaceFormatsKHR"); 3564 ASSERT_NE(GetPhysicalDeviceSurfaceFormatsKHR, nullptr); 3565 PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT = instance.load("vkCreateHeadlessSurfaceEXT"); 3566 ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); 3567 PFN_vkDestroySurfaceKHR DestroySurfaceKHR = instance.load("vkDestroySurfaceKHR"); 3568 ASSERT_NE(DestroySurfaceKHR, nullptr); 3569 PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR = 3570 instance.load("vkGetPhysicalDeviceSurfaceFormats2KHR"); 3571 ASSERT_NE(GetPhysicalDeviceSurfaceFormats2KHR, nullptr); 3572 3573 uint32_t driver_count = 1; 3574 VkPhysicalDevice physical_device; 3575 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3576 ASSERT_EQ(driver_count, 1U); 3577 3578 VkSurfaceKHR surface; 3579 VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; 3580 ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); 3581 3582 std::vector<VkSurfaceFormatKHR> props{}; 3583 uint32_t count_1 = 0; 3584 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &count_1, nullptr)); 3585 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().surface_formats.size(), count_1); 3586 props.resize(count_1); 3587 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &count_1, props.data())); 3588 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().surface_formats.size(), count_1); 3589 3590 VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; 3591 std::vector<VkSurfaceFormat2KHR> props2{}; 3592 uint32_t count_2 = 0; 3593 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2KHR(physical_device, &info, &count_2, nullptr)); 3594 ASSERT_EQ(count_1, count_2); 3595 props2.resize(count_2, VkSurfaceFormat2KHR{VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR}); 3596 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2KHR(physical_device, &info, &count_2, props2.data())); 3597 ASSERT_TRUE(CompareSurfaceFormatsData(props, props2)); 3598 3599 DestroySurfaceKHR(instance.inst, surface, nullptr); 3600} 3601 3602// Test vkGetPhysicalDeviceSurfaceFormats2 where instance supports it with some ICDs that both support 3603// and don't support it: 3604// ICD 0 supports 3605// Physical device 0 does not 3606// Physical device 1 does 3607// Physical device 2 does not 3608// ICD 1 doesn't support 3609// Physical device 3 does not 3610// ICD 2 supports 3611// Physical device 4 does not 3612// Physical device 5 does not 3613// ICD 3 supports 3614// Physical device 6 does 3615TEST(LoaderInstPhysDevExts, PhysDevSurfaceFormats2KHRMixed) { 3616 FrameworkEnvironment env{}; 3617 const uint32_t max_icd_count = 4; 3618 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 3619 const uint32_t max_phys_devs = 7; 3620 Extension first_ext{VK_KHR_SURFACE_EXTENSION_NAME}; 3621 Extension second_ext{VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}; 3622 Extension third_ext{VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME}; 3623 3624 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 3625 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 3626 auto& cur_icd = env.get_test_icd(icd); 3627 cur_icd.icd_api_version = VK_API_VERSION_1_0; 3628 cur_icd.enable_icd_wsi = true; 3629 cur_icd.min_icd_interface_version = 3; 3630 cur_icd.add_instance_extensions({first_ext, third_ext}); 3631 3632 // ICD 1 should not have 1.1 3633 if (icd != 1) { 3634 cur_icd.icd_api_version = VK_API_VERSION_1_1; 3635 cur_icd.add_instance_extension(second_ext); 3636 } 3637 3638 uint32_t rand_vendor_id; 3639 uint32_t rand_driver_vers; 3640 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 3641 3642 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 3643 uint32_t device_version = VK_API_VERSION_1_0; 3644 cur_icd.physical_devices.push_back({}); 3645 auto& cur_dev = cur_icd.physical_devices.back(); 3646 cur_dev.extensions.push_back({VK_KHR_SURFACE_EXTENSION_NAME, 0}); 3647 cur_dev.extensions.push_back({VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, 0}); 3648 3649 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 3650 if ((icd == 0 && dev == 1) || icd == 3) { 3651 cur_dev.extensions.push_back({VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, 0}); 3652 device_version = VK_API_VERSION_1_1; 3653 } 3654 3655 // Still set physical device properties (so we can determine if device is correct API version) 3656 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 3657 FillInRandomSurfaceFormatsData(cur_dev.surface_formats); 3658 } 3659 } 3660 3661 InstWrapper instance(env.vulkan_functions); 3662 instance.create_info.add_extensions( 3663 {VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME}); 3664 instance.CheckCreate(); 3665 3666 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR = 3667 instance.load("vkGetPhysicalDeviceSurfaceFormatsKHR"); 3668 ASSERT_NE(GetPhysicalDeviceSurfaceFormatsKHR, nullptr); 3669 PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT = instance.load("vkCreateHeadlessSurfaceEXT"); 3670 ASSERT_NE(CreateHeadlessSurfaceEXT, nullptr); 3671 PFN_vkDestroySurfaceKHR DestroySurfaceKHR = instance.load("vkDestroySurfaceKHR"); 3672 ASSERT_NE(DestroySurfaceKHR, nullptr); 3673 PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR = 3674 instance.load("vkGetPhysicalDeviceSurfaceFormats2KHR"); 3675 ASSERT_NE(GetPhysicalDeviceSurfaceFormats2KHR, nullptr); 3676 3677 uint32_t device_count = max_phys_devs; 3678 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 3679 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 3680 ASSERT_EQ(device_count, max_phys_devs); 3681 3682 VkSurfaceKHR surface; 3683 VkHeadlessSurfaceCreateInfoEXT create_info{VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; 3684 ASSERT_EQ(VK_SUCCESS, CreateHeadlessSurfaceEXT(instance.inst, &create_info, nullptr, &surface)); 3685 3686 for (uint32_t dev = 0; dev < device_count; ++dev) { 3687 std::vector<VkSurfaceFormatKHR> props{}; 3688 uint32_t count_1 = 0; 3689 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormatsKHR(physical_devices[dev], surface, &count_1, nullptr)); 3690 ASSERT_NE(0U, count_1); 3691 props.resize(count_1); 3692 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormatsKHR(physical_devices[dev], surface, &count_1, props.data())); 3693 ASSERT_NE(0U, count_1); 3694 3695 VkPhysicalDeviceSurfaceInfo2KHR info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface}; 3696 std::vector<VkSurfaceFormat2KHR> props2{}; 3697 uint32_t count_2 = 0; 3698 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2KHR(physical_devices[dev], &info, &count_2, nullptr)); 3699 ASSERT_EQ(count_1, count_2); 3700 props2.resize(count_2, VkSurfaceFormat2KHR{VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR}); 3701 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceSurfaceFormats2KHR(physical_devices[dev], &info, &count_2, props2.data())); 3702 ASSERT_EQ(count_1, count_2); 3703 ASSERT_TRUE(CompareSurfaceFormatsData(props, props2)); 3704 } 3705 3706 DestroySurfaceKHR(instance.inst, surface, nullptr); 3707} 3708 3709// 3710// VK_KHR_display 3711// 3712 3713// Test vkGetPhysicalDeviceDisplayPropertiesKHR where nothing supports it. 3714TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRNoSupport) { 3715 FrameworkEnvironment env{}; 3716 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3717 env.get_test_icd(0).physical_devices.push_back({}); 3718 3719 InstWrapper instance(env.vulkan_functions); 3720 instance.CheckCreate(); 3721 3722 PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR = 3723 instance.load("vkGetPhysicalDeviceDisplayPropertiesKHR"); 3724 ASSERT_EQ(GetPhysicalDeviceDisplayPropertiesKHR, nullptr); 3725} 3726 3727// Test vkGetPhysicalDeviceDisplayPropertiesKHR where instance supports it, but nothing else. 3728TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRNoICDSupport) { 3729 FrameworkEnvironment env{}; 3730 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3731 env.get_test_icd(0).physical_devices.push_back({}); 3732 3733 InstWrapper instance(env.vulkan_functions); 3734 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 3735 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 3736 3737 PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR = 3738 instance.load("vkGetPhysicalDeviceDisplayPropertiesKHR"); 3739 ASSERT_EQ(GetPhysicalDeviceDisplayPropertiesKHR, nullptr); 3740} 3741 3742VkDisplayKHR CreateRandomDisplay() { return (VkDisplayKHR)(((rand() % 0xFFFFFFFBull) << 12) * (rand() % 0xFFFFFFFull) + 1); } 3743 3744VkDisplayModeKHR CreateRandomDisplayMode() { 3745 return (VkDisplayModeKHR)(((rand() % 0xFFFFFFFBull) << 12) * (rand() % 0xFFFFFFFull) + 1); 3746} 3747 3748// Fill in random but valid data into the display property data struct for the current physical device 3749void FillInRandomDisplayPropData(std::vector<VkDisplayPropertiesKHR>& props) { 3750 props.resize((rand() % 5) + 1); 3751 for (uint32_t i = 0; i < props.size(); ++i) { 3752 props[i].display = CreateRandomDisplay(); 3753 props[i].physicalDimensions.width = static_cast<uint32_t>((rand() % 0xFFF) + 1); 3754 props[i].physicalDimensions.height = static_cast<uint32_t>((rand() % 0xFFF) + 1); 3755 props[i].physicalResolution.width = static_cast<uint32_t>((rand() % 0xFFF) + 1); 3756 props[i].physicalResolution.height = static_cast<uint32_t>((rand() % 0xFFF) + 1); 3757 props[i].supportedTransforms = static_cast<VkSurfaceTransformFlagsKHR>((rand() % 0xFFE) + 1); 3758 props[i].planeReorderPossible = rand() % 2 > 0 ? VK_TRUE : VK_FALSE; 3759 props[i].persistentContent = rand() % 2 > 0 ? VK_TRUE : VK_FALSE; 3760 } 3761} 3762 3763// Compare the display property data structs 3764bool CompareDisplayPropData(const std::vector<VkDisplayPropertiesKHR>& props1, const std::vector<VkDisplayPropertiesKHR>& props2) { 3765 if (props1.size() != props2.size()) return false; 3766 bool equal = true; 3767 for (uint32_t i = 0; i < props1.size(); ++i) { 3768 equal = equal && props1[i].display == props2[i].display; 3769 equal = equal && props1[i].physicalDimensions.width == props2[i].physicalDimensions.width; 3770 equal = equal && props1[i].physicalDimensions.height == props2[i].physicalDimensions.height; 3771 equal = equal && props1[i].physicalResolution.width == props2[i].physicalResolution.width; 3772 equal = equal && props1[i].physicalResolution.height == props2[i].physicalResolution.height; 3773 equal = equal && props1[i].supportedTransforms == props2[i].supportedTransforms; 3774 equal = equal && props1[i].planeReorderPossible == props2[i].planeReorderPossible; 3775 equal = equal && props1[i].persistentContent == props2[i].persistentContent; 3776 } 3777 return equal; 3778} 3779 3780// Test vGetPhysicalDeviceDisplayPropertiesKHR where instance and ICD supports it, but device does not support it. 3781TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRInstanceAndICDSupport) { 3782 FrameworkEnvironment env{}; 3783 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3784 env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 3785 env.get_test_icd(0).physical_devices.push_back({}); 3786 FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties); 3787 3788 InstWrapper instance(env.vulkan_functions); 3789 instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 3790 instance.CheckCreate(); 3791 3792 PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR = 3793 instance.load("vkGetPhysicalDeviceDisplayPropertiesKHR"); 3794 ASSERT_NE(GetPhysicalDeviceDisplayPropertiesKHR, nullptr); 3795 3796 uint32_t driver_count = 1; 3797 VkPhysicalDevice physical_device; 3798 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3799 ASSERT_EQ(driver_count, 1U); 3800 3801 std::vector<VkDisplayPropertiesKHR> props{}; 3802 uint32_t prop_count = 0; 3803 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_device, &prop_count, nullptr)); 3804 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_properties.size(), prop_count); 3805 props.resize(prop_count); 3806 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_device, &prop_count, props.data())); 3807 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_properties.size(), prop_count); 3808 3809 ASSERT_TRUE(CompareDisplayPropData(props, env.get_test_icd(0).physical_devices.back().display_properties)); 3810} 3811 3812// Test vkGetPhysicalDeviceDisplayPropertiesKHR where instance supports it with some ICDs that both support 3813// and don't support it: 3814// ICD 0 supports 3815// Physical device 0 does not 3816// Physical device 1 does 3817// Physical device 2 does not 3818// ICD 1 doesn't support 3819// Physical device 3 does not 3820// ICD 2 supports 3821// Physical device 4 does not 3822// Physical device 5 does not 3823// ICD 3 supports 3824// Physical device 6 does 3825TEST(LoaderInstPhysDevExts, PhysDevDispPropsKHRMixed) { 3826 FrameworkEnvironment env{}; 3827 const uint32_t max_icd_count = 4; 3828 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 3829 const uint32_t max_phys_devs = 7; 3830 3831 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 3832 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 3833 auto& cur_icd = env.get_test_icd(icd); 3834 cur_icd.icd_api_version = VK_API_VERSION_1_0; 3835 3836 // ICD 1 should not have 1.1 3837 if (icd != 1) { 3838 cur_icd.icd_api_version = VK_API_VERSION_1_1; 3839 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 3840 } 3841 3842 uint32_t rand_vendor_id; 3843 uint32_t rand_driver_vers; 3844 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 3845 3846 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 3847 uint32_t device_version = VK_API_VERSION_1_0; 3848 cur_icd.physical_devices.push_back({}); 3849 auto& cur_dev = cur_icd.physical_devices.back(); 3850 3851 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 3852 if ((icd == 0 && dev == 1) || icd == 3) { 3853 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 3854 device_version = VK_API_VERSION_1_1; 3855 } 3856 3857 // Still set physical device properties (so we can determine if device is correct API version) 3858 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 3859 FillInRandomDisplayPropData(cur_dev.display_properties); 3860 } 3861 } 3862 3863 InstWrapper instance(env.vulkan_functions); 3864 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 3865 instance.CheckCreate(); 3866 3867 PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR = 3868 instance.load("vkGetPhysicalDeviceDisplayPropertiesKHR"); 3869 ASSERT_NE(GetPhysicalDeviceDisplayPropertiesKHR, nullptr); 3870 3871 uint32_t device_count = max_phys_devs; 3872 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 3873 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 3874 ASSERT_EQ(device_count, max_phys_devs); 3875 3876 for (uint32_t dev = 0; dev < device_count; ++dev) { 3877 VkPhysicalDeviceProperties pd_props{}; 3878 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 3879 3880 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 3881 auto& cur_icd = env.get_test_icd(icd); 3882 bool found = false; 3883 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 3884 auto& cur_dev = cur_icd.physical_devices[pd]; 3885 // Find the ICD device matching the physical device we're looking at info for so we can compare the 3886 // physical devices info with the returned info. 3887 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 3888 cur_dev.properties.deviceType == pd_props.deviceType && 3889 cur_dev.properties.driverVersion == pd_props.driverVersion && 3890 cur_dev.properties.vendorID == pd_props.vendorID) { 3891 std::vector<VkDisplayPropertiesKHR> props{}; 3892 uint32_t prop_count = 0; 3893 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_devices[dev], &prop_count, nullptr)); 3894 if (icd == 1) { 3895 // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the 3896 // loader. 3897 ASSERT_EQ(0U, prop_count); 3898 } else { 3899 ASSERT_EQ(cur_dev.display_properties.size(), prop_count); 3900 props.resize(prop_count); 3901 ASSERT_EQ(VK_SUCCESS, 3902 GetPhysicalDeviceDisplayPropertiesKHR(physical_devices[dev], &prop_count, props.data())); 3903 ASSERT_EQ(cur_dev.display_properties.size(), prop_count); 3904 3905 ASSERT_TRUE(CompareDisplayPropData(props, cur_dev.display_properties)); 3906 } 3907 found = true; 3908 break; 3909 } 3910 } 3911 if (found) { 3912 break; 3913 } 3914 } 3915 } 3916} 3917 3918// Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where nothing supports it. 3919TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRNoSupport) { 3920 FrameworkEnvironment env{}; 3921 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3922 env.get_test_icd(0).physical_devices.push_back({}); 3923 3924 InstWrapper instance(env.vulkan_functions); 3925 instance.CheckCreate(); 3926 3927 PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR = 3928 instance.load("vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); 3929 ASSERT_EQ(GetPhysicalDeviceDisplayPlanePropertiesKHR, nullptr); 3930} 3931 3932// Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where instance supports it, but nothing else. 3933TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRNoICDSupport) { 3934 FrameworkEnvironment env{}; 3935 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3936 env.get_test_icd(0).physical_devices.push_back({}); 3937 3938 InstWrapper instance(env.vulkan_functions); 3939 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 3940 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 3941 3942 PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR = 3943 instance.load("vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); 3944 ASSERT_EQ(GetPhysicalDeviceDisplayPlanePropertiesKHR, nullptr); 3945} 3946 3947// Fill in random but valid data into the display plane property data struct for the current physical device 3948void FillInRandomDisplayPlanePropData(std::vector<VkDisplayPlanePropertiesKHR>& props) { 3949 props.resize((rand() % 5) + 1); 3950 for (uint32_t i = 0; i < props.size(); ++i) { 3951 props[i].currentDisplay = CreateRandomDisplay(); 3952 props[i].currentStackIndex = static_cast<uint32_t>((rand() % 0xFFF) + (rand() % 0xFFF) + 1); 3953 } 3954} 3955 3956// Compare the display plane property data structs 3957bool CompareDisplayPlanePropData(const std::vector<VkDisplayPlanePropertiesKHR>& props1, 3958 const std::vector<VkDisplayPlanePropertiesKHR>& props2) { 3959 if (props1.size() != props2.size()) return false; 3960 bool equal = true; 3961 for (uint32_t i = 0; i < props1.size(); ++i) { 3962 equal = equal && props1[i].currentDisplay == props2[i].currentDisplay; 3963 equal = equal && props1[i].currentStackIndex == props2[i].currentStackIndex; 3964 } 3965 return equal; 3966} 3967 3968// Test vGetPhysicalDeviceDisplayPlanePropertiesKHR where instance and ICD supports it, but device does not support it. 3969TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRInstanceAndICDSupport) { 3970 FrameworkEnvironment env{}; 3971 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 3972 env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 3973 env.get_test_icd(0).physical_devices.push_back({}); 3974 FillInRandomDisplayPlanePropData(env.get_test_icd(0).physical_devices.back().display_plane_properties); 3975 3976 InstWrapper instance(env.vulkan_functions); 3977 instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 3978 instance.CheckCreate(); 3979 3980 PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR = 3981 instance.load("vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); 3982 ASSERT_NE(GetPhysicalDeviceDisplayPlanePropertiesKHR, nullptr); 3983 3984 uint32_t driver_count = 1; 3985 VkPhysicalDevice physical_device; 3986 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 3987 ASSERT_EQ(driver_count, 1U); 3988 3989 std::vector<VkDisplayPlanePropertiesKHR> props{}; 3990 uint32_t prop_count = 0; 3991 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &prop_count, nullptr)); 3992 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_plane_properties.size(), prop_count); 3993 props.resize(prop_count); 3994 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &prop_count, props.data())); 3995 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_plane_properties.size(), prop_count); 3996 3997 ASSERT_TRUE(CompareDisplayPlanePropData(props, env.get_test_icd(0).physical_devices.back().display_plane_properties)); 3998} 3999 4000// Test vkGetPhysicalDeviceDisplayPlanePropertiesKHR where instance supports it with some ICDs that both support 4001// and don't support it: 4002// ICD 0 supports 4003// Physical device 0 does not 4004// Physical device 1 does 4005// Physical device 2 does not 4006// ICD 1 doesn't support 4007// Physical device 3 does not 4008// ICD 2 supports 4009// Physical device 4 does not 4010// Physical device 5 does not 4011// ICD 3 supports 4012// Physical device 6 does 4013TEST(LoaderInstPhysDevExts, PhysDevDispPlanePropsKHRMixed) { 4014 FrameworkEnvironment env{}; 4015 const uint32_t max_icd_count = 4; 4016 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 4017 const uint32_t max_phys_devs = 7; 4018 4019 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4020 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 4021 auto& cur_icd = env.get_test_icd(icd); 4022 cur_icd.icd_api_version = VK_API_VERSION_1_0; 4023 4024 // ICD 1 should not have 1.1 4025 if (icd != 1) { 4026 cur_icd.icd_api_version = VK_API_VERSION_1_1; 4027 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4028 } 4029 4030 uint32_t rand_vendor_id; 4031 uint32_t rand_driver_vers; 4032 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 4033 4034 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 4035 uint32_t device_version = VK_API_VERSION_1_0; 4036 cur_icd.physical_devices.push_back({}); 4037 auto& cur_dev = cur_icd.physical_devices.back(); 4038 4039 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 4040 if ((icd == 0 && dev == 1) || icd == 3) { 4041 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 4042 device_version = VK_API_VERSION_1_1; 4043 } 4044 4045 // Still set physical device properties (so we can determine if device is correct API version) 4046 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 4047 FillInRandomDisplayPlanePropData(cur_dev.display_plane_properties); 4048 } 4049 } 4050 4051 InstWrapper instance(env.vulkan_functions); 4052 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4053 instance.CheckCreate(); 4054 4055 PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR = 4056 instance.load("vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); 4057 ASSERT_NE(GetPhysicalDeviceDisplayPlanePropertiesKHR, nullptr); 4058 4059 uint32_t device_count = max_phys_devs; 4060 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 4061 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 4062 ASSERT_EQ(device_count, max_phys_devs); 4063 4064 for (uint32_t dev = 0; dev < device_count; ++dev) { 4065 VkPhysicalDeviceProperties pd_props{}; 4066 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 4067 4068 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4069 auto& cur_icd = env.get_test_icd(icd); 4070 bool found = false; 4071 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 4072 auto& cur_dev = cur_icd.physical_devices[pd]; 4073 // Find the ICD device matching the physical device we're looking at info for so we can compare the 4074 // physical devices info with the returned info. 4075 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 4076 cur_dev.properties.deviceType == pd_props.deviceType && 4077 cur_dev.properties.driverVersion == pd_props.driverVersion && 4078 cur_dev.properties.vendorID == pd_props.vendorID) { 4079 std::vector<VkDisplayPlanePropertiesKHR> props{}; 4080 uint32_t prop_count = 0; 4081 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_devices[dev], &prop_count, nullptr)); 4082 if (icd == 1) { 4083 // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the 4084 // loader. 4085 ASSERT_EQ(0U, prop_count); 4086 } else { 4087 ASSERT_EQ(cur_dev.display_plane_properties.size(), prop_count); 4088 props.resize(prop_count); 4089 ASSERT_EQ(VK_SUCCESS, 4090 GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_devices[dev], &prop_count, props.data())); 4091 ASSERT_EQ(cur_dev.display_plane_properties.size(), prop_count); 4092 4093 ASSERT_TRUE(CompareDisplayPlanePropData(props, cur_dev.display_plane_properties)); 4094 } 4095 found = true; 4096 break; 4097 } 4098 } 4099 if (found) { 4100 break; 4101 } 4102 } 4103 } 4104} 4105 4106// Test vkGetDisplayPlaneSupportedDisplaysKHR where nothing supports it. 4107TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRNoSupport) { 4108 FrameworkEnvironment env{}; 4109 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4110 env.get_test_icd(0).physical_devices.push_back({}); 4111 4112 InstWrapper instance(env.vulkan_functions); 4113 instance.CheckCreate(); 4114 4115 PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR = 4116 instance.load("vkGetDisplayPlaneSupportedDisplaysKHR"); 4117 ASSERT_EQ(GetDisplayPlaneSupportedDisplaysKHR, nullptr); 4118} 4119 4120// Test vkGetDisplayPlaneSupportedDisplaysKHR where instance supports it, but nothing else. 4121TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRNoICDSupport) { 4122 FrameworkEnvironment env{}; 4123 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4124 env.get_test_icd(0).physical_devices.push_back({}); 4125 4126 InstWrapper instance(env.vulkan_functions); 4127 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4128 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 4129 4130 PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR = 4131 instance.load("vkGetDisplayPlaneSupportedDisplaysKHR"); 4132 ASSERT_EQ(GetDisplayPlaneSupportedDisplaysKHR, nullptr); 4133} 4134 4135// Fill in random but valid data into the display plane property data struct for the current physical device 4136void GenerateRandomDisplays(std::vector<VkDisplayKHR>& disps) { 4137 disps.resize((rand() % 5) + 1); 4138 for (uint32_t i = 0; i < disps.size(); ++i) { 4139 disps[i] = CreateRandomDisplay(); 4140 } 4141} 4142 4143// Compare the display plane property data structs 4144bool CompareDisplays(const std::vector<VkDisplayKHR>& disps1, const std::vector<VkDisplayKHR>& disps2) { 4145 if (disps1.size() != disps2.size()) return false; 4146 bool equal = true; 4147 for (uint32_t i = 0; i < disps1.size(); ++i) { 4148 equal = equal && disps1[i] == disps2[i]; 4149 } 4150 return equal; 4151} 4152 4153// Test vGetDisplayPlaneSupportedDisplaysKHR where instance and ICD supports it, but device does not support it. 4154TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRInstanceAndICDSupport) { 4155 FrameworkEnvironment env{}; 4156 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4157 env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4158 env.get_test_icd(0).physical_devices.push_back({}); 4159 GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays); 4160 4161 InstWrapper instance(env.vulkan_functions); 4162 instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4163 instance.CheckCreate(); 4164 4165 PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR = 4166 instance.load("vkGetDisplayPlaneSupportedDisplaysKHR"); 4167 ASSERT_NE(GetDisplayPlaneSupportedDisplaysKHR, nullptr); 4168 4169 uint32_t driver_count = 1; 4170 VkPhysicalDevice physical_device; 4171 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 4172 ASSERT_EQ(driver_count, 1U); 4173 4174 std::vector<VkDisplayKHR> disps{}; 4175 uint32_t disp_count = 0; 4176 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplaysKHR(physical_device, 0, &disp_count, nullptr)); 4177 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().displays.size(), disp_count); 4178 disps.resize(disp_count); 4179 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplaysKHR(physical_device, 0, &disp_count, disps.data())); 4180 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().displays.size(), disp_count); 4181 4182 ASSERT_TRUE(CompareDisplays(disps, env.get_test_icd(0).physical_devices.back().displays)); 4183} 4184 4185// Test vkGetDisplayPlaneSupportedDisplaysKHR where instance supports it with some ICDs that both support 4186// and don't support it: 4187// ICD 0 supports 4188// Physical device 0 does not 4189// Physical device 1 does 4190// Physical device 2 does not 4191// ICD 1 doesn't support 4192// Physical device 3 does not 4193// ICD 2 supports 4194// Physical device 4 does not 4195// Physical device 5 does not 4196// ICD 3 supports 4197// Physical device 6 does 4198TEST(LoaderInstPhysDevExts, GetDispPlaneSupDispsKHRMixed) { 4199 FrameworkEnvironment env{}; 4200 const uint32_t max_icd_count = 4; 4201 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 4202 const uint32_t max_phys_devs = 7; 4203 4204 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4205 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 4206 auto& cur_icd = env.get_test_icd(icd); 4207 cur_icd.icd_api_version = VK_API_VERSION_1_0; 4208 4209 // ICD 1 should not have 1.1 4210 if (icd != 1) { 4211 cur_icd.icd_api_version = VK_API_VERSION_1_1; 4212 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4213 } 4214 4215 uint32_t rand_vendor_id; 4216 uint32_t rand_driver_vers; 4217 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 4218 4219 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 4220 uint32_t device_version = VK_API_VERSION_1_0; 4221 cur_icd.physical_devices.push_back({}); 4222 auto& cur_dev = cur_icd.physical_devices.back(); 4223 4224 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 4225 if ((icd == 0 && dev == 1) || icd == 3) { 4226 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 4227 device_version = VK_API_VERSION_1_1; 4228 } 4229 4230 // Still set physical device properties (so we can determine if device is correct API version) 4231 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 4232 GenerateRandomDisplays(cur_dev.displays); 4233 } 4234 } 4235 4236 InstWrapper instance(env.vulkan_functions); 4237 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4238 instance.CheckCreate(); 4239 4240 PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR = 4241 instance.load("vkGetDisplayPlaneSupportedDisplaysKHR"); 4242 ASSERT_NE(GetDisplayPlaneSupportedDisplaysKHR, nullptr); 4243 4244 uint32_t device_count = max_phys_devs; 4245 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 4246 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 4247 ASSERT_EQ(device_count, max_phys_devs); 4248 4249 for (uint32_t dev = 0; dev < device_count; ++dev) { 4250 VkPhysicalDeviceProperties pd_props{}; 4251 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 4252 4253 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4254 auto& cur_icd = env.get_test_icd(icd); 4255 bool found = false; 4256 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 4257 auto& cur_dev = cur_icd.physical_devices[pd]; 4258 // Find the ICD device matching the physical device we're looking at info for so we can compare the 4259 // physical devices info with the returned info. 4260 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 4261 cur_dev.properties.deviceType == pd_props.deviceType && 4262 cur_dev.properties.driverVersion == pd_props.driverVersion && 4263 cur_dev.properties.vendorID == pd_props.vendorID) { 4264 std::vector<VkDisplayKHR> disps{}; 4265 uint32_t disp_count = 0; 4266 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneSupportedDisplaysKHR(physical_devices[dev], 0, &disp_count, nullptr)); 4267 if (icd == 1) { 4268 // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the 4269 // loader. 4270 ASSERT_EQ(0U, disp_count); 4271 } else { 4272 ASSERT_EQ(cur_dev.displays.size(), disp_count); 4273 disps.resize(disp_count); 4274 ASSERT_EQ(VK_SUCCESS, 4275 GetDisplayPlaneSupportedDisplaysKHR(physical_devices[dev], 0, &disp_count, disps.data())); 4276 ASSERT_EQ(cur_dev.displays.size(), disp_count); 4277 4278 ASSERT_TRUE(CompareDisplays(disps, cur_dev.displays)); 4279 } 4280 found = true; 4281 break; 4282 } 4283 } 4284 if (found) { 4285 break; 4286 } 4287 } 4288 } 4289} 4290 4291// Test vkGetDisplayModePropertiesKHR where nothing supports it. 4292TEST(LoaderInstPhysDevExts, GetDispModePropsKHRNoSupport) { 4293 FrameworkEnvironment env{}; 4294 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4295 env.get_test_icd(0).physical_devices.push_back({}); 4296 4297 InstWrapper instance(env.vulkan_functions); 4298 instance.CheckCreate(); 4299 4300 PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR = instance.load("vkGetDisplayModePropertiesKHR"); 4301 ASSERT_EQ(GetDisplayModePropertiesKHR, nullptr); 4302} 4303 4304// Test vkGetDisplayModePropertiesKHR where instance supports it, but nothing else. 4305TEST(LoaderInstPhysDevExts, GetDispModePropsKHRNoICDSupport) { 4306 FrameworkEnvironment env{}; 4307 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4308 env.get_test_icd(0).physical_devices.push_back({}); 4309 4310 InstWrapper instance(env.vulkan_functions); 4311 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4312 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 4313 4314 PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR = instance.load("vkGetDisplayModePropertiesKHR"); 4315 ASSERT_EQ(GetDisplayModePropertiesKHR, nullptr); 4316} 4317 4318// Fill in random but valid data into the display mode properties data struct for the current physical device 4319void GenerateRandomDisplayModeProps(std::vector<VkDisplayModePropertiesKHR>& disps) { 4320 disps.resize((rand() % 5) + 1); 4321 for (uint32_t i = 0; i < disps.size(); ++i) { 4322 disps[i].displayMode = CreateRandomDisplayMode(); 4323 disps[i].parameters.visibleRegion.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4324 disps[i].parameters.visibleRegion.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4325 disps[i].parameters.refreshRate = 1 << (rand() % 8); 4326 } 4327} 4328 4329// Compare the display mode properties data structs 4330bool CompareDisplayModeProps(const std::vector<VkDisplayModePropertiesKHR>& disps1, 4331 const std::vector<VkDisplayModePropertiesKHR>& disps2) { 4332 if (disps1.size() != disps2.size()) return false; 4333 bool equal = true; 4334 for (uint32_t i = 0; i < disps1.size(); ++i) { 4335 equal = equal && disps1[i].displayMode == disps2[i].displayMode; 4336 equal = equal && disps1[i].parameters.visibleRegion.width == disps2[i].parameters.visibleRegion.width; 4337 equal = equal && disps1[i].parameters.visibleRegion.height == disps2[i].parameters.visibleRegion.height; 4338 equal = equal && disps1[i].parameters.refreshRate == disps2[i].parameters.refreshRate; 4339 } 4340 return equal; 4341} 4342 4343// Test vGetDisplayModePropertiesKHR where instance and ICD supports it, but device does not support it. 4344TEST(LoaderInstPhysDevExts, GetDispModePropsKHRInstanceAndICDSupport) { 4345 FrameworkEnvironment env{}; 4346 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4347 env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4348 env.get_test_icd(0).physical_devices.push_back({}); 4349 GenerateRandomDisplayModeProps(env.get_test_icd(0).physical_devices.back().display_mode_properties); 4350 4351 InstWrapper instance(env.vulkan_functions); 4352 instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4353 instance.CheckCreate(); 4354 4355 PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR = instance.load("vkGetDisplayModePropertiesKHR"); 4356 ASSERT_NE(GetDisplayModePropertiesKHR, nullptr); 4357 4358 uint32_t driver_count = 1; 4359 VkPhysicalDevice physical_device; 4360 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 4361 ASSERT_EQ(driver_count, 1U); 4362 4363 std::vector<VkDisplayModePropertiesKHR> props{}; 4364 uint32_t props_count = 0; 4365 ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_device, VK_NULL_HANDLE, &props_count, nullptr)); 4366 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_mode_properties.size(), props_count); 4367 props.resize(props_count); 4368 ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_device, VK_NULL_HANDLE, &props_count, props.data())); 4369 ASSERT_EQ(env.get_test_icd(0).physical_devices.back().display_mode_properties.size(), props_count); 4370 4371 ASSERT_TRUE(CompareDisplayModeProps(props, env.get_test_icd(0).physical_devices.back().display_mode_properties)); 4372} 4373 4374// Test vkGetDisplayModePropertiesKHR where instance supports it with some ICDs that both support 4375// and don't support it: 4376// ICD 0 supports 4377// Physical device 0 does not 4378// Physical device 1 does 4379// Physical device 2 does not 4380// ICD 1 doesn't support 4381// Physical device 3 does not 4382// ICD 2 supports 4383// Physical device 4 does not 4384// Physical device 5 does not 4385// ICD 3 supports 4386// Physical device 6 does 4387TEST(LoaderInstPhysDevExts, GetDispModePropsKHRMixed) { 4388 FrameworkEnvironment env{}; 4389 const uint32_t max_icd_count = 4; 4390 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 4391 const uint32_t max_phys_devs = 7; 4392 4393 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4394 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 4395 auto& cur_icd = env.get_test_icd(icd); 4396 cur_icd.icd_api_version = VK_API_VERSION_1_0; 4397 4398 // ICD 1 should not have 1.1 4399 if (icd != 1) { 4400 cur_icd.icd_api_version = VK_API_VERSION_1_1; 4401 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4402 } 4403 4404 uint32_t rand_vendor_id; 4405 uint32_t rand_driver_vers; 4406 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 4407 4408 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 4409 uint32_t device_version = VK_API_VERSION_1_0; 4410 cur_icd.physical_devices.push_back({}); 4411 auto& cur_dev = cur_icd.physical_devices.back(); 4412 4413 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 4414 if ((icd == 0 && dev == 1) || icd == 3) { 4415 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 4416 device_version = VK_API_VERSION_1_1; 4417 } 4418 4419 // Still set physical device properties (so we can determine if device is correct API version) 4420 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 4421 GenerateRandomDisplayModeProps(cur_dev.display_mode_properties); 4422 } 4423 } 4424 4425 InstWrapper instance(env.vulkan_functions); 4426 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4427 instance.CheckCreate(); 4428 4429 PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR = instance.load("vkGetDisplayModePropertiesKHR"); 4430 ASSERT_NE(GetDisplayModePropertiesKHR, nullptr); 4431 4432 uint32_t device_count = max_phys_devs; 4433 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 4434 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 4435 ASSERT_EQ(device_count, max_phys_devs); 4436 4437 for (uint32_t dev = 0; dev < device_count; ++dev) { 4438 VkPhysicalDeviceProperties pd_props{}; 4439 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 4440 4441 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4442 auto& cur_icd = env.get_test_icd(icd); 4443 bool found = false; 4444 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 4445 auto& cur_dev = cur_icd.physical_devices[pd]; 4446 // Find the ICD device matching the physical device we're looking at info for so we can compare the 4447 // physical devices info with the returned info. 4448 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 4449 cur_dev.properties.deviceType == pd_props.deviceType && 4450 cur_dev.properties.driverVersion == pd_props.driverVersion && 4451 cur_dev.properties.vendorID == pd_props.vendorID) { 4452 uint32_t props_count = 0; 4453 ASSERT_EQ(VK_SUCCESS, 4454 GetDisplayModePropertiesKHR(physical_devices[dev], VK_NULL_HANDLE, &props_count, nullptr)); 4455 if (icd == 1) { 4456 // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the 4457 // loader. 4458 ASSERT_EQ(0U, props_count); 4459 } else { 4460 std::vector<VkDisplayModePropertiesKHR> props{}; 4461 ASSERT_EQ(cur_dev.display_mode_properties.size(), props_count); 4462 props.resize(props_count); 4463 ASSERT_EQ(VK_SUCCESS, 4464 GetDisplayModePropertiesKHR(physical_devices[dev], VK_NULL_HANDLE, &props_count, props.data())); 4465 ASSERT_EQ(cur_dev.display_mode_properties.size(), props_count); 4466 4467 ASSERT_TRUE(CompareDisplayModeProps(props, cur_dev.display_mode_properties)); 4468 } 4469 found = true; 4470 break; 4471 } 4472 } 4473 if (found) { 4474 break; 4475 } 4476 } 4477 } 4478} 4479 4480// Test vkCreateDisplayModeKHR where nothing supports it. 4481TEST(LoaderInstPhysDevExts, GetDispModesKHRNoSupport) { 4482 FrameworkEnvironment env{}; 4483 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4484 env.get_test_icd(0).physical_devices.push_back({}); 4485 4486 InstWrapper instance(env.vulkan_functions); 4487 instance.CheckCreate(); 4488 4489 PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR = instance.load("vkCreateDisplayModeKHR"); 4490 ASSERT_EQ(CreateDisplayModeKHR, nullptr); 4491} 4492 4493// Test vkCreateDisplayModeKHR where instance supports it, but nothing else. 4494TEST(LoaderInstPhysDevExts, GetDispModesKHRNoICDSupport) { 4495 FrameworkEnvironment env{}; 4496 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4497 env.get_test_icd(0).physical_devices.push_back({}); 4498 4499 InstWrapper instance(env.vulkan_functions); 4500 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4501 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 4502 4503 PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR = instance.load("vkCreateDisplayModeKHR"); 4504 ASSERT_EQ(CreateDisplayModeKHR, nullptr); 4505} 4506 4507// Compare the display modes 4508bool CompareDisplayModes(const VkDisplayModeKHR& disps1, VkDisplayModeKHR& disps2) { return disps1 == disps2; } 4509 4510// Test vkCreateDisplayModeKHR where instance and ICD supports it, but device does not support it. 4511TEST(LoaderInstPhysDevExts, GetDispModesKHRInstanceAndICDSupport) { 4512 FrameworkEnvironment env{}; 4513 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4514 env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4515 env.get_test_icd(0).physical_devices.push_back({}); 4516 env.get_test_icd(0).physical_devices.back().display_mode = CreateRandomDisplayMode(); 4517 4518 InstWrapper instance(env.vulkan_functions); 4519 instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4520 instance.CheckCreate(); 4521 4522 PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR = instance.load("vkCreateDisplayModeKHR"); 4523 ASSERT_NE(CreateDisplayModeKHR, nullptr); 4524 4525 uint32_t driver_count = 1; 4526 VkPhysicalDevice physical_device; 4527 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 4528 ASSERT_EQ(driver_count, 1U); 4529 4530 VkDisplayModeKHR mode{}; 4531 VkDisplayModeCreateInfoKHR create_info{VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR}; 4532 ASSERT_EQ(VK_SUCCESS, CreateDisplayModeKHR(physical_device, VK_NULL_HANDLE, &create_info, nullptr, &mode)); 4533 ASSERT_TRUE(CompareDisplayModes(mode, env.get_test_icd(0).physical_devices.back().display_mode)); 4534} 4535 4536// Test vkCreateDisplayModeKHR where instance supports it with some ICDs that both support 4537// and don't support it: 4538// ICD 0 supports 4539// Physical device 0 does not 4540// Physical device 1 does 4541// Physical device 2 does not 4542// ICD 1 doesn't support 4543// Physical device 3 does not 4544// ICD 2 supports 4545// Physical device 4 does not 4546// Physical device 5 does not 4547// ICD 3 supports 4548// Physical device 6 does 4549TEST(LoaderInstPhysDevExts, GetDispModesKHRMixed) { 4550 FrameworkEnvironment env{}; 4551 const uint32_t max_icd_count = 4; 4552 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 4553 const uint32_t max_phys_devs = 7; 4554 4555 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4556 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 4557 auto& cur_icd = env.get_test_icd(icd); 4558 cur_icd.icd_api_version = VK_API_VERSION_1_0; 4559 4560 // ICD 1 should not have 1.1 4561 if (icd != 1) { 4562 cur_icd.icd_api_version = VK_API_VERSION_1_1; 4563 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4564 } 4565 4566 uint32_t rand_vendor_id; 4567 uint32_t rand_driver_vers; 4568 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 4569 4570 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 4571 uint32_t device_version = VK_API_VERSION_1_0; 4572 cur_icd.physical_devices.push_back({}); 4573 auto& cur_dev = cur_icd.physical_devices.back(); 4574 4575 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 4576 if ((icd == 0 && dev == 1) || icd == 3) { 4577 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 4578 device_version = VK_API_VERSION_1_1; 4579 } 4580 4581 // Still set physical device properties (so we can determine if device is correct API version) 4582 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 4583 cur_dev.display_mode = CreateRandomDisplayMode(); 4584 } 4585 } 4586 4587 InstWrapper instance(env.vulkan_functions); 4588 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4589 instance.CheckCreate(); 4590 4591 PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR = instance.load("vkCreateDisplayModeKHR"); 4592 ASSERT_NE(CreateDisplayModeKHR, nullptr); 4593 4594 uint32_t device_count = max_phys_devs; 4595 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 4596 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 4597 ASSERT_EQ(device_count, max_phys_devs); 4598 4599 for (uint32_t dev = 0; dev < device_count; ++dev) { 4600 VkPhysicalDeviceProperties pd_props{}; 4601 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 4602 4603 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4604 auto& cur_icd = env.get_test_icd(icd); 4605 bool found = false; 4606 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 4607 auto& cur_dev = cur_icd.physical_devices[pd]; 4608 // Find the ICD device matching the physical device we're looking at info for so we can compare the 4609 // physical devices info with the returned info. 4610 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 4611 cur_dev.properties.deviceType == pd_props.deviceType && 4612 cur_dev.properties.driverVersion == pd_props.driverVersion && 4613 cur_dev.properties.vendorID == pd_props.vendorID) { 4614 VkDisplayModeKHR mode{}; 4615 VkDisplayModeCreateInfoKHR create_info{VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR}; 4616 if (icd == 1) { 4617 // Unsupported ICD should return initialization failed (instead of crash) 4618 ASSERT_EQ(VK_ERROR_INITIALIZATION_FAILED, 4619 CreateDisplayModeKHR(physical_devices[dev], VK_NULL_HANDLE, &create_info, nullptr, &mode)); 4620 } else { 4621 ASSERT_EQ(VK_SUCCESS, 4622 CreateDisplayModeKHR(physical_devices[dev], VK_NULL_HANDLE, &create_info, nullptr, &mode)); 4623 ASSERT_TRUE(CompareDisplayModes(mode, cur_dev.display_mode)); 4624 } 4625 found = true; 4626 break; 4627 } 4628 } 4629 if (found) { 4630 break; 4631 } 4632 } 4633 } 4634} 4635 4636// Test vkGetDisplayPlaneCapabilitiesKHR where nothing supports it. 4637TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRNoSupport) { 4638 FrameworkEnvironment env{}; 4639 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4640 env.get_test_icd(0).physical_devices.push_back({}); 4641 4642 InstWrapper instance(env.vulkan_functions); 4643 instance.CheckCreate(); 4644 4645 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 4646 ASSERT_EQ(GetDisplayPlaneCapabilitiesKHR, nullptr); 4647} 4648 4649// Test vkGetDisplayPlaneCapabilitiesKHR where instance supports it, but nothing else. 4650TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRNoICDSupport) { 4651 FrameworkEnvironment env{}; 4652 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4653 env.get_test_icd(0).physical_devices.push_back({}); 4654 4655 InstWrapper instance(env.vulkan_functions); 4656 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4657 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 4658 4659 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 4660 ASSERT_EQ(GetDisplayPlaneCapabilitiesKHR, nullptr); 4661} 4662 4663// Fill in random but valid data into the display plane caps for the current physical device 4664void GenerateRandomDisplayPlaneCaps(VkDisplayPlaneCapabilitiesKHR& caps) { 4665 caps.supportedAlpha = static_cast<VkDisplayPlaneAlphaFlagsKHR>((rand() % 0xFFFFFFF) + 1); 4666 caps.minSrcPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4667 caps.minSrcPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4668 caps.maxSrcPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4669 caps.maxSrcPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4670 caps.minSrcExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4671 caps.minSrcExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4672 caps.maxSrcExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4673 caps.maxSrcExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4674 caps.minDstPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4675 caps.minDstPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4676 caps.maxDstPosition.x = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4677 caps.maxDstPosition.y = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4678 caps.minDstExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4679 caps.minDstExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4680 caps.maxDstExtent.width = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4681 caps.maxDstExtent.height = static_cast<uint32_t>((rand() % 0xFFFFFFF) + 1); 4682} 4683 4684// Compare the display plane caps 4685bool CompareDisplayPlaneCaps(const VkDisplayPlaneCapabilitiesKHR& caps1, VkDisplayPlaneCapabilitiesKHR& caps2, 4686 bool supported = true) { 4687 bool equal = true; 4688 if (supported) { 4689 equal = equal && caps1.supportedAlpha == caps2.supportedAlpha; 4690 equal = equal && caps1.minSrcPosition.x == caps2.minSrcPosition.x; 4691 equal = equal && caps1.minSrcPosition.y == caps2.minSrcPosition.y; 4692 equal = equal && caps1.maxSrcPosition.x == caps2.maxSrcPosition.x; 4693 equal = equal && caps1.maxSrcPosition.y == caps2.maxSrcPosition.y; 4694 equal = equal && caps1.minSrcExtent.width == caps2.minSrcExtent.width; 4695 equal = equal && caps1.minSrcExtent.height == caps2.minSrcExtent.height; 4696 equal = equal && caps1.maxSrcExtent.width == caps2.maxSrcExtent.width; 4697 equal = equal && caps1.maxSrcExtent.height == caps2.maxSrcExtent.height; 4698 equal = equal && caps1.minDstPosition.x == caps2.minDstPosition.x; 4699 equal = equal && caps1.minDstPosition.y == caps2.minDstPosition.y; 4700 equal = equal && caps1.maxDstPosition.x == caps2.maxDstPosition.x; 4701 equal = equal && caps1.maxDstPosition.y == caps2.maxDstPosition.y; 4702 equal = equal && caps1.minDstExtent.width == caps2.minDstExtent.width; 4703 equal = equal && caps1.minDstExtent.height == caps2.minDstExtent.height; 4704 equal = equal && caps1.maxDstExtent.width == caps2.maxDstExtent.width; 4705 equal = equal && caps1.maxDstExtent.height == caps2.maxDstExtent.height; 4706 } else { 4707 equal = equal && caps1.supportedAlpha == 0; 4708 equal = equal && caps1.minSrcPosition.x == 0; 4709 equal = equal && caps1.minSrcPosition.y == 0; 4710 equal = equal && caps1.maxSrcPosition.x == 0; 4711 equal = equal && caps1.maxSrcPosition.y == 0; 4712 equal = equal && caps1.minSrcExtent.width == 0; 4713 equal = equal && caps1.minSrcExtent.height == 0; 4714 equal = equal && caps1.maxSrcExtent.width == 0; 4715 equal = equal && caps1.maxSrcExtent.height == 0; 4716 equal = equal && caps1.minDstPosition.x == 0; 4717 equal = equal && caps1.minDstPosition.y == 0; 4718 equal = equal && caps1.maxDstPosition.x == 0; 4719 equal = equal && caps1.maxDstPosition.y == 0; 4720 equal = equal && caps1.minDstExtent.width == 0; 4721 equal = equal && caps1.minDstExtent.height == 0; 4722 equal = equal && caps1.maxDstExtent.width == 0; 4723 equal = equal && caps1.maxDstExtent.height == 0; 4724 } 4725 return equal; 4726} 4727 4728// Test vkGetDisplayPlaneCapabilitiesKHR where instance and ICD supports it, but device does not support it. 4729TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRInstanceAndICDSupport) { 4730 FrameworkEnvironment env{}; 4731 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4732 env.get_test_icd(0).add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4733 env.get_test_icd(0).physical_devices.push_back({}); 4734 GenerateRandomDisplayPlaneCaps(env.get_test_icd(0).physical_devices.back().display_plane_capabilities); 4735 4736 InstWrapper instance(env.vulkan_functions); 4737 instance.create_info.add_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4738 instance.CheckCreate(); 4739 4740 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 4741 ASSERT_NE(GetDisplayPlaneCapabilitiesKHR, nullptr); 4742 4743 uint32_t driver_count = 1; 4744 VkPhysicalDevice physical_device; 4745 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 4746 ASSERT_EQ(driver_count, 1U); 4747 4748 VkDisplayPlaneCapabilitiesKHR caps{}; 4749 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilitiesKHR(physical_device, 0, 0, &caps)); 4750 ASSERT_TRUE(CompareDisplayPlaneCaps(caps, env.get_test_icd(0).physical_devices.back().display_plane_capabilities)); 4751} 4752 4753// Test vkGetDisplayPlaneCapabilitiesKHR where instance supports it with some ICDs that both support 4754// and don't support it: 4755// ICD 0 supports 4756// Physical device 0 does not 4757// Physical device 1 does 4758// Physical device 2 does not 4759// ICD 1 doesn't support 4760// Physical device 3 does not 4761// ICD 2 supports 4762// Physical device 4 does not 4763// Physical device 5 does not 4764// ICD 3 supports 4765// Physical device 6 does 4766TEST(LoaderInstPhysDevExts, GetDispPlaneCapsKHRMixed) { 4767 FrameworkEnvironment env{}; 4768 const uint32_t max_icd_count = 4; 4769 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 4770 const uint32_t max_phys_devs = 7; 4771 4772 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4773 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 4774 auto& cur_icd = env.get_test_icd(icd); 4775 cur_icd.icd_api_version = VK_API_VERSION_1_0; 4776 4777 // ICD 1 should not have 1.1 4778 if (icd != 1) { 4779 cur_icd.icd_api_version = VK_API_VERSION_1_1; 4780 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4781 } 4782 4783 uint32_t rand_vendor_id; 4784 uint32_t rand_driver_vers; 4785 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 4786 4787 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 4788 uint32_t device_version = VK_API_VERSION_1_0; 4789 cur_icd.physical_devices.push_back({}); 4790 auto& cur_dev = cur_icd.physical_devices.back(); 4791 4792 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 4793 if ((icd == 0 && dev == 1) || icd == 3) { 4794 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 4795 device_version = VK_API_VERSION_1_1; 4796 } 4797 4798 // Still set physical device properties (so we can determine if device is correct API version) 4799 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 4800 GenerateRandomDisplayPlaneCaps(cur_dev.display_plane_capabilities); 4801 } 4802 } 4803 4804 InstWrapper instance(env.vulkan_functions); 4805 instance.create_info.add_extension(VK_KHR_DISPLAY_EXTENSION_NAME); 4806 instance.CheckCreate(); 4807 4808 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 4809 ASSERT_NE(GetDisplayPlaneCapabilitiesKHR, nullptr); 4810 4811 uint32_t device_count = max_phys_devs; 4812 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 4813 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 4814 ASSERT_EQ(device_count, max_phys_devs); 4815 4816 for (uint32_t dev = 0; dev < device_count; ++dev) { 4817 VkPhysicalDeviceProperties pd_props{}; 4818 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 4819 4820 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4821 auto& cur_icd = env.get_test_icd(icd); 4822 bool found = false; 4823 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 4824 auto& cur_dev = cur_icd.physical_devices[pd]; 4825 // Find the ICD device matching the physical device we're looking at info for so we can compare the 4826 // physical devices info with the returned info. 4827 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 4828 cur_dev.properties.deviceType == pd_props.deviceType && 4829 cur_dev.properties.driverVersion == pd_props.driverVersion && 4830 cur_dev.properties.vendorID == pd_props.vendorID) { 4831 VkDisplayPlaneCapabilitiesKHR caps{}; 4832 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilitiesKHR(physical_devices[dev], 0, 0, &caps)); 4833 ASSERT_TRUE(CompareDisplayPlaneCaps(caps, cur_dev.display_plane_capabilities, icd != 1)); 4834 found = true; 4835 break; 4836 } 4837 } 4838 if (found) { 4839 break; 4840 } 4841 } 4842 } 4843} 4844 4845// 4846// VK_KHR_get_display_properties2 4847// 4848 4849// Test vkGetPhysicalDeviceDisplayProperties2KHR where nothing supports it. 4850TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRNoSupport) { 4851 FrameworkEnvironment env{}; 4852 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4853 env.get_test_icd(0).physical_devices.push_back({}); 4854 4855 InstWrapper instance(env.vulkan_functions); 4856 instance.CheckCreate(); 4857 4858 PFN_vkGetPhysicalDeviceDisplayProperties2KHR GetPhysicalDeviceDisplayProperties2KHR = 4859 instance.load("vkGetPhysicalDeviceDisplayProperties2KHR"); 4860 ASSERT_EQ(GetPhysicalDeviceDisplayProperties2KHR, nullptr); 4861} 4862 4863// Test vkGetPhysicalDeviceDisplayProperties2KHR where instance supports it, but nothing else. 4864TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRNoICDSupport) { 4865 FrameworkEnvironment env{}; 4866 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4867 env.get_test_icd(0).physical_devices.push_back({}); 4868 4869 InstWrapper instance(env.vulkan_functions); 4870 instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); 4871 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 4872 4873 PFN_vkGetPhysicalDeviceDisplayProperties2KHR GetPhysicalDeviceDisplayProperties2KHR = 4874 instance.load("vkGetPhysicalDeviceDisplayProperties2KHR"); 4875 ASSERT_EQ(GetPhysicalDeviceDisplayProperties2KHR, nullptr); 4876} 4877 4878// Compare the display property data structs 4879bool CompareDisplayPropData(const std::vector<VkDisplayPropertiesKHR>& props1, const std::vector<VkDisplayProperties2KHR>& props2) { 4880 if (props1.size() != props2.size()) return false; 4881 bool equal = true; 4882 for (uint32_t i = 0; i < props1.size(); ++i) { 4883 equal = equal && props1[i].display == props2[i].displayProperties.display; 4884 equal = equal && props1[i].physicalDimensions.width == props2[i].displayProperties.physicalDimensions.width; 4885 equal = equal && props1[i].physicalDimensions.height == props2[i].displayProperties.physicalDimensions.height; 4886 equal = equal && props1[i].physicalResolution.width == props2[i].displayProperties.physicalResolution.width; 4887 equal = equal && props1[i].physicalResolution.height == props2[i].displayProperties.physicalResolution.height; 4888 equal = equal && props1[i].supportedTransforms == props2[i].displayProperties.supportedTransforms; 4889 equal = equal && props1[i].planeReorderPossible == props2[i].displayProperties.planeReorderPossible; 4890 equal = equal && props1[i].persistentContent == props2[i].displayProperties.persistentContent; 4891 } 4892 return equal; 4893} 4894 4895// Test vGetPhysicalDeviceDisplayProperties2KHR where instance and ICD supports it, but device does not support it. 4896TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRInstanceAndICDSupport) { 4897 FrameworkEnvironment env{}; 4898 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 4899 Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; 4900 Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; 4901 env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); 4902 env.get_test_icd(0).physical_devices.push_back({}); 4903 FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties); 4904 4905 InstWrapper instance(env.vulkan_functions); 4906 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 4907 instance.CheckCreate(); 4908 4909 PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR = 4910 instance.load("vkGetPhysicalDeviceDisplayPropertiesKHR"); 4911 ASSERT_NE(GetPhysicalDeviceDisplayPropertiesKHR, nullptr); 4912 PFN_vkGetPhysicalDeviceDisplayProperties2KHR GetPhysicalDeviceDisplayProperties2KHR = 4913 instance.load("vkGetPhysicalDeviceDisplayProperties2KHR"); 4914 ASSERT_NE(GetPhysicalDeviceDisplayProperties2KHR, nullptr); 4915 4916 uint32_t driver_count = 1; 4917 VkPhysicalDevice physical_device; 4918 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 4919 ASSERT_EQ(driver_count, 1U); 4920 4921 std::vector<VkDisplayPropertiesKHR> props{}; 4922 uint32_t prop_count = 0; 4923 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_device, &prop_count, nullptr)); 4924 ASSERT_NE(0U, prop_count); 4925 props.resize(prop_count); 4926 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_device, &prop_count, props.data())); 4927 4928 std::vector<VkDisplayProperties2KHR> props2{}; 4929 uint32_t prop_count_2 = 0; 4930 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2KHR(physical_device, &prop_count_2, nullptr)); 4931 ASSERT_EQ(prop_count, prop_count_2); 4932 props2.resize(prop_count_2, {VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR}); 4933 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2KHR(physical_device, &prop_count_2, props2.data())); 4934 ASSERT_EQ(prop_count, prop_count_2); 4935 4936 ASSERT_TRUE(CompareDisplayPropData(props, props2)); 4937} 4938 4939// Test vkGetPhysicalDeviceDisplayProperties2KHR where instance supports it with some ICDs that both support 4940// and don't support it: 4941// ICD 0 supports 4942// Physical device 0 does not 4943// Physical device 1 does 4944// Physical device 2 does not 4945// ICD 1 doesn't support 4946// Physical device 3 does not 4947// ICD 2 supports 4948// Physical device 4 does not 4949// Physical device 5 does not 4950// ICD 3 supports 4951// Physical device 6 does 4952TEST(LoaderInstPhysDevExts, PhysDevDispProps2KHRMixed) { 4953 FrameworkEnvironment env{}; 4954 const uint32_t max_icd_count = 4; 4955 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 4956 const uint32_t max_phys_devs = 7; 4957 4958 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 4959 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 4960 auto& cur_icd = env.get_test_icd(icd); 4961 cur_icd.icd_api_version = VK_API_VERSION_1_0; 4962 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 4963 4964 // ICD 1 should not have 1.1 4965 if (icd != 1) { 4966 cur_icd.icd_api_version = VK_API_VERSION_1_1; 4967 cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 4968 } 4969 4970 uint32_t rand_vendor_id; 4971 uint32_t rand_driver_vers; 4972 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 4973 4974 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 4975 uint32_t device_version = VK_API_VERSION_1_0; 4976 cur_icd.physical_devices.push_back({}); 4977 auto& cur_dev = cur_icd.physical_devices.back(); 4978 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 4979 4980 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 4981 if ((icd == 0 && dev == 1) || icd == 3) { 4982 cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); 4983 device_version = VK_API_VERSION_1_1; 4984 } 4985 4986 // Still set physical device properties (so we can determine if device is correct API version) 4987 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 4988 FillInRandomDisplayPropData(cur_dev.display_properties); 4989 } 4990 } 4991 4992 InstWrapper instance(env.vulkan_functions); 4993 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 4994 instance.CheckCreate(); 4995 4996 PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR = 4997 instance.load("vkGetPhysicalDeviceDisplayPropertiesKHR"); 4998 ASSERT_NE(GetPhysicalDeviceDisplayPropertiesKHR, nullptr); 4999 PFN_vkGetPhysicalDeviceDisplayProperties2KHR GetPhysicalDeviceDisplayProperties2KHR = 5000 instance.load("vkGetPhysicalDeviceDisplayProperties2KHR"); 5001 ASSERT_NE(GetPhysicalDeviceDisplayProperties2KHR, nullptr); 5002 5003 uint32_t device_count = max_phys_devs; 5004 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 5005 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 5006 ASSERT_EQ(device_count, max_phys_devs); 5007 5008 for (uint32_t dev = 0; dev < device_count; ++dev) { 5009 std::vector<VkDisplayPropertiesKHR> props{}; 5010 uint32_t prop_count = 0; 5011 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_devices[dev], &prop_count, nullptr)); 5012 ASSERT_NE(0U, prop_count); 5013 props.resize(prop_count); 5014 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPropertiesKHR(physical_devices[dev], &prop_count, props.data())); 5015 5016 std::vector<VkDisplayProperties2KHR> props2{}; 5017 uint32_t prop_count_2 = 0; 5018 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2KHR(physical_devices[dev], &prop_count_2, nullptr)); 5019 ASSERT_EQ(prop_count, prop_count_2); 5020 props2.resize(prop_count_2, {VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR}); 5021 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayProperties2KHR(physical_devices[dev], &prop_count_2, props2.data())); 5022 ASSERT_EQ(prop_count, prop_count_2); 5023 5024 ASSERT_TRUE(CompareDisplayPropData(props, props2)); 5025 } 5026} 5027 5028// Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where nothing supports it. 5029TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRNoSupport) { 5030 FrameworkEnvironment env{}; 5031 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5032 env.get_test_icd(0).physical_devices.push_back({}); 5033 5034 InstWrapper instance(env.vulkan_functions); 5035 instance.CheckCreate(); 5036 5037 PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR GetPhysicalDeviceDisplayPlaneProperties2KHR = 5038 instance.load("vkGetPhysicalDeviceDisplayPlaneProperties2KHR"); 5039 ASSERT_EQ(GetPhysicalDeviceDisplayPlaneProperties2KHR, nullptr); 5040} 5041 5042// Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where instance supports it, but nothing else. 5043TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRNoICDSupport) { 5044 FrameworkEnvironment env{}; 5045 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5046 env.get_test_icd(0).physical_devices.push_back({}); 5047 5048 InstWrapper instance(env.vulkan_functions); 5049 instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); 5050 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 5051 5052 PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR GetPhysicalDeviceDisplayPlaneProperties2KHR = 5053 instance.load("vkGetPhysicalDeviceDisplayPlaneProperties2KHR"); 5054 ASSERT_EQ(GetPhysicalDeviceDisplayPlaneProperties2KHR, nullptr); 5055} 5056 5057// Compare the display plane property data structs 5058bool CompareDisplayPlanePropData(const std::vector<VkDisplayPlanePropertiesKHR>& props1, 5059 const std::vector<VkDisplayPlaneProperties2KHR>& props2) { 5060 if (props1.size() != props2.size()) return false; 5061 bool equal = true; 5062 for (uint32_t i = 0; i < props1.size(); ++i) { 5063 equal = equal && props1[i].currentDisplay == props2[i].displayPlaneProperties.currentDisplay; 5064 equal = equal && props1[i].currentStackIndex == props2[i].displayPlaneProperties.currentStackIndex; 5065 } 5066 return equal; 5067} 5068 5069// Test vGetPhysicalDeviceDisplayPlaneProperties2KHR where instance and ICD supports it, but device does not support it. 5070TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRInstanceAndICDSupport) { 5071 FrameworkEnvironment env{}; 5072 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5073 Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; 5074 Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; 5075 env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); 5076 env.get_test_icd(0).physical_devices.push_back({}); 5077 FillInRandomDisplayPlanePropData(env.get_test_icd(0).physical_devices.back().display_plane_properties); 5078 5079 InstWrapper instance(env.vulkan_functions); 5080 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5081 instance.CheckCreate(); 5082 5083 PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR = 5084 instance.load("vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); 5085 ASSERT_NE(GetPhysicalDeviceDisplayPlanePropertiesKHR, nullptr); 5086 PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR GetPhysicalDeviceDisplayPlaneProperties2KHR = 5087 instance.load("vkGetPhysicalDeviceDisplayPlaneProperties2KHR"); 5088 ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties2KHR, nullptr); 5089 5090 uint32_t driver_count = 1; 5091 VkPhysicalDevice physical_device; 5092 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 5093 ASSERT_EQ(driver_count, 1U); 5094 5095 std::vector<VkDisplayPlanePropertiesKHR> props{}; 5096 uint32_t prop_count = 0; 5097 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &prop_count, nullptr)); 5098 ASSERT_NE(0U, prop_count); 5099 props.resize(prop_count); 5100 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &prop_count, props.data())); 5101 5102 std::vector<VkDisplayPlaneProperties2KHR> props2{}; 5103 uint32_t prop_count2 = 0; 5104 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2KHR(physical_device, &prop_count2, nullptr)); 5105 ASSERT_EQ(prop_count, prop_count2); 5106 props2.resize(prop_count2, {VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR}); 5107 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2KHR(physical_device, &prop_count2, props2.data())); 5108 5109 ASSERT_TRUE(CompareDisplayPlanePropData(props, props2)); 5110} 5111 5112// Test vkGetPhysicalDeviceDisplayPlaneProperties2KHR where instance supports it with some ICDs that both support 5113// and don't support it: 5114// ICD 0 supports 5115// Physical device 0 does not 5116// Physical device 1 does 5117// Physical device 2 does not 5118// ICD 1 doesn't support 5119// Physical device 3 does not 5120// ICD 2 supports 5121// Physical device 4 does not 5122// Physical device 5 does not 5123// ICD 3 supports 5124// Physical device 6 does 5125TEST(LoaderInstPhysDevExts, PhysDevDispPlaneProps2KHRMixed) { 5126 FrameworkEnvironment env{}; 5127 const uint32_t max_icd_count = 4; 5128 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 5129 const uint32_t max_phys_devs = 7; 5130 5131 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 5132 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 5133 auto& cur_icd = env.get_test_icd(icd); 5134 cur_icd.icd_api_version = VK_API_VERSION_1_0; 5135 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 5136 5137 // ICD 1 should not have 1.1 5138 if (icd != 1) { 5139 cur_icd.icd_api_version = VK_API_VERSION_1_1; 5140 cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5141 } 5142 5143 uint32_t rand_vendor_id; 5144 uint32_t rand_driver_vers; 5145 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 5146 5147 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 5148 uint32_t device_version = VK_API_VERSION_1_0; 5149 cur_icd.physical_devices.push_back({}); 5150 auto& cur_dev = cur_icd.physical_devices.back(); 5151 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 5152 5153 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 5154 if ((icd == 0 && dev == 1) || icd == 3) { 5155 cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); 5156 device_version = VK_API_VERSION_1_1; 5157 } 5158 5159 // Still set physical device properties (so we can determine if device is correct API version) 5160 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 5161 FillInRandomDisplayPlanePropData(cur_dev.display_plane_properties); 5162 } 5163 } 5164 5165 InstWrapper instance(env.vulkan_functions); 5166 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5167 instance.CheckCreate(); 5168 5169 PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR = 5170 instance.load("vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); 5171 ASSERT_NE(GetPhysicalDeviceDisplayPlanePropertiesKHR, nullptr); 5172 PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR GetPhysicalDeviceDisplayPlaneProperties2KHR = 5173 instance.load("vkGetPhysicalDeviceDisplayPlaneProperties2KHR"); 5174 ASSERT_NE(GetPhysicalDeviceDisplayPlaneProperties2KHR, nullptr); 5175 5176 uint32_t device_count = max_phys_devs; 5177 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 5178 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 5179 ASSERT_EQ(device_count, max_phys_devs); 5180 5181 for (uint32_t dev = 0; dev < device_count; ++dev) { 5182 std::vector<VkDisplayPlanePropertiesKHR> props{}; 5183 uint32_t prop_count = 0; 5184 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_devices[dev], &prop_count, nullptr)); 5185 ASSERT_NE(0U, prop_count); 5186 props.resize(prop_count); 5187 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlanePropertiesKHR(physical_devices[dev], &prop_count, props.data())); 5188 5189 std::vector<VkDisplayPlaneProperties2KHR> props2{}; 5190 uint32_t prop_count2 = 0; 5191 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2KHR(physical_devices[dev], &prop_count2, nullptr)); 5192 ASSERT_EQ(prop_count, prop_count2); 5193 props2.resize(prop_count2, {VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR}); 5194 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceDisplayPlaneProperties2KHR(physical_devices[dev], &prop_count2, props2.data())); 5195 5196 ASSERT_TRUE(CompareDisplayPlanePropData(props, props2)); 5197 } 5198} 5199 5200// Test vkGetDisplayModeProperties2KHR where nothing supports it. 5201TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRNoSupport) { 5202 FrameworkEnvironment env{}; 5203 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5204 env.get_test_icd(0).physical_devices.push_back({}); 5205 5206 InstWrapper instance(env.vulkan_functions); 5207 instance.CheckCreate(); 5208 5209 PFN_vkGetDisplayModeProperties2KHR GetDisplayModeProperties2KHR = instance.load("vkGetDisplayModeProperties2KHR"); 5210 ASSERT_EQ(GetDisplayModeProperties2KHR, nullptr); 5211} 5212 5213// Test vkGetDisplayModeProperties2KHR where instance supports it, but nothing else. 5214TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRNoICDSupport) { 5215 FrameworkEnvironment env{}; 5216 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5217 env.get_test_icd(0).physical_devices.push_back({}); 5218 5219 InstWrapper instance(env.vulkan_functions); 5220 instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); 5221 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 5222 5223 PFN_vkGetDisplayModeProperties2KHR GetDisplayModeProperties2KHR = instance.load("vkGetDisplayModeProperties2KHR"); 5224 ASSERT_EQ(GetDisplayModeProperties2KHR, nullptr); 5225} 5226 5227// Compare the display mode properties data structs 5228bool CompareDisplayModeProps(const std::vector<VkDisplayModePropertiesKHR>& disps1, 5229 const std::vector<VkDisplayModeProperties2KHR>& disps2) { 5230 if (disps1.size() != disps2.size()) return false; 5231 5232 bool equal = true; 5233 for (uint32_t i = 0; i < disps1.size(); ++i) { 5234 equal = equal && disps1[i].displayMode == disps2[i].displayModeProperties.displayMode; 5235 equal = equal && disps1[i].parameters.visibleRegion.width == disps2[i].displayModeProperties.parameters.visibleRegion.width; 5236 equal = 5237 equal && disps1[i].parameters.visibleRegion.height == disps2[i].displayModeProperties.parameters.visibleRegion.height; 5238 equal = equal && disps1[i].parameters.refreshRate == disps2[i].displayModeProperties.parameters.refreshRate; 5239 } 5240 return equal; 5241} 5242 5243// Test vGetDisplayModeProperties2KHR where instance and ICD supports it, but device does not support it. 5244TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRInstanceAndICDSupport) { 5245 FrameworkEnvironment env{}; 5246 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5247 Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; 5248 Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; 5249 env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); 5250 env.get_test_icd(0).physical_devices.push_back({}); 5251 GenerateRandomDisplayModeProps(env.get_test_icd(0).physical_devices.back().display_mode_properties); 5252 5253 InstWrapper instance(env.vulkan_functions); 5254 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5255 instance.CheckCreate(); 5256 5257 PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR = instance.load("vkGetDisplayModePropertiesKHR"); 5258 ASSERT_NE(GetDisplayModePropertiesKHR, nullptr); 5259 PFN_vkGetDisplayModeProperties2KHR GetDisplayModeProperties2KHR = instance.load("vkGetDisplayModeProperties2KHR"); 5260 ASSERT_NE(GetDisplayModeProperties2KHR, nullptr); 5261 5262 uint32_t driver_count = 1; 5263 VkPhysicalDevice physical_device; 5264 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 5265 ASSERT_EQ(driver_count, 1U); 5266 5267 std::vector<VkDisplayModePropertiesKHR> props{}; 5268 uint32_t props_count1 = 0; 5269 ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_device, VK_NULL_HANDLE, &props_count1, nullptr)); 5270 ASSERT_NE(0U, props_count1); 5271 props.resize(props_count1); 5272 ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_device, VK_NULL_HANDLE, &props_count1, props.data())); 5273 5274 std::vector<VkDisplayModeProperties2KHR> props2{}; 5275 uint32_t props_count2 = 0; 5276 ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2KHR(physical_device, VK_NULL_HANDLE, &props_count2, nullptr)); 5277 ASSERT_EQ(props_count1, props_count2); 5278 props2.resize(props_count2, {VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR}); 5279 ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2KHR(physical_device, VK_NULL_HANDLE, &props_count2, props2.data())); 5280 5281 ASSERT_TRUE(CompareDisplayModeProps(props, props2)); 5282} 5283 5284// Test vkGetDisplayModeProperties2KHR where instance supports it with some ICDs that both support 5285// and don't support it: 5286// ICD 0 supports 5287// Physical device 0 does not 5288// Physical device 1 does 5289// Physical device 2 does not 5290// ICD 1 doesn't support 5291// Physical device 3 does not 5292// ICD 2 supports 5293// Physical device 4 does not 5294// Physical device 5 does not 5295// ICD 3 supports 5296// Physical device 6 does 5297TEST(LoaderInstPhysDevExts, GetDispModeProps2KHRMixed) { 5298 FrameworkEnvironment env{}; 5299 const uint32_t max_icd_count = 4; 5300 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 5301 const uint32_t max_phys_devs = 7; 5302 5303 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 5304 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 5305 auto& cur_icd = env.get_test_icd(icd); 5306 cur_icd.icd_api_version = VK_API_VERSION_1_0; 5307 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 5308 5309 // ICD 1 should not have 1.1 5310 if (icd != 1) { 5311 cur_icd.icd_api_version = VK_API_VERSION_1_1; 5312 cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5313 } 5314 5315 uint32_t rand_vendor_id; 5316 uint32_t rand_driver_vers; 5317 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 5318 5319 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 5320 uint32_t device_version = VK_API_VERSION_1_0; 5321 cur_icd.physical_devices.push_back({}); 5322 auto& cur_dev = cur_icd.physical_devices.back(); 5323 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 5324 5325 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 5326 if ((icd == 0 && dev == 1) || icd == 3) { 5327 cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); 5328 device_version = VK_API_VERSION_1_1; 5329 } 5330 5331 // Still set physical device properties (so we can determine if device is correct API version) 5332 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 5333 GenerateRandomDisplayModeProps(cur_dev.display_mode_properties); 5334 } 5335 } 5336 5337 InstWrapper instance(env.vulkan_functions); 5338 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5339 instance.CheckCreate(); 5340 5341 PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR = instance.load("vkGetDisplayModePropertiesKHR"); 5342 ASSERT_NE(GetDisplayModePropertiesKHR, nullptr); 5343 PFN_vkGetDisplayModeProperties2KHR GetDisplayModeProperties2KHR = instance.load("vkGetDisplayModeProperties2KHR"); 5344 ASSERT_NE(GetDisplayModeProperties2KHR, nullptr); 5345 5346 uint32_t device_count = max_phys_devs; 5347 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 5348 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 5349 ASSERT_EQ(device_count, max_phys_devs); 5350 5351 for (uint32_t dev = 0; dev < device_count; ++dev) { 5352 std::vector<VkDisplayModePropertiesKHR> props{}; 5353 uint32_t props_count1 = 0; 5354 ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_devices[dev], VK_NULL_HANDLE, &props_count1, nullptr)); 5355 ASSERT_NE(0U, props_count1); 5356 props.resize(props_count1); 5357 ASSERT_EQ(VK_SUCCESS, GetDisplayModePropertiesKHR(physical_devices[dev], VK_NULL_HANDLE, &props_count1, props.data())); 5358 5359 std::vector<VkDisplayModeProperties2KHR> props2{}; 5360 uint32_t props_count2 = 0; 5361 ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2KHR(physical_devices[dev], VK_NULL_HANDLE, &props_count2, nullptr)); 5362 ASSERT_EQ(props_count1, props_count2); 5363 props2.resize(props_count2, {VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR}); 5364 ASSERT_EQ(VK_SUCCESS, GetDisplayModeProperties2KHR(physical_devices[dev], VK_NULL_HANDLE, &props_count2, props2.data())); 5365 5366 ASSERT_TRUE(CompareDisplayModeProps(props, props2)); 5367 } 5368} 5369 5370// Test vkGetDisplayPlaneCapabilities2KHR where nothing supports it. 5371TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRNoSupport) { 5372 FrameworkEnvironment env{}; 5373 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5374 env.get_test_icd(0).physical_devices.push_back({}); 5375 5376 InstWrapper instance(env.vulkan_functions); 5377 instance.CheckCreate(); 5378 5379 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 5380 ASSERT_EQ(GetDisplayPlaneCapabilitiesKHR, nullptr); 5381} 5382 5383// Test vkGetDisplayPlaneCapabilities2KHR where instance supports it, but nothing else. 5384TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRNoICDSupport) { 5385 FrameworkEnvironment env{}; 5386 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5387 env.get_test_icd(0).physical_devices.push_back({}); 5388 5389 InstWrapper instance(env.vulkan_functions); 5390 instance.create_info.add_extension(VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME); 5391 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 5392 5393 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 5394 ASSERT_EQ(GetDisplayPlaneCapabilitiesKHR, nullptr); 5395} 5396 5397// Compare the display plane caps 5398bool CompareDisplayPlaneCaps(const VkDisplayPlaneCapabilitiesKHR& caps1, VkDisplayPlaneCapabilities2KHR& caps2) { 5399 bool equal = true; 5400 equal = equal && caps1.supportedAlpha == caps2.capabilities.supportedAlpha; 5401 equal = equal && caps1.minSrcPosition.x == caps2.capabilities.minSrcPosition.x; 5402 equal = equal && caps1.minSrcPosition.y == caps2.capabilities.minSrcPosition.y; 5403 equal = equal && caps1.maxSrcPosition.x == caps2.capabilities.maxSrcPosition.x; 5404 equal = equal && caps1.maxSrcPosition.y == caps2.capabilities.maxSrcPosition.y; 5405 equal = equal && caps1.minSrcExtent.width == caps2.capabilities.minSrcExtent.width; 5406 equal = equal && caps1.minSrcExtent.height == caps2.capabilities.minSrcExtent.height; 5407 equal = equal && caps1.maxSrcExtent.width == caps2.capabilities.maxSrcExtent.width; 5408 equal = equal && caps1.maxSrcExtent.height == caps2.capabilities.maxSrcExtent.height; 5409 equal = equal && caps1.minDstPosition.x == caps2.capabilities.minDstPosition.x; 5410 equal = equal && caps1.minDstPosition.y == caps2.capabilities.minDstPosition.y; 5411 equal = equal && caps1.maxDstPosition.x == caps2.capabilities.maxDstPosition.x; 5412 equal = equal && caps1.maxDstPosition.y == caps2.capabilities.maxDstPosition.y; 5413 equal = equal && caps1.minDstExtent.width == caps2.capabilities.minDstExtent.width; 5414 equal = equal && caps1.minDstExtent.height == caps2.capabilities.minDstExtent.height; 5415 equal = equal && caps1.maxDstExtent.width == caps2.capabilities.maxDstExtent.width; 5416 equal = equal && caps1.maxDstExtent.height == caps2.capabilities.maxDstExtent.height; 5417 return equal; 5418} 5419 5420// Test vkGetDisplayPlaneCapabilities2KHR where instance and ICD supports it, but device does not support it. 5421TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRInstanceAndICDSupport) { 5422 FrameworkEnvironment env{}; 5423 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5424 Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; 5425 Extension second_ext{VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}; 5426 env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); 5427 env.get_test_icd(0).physical_devices.push_back({}); 5428 FillInRandomDisplayPropData(env.get_test_icd(0).physical_devices.back().display_properties); 5429 5430 InstWrapper instance(env.vulkan_functions); 5431 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5432 instance.CheckCreate(); 5433 5434 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 5435 ASSERT_NE(GetDisplayPlaneCapabilitiesKHR, nullptr); 5436 PFN_vkGetDisplayPlaneCapabilities2KHR GetDisplayPlaneCapabilities2KHR = instance.load("vkGetDisplayPlaneCapabilities2KHR"); 5437 ASSERT_NE(GetDisplayPlaneCapabilities2KHR, nullptr); 5438 5439 uint32_t driver_count = 1; 5440 VkPhysicalDevice physical_device; 5441 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 5442 ASSERT_EQ(driver_count, 1U); 5443 5444 VkDisplayPlaneCapabilitiesKHR caps{}; 5445 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilitiesKHR(physical_device, 0, 0, &caps)); 5446 VkDisplayPlaneCapabilities2KHR caps2{}; 5447 VkDisplayPlaneInfo2KHR info{VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR}; 5448 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities2KHR(physical_device, &info, &caps2)); 5449 ASSERT_TRUE(CompareDisplayPlaneCaps(caps, caps2)); 5450} 5451 5452// Test vkGetDisplayPlaneCapabilities2KHR where instance supports it with some ICDs that both support 5453// and don't support it: 5454// ICD 0 supports 5455// Physical device 0 does not 5456// Physical device 1 does 5457// Physical device 2 does not 5458// ICD 1 doesn't support 5459// Physical device 3 does not 5460// ICD 2 supports 5461// Physical device 4 does not 5462// Physical device 5 does not 5463// ICD 3 supports 5464// Physical device 6 does 5465TEST(LoaderInstPhysDevExts, GetDispPlaneCaps2KHRMixed) { 5466 FrameworkEnvironment env{}; 5467 const uint32_t max_icd_count = 4; 5468 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 5469 const uint32_t max_phys_devs = 7; 5470 5471 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 5472 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 5473 auto& cur_icd = env.get_test_icd(icd); 5474 cur_icd.icd_api_version = VK_API_VERSION_1_0; 5475 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 5476 5477 // ICD 1 should not have 1.1 5478 if (icd != 1) { 5479 cur_icd.icd_api_version = VK_API_VERSION_1_1; 5480 cur_icd.add_instance_extension({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5481 } 5482 5483 uint32_t rand_vendor_id; 5484 uint32_t rand_driver_vers; 5485 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 5486 5487 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 5488 uint32_t device_version = VK_API_VERSION_1_0; 5489 cur_icd.physical_devices.push_back({}); 5490 auto& cur_dev = cur_icd.physical_devices.back(); 5491 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 5492 5493 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 5494 if ((icd == 0 && dev == 1) || icd == 3) { 5495 cur_dev.extensions.push_back({VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, 0}); 5496 device_version = VK_API_VERSION_1_1; 5497 } 5498 5499 // Still set physical device properties (so we can determine if device is correct API version) 5500 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 5501 GenerateRandomDisplayPlaneCaps(cur_dev.display_plane_capabilities); 5502 } 5503 } 5504 5505 InstWrapper instance(env.vulkan_functions); 5506 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME}); 5507 instance.CheckCreate(); 5508 5509 PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR = instance.load("vkGetDisplayPlaneCapabilitiesKHR"); 5510 ASSERT_NE(GetDisplayPlaneCapabilitiesKHR, nullptr); 5511 PFN_vkGetDisplayPlaneCapabilities2KHR GetDisplayPlaneCapabilities2KHR = instance.load("vkGetDisplayPlaneCapabilities2KHR"); 5512 ASSERT_NE(GetDisplayPlaneCapabilities2KHR, nullptr); 5513 5514 uint32_t device_count = max_phys_devs; 5515 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 5516 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 5517 ASSERT_EQ(device_count, max_phys_devs); 5518 5519 for (uint32_t dev = 0; dev < device_count; ++dev) { 5520 VkDisplayPlaneCapabilitiesKHR caps{}; 5521 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilitiesKHR(physical_devices[dev], 0, 0, &caps)); 5522 VkDisplayPlaneCapabilities2KHR caps2{}; 5523 VkDisplayPlaneInfo2KHR info{VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR}; 5524 ASSERT_EQ(VK_SUCCESS, GetDisplayPlaneCapabilities2KHR(physical_devices[dev], &info, &caps2)); 5525 CompareDisplayPlaneCaps(caps, caps2); 5526 } 5527} 5528 5529// 5530// VK_EXT_acquire_drm_display 5531// 5532 5533// Test vkAcquireDrmDisplayEXT where nothing supports it. 5534TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTNoSupport) { 5535 FrameworkEnvironment env{}; 5536 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5537 env.get_test_icd(0).physical_devices.push_back({}); 5538 5539 InstWrapper instance(env.vulkan_functions); 5540 instance.CheckCreate(); 5541 5542 PFN_vkAcquireDrmDisplayEXT AcquireDrmDisplayEXT = instance.load("vkAcquireDrmDisplayEXT"); 5543 ASSERT_EQ(AcquireDrmDisplayEXT, nullptr); 5544} 5545 5546// Test vkAcquireDrmDisplayEXT where instance supports it, but nothing else. 5547TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTNoICDSupport) { 5548 FrameworkEnvironment env{}; 5549 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5550 env.get_test_icd(0).physical_devices.push_back({}); 5551 5552 InstWrapper instance(env.vulkan_functions); 5553 instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME); 5554 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 5555 5556 PFN_vkAcquireDrmDisplayEXT AcquireDrmDisplayEXT = instance.load("vkAcquireDrmDisplayEXT"); 5557 ASSERT_EQ(AcquireDrmDisplayEXT, nullptr); 5558} 5559 5560// Test vkAcquireDrmDisplayEXT where instance and ICD supports it, but device does not support it. 5561TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTInstanceAndICDSupport) { 5562 FrameworkEnvironment env{}; 5563 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5564 Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; 5565 Extension second_ext{VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}; 5566 env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); 5567 env.get_test_icd(0).physical_devices.push_back({}); 5568 GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays); 5569 5570 InstWrapper instance(env.vulkan_functions); 5571 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); 5572 instance.CheckCreate(); 5573 5574 PFN_vkAcquireDrmDisplayEXT AcquireDrmDisplayEXT = instance.load("vkAcquireDrmDisplayEXT"); 5575 ASSERT_NE(AcquireDrmDisplayEXT, nullptr); 5576 5577 uint32_t driver_count = 1; 5578 VkPhysicalDevice physical_device; 5579 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 5580 ASSERT_EQ(driver_count, 1U); 5581 5582 VkDisplayKHR display = VK_NULL_HANDLE; 5583 ASSERT_EQ(VK_SUCCESS, AcquireDrmDisplayEXT(physical_device, 0, display)); 5584} 5585 5586// Test vkAcquireDrmDisplayEXT where instance supports it with some ICDs that both support 5587// and don't support it: 5588// ICD 0 supports 5589// Physical device 0 does not 5590// Physical device 1 does 5591// Physical device 2 does not 5592// ICD 1 doesn't support 5593// Physical device 3 does not 5594// ICD 2 supports 5595// Physical device 4 does not 5596// Physical device 5 does not 5597// ICD 3 supports 5598// Physical device 6 does 5599TEST(LoaderInstPhysDevExts, AcquireDrmDisplayEXTMixed) { 5600 FrameworkEnvironment env{}; 5601 const uint32_t max_icd_count = 4; 5602 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 5603 const uint32_t max_phys_devs = 7; 5604 5605 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 5606 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 5607 auto& cur_icd = env.get_test_icd(icd); 5608 cur_icd.icd_api_version = VK_API_VERSION_1_0; 5609 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 5610 5611 // ICD 1 should not have 1.1 5612 if (icd != 1) { 5613 cur_icd.icd_api_version = VK_API_VERSION_1_1; 5614 cur_icd.add_instance_extension({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); 5615 } 5616 5617 uint32_t rand_vendor_id; 5618 uint32_t rand_driver_vers; 5619 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 5620 5621 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 5622 uint32_t device_version = VK_API_VERSION_1_0; 5623 cur_icd.physical_devices.push_back({}); 5624 auto& cur_dev = cur_icd.physical_devices.back(); 5625 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 5626 5627 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 5628 if ((icd == 0 && dev == 1) || icd == 3) { 5629 cur_dev.extensions.push_back({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME, 0}); 5630 device_version = VK_API_VERSION_1_1; 5631 } 5632 5633 // Still set physical device properties (so we can determine if device is correct API version) 5634 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 5635 GenerateRandomDisplays(cur_dev.displays); 5636 } 5637 } 5638 5639 InstWrapper instance(env.vulkan_functions); 5640 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); 5641 instance.CheckCreate(); 5642 5643 PFN_vkAcquireDrmDisplayEXT AcquireDrmDisplayEXT = instance.load("vkAcquireDrmDisplayEXT"); 5644 ASSERT_NE(AcquireDrmDisplayEXT, nullptr); 5645 5646 uint32_t device_count = max_phys_devs; 5647 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 5648 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 5649 ASSERT_EQ(device_count, max_phys_devs); 5650 5651 for (uint32_t dev = 0; dev < device_count; ++dev) { 5652 VkPhysicalDeviceProperties pd_props{}; 5653 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 5654 5655 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 5656 auto& cur_icd = env.get_test_icd(icd); 5657 bool found = false; 5658 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 5659 auto& cur_dev = cur_icd.physical_devices[pd]; 5660 // Find the ICD device matching the physical device we're looking at info for so we can compare the 5661 // physical devices info with the returned info. 5662 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 5663 cur_dev.properties.deviceType == pd_props.deviceType && 5664 cur_dev.properties.driverVersion == pd_props.driverVersion && 5665 cur_dev.properties.vendorID == pd_props.vendorID) { 5666 VkDisplayKHR display = VK_NULL_HANDLE; 5667 if (icd == 1) { 5668 // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the 5669 // loader. 5670 ASSERT_EQ(VK_ERROR_EXTENSION_NOT_PRESENT, AcquireDrmDisplayEXT(physical_devices[dev], 0, display)); 5671 } else { 5672 ASSERT_EQ(VK_SUCCESS, AcquireDrmDisplayEXT(physical_devices[dev], 0, display)); 5673 } 5674 found = true; 5675 break; 5676 } 5677 } 5678 if (found) { 5679 break; 5680 } 5681 } 5682 } 5683} 5684 5685// Test vkGetDrmDisplayEXT where nothing supports it. 5686TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTNoSupport) { 5687 FrameworkEnvironment env{}; 5688 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5689 env.get_test_icd(0).physical_devices.push_back({}); 5690 5691 InstWrapper instance(env.vulkan_functions); 5692 instance.CheckCreate(); 5693 5694 PFN_vkGetDrmDisplayEXT GetDrmDisplayEXT = instance.load("vkGetDrmDisplayEXT"); 5695 ASSERT_EQ(GetDrmDisplayEXT, nullptr); 5696} 5697 5698// Test vkGetDrmDisplayEXT where instance supports it, but nothing else. 5699TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTNoICDSupport) { 5700 FrameworkEnvironment env{}; 5701 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5702 env.get_test_icd(0).physical_devices.push_back({}); 5703 5704 InstWrapper instance(env.vulkan_functions); 5705 instance.create_info.add_extension(VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME); 5706 instance.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT); 5707 5708 PFN_vkGetDrmDisplayEXT GetDrmDisplayEXT = instance.load("vkGetDrmDisplayEXT"); 5709 ASSERT_EQ(GetDrmDisplayEXT, nullptr); 5710} 5711 5712// Test vkGetDrmDisplayEXT where instance and ICD supports it, but device does not support it. 5713TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTInstanceAndICDSupport) { 5714 FrameworkEnvironment env{}; 5715 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); 5716 Extension first_ext{VK_KHR_DISPLAY_EXTENSION_NAME}; 5717 Extension second_ext{VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}; 5718 env.get_test_icd(0).add_instance_extensions({first_ext, second_ext}); 5719 env.get_test_icd(0).physical_devices.push_back({}); 5720 GenerateRandomDisplays(env.get_test_icd(0).physical_devices.back().displays); 5721 5722 InstWrapper instance(env.vulkan_functions); 5723 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); 5724 instance.CheckCreate(); 5725 5726 PFN_vkGetDrmDisplayEXT GetDrmDisplayEXT = instance.load("vkGetDrmDisplayEXT"); 5727 ASSERT_NE(GetDrmDisplayEXT, nullptr); 5728 5729 uint32_t driver_count = 1; 5730 VkPhysicalDevice physical_device; 5731 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &driver_count, &physical_device)); 5732 ASSERT_EQ(driver_count, 1U); 5733 5734 VkDisplayKHR display = VK_NULL_HANDLE; 5735 ASSERT_EQ(VK_SUCCESS, GetDrmDisplayEXT(physical_device, 0, 0, &display)); 5736 ASSERT_EQ(display, env.get_test_icd(0).physical_devices.back().displays[0]); 5737} 5738 5739// Test vkGetDrmDisplayEXT where instance supports it with some ICDs that both support 5740// and don't support it: 5741// ICD 0 supports 5742// Physical device 0 does not 5743// Physical device 1 does 5744// Physical device 2 does not 5745// ICD 1 doesn't support 5746// Physical device 3 does not 5747// ICD 2 supports 5748// Physical device 4 does not 5749// Physical device 5 does not 5750// ICD 3 supports 5751// Physical device 6 does 5752TEST(LoaderInstPhysDevExts, GetDrmDisplayEXTMixed) { 5753 FrameworkEnvironment env{}; 5754 const uint32_t max_icd_count = 4; 5755 const uint32_t dev_counts[max_icd_count] = {3, 1, 2, 1}; 5756 const uint32_t max_phys_devs = 7; 5757 5758 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 5759 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, icd != 1 ? VK_API_VERSION_1_1 : VK_API_VERSION_1_0)); 5760 auto& cur_icd = env.get_test_icd(icd); 5761 cur_icd.icd_api_version = VK_API_VERSION_1_0; 5762 cur_icd.add_instance_extension({VK_KHR_DISPLAY_EXTENSION_NAME}); 5763 5764 // ICD 1 should not have 1.1 5765 if (icd != 1) { 5766 cur_icd.icd_api_version = VK_API_VERSION_1_1; 5767 cur_icd.add_instance_extension({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); 5768 } 5769 5770 uint32_t rand_vendor_id; 5771 uint32_t rand_driver_vers; 5772 FillInRandomICDInfo(rand_vendor_id, rand_driver_vers); 5773 5774 for (uint32_t dev = 0; dev < dev_counts[icd]; ++dev) { 5775 uint32_t device_version = VK_API_VERSION_1_0; 5776 cur_icd.physical_devices.push_back({}); 5777 auto& cur_dev = cur_icd.physical_devices.back(); 5778 cur_dev.extensions.push_back({VK_KHR_DISPLAY_EXTENSION_NAME, 0}); 5779 5780 // 2nd device in ICD 0 and the one device in ICD 3 support the extension and 1.1 5781 if ((icd == 0 && dev == 1) || icd == 3) { 5782 cur_dev.extensions.push_back({VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME, 0}); 5783 device_version = VK_API_VERSION_1_1; 5784 } 5785 5786 // Still set physical device properties (so we can determine if device is correct API version) 5787 FillInRandomDeviceProps(cur_dev.properties, device_version, rand_vendor_id, rand_driver_vers); 5788 GenerateRandomDisplays(cur_dev.displays); 5789 } 5790 } 5791 5792 InstWrapper instance(env.vulkan_functions); 5793 instance.create_info.add_extensions({VK_KHR_DISPLAY_EXTENSION_NAME, VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME}); 5794 instance.CheckCreate(); 5795 5796 PFN_vkGetDrmDisplayEXT GetDrmDisplayEXT = instance.load("vkGetDrmDisplayEXT"); 5797 ASSERT_NE(GetDrmDisplayEXT, nullptr); 5798 5799 uint32_t device_count = max_phys_devs; 5800 std::array<VkPhysicalDevice, max_phys_devs> physical_devices; 5801 ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data())); 5802 ASSERT_EQ(device_count, max_phys_devs); 5803 5804 for (uint32_t dev = 0; dev < device_count; ++dev) { 5805 VkPhysicalDeviceProperties pd_props{}; 5806 instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &pd_props); 5807 5808 for (uint32_t icd = 0; icd < max_icd_count; ++icd) { 5809 auto& cur_icd = env.get_test_icd(icd); 5810 bool found = false; 5811 for (uint32_t pd = 0; pd < dev_counts[icd]; ++pd) { 5812 auto& cur_dev = cur_icd.physical_devices[pd]; 5813 // Find the ICD device matching the physical device we're looking at info for so we can compare the 5814 // physical devices info with the returned info. 5815 if (cur_dev.properties.apiVersion == pd_props.apiVersion && cur_dev.properties.deviceID == pd_props.deviceID && 5816 cur_dev.properties.deviceType == pd_props.deviceType && 5817 cur_dev.properties.driverVersion == pd_props.driverVersion && 5818 cur_dev.properties.vendorID == pd_props.vendorID) { 5819 VkDisplayKHR display = VK_NULL_HANDLE; 5820 if (icd == 1) { 5821 // For this extension, if no support exists (like for ICD 1), the value of 0 should be returned by the 5822 // loader. 5823 ASSERT_EQ(VK_ERROR_EXTENSION_NOT_PRESENT, GetDrmDisplayEXT(physical_devices[dev], 0, 0, &display)); 5824 } else { 5825 ASSERT_EQ(VK_SUCCESS, GetDrmDisplayEXT(physical_devices[dev], 0, 0, &display)); 5826 ASSERT_EQ(display, cur_dev.displays[0]); 5827 } 5828 found = true; 5829 break; 5830 } 5831 } 5832 if (found) { 5833 break; 5834 } 5835 } 5836 } 5837} 5838 5839TEST(LoaderInstPhysDevExts, DifferentInstanceExtensions) { 5840 FrameworkEnvironment env{}; 5841 5842 // Add 3 drivers each of which supports a different instance extension 5843 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); 5844 env.get_test_icd(0).add_instance_extension({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}); 5845 env.get_test_icd(0).physical_devices.push_back({"pd0"}); 5846 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 0}); 5847 5848 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); 5849 env.get_test_icd(1).add_instance_extension({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME}); 5850 env.get_test_icd(1).physical_devices.push_back({"pd1"}); 5851 env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 0}); 5852 5853 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); 5854 env.get_test_icd(2).add_instance_extension({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); 5855 env.get_test_icd(2).physical_devices.push_back({"pd2"}); 5856 env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, 0}); 5857 5858 DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; 5859 InstWrapper inst{env.vulkan_functions}; 5860 inst.create_info.add_extensions({VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 5861 VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, 5862 VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME}); 5863 FillDebugUtilsCreateDetails(inst.create_info, log); 5864 inst.CheckCreate(); 5865 5866 const uint32_t expected_device_count = 3; 5867 auto physical_devices = inst.GetPhysDevs(expected_device_count); 5868 5869 PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferProperties = 5870 inst.load("vkGetPhysicalDeviceExternalBufferPropertiesKHR"); 5871 PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphoreProperties = 5872 inst.load("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"); 5873 PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFenceProperties = 5874 inst.load("vkGetPhysicalDeviceExternalFencePropertiesKHR"); 5875 ASSERT_NE(nullptr, GetPhysicalDeviceExternalBufferProperties); 5876 ASSERT_NE(nullptr, GetPhysicalDeviceExternalSemaphoreProperties); 5877 ASSERT_NE(nullptr, GetPhysicalDeviceExternalFenceProperties); 5878 5879 // The above are instance extensions, so shouldn't crash even if only one physical device supports each 5880 // extension. 5881 for (uint32_t dev = 0; dev < expected_device_count; ++dev) { 5882 VkPhysicalDeviceExternalBufferInfo ext_buf_info{}; 5883 VkExternalBufferProperties ext_buf_props{}; 5884 VkPhysicalDeviceExternalSemaphoreInfo ext_sem_info{}; 5885 VkExternalSemaphoreProperties ext_sem_props{}; 5886 VkPhysicalDeviceExternalFenceInfo ext_fence_info{}; 5887 VkExternalFenceProperties ext_fence_props{}; 5888 GetPhysicalDeviceExternalBufferProperties(physical_devices[dev], &ext_buf_info, &ext_buf_props); 5889 GetPhysicalDeviceExternalSemaphoreProperties(physical_devices[dev], &ext_sem_info, &ext_sem_props); 5890 GetPhysicalDeviceExternalFenceProperties(physical_devices[dev], &ext_fence_info, &ext_fence_props); 5891 } 5892} 5893 5894TEST(LoaderInstPhysDevExts, DifferentPhysicalDeviceExtensions) { 5895 FrameworkEnvironment env{}; 5896 5897 // Add 3 drivers each of which supports a different physical device extension 5898 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); 5899 env.get_test_icd(0).physical_devices.push_back("pd0"); 5900 env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, 0}); 5901 5902 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); 5903 env.get_test_icd(1).physical_devices.push_back("pd1"); 5904 env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, 0}); 5905 5906 env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0)); 5907 env.get_test_icd(2).physical_devices.push_back("pd2"); 5908 env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, 0}); 5909 5910 DebugUtilsLogger log{VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT}; 5911 InstWrapper inst{env.vulkan_functions}; 5912 FillDebugUtilsCreateDetails(inst.create_info, log); 5913 inst.CheckCreate(); 5914 5915 const uint32_t expected_device_count = 3; 5916 auto physical_devices = inst.GetPhysDevs(expected_device_count); 5917 5918 PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR 5919 EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR = 5920 inst.load("vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR"); 5921 PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT = 5922 inst.load("vkGetPhysicalDeviceMultisamplePropertiesEXT"); 5923 PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT GetPhysicalDeviceCalibrateableTimeDomainsEXT = 5924 inst.load("vkGetPhysicalDeviceCalibrateableTimeDomainsEXT"); 5925 ASSERT_NE(nullptr, EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR); 5926 ASSERT_NE(nullptr, GetPhysicalDeviceMultisamplePropertiesEXT); 5927 ASSERT_NE(nullptr, GetPhysicalDeviceCalibrateableTimeDomainsEXT); 5928 5929 for (uint32_t dev = 0; dev < expected_device_count; ++dev) { 5930 uint32_t extension_count = 0; 5931 std::vector<VkExtensionProperties> device_extensions; 5932 bool supports_query = false; 5933 bool supports_samples = false; 5934 bool supports_timestamps = false; 5935 ASSERT_EQ(VK_SUCCESS, 5936 inst->vkEnumerateDeviceExtensionProperties(physical_devices[dev], nullptr, &extension_count, nullptr)); 5937 ASSERT_GT(extension_count, 0U); 5938 device_extensions.resize(extension_count); 5939 ASSERT_EQ(VK_SUCCESS, inst->vkEnumerateDeviceExtensionProperties(physical_devices[dev], nullptr, &extension_count, 5940 device_extensions.data())); 5941 for (uint32_t ext = 0; ext < extension_count; ++ext) { 5942 if (string_eq(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME, &device_extensions[ext].extensionName[0])) { 5943 supports_query = true; 5944 } 5945 if (string_eq(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME, &device_extensions[ext].extensionName[0])) { 5946 supports_samples = true; 5947 } 5948 if (string_eq(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME, &device_extensions[ext].extensionName[0])) { 5949 supports_timestamps = true; 5950 } 5951 } 5952 5953 // For physical device extensions, they should work for devices that support it and crash for those that don't. 5954 if (supports_query) { 5955 ASSERT_EQ(VK_SUCCESS, EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(physical_devices[dev], 0, nullptr, 5956 nullptr, nullptr)); 5957 } else { 5958 ASSERT_DEATH( 5959 EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(physical_devices[dev], 0, nullptr, nullptr, nullptr), 5960 ""); 5961 ASSERT_FALSE( 5962 log.find("ICD associated with VkPhysicalDevice does not support " 5963 "EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR")); 5964 } 5965 if (supports_samples) { 5966 GetPhysicalDeviceMultisamplePropertiesEXT(physical_devices[dev], VK_SAMPLE_COUNT_2_BIT, nullptr); 5967 } else { 5968 ASSERT_DEATH(GetPhysicalDeviceMultisamplePropertiesEXT(physical_devices[dev], VK_SAMPLE_COUNT_2_BIT, nullptr), ""); 5969 ASSERT_FALSE( 5970 log.find("ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceMultisamplePropertiesEXT")); 5971 } 5972 if (supports_timestamps) { 5973 ASSERT_EQ(VK_SUCCESS, GetPhysicalDeviceCalibrateableTimeDomainsEXT(physical_devices[dev], nullptr, nullptr)); 5974 } else { 5975 ASSERT_DEATH(GetPhysicalDeviceCalibrateableTimeDomainsEXT(physical_devices[dev], nullptr, nullptr), ""); 5976 ASSERT_FALSE( 5977 log.find("ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceCalibrateableTimeDomainsEXT")); 5978 } 5979 } 5980} 5981