1 /*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Device Initialization Tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktApiDeviceInitializationTests.hpp" 25 #include "vktTestCaseUtil.hpp" 26 27 #include "vkDefs.hpp" 28 #include "vkPlatform.hpp" 29 #include "vkStrUtil.hpp" 30 #include "vkRef.hpp" 31 #include "vkRefUtil.hpp" 32 #include "vkQueryUtil.hpp" 33 #include "vkMemUtil.hpp" 34 #include "vkDeviceUtil.hpp" 35 #include "vkApiVersion.hpp" 36 37 #include "tcuTestLog.hpp" 38 #include "tcuResultCollector.hpp" 39 40 #include "deUniquePtr.hpp" 41 #include "deStringUtil.hpp" 42 43 #include <vector> 44 45 namespace vkt 46 { 47 namespace api 48 { 49 50 namespace 51 { 52 53 using namespace vk; 54 using namespace std; 55 using std::vector; 56 using tcu::TestLog; 57 58 tcu::TestStatus createInstanceTest (Context& context) 59 { 60 tcu::TestLog& log = context.getTestContext().getLog(); 61 tcu::ResultCollector resultCollector (log); 62 const char* appNames[] = { "appName", DE_NULL, "", "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" }; 63 const char* engineNames[] = { "engineName", DE_NULL, "", "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" }; 64 const int patchNumbers[] = { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 }; 65 const deUint32 appVersions[] = { 0, 1, (deUint32)-1 }; 66 const deUint32 engineVersions[] = { 0, 1, (deUint32)-1 }; 67 const PlatformInterface& platformInterface = context.getPlatformInterface(); 68 const deUint32 apiVersion = context.getUsedApiVersion(); 69 vector<VkApplicationInfo> appInfos; 70 71 // test over appName 72 for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++) 73 { 74 const VkApplicationInfo appInfo = 75 { 76 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 77 DE_NULL, // const void* pNext; 78 appNames[appNameNdx], // const char* pAppName; 79 0u, // deUint32 appVersion; 80 "engineName", // const char* pEngineName; 81 0u, // deUint32 engineVersion; 82 apiVersion, // deUint32 apiVersion; 83 }; 84 85 appInfos.push_back(appInfo); 86 } 87 88 // test over engineName 89 for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++) 90 { 91 const VkApplicationInfo appInfo = 92 { 93 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 94 DE_NULL, // const void* pNext; 95 "appName", // const char* pAppName; 96 0u, // deUint32 appVersion; 97 engineNames[engineNameNdx], // const char* pEngineName; 98 0u, // deUint32 engineVersion; 99 apiVersion, // deUint32 apiVersion; 100 }; 101 102 appInfos.push_back(appInfo); 103 } 104 105 // test over appVersion 106 for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++) 107 { 108 const VkApplicationInfo appInfo = 109 { 110 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 111 DE_NULL, // const void* pNext; 112 "appName", // const char* pAppName; 113 appVersions[appVersionNdx], // deUint32 appVersion; 114 "engineName", // const char* pEngineName; 115 0u, // deUint32 engineVersion; 116 apiVersion, // deUint32 apiVersion; 117 }; 118 119 appInfos.push_back(appInfo); 120 } 121 122 // test over engineVersion 123 for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++) 124 { 125 const VkApplicationInfo appInfo = 126 { 127 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 128 DE_NULL, // const void* pNext; 129 "appName", // const char* pAppName; 130 0u, // deUint32 appVersion; 131 "engineName", // const char* pEngineName; 132 engineVersions[engineVersionNdx], // deUint32 engineVersion; 133 apiVersion, // deUint32 apiVersion; 134 }; 135 136 appInfos.push_back(appInfo); 137 } 138 const deUint32 manjorNum = unpackVersion(apiVersion).majorNum; 139 const deUint32 minorNum = unpackVersion(apiVersion).minorNum; 140 141 // patch component of api version checking (should be ignored by implementation) 142 for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++) 143 { 144 const VkApplicationInfo appInfo = 145 { 146 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 147 DE_NULL, // const void* pNext; 148 "appName", // const char* pAppName; 149 0u, // deUint32 appVersion; 150 "engineName", // const char* pEngineName; 151 0u, // deUint32 engineVersion; 152 VK_MAKE_VERSION(manjorNum, minorNum, patchNumbers[patchVersion]), // deUint32 apiVersion; 153 }; 154 155 appInfos.push_back(appInfo); 156 } 157 158 // test when apiVersion is 0 159 { 160 const VkApplicationInfo appInfo = 161 { 162 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 163 DE_NULL, // const void* pNext; 164 "appName", // const char* pAppName; 165 0u, // deUint32 appVersion; 166 "engineName", // const char* pEngineName; 167 0u, // deUint32 engineVersion; 168 0u, // deUint32 apiVersion; 169 }; 170 171 appInfos.push_back(appInfo); 172 } 173 174 // run the tests! 175 for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx) 176 { 177 const VkApplicationInfo& appInfo = appInfos[appInfoNdx]; 178 const VkInstanceCreateInfo instanceCreateInfo = 179 { 180 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType; 181 DE_NULL, // const void* pNext; 182 (VkInstanceCreateFlags)0u, // VkInstanceCreateFlags flags; 183 &appInfo, // const VkApplicationInfo* pAppInfo; 184 0u, // deUint32 layerCount; 185 DE_NULL, // const char*const* ppEnabledLayernames; 186 0u, // deUint32 extensionCount; 187 DE_NULL, // const char*const* ppEnabledExtensionNames; 188 }; 189 190 log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage; 191 192 try 193 { 194 const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo)); 195 log << TestLog::Message << "Succeeded" << TestLog::EndMessage; 196 } 197 catch (const vk::Error& err) 198 { 199 resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage())); 200 } 201 } 202 203 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage()); 204 } 205 206 tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context) 207 { 208 tcu::TestLog& log = context.getTestContext().getLog(); 209 tcu::ResultCollector resultCollector (log); 210 const PlatformInterface& platformInterface = context.getPlatformInterface(); 211 212 deUint32 instanceApiVersion = 0u; 213 context.getPlatformInterface().enumerateInstanceVersion(&instanceApiVersion); 214 215 const ApiVersion apiVersion = unpackVersion(instanceApiVersion); 216 217 const deUint32 invalidMajorVersion = (1 << 10) - 1; 218 const deUint32 invalidMinorVersion = (1 << 10) - 1; 219 vector<ApiVersion> invalidApiVersions; 220 221 invalidApiVersions.push_back(ApiVersion(invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum)); 222 invalidApiVersions.push_back(ApiVersion(apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum)); 223 224 for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++) 225 { 226 const VkApplicationInfo appInfo = 227 { 228 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 229 DE_NULL, // const void* pNext; 230 "appName", // const char* pAppName; 231 0u, // deUint32 appVersion; 232 "engineName", // const char* pEngineName; 233 0u, // deUint32 engineVersion; 234 pack(invalidApiVersions[apiVersionNdx]), // deUint32 apiVersion; 235 }; 236 const VkInstanceCreateInfo instanceCreateInfo = 237 { 238 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType; 239 DE_NULL, // const void* pNext; 240 (VkInstanceCreateFlags)0u, // VkInstanceCreateFlags flags; 241 &appInfo, // const VkApplicationInfo* pAppInfo; 242 0u, // deUint32 layerCount; 243 DE_NULL, // const char*const* ppEnabledLayernames; 244 0u, // deUint32 extensionCount; 245 DE_NULL, // const char*const* ppEnabledExtensionNames; 246 }; 247 248 249 log << TestLog::Message 250 << "API version reported by enumerateInstanceVersion: " << apiVersion 251 << ", api version used to create instance: " << invalidApiVersions[apiVersionNdx] 252 << TestLog::EndMessage; 253 254 { 255 VkInstance instance = (VkInstance)0; 256 const VkResult result = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance); 257 const bool gotInstance = !!instance; 258 259 if (instance) 260 { 261 const InstanceDriver instanceIface(platformInterface, instance); 262 instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/); 263 } 264 265 if (apiVersion.majorNum == 1 && apiVersion.minorNum == 0) 266 { 267 if (result == VK_ERROR_INCOMPATIBLE_DRIVER) 268 { 269 TCU_CHECK(!gotInstance); 270 log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage; 271 } 272 else 273 resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected"); 274 } 275 else if (apiVersion.majorNum == 1 && apiVersion.minorNum >= 1) 276 { 277 if (result == VK_SUCCESS) 278 { 279 TCU_CHECK(gotInstance); 280 log << TestLog::Message << "Pass, instance creation with nonstandard apiVersion succeeds for Vulkan 1.1" << TestLog::EndMessage; 281 } 282 else if (result == VK_ERROR_INCOMPATIBLE_DRIVER) 283 { 284 resultCollector.fail("Fail, In Vulkan 1.1 instance creation must not return VK_ERROR_INCOMPATIBLE_DRIVER."); 285 } 286 else 287 { 288 std::ostringstream message; 289 message << "Fail, createInstance failed with " << result; 290 resultCollector.fail(message.str().c_str()); 291 } 292 } 293 } 294 } 295 296 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage()); 297 } 298 299 tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context) 300 { 301 tcu::TestLog& log = context.getTestContext().getLog(); 302 tcu::ResultCollector resultCollector (log); 303 const PlatformInterface& platformInterface = context.getPlatformInterface(); 304 305 const VkInstanceCreateInfo instanceCreateInfo = 306 { 307 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType; 308 DE_NULL, // const void* pNext; 309 (VkInstanceCreateFlags)0u, // VkInstanceCreateFlags flags; 310 DE_NULL, // const VkApplicationInfo* pAppInfo; 311 0u, // deUint32 layerCount; 312 DE_NULL, // const char*const* ppEnabledLayernames; 313 0u, // deUint32 extensionCount; 314 DE_NULL, // const char*const* ppEnabledExtensionNames; 315 }; 316 317 log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage; 318 319 try 320 { 321 const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo)); 322 log << TestLog::Message << "Succeeded" << TestLog::EndMessage; 323 } 324 catch (const vk::Error& err) 325 { 326 resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage())); 327 } 328 329 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage()); 330 } 331 332 tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context) 333 { 334 tcu::TestLog& log = context.getTestContext().getLog(); 335 const PlatformInterface& platformInterface = context.getPlatformInterface(); 336 const char* enabledExtensions[] = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"}; 337 const deUint32 apiVersion = context.getUsedApiVersion(); 338 const VkApplicationInfo appInfo = 339 { 340 VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType; 341 DE_NULL, // const void* pNext; 342 "appName", // const char* pAppName; 343 0u, // deUint32 appVersion; 344 "engineName", // const char* pEngineName; 345 0u, // deUint32 engineVersion; 346 apiVersion, // deUint32 apiVersion; 347 }; 348 const VkInstanceCreateInfo instanceCreateInfo = 349 { 350 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType; 351 DE_NULL, // const void* pNext; 352 (VkInstanceCreateFlags)0u, // VkInstanceCreateFlags flags; 353 &appInfo, // const VkApplicationInfo* pAppInfo; 354 0u, // deUint32 layerCount; 355 DE_NULL, // const char*const* ppEnabledLayernames; 356 DE_LENGTH_OF_ARRAY(enabledExtensions), // deUint32 extensionCount; 357 enabledExtensions, // const char*const* ppEnabledExtensionNames; 358 }; 359 360 log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage; 361 362 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++) 363 log << TestLog::Message << enabledExtensions[ndx] << TestLog::EndMessage; 364 365 { 366 VkInstance instance = (VkInstance)0; 367 const VkResult result = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance); 368 const bool gotInstance = !!instance; 369 370 if (instance) 371 { 372 const InstanceDriver instanceIface (platformInterface, instance); 373 instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/); 374 } 375 376 if (result == VK_ERROR_EXTENSION_NOT_PRESENT) 377 { 378 TCU_CHECK(!gotInstance); 379 return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected."); 380 } 381 else 382 return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded."); 383 } 384 } 385 386 tcu::TestStatus createDeviceTest (Context& context) 387 { 388 const PlatformInterface& platformInterface = context.getPlatformInterface(); 389 const Unique<VkInstance> instance (createDefaultInstance(platformInterface, context.getUsedApiVersion())); 390 const InstanceDriver instanceDriver (platformInterface, instance.get()); 391 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine()); 392 const deUint32 queueFamilyIndex = 0; 393 const deUint32 queueCount = 1; 394 const deUint32 queueIndex = 0; 395 const float queuePriority = 1.0f; 396 const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 397 { 398 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 399 DE_NULL, 400 (VkDeviceQueueCreateFlags)0u, 401 queueFamilyIndex, //queueFamilyIndex; 402 queueCount, //queueCount; 403 &queuePriority, //pQueuePriorities; 404 }; 405 const VkDeviceCreateInfo deviceCreateInfo = 406 { 407 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType; 408 DE_NULL, //pNext; 409 (VkDeviceCreateFlags)0u, 410 1, //queueRecordCount; 411 &deviceQueueCreateInfo, //pRequestedQueues; 412 0, //layerCount; 413 DE_NULL, //ppEnabledLayerNames; 414 0, //extensionCount; 415 DE_NULL, //ppEnabledExtensionNames; 416 DE_NULL, //pEnabledFeatures; 417 }; 418 419 const Unique<VkDevice> device (createDevice(instanceDriver, physicalDevice, &deviceCreateInfo)); 420 const DeviceDriver deviceDriver (instanceDriver, device.get()); 421 const VkQueue queue = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex); 422 423 VK_CHECK(deviceDriver.queueWaitIdle(queue)); 424 425 return tcu::TestStatus::pass("Pass"); 426 } 427 428 tcu::TestStatus createMultipleDevicesTest (Context& context) 429 { 430 tcu::TestLog& log = context.getTestContext().getLog(); 431 tcu::ResultCollector resultCollector (log); 432 const int numDevices = 5; 433 const PlatformInterface& platformInterface = context.getPlatformInterface(); 434 const Unique<VkInstance> instance (createDefaultInstance(platformInterface, context.getUsedApiVersion())); 435 const InstanceDriver instanceDriver (platformInterface, instance.get()); 436 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine()); 437 const deUint32 queueFamilyIndex = 0; 438 const deUint32 queueCount = 1; 439 const deUint32 queueIndex = 0; 440 const float queuePriority = 1.0f; 441 const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 442 { 443 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 444 DE_NULL, 445 (VkDeviceQueueCreateFlags)0u, //flags; 446 queueFamilyIndex, //queueFamilyIndex; 447 queueCount, //queueCount; 448 &queuePriority, //pQueuePriorities; 449 }; 450 const VkDeviceCreateInfo deviceCreateInfo = 451 { 452 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType; 453 DE_NULL, //pNext; 454 (VkDeviceCreateFlags)0u, 455 1, //queueRecordCount; 456 &deviceQueueCreateInfo, //pRequestedQueues; 457 0, //layerCount; 458 DE_NULL, //ppEnabledLayerNames; 459 0, //extensionCount; 460 DE_NULL, //ppEnabledExtensionNames; 461 DE_NULL, //pEnabledFeatures; 462 }; 463 vector<VkDevice> devices(numDevices, (VkDevice)DE_NULL); 464 465 try 466 { 467 for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++) 468 { 469 const VkResult result = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]); 470 471 if (result != VK_SUCCESS) 472 { 473 resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result)); 474 break; 475 } 476 477 { 478 const DeviceDriver deviceDriver (instanceDriver, devices[deviceNdx]); 479 const VkQueue queue = getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex); 480 481 VK_CHECK(deviceDriver.queueWaitIdle(queue)); 482 } 483 } 484 } 485 catch (const vk::Error& error) 486 { 487 resultCollector.fail(de::toString(error.getError())); 488 } 489 catch (...) 490 { 491 for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--) 492 { 493 if (devices[deviceNdx] != (VkDevice)DE_NULL) 494 { 495 DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]); 496 deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/); 497 } 498 } 499 500 throw; 501 } 502 503 for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--) 504 { 505 if (devices[deviceNdx] != (VkDevice)DE_NULL) 506 { 507 DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]); 508 deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/); 509 } 510 } 511 512 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage()); 513 } 514 515 tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context) 516 { 517 tcu::TestLog& log = context.getTestContext().getLog(); 518 const PlatformInterface& platformInterface = context.getPlatformInterface(); 519 const Unique<VkInstance> instance (createDefaultInstance(platformInterface, context.getUsedApiVersion())); 520 const InstanceDriver instanceDriver (platformInterface, instance.get()); 521 const char* enabledExtensions[] = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"}; 522 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine()); 523 const float queuePriority = 1.0f; 524 const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 525 { 526 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 527 DE_NULL, 528 (VkDeviceQueueCreateFlags)0u, 529 0, //queueFamilyIndex; 530 1, //queueCount; 531 &queuePriority, //pQueuePriorities; 532 }; 533 const VkDeviceCreateInfo deviceCreateInfo = 534 { 535 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType; 536 DE_NULL, //pNext; 537 (VkDeviceCreateFlags)0u, 538 1, //queueRecordCount; 539 &deviceQueueCreateInfo, //pRequestedQueues; 540 0, //layerCount; 541 DE_NULL, //ppEnabledLayerNames; 542 DE_LENGTH_OF_ARRAY(enabledExtensions), //extensionCount; 543 enabledExtensions, //ppEnabledExtensionNames; 544 DE_NULL, //pEnabledFeatures; 545 }; 546 547 log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage; 548 549 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++) 550 log << TestLog::Message << enabledExtensions[ndx] << TestLog::EndMessage; 551 552 { 553 VkDevice device = (VkDevice)0; 554 const VkResult result = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device); 555 const bool gotDevice = !!device; 556 557 if (device) 558 { 559 const DeviceDriver deviceIface (instanceDriver, device); 560 deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/); 561 } 562 563 if (result == VK_ERROR_EXTENSION_NOT_PRESENT) 564 { 565 TCU_CHECK(!gotDevice); 566 return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected."); 567 } 568 else 569 return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed."); 570 } 571 } 572 573 deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties) 574 { 575 deUint32 maxQueueCount = 0; 576 577 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++) 578 { 579 maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount); 580 } 581 582 return maxQueueCount; 583 } 584 585 tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context) 586 { 587 tcu::TestLog& log = context.getTestContext().getLog(); 588 const int queueCountDiff = 1; 589 const PlatformInterface& platformInterface = context.getPlatformInterface(); 590 const Unique<VkInstance> instance (createDefaultInstance(platformInterface, context.getUsedApiVersion())); 591 const InstanceDriver instanceDriver (platformInterface, instance.get()); 592 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine()); 593 const vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice); 594 const vector<float> queuePriorities (getGlobalMaxQueueCount(queueFamilyProperties), 1.0f); 595 vector<VkDeviceQueueCreateInfo> deviceQueueCreateInfos; 596 597 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++) 598 { 599 const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount; 600 601 for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff) 602 { 603 const VkDeviceQueueCreateInfo queueCreateInfo = 604 { 605 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 606 DE_NULL, 607 (VkDeviceQueueCreateFlags)0u, 608 queueFamilyNdx, 609 queueCount, 610 queuePriorities.data() 611 }; 612 613 deviceQueueCreateInfos.push_back(queueCreateInfo); 614 } 615 } 616 617 for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++) 618 { 619 const VkDeviceQueueCreateInfo& queueCreateInfo = deviceQueueCreateInfos[testNdx]; 620 const VkDeviceCreateInfo deviceCreateInfo = 621 { 622 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType; 623 DE_NULL, //pNext; 624 (VkDeviceCreateFlags)0u, 625 1, //queueRecordCount; 626 &queueCreateInfo, //pRequestedQueues; 627 0, //layerCount; 628 DE_NULL, //ppEnabledLayerNames; 629 0, //extensionCount; 630 DE_NULL, //ppEnabledExtensionNames; 631 DE_NULL, //pEnabledFeatures; 632 }; 633 const Unique<VkDevice> device (createDevice(instanceDriver, physicalDevice, &deviceCreateInfo)); 634 const DeviceDriver deviceDriver (instanceDriver, device.get()); 635 const deUint32 queueFamilyIndex = deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex; 636 const deUint32 queueCount = deviceCreateInfo.pQueueCreateInfos->queueCount; 637 638 for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++) 639 { 640 const VkQueue queue = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex); 641 VkResult result; 642 643 TCU_CHECK(!!queue); 644 645 result = deviceDriver.queueWaitIdle(queue); 646 if (result != VK_SUCCESS) 647 { 648 log << TestLog::Message 649 << "vkQueueWaitIdle failed" 650 << ", queueIndex = " << queueIndex 651 << ", queueCreateInfo " << queueCreateInfo 652 << ", Error Code: " << result 653 << TestLog::EndMessage; 654 return tcu::TestStatus::fail("Fail"); 655 } 656 } 657 } 658 return tcu::TestStatus::pass("Pass"); 659 } 660 661 Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, const char* extensionName, Context& context) 662 { 663 const vector<VkExtensionProperties> instanceExts = enumerateInstanceExtensionProperties(vkp, DE_NULL); 664 vector<string> enabledExts; 665 666 const deUint32 instanceVersion = context.getUsedApiVersion(); 667 668 if (!isCoreInstanceExtension(instanceVersion, extensionName)) 669 { 670 if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName))) 671 TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str()); 672 else 673 enabledExts.push_back(extensionName); 674 } 675 676 return createDefaultInstance(vkp, instanceVersion, vector<string>() /* layers */, enabledExts); 677 } 678 679 tcu::TestStatus createDeviceFeatures2Test (Context& context) 680 { 681 const PlatformInterface& vkp = context.getPlatformInterface(); 682 const Unique<VkInstance> instance (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context)); 683 const InstanceDriver vki (vkp, instance.get()); 684 const VkPhysicalDevice physicalDevice = chooseDevice(vki, instance.get(), context.getTestContext().getCommandLine()); 685 const deUint32 queueFamilyIndex = 0; 686 const deUint32 queueCount = 1; 687 const deUint32 queueIndex = 0; 688 const float queuePriority = 1.0f; 689 690 VkPhysicalDeviceFeatures2 enabledFeatures; 691 const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 692 { 693 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 694 DE_NULL, 695 (VkDeviceQueueCreateFlags)0u, 696 queueFamilyIndex, 697 queueCount, 698 &queuePriority, 699 }; 700 const VkDeviceCreateInfo deviceCreateInfo = 701 { 702 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 703 &enabledFeatures, 704 (VkDeviceCreateFlags)0u, 705 1, 706 &deviceQueueCreateInfo, 707 0, 708 DE_NULL, 709 0, 710 DE_NULL, 711 DE_NULL, 712 }; 713 714 // Populate enabledFeatures 715 enabledFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 716 enabledFeatures.pNext = DE_NULL; 717 718 vki.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures); 719 720 { 721 const Unique<VkDevice> device (createDevice(vki, physicalDevice, &deviceCreateInfo)); 722 const DeviceDriver vkd (vki, device.get()); 723 const VkQueue queue = getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex); 724 725 VK_CHECK(vkd.queueWaitIdle(queue)); 726 } 727 728 return tcu::TestStatus::pass("Pass"); 729 } 730 731 struct Feature 732 { 733 const char* name; 734 size_t offset; 735 }; 736 737 #define FEATURE_ITEM(MEMBER) {#MEMBER, DE_OFFSET_OF(VkPhysicalDeviceFeatures, MEMBER)} 738 739 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context) 740 { 741 tcu::TestLog& log = context.getTestContext().getLog(); 742 tcu::ResultCollector resultCollector (log); 743 const PlatformInterface& platformInterface = context.getPlatformInterface(); 744 const Move<VkInstance> instance (createDefaultInstance(platformInterface, context.getUsedApiVersion())); 745 const InstanceDriver instanceDriver (platformInterface, instance.get()); 746 const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine()); 747 const deUint32 queueFamilyIndex = 0; 748 const deUint32 queueCount = 1; 749 const float queuePriority = 1.0f; 750 VkPhysicalDeviceFeatures physicalDeviceFeatures; 751 752 instanceDriver.getPhysicalDeviceFeatures(physicalDevice, &physicalDeviceFeatures); 753 754 static const Feature features[] = 755 { 756 FEATURE_ITEM(robustBufferAccess), 757 FEATURE_ITEM(fullDrawIndexUint32), 758 FEATURE_ITEM(imageCubeArray), 759 FEATURE_ITEM(independentBlend), 760 FEATURE_ITEM(geometryShader), 761 FEATURE_ITEM(tessellationShader), 762 FEATURE_ITEM(sampleRateShading), 763 FEATURE_ITEM(dualSrcBlend), 764 FEATURE_ITEM(logicOp), 765 FEATURE_ITEM(multiDrawIndirect), 766 FEATURE_ITEM(drawIndirectFirstInstance), 767 FEATURE_ITEM(depthClamp), 768 FEATURE_ITEM(depthBiasClamp), 769 FEATURE_ITEM(fillModeNonSolid), 770 FEATURE_ITEM(depthBounds), 771 FEATURE_ITEM(wideLines), 772 FEATURE_ITEM(largePoints), 773 FEATURE_ITEM(alphaToOne), 774 FEATURE_ITEM(multiViewport), 775 FEATURE_ITEM(samplerAnisotropy), 776 FEATURE_ITEM(textureCompressionETC2), 777 FEATURE_ITEM(textureCompressionASTC_LDR), 778 FEATURE_ITEM(textureCompressionBC), 779 FEATURE_ITEM(occlusionQueryPrecise), 780 FEATURE_ITEM(pipelineStatisticsQuery), 781 FEATURE_ITEM(vertexPipelineStoresAndAtomics), 782 FEATURE_ITEM(fragmentStoresAndAtomics), 783 FEATURE_ITEM(shaderTessellationAndGeometryPointSize), 784 FEATURE_ITEM(shaderImageGatherExtended), 785 FEATURE_ITEM(shaderStorageImageExtendedFormats), 786 FEATURE_ITEM(shaderStorageImageMultisample), 787 FEATURE_ITEM(shaderStorageImageReadWithoutFormat), 788 FEATURE_ITEM(shaderStorageImageWriteWithoutFormat), 789 FEATURE_ITEM(shaderUniformBufferArrayDynamicIndexing), 790 FEATURE_ITEM(shaderSampledImageArrayDynamicIndexing), 791 FEATURE_ITEM(shaderStorageBufferArrayDynamicIndexing), 792 FEATURE_ITEM(shaderStorageImageArrayDynamicIndexing), 793 FEATURE_ITEM(shaderClipDistance), 794 FEATURE_ITEM(shaderCullDistance), 795 FEATURE_ITEM(shaderFloat64), 796 FEATURE_ITEM(shaderInt64), 797 FEATURE_ITEM(shaderInt16), 798 FEATURE_ITEM(shaderResourceResidency), 799 FEATURE_ITEM(shaderResourceMinLod), 800 FEATURE_ITEM(sparseBinding), 801 FEATURE_ITEM(sparseResidencyBuffer), 802 FEATURE_ITEM(sparseResidencyImage2D), 803 FEATURE_ITEM(sparseResidencyImage3D), 804 FEATURE_ITEM(sparseResidency2Samples), 805 FEATURE_ITEM(sparseResidency4Samples), 806 FEATURE_ITEM(sparseResidency8Samples), 807 FEATURE_ITEM(sparseResidency16Samples), 808 FEATURE_ITEM(sparseResidencyAliased), 809 FEATURE_ITEM(variableMultisampleRate), 810 FEATURE_ITEM(inheritedQueries) 811 }; 812 813 const int numFeatures = DE_LENGTH_OF_ARRAY(features); 814 int numErrors = 0; 815 816 for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++) 817 { 818 // Test only features that are not supported. 819 if (*(((VkBool32*)((deUint8*)(&physicalDeviceFeatures) + features[featureNdx].offset)))) 820 continue; 821 822 VkPhysicalDeviceFeatures enabledFeatures; 823 824 for (int i = 0; i < numFeatures; i++) 825 *((VkBool32*)((deUint8*)(&enabledFeatures) + features[i].offset)) = (i == featureNdx ? VK_TRUE : VK_FALSE); 826 827 const VkDeviceQueueCreateInfo deviceQueueCreateInfo = 828 { 829 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 830 DE_NULL, 831 (VkDeviceQueueCreateFlags)0u, 832 queueFamilyIndex, 833 queueCount, 834 &queuePriority 835 }; 836 const VkDeviceCreateInfo deviceCreateInfo = 837 { 838 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 839 DE_NULL, 840 (VkDeviceCreateFlags)0u, 841 1, 842 &deviceQueueCreateInfo, 843 0, 844 DE_NULL, 845 0, 846 DE_NULL, 847 &enabledFeatures 848 }; 849 850 VkDevice device; 851 const VkResult res = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL, &device); 852 853 if (res != VK_ERROR_FEATURE_NOT_PRESENT) 854 { 855 numErrors++; 856 resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature " 857 + de::toString(features[featureNdx].name) + ", which was reported as unsupported."); 858 } 859 } 860 861 if (numErrors > 1) 862 return tcu::TestStatus(resultCollector.getResult(), "Enabling " + de::toString(numErrors) + " unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT."); 863 else 864 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage()); 865 } 866 867 } // anonymous 868 869 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx) 870 { 871 de::MovePtr<tcu::TestCaseGroup> deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests")); 872 873 addFunctionCase(deviceInitializationTests.get(), "create_instance_name_version", "", createInstanceTest); 874 addFunctionCase(deviceInitializationTests.get(), "create_instance_invalid_api_version", "", createInstanceWithInvalidApiVersionTest); 875 addFunctionCase(deviceInitializationTests.get(), "create_instance_null_appinfo", "", createInstanceWithNullApplicationInfoTest); 876 addFunctionCase(deviceInitializationTests.get(), "create_instance_unsupported_extensions", "", createInstanceWithUnsupportedExtensionsTest); 877 addFunctionCase(deviceInitializationTests.get(), "create_device", "", createDeviceTest); 878 addFunctionCase(deviceInitializationTests.get(), "create_multiple_devices", "", createMultipleDevicesTest); 879 addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_extensions", "", createDeviceWithUnsupportedExtensionsTest); 880 addFunctionCase(deviceInitializationTests.get(), "create_device_various_queue_counts", "", createDeviceWithVariousQueueCountsTest); 881 addFunctionCase(deviceInitializationTests.get(), "create_device_features2", "", createDeviceFeatures2Test); 882 addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_features", "", createDeviceWithUnsupportedFeaturesTest); 883 884 return deviceInitializationTests.release(); 885 } 886 887 } // api 888 } // vkt 889