1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2017 The Khronos Group 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 Vulkan VK_KHR_display extensions coverage tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktWsiDisplayTests.hpp" 25 26 #include "vktTestCase.hpp" 27 #include "vkStrUtil.hpp" 28 #include "vkPrograms.hpp" 29 #include "vkRef.hpp" 30 31 #include "tcuDefs.hpp" 32 #include "tcuTestLog.hpp" 33 #include "tcuResultCollector.hpp" 34 35 #include "deMemory.h" 36 #include "deSTLUtil.hpp" 37 #include "deStringUtil.hpp" 38 39 #include <set> 40 #include <map> 41 #include <limits> 42 43 namespace vkt 44 { 45 namespace wsi 46 { 47 using namespace vk; 48 using std::vector; 49 using std::map; 50 using std::set; 51 using std::string; 52 53 #ifndef TCU_FAIL_STR 54 #define TCU_FAIL_STR(MSG) TCU_FAIL(string(MSG).c_str()) 55 #endif 56 57 enum DisplayIndexTest 58 { 59 DISPLAY_TEST_INDEX_START, 60 DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES, 61 DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES, 62 DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY, 63 DISPLAY_TEST_INDEX_GET_DISPLAY_MODE, 64 DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE, 65 DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES, 66 DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE, 67 DISPLAY_TEST_INDEX_LAST 68 }; 69 70 template <typename Type> 71 class BinaryCompare 72 { 73 public: 74 bool operator() (const Type& a, const Type& b) const 75 { 76 return deMemCmp(&a, &b, sizeof(Type)) < 0; 77 } 78 }; 79 80 typedef std::set<vk::VkDisplayKHR, BinaryCompare<vk::VkDisplayKHR> > DisplaySet; 81 typedef std::vector<vk::VkDisplayKHR> DisplayVector; 82 typedef std::vector<vk::VkDisplayModePropertiesKHR> DisplayModePropertiesVector; 83 84 const deUint32 DEUINT32_MAX = std::numeric_limits<deUint32>::max(); 85 86 const deUint32 RECOGNIZED_SURFACE_TRANSFORM_FLAGS = 87 vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR 88 | vk::VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR 89 | vk::VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR 90 | vk::VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR 91 | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR 92 | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR 93 | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR 94 | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR 95 | vk::VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR; 96 97 const deUint32 RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS = 98 VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR 99 | VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR 100 | VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR 101 | VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR; 102 enum DisplayMaxTestedConsts 103 { 104 MAX_TESTED_DISPLAY_COUNT = 16, 105 MAX_TESTED_PLANE_COUNT = 16, 106 }; 107 108 /*--------------------------------------------------------------------*//*! 109 * \brief Return Vulkan result name or code as std::string. 110 * 111 * \param result Vulkan code to convert to string 112 * \return Vulkun result code name or code number as std::string 113 *//*--------------------------------------------------------------------*/ 114 std::string getResultAsString (vk::VkResult result) 115 { 116 const char* resultAsChar = vk::getResultName(result); 117 118 if (resultAsChar != DE_NULL) 119 return std::string(resultAsChar); 120 else 121 return de::toString(result); 122 } 123 124 /*--------------------------------------------------------------------*//*! 125 * \brief Moves test index to next test skipping middle tests. 126 * 127 * Gets first 3 tests and last 3 tests on long sequences. 128 * After test number 2 moves index value to endIndex - 3. 129 * Shortens the number of tests executed by skipping middle tests. 130 * 131 * Example: 132 * for (i=0; i<endIndex; nextTestNumber(i, endIndex)) 133 * with endIndex = 4 generates 0,1,2,3 134 * with endIndex = 9 generates 0,1,2,6,7,8 135 * 136 * \param index Current iterator value 137 * \param endIndex First number out of iteration sequence 138 * \return new iterator value 139 *//*--------------------------------------------------------------------*/ 140 deUint32 nextTestNumber (deUint32 index, deUint32 endIndex) 141 { 142 deUint32 result; 143 144 if (endIndex > 6 && index == 2) 145 result = endIndex - 3; 146 else 147 result = index + 1; 148 149 return result; 150 } 151 152 /*--------------------------------------------------------------------*//*! 153 * \brief Vulkan VK_KHR_display extensions coverage tests 154 *//*--------------------------------------------------------------------*/ 155 class DisplayCoverageTestInstance : public TestInstance 156 { 157 public: 158 DisplayCoverageTestInstance (Context& context, const DisplayIndexTest testId); 159 private: 160 typedef void (DisplayCoverageTestInstance::*EachSurfaceFunctionPtr) 161 (VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties); 162 163 bool getDisplays (DisplayVector& displays); 164 bool getDisplaysForPlane (deUint32 plane, DisplayVector& displays); 165 bool getDisplayModeProperties (VkDisplayKHR display, DisplayModePropertiesVector& modeProperties); 166 167 tcu::TestStatus testGetPhysicalDeviceDisplayPropertiesKHR (void); 168 tcu::TestStatus testGetPhysicalDeviceDisplayPlanePropertiesKHR (void); 169 tcu::TestStatus testGetDisplayPlaneSupportedDisplaysKHR (void); 170 tcu::TestStatus testGetDisplayModePropertiesKHR (void); 171 tcu::TestStatus testCreateDisplayModeKHR (void); 172 tcu::TestStatus testGetDisplayPlaneCapabilitiesKHR (void); 173 tcu::TestStatus testCreateDisplayPlaneSurfaceKHR (void); 174 tcu::TestStatus testCreateSharedSwapchainsKHR (void); 175 tcu::TestStatus iterate (void); 176 177 void testCreateSharedSwapchainsKHRforSurface (VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties); 178 179 const InstanceInterface& m_vki; 180 const DeviceInterface& m_vkd; 181 tcu::TestLog& m_log; 182 const VkPhysicalDevice m_physicalDevice; 183 const DisplayIndexTest m_testId; 184 }; 185 186 187 /*--------------------------------------------------------------------*//*! 188 * \brief DisplayCoverageTestInstance constructor 189 * 190 * Initializes DisplayCoverageTestInstance object 191 * 192 * \param context Context object 193 * \param parameters Test parameters structure 194 *//*--------------------------------------------------------------------*/ 195 DisplayCoverageTestInstance::DisplayCoverageTestInstance (Context& context, const DisplayIndexTest testId) 196 : TestInstance (context) 197 , m_vki (m_context.getInstanceInterface()) 198 , m_vkd (m_context.getDeviceInterface()) 199 , m_log (m_context.getTestContext().getLog()) 200 , m_physicalDevice (m_context.getPhysicalDevice()) 201 , m_testId (testId) 202 { 203 const std::string extensionName("VK_KHR_display"); 204 205 if(!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionName)) 206 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); 207 } 208 209 /*--------------------------------------------------------------------*//*! 210 * \brief Step forward test execution 211 * 212 * \return true if application should call iterate() again and false 213 * if test execution session is complete. 214 *//*--------------------------------------------------------------------*/ 215 tcu::TestStatus DisplayCoverageTestInstance::iterate (void) 216 { 217 switch (m_testId) 218 { 219 case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES: return testGetPhysicalDeviceDisplayPropertiesKHR(); break; 220 case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES: return testGetPhysicalDeviceDisplayPlanePropertiesKHR(); break; 221 case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY: return testGetDisplayPlaneSupportedDisplaysKHR(); break; 222 case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE: return testGetDisplayModePropertiesKHR(); break; 223 case DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE: return testCreateDisplayModeKHR(); break; 224 case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES: return testGetDisplayPlaneCapabilitiesKHR(); break; 225 case DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE: return testCreateDisplayPlaneSurfaceKHR(); break; 226 default: 227 { 228 DE_FATAL("Impossible"); 229 } 230 } 231 232 TCU_FAIL("Invalid test identifier"); 233 } 234 235 /*--------------------------------------------------------------------*//*! 236 * \brief Fills vector with available displays. Clears passed vector at start. 237 * 238 * \param displays The vector filled with display handles 239 * \return true on success, false on error 240 *//*--------------------------------------------------------------------*/ 241 bool DisplayCoverageTestInstance::getDisplays(DisplayVector& displays) 242 { 243 deUint32 countReported = 0u; 244 deUint32 countRetrieved = 0u; 245 std::vector<VkDisplayPropertiesKHR> displaysProps; 246 VkResult result; 247 248 displays.clear(); 249 250 result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 251 &countReported, // uint32_t* pPropertyCount 252 DE_NULL); // VkDisplayPropertiesKHR* pProperties 253 254 if (result != VK_SUCCESS) 255 { 256 m_log << tcu::TestLog::Message 257 << "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result) 258 << " reported items count " << countReported 259 << tcu::TestLog::EndMessage; 260 261 return false; 262 } 263 264 displaysProps.resize(countReported); 265 266 countRetrieved = countReported; 267 268 result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 269 &countRetrieved, // uint32_t* pPropertyCount 270 &displaysProps[0]); // VkDisplayPropertiesKHR* pProperties 271 272 if (result != VK_SUCCESS || countRetrieved > countReported) 273 { 274 m_log << tcu::TestLog::Message 275 << "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result) 276 << " reported items count " << countReported 277 << " retrieved items count " << countRetrieved 278 << tcu::TestLog::EndMessage; 279 280 return false; 281 } 282 283 displays.reserve(countRetrieved); 284 285 for (deUint32 displayIndex = 0; 286 displayIndex < countRetrieved; 287 displayIndex++) 288 { 289 const VkDisplayKHR display = displaysProps[displayIndex].display; 290 291 if (display == DE_NULL) 292 { 293 displays.clear(); 294 295 return false; 296 } 297 298 displays.push_back(display); 299 } 300 301 return true; 302 } 303 304 /*--------------------------------------------------------------------*//*! 305 * \brief Fills vector with available displays for plane specified. 306 * 307 * Clears passed vector at start and on error. 308 * 309 * \param plane The plane to get displays for 310 * \param displays The vector filled with display handles 311 * \return true on success, false on error 312 *//*--------------------------------------------------------------------*/ 313 bool DisplayCoverageTestInstance::getDisplaysForPlane(deUint32 plane, DisplayVector& displays) 314 { 315 deUint32 countReported = 0u; 316 deUint32 countRetrieved = 0u; 317 VkResult result; 318 319 displays.clear(); 320 321 result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 322 plane, // uint32_t planeIndex 323 &countReported, // uint32_t* pDisplayCount 324 DE_NULL); // VkDisplayKHR* pDisplays 325 326 if (result != VK_SUCCESS) 327 { 328 m_log << tcu::TestLog::Message 329 << "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result) 330 << " for plane " << plane 331 << " reported items count " << countReported 332 << tcu::TestLog::EndMessage; 333 334 return false; 335 } 336 337 displays.resize(countReported); 338 339 countRetrieved = countReported; 340 341 result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 342 plane, // uint32_t planeIndex 343 &countRetrieved, // uint32_t* pDisplayCount 344 &displays[0]); // VkDisplayKHR* pDisplays 345 346 if (result != VK_SUCCESS || countRetrieved > countReported) 347 { 348 m_log << tcu::TestLog::Message 349 << "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result) 350 << " for plane " << plane 351 << " reported items count " << countReported 352 << " retrieved items count " << countRetrieved 353 << tcu::TestLog::EndMessage; 354 355 displays.clear(); 356 357 return false; 358 } 359 360 if (countRetrieved < countReported) 361 displays.resize(countRetrieved); 362 363 return true; 364 } 365 366 /*--------------------------------------------------------------------*//*! 367 * \brief Fills vector with available modes properties for display specified. 368 * 369 * Clears passed vector at start and on error. 370 * 371 * \param display The display to get modes for 372 * \param modes The vector filled with display mode properties structures 373 * \return true on success, false on error 374 *//*--------------------------------------------------------------------*/ 375 bool DisplayCoverageTestInstance::getDisplayModeProperties(VkDisplayKHR display, DisplayModePropertiesVector& modeProperties) 376 { 377 deUint32 countReported = 0u; 378 deUint32 countRetrieved = 0u; 379 VkResult result; 380 381 modeProperties.clear(); 382 383 result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 384 display, // VkDisplayKHR display 385 &countReported, // uint32_t* pPropertyCount 386 DE_NULL); // VkDisplayModePropertiesKHR* pProperties 387 388 if (result != VK_SUCCESS) 389 { 390 m_log << tcu::TestLog::Message 391 << "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result) 392 << " for display " << display 393 << " reported items count " << countReported 394 << tcu::TestLog::EndMessage; 395 396 return false; 397 } 398 399 modeProperties.resize(countReported); 400 401 countRetrieved = countReported; 402 403 result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 404 display, // VkDisplayKHR display 405 &countRetrieved, // uint32_t* pPropertyCount 406 &modeProperties[0]); // VkDisplayModePropertiesKHR* pProperties 407 408 if (result != VK_SUCCESS || countRetrieved > countReported) 409 { 410 m_log << tcu::TestLog::Message 411 << "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result) 412 << " for display " << display 413 << " reported items count " << countReported 414 << " retrieved items count " << countReported 415 << tcu::TestLog::EndMessage; 416 417 modeProperties.clear(); 418 419 return false; 420 } 421 422 if (countRetrieved < countReported) 423 modeProperties.resize(countRetrieved); 424 425 return true; 426 } 427 428 /*--------------------------------------------------------------------*//*! 429 * \brief Display enumeration coverage test 430 * 431 * Throws ResourceError exception in case no displays available. 432 * Throws an exception on fail. 433 * 434 * \return tcu::TestStatus::pass on success 435 *//*--------------------------------------------------------------------*/ 436 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPropertiesKHR(void) 437 { 438 deUint32 displayCountReported = 0u; 439 deUint32 displayCountToTest = 0u; 440 tcu::ResultCollector results (m_log); 441 VkResult result; 442 443 result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 444 &displayCountReported, // uint32_t* pPropertyCount 445 DE_NULL); // VkDisplayPropertiesKHR* pProperties 446 447 if ( result != VK_SUCCESS 448 && result != VK_INCOMPLETE 449 && result != VK_ERROR_OUT_OF_HOST_MEMORY 450 && result != VK_ERROR_OUT_OF_DEVICE_MEMORY 451 ) 452 { 453 TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); 454 } 455 456 if (result != VK_SUCCESS) 457 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 458 459 if (displayCountReported == 0) 460 TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str()); 461 462 displayCountToTest = displayCountReported; 463 if (displayCountReported > MAX_TESTED_DISPLAY_COUNT) 464 { 465 m_log << tcu::TestLog::Message 466 << "Number of displays reported is too high " << displayCountReported 467 << ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT 468 << tcu::TestLog::EndMessage; 469 470 displayCountToTest = MAX_TESTED_DISPLAY_COUNT; 471 } 472 473 // Test the call correctly writes data in various size arrays 474 for (deUint32 displayCountRequested = 0; 475 displayCountRequested < displayCountToTest + 2; 476 displayCountRequested++) 477 { 478 const deUint32 displayCountExpected = std::min(displayCountRequested, displayCountReported); 479 const VkDisplayPropertiesKHR invalidDisplayProps = { // Most values are set to fail the test to make sure driver updates these 480 DE_NULL, // VkDisplayKHR display; 481 DE_NULL, // const char* displayName; 482 {0, 0}, // VkExtent2D physicalDimensions; 483 {0, 0}, // VkExtent2D physicalResolution; 484 ~RECOGNIZED_SURFACE_TRANSFORM_FLAGS, // VkSurfaceTransformFlagsKHR supportedTransforms; 485 (vk::VkBool32)(VK_TRUE + 1), // VkBool32 planeReorderPossible; 486 (vk::VkBool32)(VK_TRUE + 1) // VkBool32 persistentContent; 487 }; 488 const VkDisplayKHR canaryDisplay = static_cast<VkDisplayKHR>(0xABCDEF11); 489 const deUint32 canaryItemCount = 1; 490 std::vector<VkDisplayPropertiesKHR> displaysProps (displayCountRequested + canaryItemCount, invalidDisplayProps); 491 deUint32 displayCountRetrieved = displayCountRequested; 492 DisplaySet displaySet; 493 494 displaysProps[displayCountExpected].display = canaryDisplay; 495 496 result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 497 &displayCountRetrieved, // uint32_t* pPropertyCount 498 &displaysProps[0]); // VkDisplayPropertiesKHR* pProperties 499 500 // Check amount of data written equals to expected 501 if (displayCountRetrieved != displayCountExpected) 502 TCU_FAIL_STR( string("displayCountRetrieved != displayCountExpected, ") + 503 de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected)); 504 505 if (displayCountRequested >= displayCountReported) 506 { 507 if (result != VK_SUCCESS) 508 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 509 } 510 else 511 { 512 if (result != VK_INCOMPLETE) 513 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); 514 } 515 516 // Check the driver has written something 517 for (deUint32 displayIndex = 0; 518 displayIndex < displayCountRetrieved; 519 displayIndex++) 520 { 521 displaySet.insert(displaysProps[displayIndex].display); 522 523 results.check( displaysProps[displayIndex].display != invalidDisplayProps.display, 524 "Invalid display handle for display number " + de::toString(displayIndex)); 525 526 results.check( displaysProps[displayIndex].planeReorderPossible == VK_TRUE || displaysProps[displayIndex].planeReorderPossible == VK_FALSE, 527 "planeReorderPossible neither VK_TRUE, nor VK_FALSE"); 528 529 results.check( displaysProps[displayIndex].persistentContent == VK_TRUE || displaysProps[displayIndex].persistentContent == VK_FALSE, 530 "persistentContent neither VK_TRUE, nor VK_FALSE"); 531 532 results.check( (displaysProps[displayIndex].supportedTransforms & invalidDisplayProps.supportedTransforms) == 0, 533 "supportedTransforms contains unrecognized flags"); 534 535 // Outside specification, but resolution 0x0 pixels will break many applications 536 results.check( displaysProps[displayIndex].physicalResolution.height != 0, 537 "physicalResolution.height cannot be zero"); 538 539 // Outside specification, but resolution 0x0 pixels will break many applications 540 results.check( displaysProps[displayIndex].physicalResolution.width != 0, 541 "physicalResolution.width cannot be zero"); 542 543 if (results.getResult() != QP_TEST_RESULT_PASS) 544 { 545 m_log << tcu::TestLog::Message 546 << "Error detected " << results.getMessage() 547 << " for display " << displayIndex << " with properties " << displaysProps[displayIndex] 548 << " invalid display properties are " << invalidDisplayProps 549 << tcu::TestLog::EndMessage; 550 551 TCU_FAIL_STR(results.getMessage()); 552 } 553 } 554 555 // Check the driver has not written more than requested 556 if (displaysProps[displayCountExpected].display != canaryDisplay) 557 TCU_FAIL("Memory damage detected: driver has written more than expected"); 558 559 // Check display handle uniqueness 560 if (displaySet.size() != displayCountRetrieved) 561 TCU_FAIL("Display handle duplication detected"); 562 } 563 564 return tcu::TestStatus::pass("pass"); 565 } 566 567 /*--------------------------------------------------------------------*//*! 568 * \brief Plane enumeration coverage test 569 * 570 * Throws an exception on fail. 571 * 572 * \return tcu::TestStatus::pass on success 573 *//*--------------------------------------------------------------------*/ 574 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlanePropertiesKHR(void) 575 { 576 DisplayVector displaysVector; 577 DisplaySet displaySet; 578 deUint32 planeCountReported = 0u; 579 deUint32 planeCountTested = 0u; 580 tcu::ResultCollector results (m_log); 581 VkResult result; 582 583 // Create a list of displays available 584 if (!getDisplays(displaysVector)) 585 TCU_FAIL("Failed to retrieve displays"); 586 587 if (displaysVector.empty()) 588 TCU_THROW(NotSupportedError, "No displays reported"); 589 590 displaySet = DisplaySet(displaysVector.begin(), displaysVector.end()); 591 592 // Get planes to test 593 result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 594 &planeCountReported, // uint32_t* pPropertyCount 595 DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties 596 597 if ( result != VK_SUCCESS 598 && result != VK_INCOMPLETE 599 && result != VK_ERROR_OUT_OF_HOST_MEMORY 600 && result != VK_ERROR_OUT_OF_DEVICE_MEMORY 601 ) 602 { 603 TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); 604 } 605 606 if (result != VK_SUCCESS) 607 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 608 609 if (planeCountReported == 0) 610 TCU_THROW(ResourceError, "Cannot perform test: no planes found"); 611 612 planeCountTested = planeCountReported; 613 if (planeCountReported > MAX_TESTED_PLANE_COUNT) 614 { 615 m_log << tcu::TestLog::Message 616 << "Number of planes reported is too high " << planeCountReported 617 << ". Test is limited to " << MAX_TESTED_PLANE_COUNT 618 << tcu::TestLog::EndMessage; 619 620 planeCountTested = MAX_TESTED_PLANE_COUNT; 621 } 622 623 // Test the call correctly writes data in various size arrays 624 for (deUint32 planeCountRequested = 0; 625 planeCountRequested < planeCountTested + 2; 626 planeCountRequested++) 627 { 628 const deUint32 planeCountExpected = std::min(planeCountRequested, planeCountReported); 629 const VkDisplayPlanePropertiesKHR invalidPlaneProps = { // Most values are set to fail the test to make sure driver updates these 630 DE_NULL, // VkDisplayKHR currentDisplay 631 DEUINT32_MAX // deUint32 currentStackIndex 632 }; 633 const VkDisplayKHR canaryDisplay = static_cast<VkDisplayKHR>(0xABCDEF11); 634 const deUint32 canaryItemCount = 1; 635 std::vector<VkDisplayPlanePropertiesKHR> planeProps (planeCountRequested + canaryItemCount, invalidPlaneProps); 636 deUint32 planeCountRetrieved = planeCountRequested; 637 638 planeProps[planeCountExpected].currentDisplay = canaryDisplay; 639 640 result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 641 &planeCountRetrieved, // uint32_t* pPropertyCount 642 &planeProps[0]); // VkDisplayPlanePropertiesKHR* pProperties 643 644 // Check amount of data written equals to expected 645 if (planeCountRetrieved != planeCountExpected) 646 TCU_FAIL_STR( string("planeCountRetrieved != planeCountExpected, ") + 647 de::toString(planeCountRetrieved) + " != " + de::toString(planeCountExpected)); 648 649 if (planeCountRequested >= planeCountReported) 650 { 651 if (result != VK_SUCCESS) 652 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 653 } 654 else 655 { 656 if (result != VK_INCOMPLETE) 657 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); 658 } 659 660 // Check the driver has written something 661 for (deUint32 planeIndex = 0; 662 planeIndex < planeCountRetrieved; 663 planeIndex++) 664 { 665 const VkDisplayKHR currentDisplay = planeProps[planeIndex].currentDisplay; 666 667 results.check( planeProps[planeIndex].currentStackIndex < planeCountReported, 668 "CurrentStackIndex must be less than the number of planes reported " + de::toString(planeCountReported)); 669 670 results.check( currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay), 671 "Plane bound to invalid handle " + de::toString(currentDisplay)); 672 673 if (results.getResult() != QP_TEST_RESULT_PASS) 674 { 675 m_log << tcu::TestLog::Message 676 << "Error detected " << results.getMessage() 677 << " for plane " << planeIndex << " with properties " << planeProps[planeIndex] 678 << tcu::TestLog::EndMessage; 679 680 TCU_FAIL_STR(results.getMessage()); 681 } 682 } 683 684 // Check the driver has not written more than requested 685 if (planeProps[planeCountExpected].currentDisplay != canaryDisplay) 686 TCU_FAIL("Memory damage detected: driver has written more than expected"); 687 } 688 689 return tcu::TestStatus::pass("pass"); 690 } 691 692 /*--------------------------------------------------------------------*//*! 693 * \brief Display plane support coverage test 694 * 695 * Throws an exception on fail. 696 * 697 * \return tcu::TestStatus::pass on success 698 *//*--------------------------------------------------------------------*/ 699 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneSupportedDisplaysKHR(void) 700 { 701 deUint32 planeCountReported = 0u; 702 deUint32 planeCountTested = 0u; 703 VkResult result; 704 DisplayVector displaysVector; 705 DisplaySet displaySet; 706 707 if (!getDisplays(displaysVector)) 708 TCU_FAIL("Failed to retrieve displays"); 709 710 if (displaysVector.empty()) 711 TCU_THROW(NotSupportedError, "No displays reported"); 712 713 displaySet = DisplaySet(displaysVector.begin(), displaysVector.end()); 714 715 result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 716 &planeCountReported, // uint32_t* pPropertyCount 717 DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties 718 719 if ( result != VK_SUCCESS 720 && result != VK_INCOMPLETE 721 && result != VK_ERROR_OUT_OF_HOST_MEMORY 722 && result != VK_ERROR_OUT_OF_DEVICE_MEMORY 723 ) 724 { 725 TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); 726 } 727 728 if (result != VK_SUCCESS) 729 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 730 731 if (planeCountReported == 0) 732 TCU_THROW(ResourceError, "Cannot perform test: no planes supported"); 733 734 planeCountTested = planeCountReported; 735 if (planeCountReported > MAX_TESTED_PLANE_COUNT) 736 { 737 m_log << tcu::TestLog::Message 738 << "Number of planes reported is too high " << planeCountReported 739 << ". Test is limited to " << MAX_TESTED_PLANE_COUNT 740 << tcu::TestLog::EndMessage; 741 742 planeCountTested = MAX_TESTED_PLANE_COUNT; 743 } 744 745 for (deUint32 planeIndex = 0; 746 planeIndex < planeCountTested; 747 planeIndex++) 748 { 749 deUint32 displayCountReported = 0u; 750 751 result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 752 planeIndex, // uint32_t planeIndex 753 &displayCountReported, // uint32_t* pDisplayCount 754 DE_NULL); // VkDisplayKHR* pDisplays 755 756 if (result != VK_SUCCESS) 757 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 758 759 // Test the call correctly writes data in various size arrays 760 for (deUint32 displayCountRequested = 0; 761 displayCountRequested < displayCountReported + 2; 762 displayCountRequested++) 763 { 764 const deUint32 displayCountExpected = std::min(displayCountRequested, displayCountReported); 765 const VkDisplayKHR nullDisplay = DE_NULL; 766 const VkDisplayKHR canaryDisplay = static_cast<VkDisplayKHR>(0xABCDEF11); 767 const deUint32 canaryItemCount = 1; 768 std::vector<VkDisplayKHR> displaysForPlane (displayCountRequested + canaryItemCount, nullDisplay); 769 deUint32 displayCountRetrieved = displayCountRequested; 770 771 displaysForPlane[displayCountExpected] = canaryDisplay; 772 773 result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 774 planeIndex, // uint32_t planeIndex 775 &displayCountRetrieved, // uint32_t* pDisplayCount 776 &displaysForPlane[0]); // VkDisplayKHR* pDisplays 777 778 // Check amount of data written equals to expected 779 if (displayCountRetrieved != displayCountExpected) 780 TCU_FAIL_STR( string("displayCountRetrieved != displayCountExpected, ") + 781 de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected)); 782 783 if (displayCountRequested >= displayCountReported) 784 { 785 if (result != VK_SUCCESS) 786 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 787 } 788 else 789 { 790 if (result != VK_INCOMPLETE) 791 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); 792 } 793 794 // Check the driver has written something 795 for (deUint32 displayIndex = 0; 796 displayIndex < displayCountExpected; 797 displayIndex++) 798 { 799 const VkDisplayKHR display = displaysForPlane[displayIndex]; 800 801 if (display != nullDisplay) 802 { 803 if (!de::contains(displaySet, display)) 804 { 805 TCU_FAIL_STR("Invalid display handle " + de::toString(display)); 806 } 807 } 808 } 809 810 // Check the driver has not written more than requested 811 if (displaysForPlane[displayCountExpected] != canaryDisplay) 812 TCU_FAIL("Memory damage detected: driver has written more than expected"); 813 } 814 } 815 816 return tcu::TestStatus::pass("pass"); 817 } 818 819 /*--------------------------------------------------------------------*//*! 820 * \brief Display mode properties coverage test 821 * 822 * Throws an exception on fail. 823 * 824 * \return tcu::TestStatus::pass on success 825 *//*--------------------------------------------------------------------*/ 826 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModePropertiesKHR(void) 827 { 828 VkResult result; 829 DisplayVector displaysVector; 830 831 if (!getDisplays(displaysVector)) 832 TCU_FAIL("Failed to retrieve displays list"); 833 834 if (displaysVector.empty()) 835 TCU_THROW(NotSupportedError, "No displays reported"); 836 837 for (DisplayVector::iterator it = displaysVector.begin(); 838 it != displaysVector.end(); 839 it++) 840 { 841 VkDisplayKHR display = *it; 842 deUint32 modesCountReported = 0u; 843 844 result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 845 display, // VkDisplayKHR display 846 &modesCountReported, // uint32_t* pPropertyCount 847 DE_NULL); // VkDisplayModePropertiesKHR* pProperties 848 849 // Test the call correctly writes data in various size arrays 850 for (deUint32 modesCountRequested = 0; 851 modesCountRequested < modesCountReported + 2; 852 modesCountRequested = nextTestNumber(modesCountRequested, modesCountReported + 2)) 853 { 854 const deUint32 modesCountExpected = std::min(modesCountRequested, modesCountReported); 855 const VkDisplayModeKHR nullDisplayMode = DE_NULL; 856 const VkDisplayModePropertiesKHR nullMode = { 857 nullDisplayMode, // VkDisplayModeKHR displayMode 858 { // VkDisplayModeParametersKHR parameters 859 {0, 0}, // VkExtent2D visibleRegion 860 0 // uint32_t refreshRate 861 } 862 }; 863 const VkDisplayModeKHR canaryDisplayMode = static_cast<VkDisplayModeKHR>(0xABCDEF11); 864 const deUint32 canaryItemCount = 1; 865 std::vector<VkDisplayModePropertiesKHR> modesForDisplay (modesCountRequested + canaryItemCount, nullMode); 866 deUint32 modesCountRetrieved = modesCountRequested; 867 868 modesForDisplay[modesCountExpected].displayMode = canaryDisplayMode; 869 870 result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 871 display, // VkDisplayKHR display 872 &modesCountRetrieved, // uint32_t* pPropertyCount 873 &modesForDisplay[0]); // VkDisplayModePropertiesKHR* pProperties 874 875 // Check amount of data written equals to expected 876 if (modesCountRetrieved != modesCountExpected) 877 TCU_FAIL_STR( string("modesCountRetrieved != modesCountExpected, ") + 878 de::toString(modesCountRetrieved) + " != " + de::toString(modesCountExpected)); 879 880 if (modesCountRequested >= modesCountReported) 881 { 882 if (result != VK_SUCCESS) 883 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 884 } 885 else 886 { 887 if (result != VK_INCOMPLETE) 888 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); 889 } 890 891 // Check the driver has written something 892 for (deUint32 modeIndex = 0; 893 modeIndex < modesCountExpected; 894 modeIndex++) 895 { 896 const VkDisplayModePropertiesKHR theModeProperties = modesForDisplay[modeIndex]; 897 898 if (theModeProperties.displayMode == nullMode.displayMode) 899 TCU_FAIL_STR("Invalid mode display handle reported for display " + de::toString(display)); 900 } 901 902 // Check the driver has not written more than requested 903 if (modesForDisplay[modesCountExpected].displayMode != canaryDisplayMode) 904 TCU_FAIL("Memory damage detected: driver has written more than expected"); 905 } 906 } 907 908 return tcu::TestStatus::pass("pass"); 909 } 910 911 /*--------------------------------------------------------------------*//*! 912 * \brief Create display mode coverage test 913 * 914 * Throws an exception on fail. 915 * 916 * \return tcu::TestStatus::pass on success 917 *//*--------------------------------------------------------------------*/ 918 tcu::TestStatus DisplayCoverageTestInstance::testCreateDisplayModeKHR(void) 919 { 920 DisplayVector displaysVector; 921 VkResult result; 922 923 if (!getDisplays(displaysVector)) 924 TCU_FAIL("Failed to retrieve displays"); 925 926 if (displaysVector.empty()) 927 TCU_THROW(NotSupportedError, "No displays reported"); 928 929 for (DisplayVector::iterator it = displaysVector.begin(); 930 it != displaysVector.end(); 931 it++) 932 { 933 const VkDisplayKHR display = *it; 934 DisplayModePropertiesVector::size_type builtinModesCount = 0u; 935 VkDisplayModePropertiesKHR validModeProperties; 936 VkDisplayModeKHR mode = DE_NULL; 937 DisplayModePropertiesVector modes; 938 VkDisplayModeCreateInfoKHR createInfo = { 939 VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR, // VkStructureType sType 940 DE_NULL, // const void* pNext 941 0, // VkDisplayModeCreateFlagsKHR flags 942 { // VkDisplayModeParametersKHR parameters 943 {0, 0}, // VkExtent2D visibleRegion 944 0 // uint32_t refreshRate 945 } 946 }; 947 948 if (!getDisplayModeProperties(display, modes)) 949 TCU_FAIL("Failed to retrieve display mode properties"); 950 951 if (modes.size() < 1) 952 TCU_FAIL("At least one mode expected to be returned"); 953 954 // Builtin mode count should not be updated with a new mode. Get initial builtin mode count 955 builtinModesCount = modes.size(); 956 957 // Assume first available builtin mode as a valid mode sample 958 validModeProperties = modes[0]; 959 960 // Do negative test by making one of parameters unacceptable 961 for (deUint32 testIndex = 0; 962 testIndex < 3; 963 testIndex++) 964 { 965 VkDisplayModeCreateInfoKHR createInfoFail (createInfo); 966 VkDisplayModeKHR modeFail = DE_NULL; 967 968 createInfoFail.parameters = validModeProperties.parameters; 969 970 switch (testIndex) 971 { 972 case 0: createInfoFail.parameters.refreshRate = 0; break; 973 case 1: createInfoFail.parameters.visibleRegion.width = 0; break; 974 case 2: createInfoFail.parameters.visibleRegion.height = 0; break; 975 default: DE_FATAL("Impossible"); break; 976 } 977 978 result = m_vki.createDisplayModeKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 979 display, // VkDisplayKHR display 980 &createInfoFail, // const VkDisplayModeCreateInfoKHR* pCreateInfo 981 DE_NULL, // const VkAllocationCallbacks* pAllocator 982 &modeFail); // VkDisplayModeKHR* pMode 983 984 if (result != VK_ERROR_INITIALIZATION_FAILED) 985 TCU_FAIL_STR(string("Expected VK_ERROR_INITIALIZATION_FAILED. Have ") + getResultAsString(result)); 986 987 if (modeFail != DE_NULL) 988 TCU_FAIL("Mode should be kept invalid on fail"); 989 } 990 991 // At last create valid display mode 992 createInfo.parameters = validModeProperties.parameters; 993 994 result = m_vki.createDisplayModeKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 995 display, // VkDisplayKHR display 996 &createInfo, // const VkDisplayModeCreateInfoKHR* pCreateInfo 997 DE_NULL, // const VkAllocationCallbacks* pAllocator 998 &mode); // VkDisplayModeKHR* pMode 999 1000 if (result != VK_SUCCESS) 1001 TCU_FAIL_STR("Expected VK_SUCCESS. Have " + getResultAsString(result)); 1002 1003 if (mode == DE_NULL) 1004 TCU_FAIL("Valid handle expected"); 1005 1006 // Builtin mode count should not be updated with a new mode 1007 modes.clear(); 1008 1009 if (!getDisplayModeProperties(display, modes)) 1010 TCU_FAIL("Failed to retrieve display mode properties"); 1011 1012 if (builtinModesCount != modes.size()) 1013 TCU_FAIL_STR( string("Mode count has changed from ") + de::toString(builtinModesCount) + 1014 string(" to ") + de::toString(modes.size())); 1015 } 1016 1017 return tcu::TestStatus::pass("pass"); 1018 } 1019 1020 /*--------------------------------------------------------------------*//*! 1021 * \brief Display-plane capabilities coverage test 1022 * 1023 * Throws an exception on fail. 1024 * 1025 * \return tcu::TestStatus::pass on success 1026 *//*--------------------------------------------------------------------*/ 1027 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneCapabilitiesKHR(void) 1028 { 1029 deUint32 planeCountReported = 0u; 1030 VkResult result; 1031 1032 result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 1033 &planeCountReported, // uint32_t* pPropertyCount 1034 DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties 1035 1036 if (result != VK_SUCCESS) 1037 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 1038 1039 if (planeCountReported == 0) 1040 { 1041 DisplayVector displaysVector; 1042 1043 // If we don't have any displays then it's alright to have no planes, as 1044 // per the Vulkan Spec: 1045 // Devices must support at least one plane on each display 1046 if (!getDisplays(displaysVector)) 1047 TCU_FAIL("Failed to retrieve displays"); 1048 1049 if (displaysVector.empty()) 1050 TCU_THROW(NotSupportedError, "No display planes reported"); 1051 1052 TCU_FAIL("No planes defined"); 1053 } 1054 1055 if (planeCountReported > MAX_TESTED_PLANE_COUNT) 1056 { 1057 m_log << tcu::TestLog::Message 1058 << "Number of planes reported is too high " << planeCountReported 1059 << ". Test is limited to " << MAX_TESTED_PLANE_COUNT 1060 << tcu::TestLog::EndMessage; 1061 1062 planeCountReported = MAX_TESTED_PLANE_COUNT; 1063 } 1064 1065 for (deUint32 planeIndex = 0; 1066 planeIndex < planeCountReported; 1067 planeIndex++) 1068 { 1069 std::vector<VkDisplayKHR> displaysForPlane; 1070 1071 if (!getDisplaysForPlane(planeIndex, displaysForPlane)) 1072 TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex)); 1073 1074 if (displaysForPlane.empty()) 1075 continue; 1076 1077 // Check the driver has written something 1078 for (deUint32 displayIndex = 0; 1079 displayIndex < displaysForPlane.size(); 1080 displayIndex++) 1081 { 1082 const VkDisplayKHR display = displaysForPlane[displayIndex]; 1083 std::vector<VkDisplayModePropertiesKHR> modesPropertiesForDisplay; 1084 1085 if (!getDisplayModeProperties(display, modesPropertiesForDisplay)) 1086 TCU_FAIL("Failed to retrieve display mode properties"); 1087 1088 for (deUint32 modeIndex = 0; 1089 modeIndex < modesPropertiesForDisplay.size(); 1090 modeIndex++) 1091 { 1092 const VkDisplayModeKHR theDisplayMode = modesPropertiesForDisplay[modeIndex].displayMode; 1093 const deUint32 unrecognizedAlphaFlags = ~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS; 1094 VkDisplayPlaneCapabilitiesKHR planeCapabilities = { 1095 unrecognizedAlphaFlags, // VkDisplayPlaneAlphaFlagsKHR supportedAlpha; 1096 { -1, -1 }, // VkOffset2D minSrcPosition; 1097 { -1, -1 }, // VkOffset2D maxSrcPosition; 1098 { 1, 1 }, // VkExtent2D minSrcExtent; 1099 { 0, 0 }, // VkExtent2D maxSrcExtent; 1100 { 1, 1 }, // VkOffset2D minDstPosition; 1101 { 0, 0 }, // VkOffset2D maxDstPosition; 1102 { 1, 1 }, // VkExtent2D minDstExtent; 1103 { 0, 0 }, // VkExtent2D maxDstExtent; 1104 }; 1105 tcu::ResultCollector results (m_log); 1106 1107 result = m_vki.getDisplayPlaneCapabilitiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 1108 theDisplayMode, // VkDisplayModeKHR mode 1109 planeIndex, // uint32_t planeIndex 1110 &planeCapabilities); // VkDisplayPlaneCapabilitiesKHR* pCapabilities 1111 1112 results.check( result == VK_SUCCESS, 1113 string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 1114 1115 results.check( (planeCapabilities.supportedAlpha & unrecognizedAlphaFlags) == 0, 1116 "supportedAlpha contains unrecognized value"); 1117 1118 results.check( planeCapabilities.minSrcPosition.x >= 0, 1119 "minSrcPosition.x >= 0"); 1120 1121 results.check( planeCapabilities.minSrcPosition.y >= 0, 1122 "minSrcPosition.y >= 0"); 1123 1124 results.check( planeCapabilities.maxSrcPosition.x >= 0, 1125 "maxSrcPosition.x >= 0"); 1126 1127 results.check( planeCapabilities.maxSrcPosition.y >= 0, 1128 "maxSrcPosition.y >= 0"); 1129 1130 results.check( planeCapabilities.minSrcPosition.x <= planeCapabilities.maxSrcPosition.x, 1131 "minSrcPosition.x <= maxSrcPosition.x"); 1132 1133 results.check( planeCapabilities.minSrcPosition.y <= planeCapabilities.maxSrcPosition.y, 1134 "minSrcPosition.y <= maxSrcPosition.y"); 1135 1136 results.check( planeCapabilities.minDstPosition.x <= planeCapabilities.maxDstPosition.x, 1137 "minDstPosition.x <= maxDstPosition.x"); 1138 1139 results.check( planeCapabilities.minDstPosition.y <= planeCapabilities.maxDstPosition.y, 1140 "minDstPosition.y <= maxDstPosition.y"); 1141 1142 results.check( planeCapabilities.minSrcExtent.width <= planeCapabilities.maxSrcExtent.width, 1143 "minSrcExtent.width <= maxSrcExtent.width"); 1144 1145 results.check( planeCapabilities.minSrcExtent.height <= planeCapabilities.maxSrcExtent.height, 1146 "minSrcExtent.height <= maxSrcExtent.height"); 1147 1148 results.check( planeCapabilities.minDstExtent.width <= planeCapabilities.maxDstExtent.width, 1149 "minDstExtent.width <= maxDstExtent.width"); 1150 1151 results.check( planeCapabilities.minDstExtent.height <= planeCapabilities.maxDstExtent.height, 1152 "minDstExtent.height <= maxDstExtent.height"); 1153 1154 if (results.getResult() != QP_TEST_RESULT_PASS) 1155 { 1156 m_log << tcu::TestLog::Message 1157 << "Error detected " << results.getMessage() 1158 << " for plane's " << planeIndex 1159 << " display " << displayIndex 1160 << " and mode " << modeIndex 1161 << " with capabilities " << planeCapabilities 1162 << tcu::TestLog::EndMessage; 1163 1164 TCU_FAIL_STR(results.getMessage()); 1165 } 1166 1167 } 1168 } 1169 } 1170 1171 return tcu::TestStatus::pass("pass"); 1172 } 1173 1174 /*--------------------------------------------------------------------*//*! 1175 * \brief Create display plane surface coverage test 1176 * 1177 * Throws an exception on fail. 1178 * 1179 * \return tcu::TestStatus::pass on success 1180 *//*--------------------------------------------------------------------*/ 1181 tcu::TestStatus DisplayCoverageTestInstance::testCreateDisplayPlaneSurfaceKHR(void) 1182 { 1183 deUint32 planeCountReported = 0u; 1184 deUint32 planeCountTested = 0u; 1185 deUint32 planeCountRetrieved = 0u; 1186 std::vector<VkDisplayPlanePropertiesKHR> planeProperties; 1187 bool testPerformed = false; 1188 DisplayVector displaysVector; 1189 VkResult result; 1190 1191 // Get displays 1192 if (!getDisplays(displaysVector)) 1193 TCU_FAIL("Failed to retrieve displays"); 1194 1195 if (displaysVector.empty()) 1196 TCU_THROW(NotSupportedError, "No displays reported"); 1197 1198 // Get planes 1199 result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 1200 &planeCountReported, // uint32_t* pPropertyCount 1201 DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties 1202 1203 if (result != VK_SUCCESS) 1204 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 1205 1206 if (planeCountReported == 0) 1207 TCU_FAIL("No planes defined"); 1208 1209 planeCountTested = planeCountReported; 1210 if (planeCountReported > MAX_TESTED_PLANE_COUNT) 1211 { 1212 m_log << tcu::TestLog::Message 1213 << "Number of planes reported is too high " << planeCountReported 1214 << ". Test is limited to " << MAX_TESTED_PLANE_COUNT 1215 << tcu::TestLog::EndMessage; 1216 1217 planeCountTested = MAX_TESTED_PLANE_COUNT; 1218 } 1219 1220 planeProperties.resize(planeCountTested); 1221 planeCountRetrieved = planeCountTested; 1222 1223 result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 1224 &planeCountRetrieved, // uint32_t* pPropertyCount 1225 &planeProperties[0]); // VkDisplayPlanePropertiesKHR* pProperties 1226 1227 if (result != VK_SUCCESS && result != VK_INCOMPLETE ) 1228 TCU_FAIL_STR(string("Expected VK_SUCCESS or VK_INCOMPLETE expected. Have ") + getResultAsString(result)); 1229 1230 if (planeCountRetrieved != planeCountTested) 1231 TCU_FAIL_STR( string("Number of planes requested (") + de::toString(planeCountTested) + 1232 ") does not match retrieved (" + de::toString(planeCountRetrieved) + ")"); 1233 1234 // Iterate through displays-modes 1235 for (DisplayVector::iterator it = displaysVector.begin(); 1236 it != displaysVector.end(); 1237 it++) 1238 { 1239 const VkDisplayKHR display = *it; 1240 std::vector<VkDisplayModePropertiesKHR> modesPropertiesForDisplay; 1241 1242 if (!getDisplayModeProperties(display, modesPropertiesForDisplay)) 1243 TCU_FAIL("Failed to retrieve display mode properties"); 1244 1245 for (deUint32 modeIndex = 0; 1246 modeIndex < modesPropertiesForDisplay.size(); 1247 modeIndex++) 1248 { 1249 const VkDisplayModeKHR displayMode = modesPropertiesForDisplay[modeIndex].displayMode; 1250 const VkDisplayModePropertiesKHR& modeProperties = modesPropertiesForDisplay[modeIndex]; 1251 1252 for (deUint32 planeIndex = 0; 1253 planeIndex < planeCountTested; 1254 planeIndex++) 1255 { 1256 std::vector<VkDisplayKHR> displaysForPlane; 1257 1258 if (!getDisplaysForPlane(planeIndex, displaysForPlane)) 1259 TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex)); 1260 1261 if (displaysForPlane.empty()) 1262 continue; 1263 1264 // Iterate through displays supported by the plane 1265 for (deUint32 displayIndex = 0; 1266 displayIndex < displaysForPlane.size(); 1267 displayIndex++) 1268 { 1269 const VkDisplayKHR planeDisplay = displaysForPlane[displayIndex]; 1270 VkDisplayPlaneCapabilitiesKHR planeCapabilities; 1271 bool fullDisplayPlane; 1272 1273 if (display == planeDisplay) 1274 { 1275 deMemset(&planeCapabilities, 0, sizeof(planeCapabilities)); 1276 1277 result = m_vki.getDisplayPlaneCapabilitiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice 1278 displayMode, // VkDisplayModeKHR mode 1279 planeIndex, // uint32_t planeIndex 1280 &planeCapabilities); // VkDisplayPlaneCapabilitiesKHR* pCapabilities 1281 1282 if (result != VK_SUCCESS) 1283 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 1284 1285 fullDisplayPlane = planeCapabilities.minDstExtent.height == modeProperties.parameters.visibleRegion.height 1286 && planeCapabilities.minDstExtent.width == modeProperties.parameters.visibleRegion.width; 1287 1288 if (fullDisplayPlane && (planeCapabilities.supportedAlpha & VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR) != 0) 1289 { 1290 const VkDisplayPlaneAlphaFlagBitsKHR alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; 1291 const VkInstance instance = m_context.getInstance(); 1292 const VkDisplaySurfaceCreateInfoKHR createInfo = { 1293 VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, // VkStructureType sType 1294 DE_NULL, // const void* pNext 1295 0, // VkDisplaySurfaceCreateFlagsKHR flags 1296 displayMode, // VkDisplayModeKHR displayMode 1297 planeIndex, // uint32_t planeIndex 1298 planeProperties[planeIndex].currentStackIndex, // uint32_t planeStackIndex 1299 VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, // VkSurfaceTransformFlagBitsKHR transform 1300 1.0f, // float globalAlpha 1301 alphaMode, // VkDisplayPlaneAlphaFlagBitsKHR alphaMode 1302 { // VkExtent2D imageExtent 1303 planeCapabilities.minDstExtent.width, 1304 planeCapabilities.minDstExtent.height 1305 } 1306 }; 1307 VkSurfaceKHR surface = DE_NULL; 1308 1309 result = m_vki.createDisplayPlaneSurfaceKHR( instance, // VkInstance instance 1310 &createInfo, // const VkDisplaySurfaceCreateInfoKHR* pCreateInfo 1311 DE_NULL, // const VkAllocationCallbacks* pAllocator 1312 &surface); // VkSurfaceKHR* pSurface 1313 1314 if (result != VK_SUCCESS) 1315 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); 1316 1317 if (surface == DE_NULL) 1318 TCU_FAIL("Invalid surface handle returned"); 1319 1320 m_vki.destroySurfaceKHR( instance, // VkInstance instance 1321 surface, // VkSurfaceKHR* pSurface 1322 DE_NULL); // const VkAllocationCallbacks* pAllocator 1323 1324 testPerformed = true; 1325 } 1326 } 1327 } 1328 } 1329 } 1330 } 1331 1332 if (!testPerformed) 1333 TCU_THROW(NotSupportedError, "Cannot find suitable parameters for the test"); 1334 1335 return tcu::TestStatus::pass("pass"); 1336 } 1337 1338 1339 /*--------------------------------------------------------------------*//*! 1340 * \brief Display coverage tests case class 1341 *//*--------------------------------------------------------------------*/ 1342 class DisplayCoverageTestsCase : public vkt::TestCase 1343 { 1344 public: 1345 DisplayCoverageTestsCase (tcu::TestContext &context, const char *name, const char *description, const DisplayIndexTest testId) 1346 : TestCase (context, name, description) 1347 , m_testId (testId) 1348 { 1349 } 1350 private: 1351 const DisplayIndexTest m_testId; 1352 1353 vkt::TestInstance* createInstance (vkt::Context& context) const 1354 { 1355 return new DisplayCoverageTestInstance(context, m_testId); 1356 } 1357 }; 1358 1359 1360 /*--------------------------------------------------------------------*//*! 1361 * \brief Adds a test into group 1362 *//*--------------------------------------------------------------------*/ 1363 static void addTest (tcu::TestCaseGroup* group, const DisplayIndexTest testId, const char* name, const char* description) 1364 { 1365 tcu::TestContext& testCtx = group->getTestContext(); 1366 1367 group->addChild(new DisplayCoverageTestsCase(testCtx, name, description, testId)); 1368 } 1369 1370 /*--------------------------------------------------------------------*//*! 1371 * \brief Adds VK_KHR_display and VK_KHR_display_swapchain extension tests into group 1372 *//*--------------------------------------------------------------------*/ 1373 void createDisplayCoverageTests (tcu::TestCaseGroup* group) 1374 { 1375 addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES, "get_display_properties", "Display enumeration coverage test"); 1376 addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES, "get_display_plane_properties", "Planes enumeration coverage test"); 1377 addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY, "get_display_plane_supported_displays", "Display plane support coverage test"); 1378 addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE, "get_display_mode_properties", "Display mode properties coverage test"); 1379 addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE, "create_display_mode", "Create display mode coverage test"); 1380 addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES, "get_display_plane_capabilities", "Display-plane capabilities coverage test"); 1381 addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE, "create_display_plane_surface", "Create display plane surface coverage test"); 1382 } 1383 1384 } //wsi 1385 } //vkt 1386 1387