/*------------------------------------------------------------------------ * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2017 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Vulkan coverage tests for extensions VK_KHR_display, * VK_KHR_get_display_properties2 *//*--------------------------------------------------------------------*/ #include "vktWsiDisplayTests.hpp" #include "vktTestCase.hpp" #include "vkStrUtil.hpp" #include "vkPrograms.hpp" #include "vkRef.hpp" #include "vkQueryUtil.hpp" #include "vkWsiUtil.hpp" #include "tcuDefs.hpp" #include "tcuTestLog.hpp" #include "tcuResultCollector.hpp" #include "deMemory.h" #include "deSTLUtil.hpp" #include "deStringUtil.hpp" #include #include #include #include #include namespace vkt { namespace wsi { using namespace vk; using std::vector; using std::map; using std::set; using std::string; #ifndef TCU_FAIL_STR #define TCU_FAIL_STR(MSG) TCU_FAIL(string(MSG).c_str()) #endif enum DisplayIndexTest { DISPLAY_TEST_INDEX_START, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE, DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES, DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE, DISPLAY_TEST_INDEX_SURFACE_COUNTERS, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2, DISPLAY_TEST_INDEX_LAST }; template class BinaryCompare { public: bool operator() (const Type& a, const Type& b) const { return deMemCmp(&a, &b, sizeof(Type)) < 0; } }; typedef std::set > DisplaySet; typedef std::vector DisplayVector; typedef std::vector DisplayModePropertiesVector; typedef std::vector DisplayModeProperties2Vector; const deUint32 DEUINT32_MAX = std::numeric_limits::max(); const deUint32 RECOGNIZED_SURFACE_TRANSFORM_FLAGS = vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR | vk::VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR | vk::VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR | vk::VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR | vk::VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR; const deUint32 RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR | VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR | VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR | VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR; enum DisplayMaxTestedConsts { MAX_TESTED_DISPLAY_COUNT = 16, MAX_TESTED_PLANE_COUNT = 16, }; /*--------------------------------------------------------------------*//*! * \brief Return Vulkan result name or code as std::string. * * \param result Vulkan code to convert to string * \return Vulkun result code name or code number as std::string *//*--------------------------------------------------------------------*/ std::string getResultAsString (vk::VkResult result) { const char* resultAsChar = vk::getResultName(result); if (resultAsChar != DE_NULL) return std::string(resultAsChar); else return de::toString(result); } /*--------------------------------------------------------------------*//*! * \brief Moves test index to next test skipping middle tests. * * Gets first 3 tests and last 3 tests on long sequences. * After test number 2 moves index value to endIndex - 3. * Shortens the number of tests executed by skipping middle tests. * * Example: * for (i=0; i 6 && index == 2) result = endIndex - 3; else result = index + 1; return result; } /*--------------------------------------------------------------------*//*! * \brief Vulkan VK_KHR_display extensions coverage tests *//*--------------------------------------------------------------------*/ class DisplayCoverageTestInstance : public TestInstance { public: DisplayCoverageTestInstance (Context& context, const DisplayIndexTest testId); private: typedef void (DisplayCoverageTestInstance::*EachSurfaceFunctionPtr) (VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties); bool getDisplays (DisplayVector& displays); bool getDisplaysForPlane (deUint32 plane, DisplayVector& displays); bool getDisplayModeProperties (VkDisplayKHR display, DisplayModePropertiesVector& modeProperties); bool getDisplays2 (DisplayVector& displays); bool getDisplayModeProperties2 (VkDisplayKHR display, DisplayModeProperties2Vector& modeProperties); void validateDisplayProperties ( tcu::ResultCollector& results, const VkDisplayPropertiesKHR& toValidate, const VkDisplayPropertiesKHR& nonUpdated); void validateDisplayPlaneProperties ( tcu::ResultCollector& results, const VkDisplayPlanePropertiesKHR& toValidate, const VkDisplayPlanePropertiesKHR& nonUpdated, DisplaySet& displaySet); void validateDisplayPlaneCapabilities ( tcu::ResultCollector& results, const VkDisplayPlaneCapabilitiesKHR& toValidate, const VkDisplayPlaneCapabilitiesKHR& nonUpdated); void validateDisplayModeProperties ( tcu::ResultCollector& results, const VkDisplayModePropertiesKHR& toValidate, const VkDisplayModePropertiesKHR& nonUpdated); // VK_KHR_display extension tests tcu::TestStatus testGetPhysicalDeviceDisplayPropertiesKHR (void); tcu::TestStatus testGetPhysicalDeviceDisplayPlanePropertiesKHR (void); tcu::TestStatus testGetDisplayPlaneSupportedDisplaysKHR (void); tcu::TestStatus testGetDisplayModePropertiesKHR (void); tcu::TestStatus testCreateDisplayModeKHR (void); tcu::TestStatus testGetDisplayPlaneCapabilitiesKHR (void); enum SurfaceTestKind { SURFACE_CREATE = 0, SURFACE_COUNTERS, SURFACE_TEST_KIND_MAX_ENUM }; tcu::TestStatus testDisplaySurface (SurfaceTestKind testKind); // VK_KHR_get_display_properties2 extension tests tcu::TestStatus testGetPhysicalDeviceDisplayProperties2KHR (void); tcu::TestStatus testGetPhysicalDeviceDisplayPlaneProperties2KHR (void); tcu::TestStatus testGetDisplayModeProperties2KHR (void); tcu::TestStatus testGetDisplayPlaneCapabilities2KHR (void); tcu::TestStatus iterate (void); void testCreateSharedSwapchainsKHRforSurface (VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties); const InstanceInterface& m_vki; const DeviceInterface& m_vkd; tcu::TestLog& m_log; const VkPhysicalDevice m_physicalDevice; const DisplayIndexTest m_testId; }; /*--------------------------------------------------------------------*//*! * \brief DisplayCoverageTestInstance constructor * * Initializes DisplayCoverageTestInstance object * * \param context Context object * \param parameters Test parameters structure *//*--------------------------------------------------------------------*/ DisplayCoverageTestInstance::DisplayCoverageTestInstance (Context& context, const DisplayIndexTest testId) : TestInstance (context) , m_vki (m_context.getInstanceInterface()) , m_vkd (m_context.getDeviceInterface()) , m_log (m_context.getTestContext().getLog()) , m_physicalDevice (m_context.getPhysicalDevice()) , m_testId (testId) { const std::string extensionName("VK_KHR_display"); if(!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionName)) TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); switch (m_testId) { case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2: case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2: case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2: case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2: { const std::string extensionNameAddition("VK_KHR_get_display_properties2"); if(!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionNameAddition)) TCU_THROW(NotSupportedError, std::string(extensionNameAddition + " is not supported").c_str()); break; } default: { break; } } } /*--------------------------------------------------------------------*//*! * \brief Step forward test execution * * \return true if application should call iterate() again and false * if test execution session is complete. *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::iterate (void) { switch (m_testId) { case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES: return testGetPhysicalDeviceDisplayPropertiesKHR(); case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES: return testGetPhysicalDeviceDisplayPlanePropertiesKHR(); case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY: return testGetDisplayPlaneSupportedDisplaysKHR(); case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE: return testGetDisplayModePropertiesKHR(); case DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE: return testCreateDisplayModeKHR(); case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES: return testGetDisplayPlaneCapabilitiesKHR(); case DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE: return testDisplaySurface(SURFACE_CREATE); case DISPLAY_TEST_INDEX_SURFACE_COUNTERS: return testDisplaySurface(SURFACE_COUNTERS); case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2: return testGetPhysicalDeviceDisplayProperties2KHR(); case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2: return testGetPhysicalDeviceDisplayPlaneProperties2KHR(); case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2: return testGetDisplayModeProperties2KHR(); case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2: return testGetDisplayPlaneCapabilities2KHR(); default: { DE_FATAL("Impossible"); } } TCU_FAIL("Invalid test identifier"); } /*--------------------------------------------------------------------*//*! * \brief Fills vector with available displays. Clears passed vector at start. * * \param displays The vector filled with display handles * \return true on success, false on error *//*--------------------------------------------------------------------*/ bool DisplayCoverageTestInstance::getDisplays (DisplayVector& displays) { deUint32 countReported = 0u; deUint32 countRetrieved = 0u; std::vector displaysProps; VkResult result; displays.clear(); result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &countReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPropertiesKHR* pProperties if (result != VK_SUCCESS) { m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result) << " reported items count " << countReported << tcu::TestLog::EndMessage; return false; } if (!countReported) TCU_THROW(NotSupportedError, "No displays reported"); displaysProps.resize(countReported); countRetrieved = countReported; result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &countRetrieved, // uint32_t* pPropertyCount &displaysProps[0]); // VkDisplayPropertiesKHR* pProperties if (result != VK_SUCCESS || countRetrieved > countReported) { m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result) << " reported items count " << countReported << " retrieved items count " << countRetrieved << tcu::TestLog::EndMessage; return false; } displays.reserve(countRetrieved); for (deUint32 displayIndex = 0; displayIndex < countRetrieved; displayIndex++) { const VkDisplayKHR display = displaysProps[displayIndex].display; if (display == DE_NULL) { displays.clear(); return false; } displays.push_back(display); } return true; } /*--------------------------------------------------------------------*//*! * \brief Fills vector with available displays for plane specified. * * Clears passed vector at start and on error. * * \param plane The plane to get displays for * \param displays The vector filled with display handles * \return true on success, false on error *//*--------------------------------------------------------------------*/ bool DisplayCoverageTestInstance::getDisplaysForPlane(deUint32 plane, DisplayVector& displays) { deUint32 countReported = 0u; deUint32 countRetrieved = 0u; VkResult result; displays.clear(); result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice plane, // uint32_t planeIndex &countReported, // uint32_t* pDisplayCount DE_NULL); // VkDisplayKHR* pDisplays if (result != VK_SUCCESS) { m_log << tcu::TestLog::Message << "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result) << " for plane " << plane << " reported items count " << countReported << tcu::TestLog::EndMessage; return false; } displays.resize(countReported); countRetrieved = countReported; result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice plane, // uint32_t planeIndex &countRetrieved, // uint32_t* pDisplayCount &displays[0]); // VkDisplayKHR* pDisplays if (result != VK_SUCCESS || countRetrieved > countReported) { m_log << tcu::TestLog::Message << "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result) << " for plane " << plane << " reported items count " << countReported << " retrieved items count " << countRetrieved << tcu::TestLog::EndMessage; displays.clear(); return false; } if (countRetrieved < countReported) displays.resize(countRetrieved); return true; } /*--------------------------------------------------------------------*//*! * \brief Fills vector with available modes properties for display specified. * * Clears passed vector at start and on error. * * \param display The display to get modes for * \param modes The vector filled with display mode properties structures * \return true on success, false on error *//*--------------------------------------------------------------------*/ bool DisplayCoverageTestInstance::getDisplayModeProperties(VkDisplayKHR display, DisplayModePropertiesVector& modeProperties) { deUint32 countReported = 0u; deUint32 countRetrieved = 0u; VkResult result; modeProperties.clear(); result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &countReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayModePropertiesKHR* pProperties if (result != VK_SUCCESS) { m_log << tcu::TestLog::Message << "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result) << " for display " << display << " reported items count " << countReported << tcu::TestLog::EndMessage; return false; } modeProperties.resize(countReported); countRetrieved = countReported; result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &countRetrieved, // uint32_t* pPropertyCount &modeProperties[0]); // VkDisplayModePropertiesKHR* pProperties if (result != VK_SUCCESS || countRetrieved > countReported) { m_log << tcu::TestLog::Message << "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result) << " for display " << display << " reported items count " << countReported << " retrieved items count " << countReported << tcu::TestLog::EndMessage; modeProperties.clear(); return false; } if (countRetrieved < countReported) modeProperties.resize(countRetrieved); return true; } /*--------------------------------------------------------------------*//*! * \brief Fills vector with available displays. Clears passed vector at start. * * Uses VK_KHR_get_display_properties2 extension API. * Clears passed vector at start. * * \param displays The vector filled with display handles * \return true on success, false on error *//*--------------------------------------------------------------------*/ bool DisplayCoverageTestInstance::getDisplays2 (DisplayVector& displays) { deUint32 countReported = 0u; deUint32 countRetrieved = 0u; const VkDisplayPropertiesKHR displayProperties = { DE_NULL, // VkDisplayKHR display DE_NULL, // const char* displayName {0, 0}, // VkExtent2D physicalDimensions {0, 0}, // VkExtent2D physicalResolution 0, // VkSurfaceTransformFlagsKHR supportedTransforms VK_FALSE, // VkBool32 planeReorderPossible VK_FALSE // VkBool32 persistentContent }; const VkDisplayProperties2KHR displayProperties2 = { VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR, // VkStructureType sType DE_NULL, // void* pNext displayProperties // VkDisplayPropertiesKHR displayProperties }; std::vector displaysProps; VkResult result; displays.clear(); result = m_vki.getPhysicalDeviceDisplayProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &countReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayProperties2KHR* pProperties if (result != VK_SUCCESS) { m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayProperties2KHR failed with " << getResultAsString(result) << " reported items count " << countReported << tcu::TestLog::EndMessage; return false; } if (!countReported) TCU_THROW(NotSupportedError, "No displays reported"); displaysProps.resize(countReported, displayProperties2); countRetrieved = countReported; result = m_vki.getPhysicalDeviceDisplayProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &countRetrieved, // uint32_t* pPropertyCount &displaysProps[0]); // VkDisplayPropertiesKHR* pProperties if (result != VK_SUCCESS || countRetrieved > countReported) { m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayProperties2KHR failed with " << getResultAsString(result) << " reported items count " << countReported << " retrieved items count " << countRetrieved << tcu::TestLog::EndMessage; return false; } displays.reserve(countRetrieved); for (deUint32 displayIndex = 0; displayIndex < countRetrieved; displayIndex++) { const VkDisplayKHR display = displaysProps[displayIndex].displayProperties.display; if (display == DE_NULL) { displays.clear(); return false; } displays.push_back(display); } return true; } /*--------------------------------------------------------------------*//*! * \brief Fills vector with available modes properties for display specified. * * Uses VK_KHR_get_display_properties2 extension API. * Clears passed vector at start and on error. * * \param display The display to get modes for * \param modes The vector filled with display mode properties structures * \return true on success, false on error *//*--------------------------------------------------------------------*/ bool DisplayCoverageTestInstance::getDisplayModeProperties2 (VkDisplayKHR display, DisplayModeProperties2Vector& modeProperties) { deUint32 countReported = 0u; deUint32 countRetrieved = 0u; const VkDisplayModePropertiesKHR displayModeProperties = { DE_NULL, // VkDisplayModeKHR displayMode { // VkDisplayModeParametersKHR parameters {0, 0}, // VkExtent2D visibleRegion 0 // uint32_t refreshRate } }; const VkDisplayModeProperties2KHR displayModeProperties2 = { VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR, // VkStructureType sType DE_NULL, // void* pNext displayModeProperties // VkDisplayModePropertiesKHR displayModeProperties }; VkResult result; modeProperties.clear(); result = m_vki.getDisplayModeProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &countReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayModeProperties2KHR* pProperties if (result != VK_SUCCESS) { m_log << tcu::TestLog::Message << "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result) << " for display " << display << " reported items count " << countReported << tcu::TestLog::EndMessage; return false; } modeProperties.resize(countReported, displayModeProperties2); countRetrieved = countReported; result = m_vki.getDisplayModeProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &countRetrieved, // uint32_t* pPropertyCount &modeProperties[0]); // VkDisplayModeProperties2KHR* pProperties if (result != VK_SUCCESS || countRetrieved > countReported) { m_log << tcu::TestLog::Message << "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result) << " for display " << display << " reported items count " << countReported << " retrieved items count " << countReported << tcu::TestLog::EndMessage; modeProperties.clear(); return false; } if (countRetrieved < countReported) modeProperties.resize(countRetrieved); return true; } /*--------------------------------------------------------------------*//*! * \brief Validate display properties and report failures * into results collector * * \param results Results collector * \param toValidate Display properties to validate * \param nonUpdated Display properties to compare with *//*--------------------------------------------------------------------*/ void DisplayCoverageTestInstance::validateDisplayProperties ( tcu::ResultCollector& results, const VkDisplayPropertiesKHR& toValidate, const VkDisplayPropertiesKHR& nonUpdated) { results.check( toValidate.display != nonUpdated.display, "Invalid display handle"); results.check( toValidate.planeReorderPossible == VK_TRUE || toValidate.planeReorderPossible == VK_FALSE, "planeReorderPossible neither VK_TRUE, nor VK_FALSE"); results.check( toValidate.persistentContent == VK_TRUE || toValidate.persistentContent == VK_FALSE, "persistentContent neither VK_TRUE, nor VK_FALSE"); results.check( (toValidate.supportedTransforms & nonUpdated.supportedTransforms) == 0, "supportedTransforms contains unrecognized flags"); // Outside specification, but resolution 0x0 pixels will break many applications results.check( toValidate.physicalResolution.height != 0, "physicalResolution.height cannot be zero"); // Outside specification, but resolution 0x0 pixels will break many applications results.check( toValidate.physicalResolution.width != 0, "physicalResolution.width cannot be zero"); } /*--------------------------------------------------------------------*//*! * \brief Validates display plane properties and report failures * into results collector * * \param results Results collector * \param toValidate Display plane properties to validate * \param nonUpdated Display plane properties to compare with * \param displaySet Set of valid display handles *//*--------------------------------------------------------------------*/ void DisplayCoverageTestInstance::validateDisplayPlaneProperties ( tcu::ResultCollector& results, const VkDisplayPlanePropertiesKHR& toValidate, const VkDisplayPlanePropertiesKHR& nonUpdated, DisplaySet& displaySet) { const VkDisplayKHR currentDisplay = toValidate.currentDisplay; results.check( toValidate.currentStackIndex < nonUpdated.currentStackIndex, "CurrentStackIndex must be less than the number of planes reported " + de::toString(nonUpdated.currentStackIndex)); results.check( currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay), "Plane bound to invalid handle " + de::toString(toValidate.currentDisplay)); } /*--------------------------------------------------------------------*//*! * \brief Validate display plane capabilities and report failures * into results collector * * \param results Results collector * \param toValidate Display plane capabilities to validate * \param nonUpdated Display plane capabilities to compare with *//*--------------------------------------------------------------------*/ void DisplayCoverageTestInstance::validateDisplayPlaneCapabilities ( tcu::ResultCollector& results, const VkDisplayPlaneCapabilitiesKHR& toValidate, const VkDisplayPlaneCapabilitiesKHR& nonUpdated) { results.check( (toValidate.supportedAlpha & nonUpdated.supportedAlpha) == 0, "supportedAlpha contains unrecognized value"); results.check( toValidate.minSrcPosition.x >= 0, "minSrcPosition.x >= 0"); results.check( toValidate.minSrcPosition.y >= 0, "minSrcPosition.y >= 0"); results.check( toValidate.maxSrcPosition.x >= 0, "maxSrcPosition.x >= 0"); results.check( toValidate.maxSrcPosition.y >= 0, "maxSrcPosition.y >= 0"); results.check( toValidate.minSrcPosition.x <= toValidate.maxSrcPosition.x, "minSrcPosition.x <= maxSrcPosition.x"); results.check( toValidate.minSrcPosition.y <= toValidate.maxSrcPosition.y, "minSrcPosition.y <= maxSrcPosition.y"); results.check( toValidate.minDstPosition.x <= toValidate.maxDstPosition.x, "minDstPosition.x <= maxDstPosition.x"); results.check( toValidate.minDstPosition.y <= toValidate.maxDstPosition.y, "minDstPosition.y <= maxDstPosition.y"); results.check( toValidate.minSrcExtent.width <= toValidate.maxSrcExtent.width, "minSrcExtent.width <= maxSrcExtent.width"); results.check( toValidate.minSrcExtent.height <= toValidate.maxSrcExtent.height, "minSrcExtent.height <= maxSrcExtent.height"); results.check( toValidate.minDstExtent.width <= toValidate.maxDstExtent.width, "minDstExtent.width <= maxDstExtent.width"); results.check( toValidate.minDstExtent.height <= toValidate.maxDstExtent.height, "minDstExtent.height <= maxDstExtent.height"); } /*--------------------------------------------------------------------*//*! * \brief Validate display mode properties and report failures * into results collector * * \param results Results collector * \param toValidate Display mode properties to validate * \param nonUpdated Display mode properties to compare with *//*--------------------------------------------------------------------*/ void DisplayCoverageTestInstance::validateDisplayModeProperties ( tcu::ResultCollector& results, const VkDisplayModePropertiesKHR& toValidate, const VkDisplayModePropertiesKHR& nonUpdated) { results.check( toValidate.displayMode != nonUpdated.displayMode, "Invalid mode display handle reported"); } /*--------------------------------------------------------------------*//*! * \brief Display enumeration coverage test * * Throws ResourceError exception in case no displays available. * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPropertiesKHR (void) { deUint32 displayCountReported = 0u; deUint32 displayCountToTest = 0u; tcu::ResultCollector results (m_log); VkResult result; result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &displayCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPropertiesKHR* pProperties if ( result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY && result != VK_ERROR_OUT_OF_DEVICE_MEMORY ) { TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); } if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (displayCountReported == 0) TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str()); displayCountToTest = displayCountReported; if (displayCountReported > MAX_TESTED_DISPLAY_COUNT) { m_log << tcu::TestLog::Message << "Number of displays reported is too high " << displayCountReported << ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT << tcu::TestLog::EndMessage; displayCountToTest = MAX_TESTED_DISPLAY_COUNT; } // Test the call correctly writes data in various size arrays for (deUint32 displayCountRequested = 0; displayCountRequested < displayCountToTest + 2; displayCountRequested++) { const deUint32 displayCountExpected = std::min(displayCountRequested, displayCountReported); const VkDisplayPropertiesKHR invalidDisplayProps = { // Most values are set to fail the test to make sure driver updates these DE_NULL, // VkDisplayKHR display; DE_NULL, // const char* displayName; {0, 0}, // VkExtent2D physicalDimensions; {0, 0}, // VkExtent2D physicalResolution; ~RECOGNIZED_SURFACE_TRANSFORM_FLAGS, // VkSurfaceTransformFlagsKHR supportedTransforms; (vk::VkBool32)(VK_TRUE + 1), // VkBool32 planeReorderPossible; (vk::VkBool32)(VK_TRUE + 1) // VkBool32 persistentContent; }; const VkDisplayKHR canaryDisplay = static_cast(0xABCDEF11); const deUint32 canaryItemCount = 1; std::vector displaysProps (displayCountRequested + canaryItemCount, invalidDisplayProps); deUint32 displayCountRetrieved = displayCountRequested; DisplaySet displaySet; displaysProps[displayCountExpected].display = canaryDisplay; result = m_vki.getPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &displayCountRetrieved, // uint32_t* pPropertyCount &displaysProps[0]); // VkDisplayPropertiesKHR* pProperties // Check amount of data written equals to expected if (displayCountRetrieved != displayCountExpected) TCU_FAIL_STR( string("displayCountRetrieved != displayCountExpected, ") + de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected)); if (displayCountRequested >= displayCountReported) { if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); } else { if (result != VK_INCOMPLETE) TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); } // Check the driver has written something for (deUint32 displayIndex = 0; displayIndex < displayCountRetrieved; displayIndex++) { displaySet.insert(displaysProps[displayIndex].display); results.check( displaysProps[displayIndex].display != invalidDisplayProps.display, "Invalid display handle for display number " + de::toString(displayIndex)); results.check( displaysProps[displayIndex].planeReorderPossible == VK_TRUE || displaysProps[displayIndex].planeReorderPossible == VK_FALSE, "planeReorderPossible neither VK_TRUE, nor VK_FALSE"); results.check( displaysProps[displayIndex].persistentContent == VK_TRUE || displaysProps[displayIndex].persistentContent == VK_FALSE, "persistentContent neither VK_TRUE, nor VK_FALSE"); results.check( (displaysProps[displayIndex].supportedTransforms & invalidDisplayProps.supportedTransforms) == 0, "supportedTransforms contains unrecognized flags"); // Outside specification, but resolution 0x0 pixels will break many applications results.check( displaysProps[displayIndex].physicalResolution.height != 0, "physicalResolution.height cannot be zero"); // Outside specification, but resolution 0x0 pixels will break many applications results.check( displaysProps[displayIndex].physicalResolution.width != 0, "physicalResolution.width cannot be zero"); if (results.getResult() != QP_TEST_RESULT_PASS) { m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for display " << displayIndex << " with properties " << displaysProps[displayIndex] << " invalid display properties are " << invalidDisplayProps << tcu::TestLog::EndMessage; TCU_FAIL_STR(results.getMessage()); } } // Check the driver has not written more than requested if (displaysProps[displayCountExpected].display != canaryDisplay) TCU_FAIL("Memory damage detected: driver has written more than expected"); // Check display handle uniqueness if (displaySet.size() != displayCountRetrieved) TCU_FAIL("Display handle duplication detected"); } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Plane enumeration coverage test * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlanePropertiesKHR (void) { DisplayVector displaysVector; DisplaySet displaySet; deUint32 planeCountReported = 0u; deUint32 planeCountTested = 0u; tcu::ResultCollector results (m_log); VkResult result; // Create a list of displays available if (!getDisplays(displaysVector)) TCU_FAIL("Failed to retrieve displays"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No displays reported"); displaySet = DisplaySet(displaysVector.begin(), displaysVector.end()); // Get planes to test result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties if ( result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY && result != VK_ERROR_OUT_OF_DEVICE_MEMORY ) { TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); } if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (planeCountReported == 0) TCU_THROW(ResourceError, "Cannot perform test: no planes found"); planeCountTested = planeCountReported; if (planeCountReported > MAX_TESTED_PLANE_COUNT) { m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage; planeCountTested = MAX_TESTED_PLANE_COUNT; } // Test the call correctly writes data in various size arrays for (deUint32 planeCountRequested = 0; planeCountRequested < planeCountTested + 2; planeCountRequested++) { const deUint32 planeCountExpected = std::min(planeCountRequested, planeCountReported); const VkDisplayPlanePropertiesKHR invalidPlaneProps = { // Most values are set to fail the test to make sure driver updates these DE_NULL, // VkDisplayKHR currentDisplay DEUINT32_MAX // deUint32 currentStackIndex }; const VkDisplayKHR canaryDisplay = static_cast(0xABCDEF11); const deUint32 canaryItemCount = 1; std::vector planeProps (planeCountRequested + canaryItemCount, invalidPlaneProps); deUint32 planeCountRetrieved = planeCountRequested; planeProps[planeCountExpected].currentDisplay = canaryDisplay; result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountRetrieved, // uint32_t* pPropertyCount &planeProps[0]); // VkDisplayPlanePropertiesKHR* pProperties // Check amount of data written equals to expected if (planeCountRetrieved != planeCountExpected) TCU_FAIL_STR( string("planeCountRetrieved != planeCountExpected, ") + de::toString(planeCountRetrieved) + " != " + de::toString(planeCountExpected)); if (planeCountRequested >= planeCountReported) { if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); } else { if (result != VK_INCOMPLETE) TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); } // Check the driver has written something for (deUint32 planeIndex = 0; planeIndex < planeCountRetrieved; planeIndex++) { const VkDisplayKHR currentDisplay = planeProps[planeIndex].currentDisplay; results.check( planeProps[planeIndex].currentStackIndex < planeCountReported, "CurrentStackIndex must be less than the number of planes reported " + de::toString(planeCountReported)); results.check( currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay), "Plane bound to invalid handle " + de::toString(currentDisplay)); if (results.getResult() != QP_TEST_RESULT_PASS) { m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane " << planeIndex << " with properties " << planeProps[planeIndex] << tcu::TestLog::EndMessage; TCU_FAIL_STR(results.getMessage()); } } // Check the driver has not written more than requested if (planeProps[planeCountExpected].currentDisplay != canaryDisplay) TCU_FAIL("Memory damage detected: driver has written more than expected"); } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Display plane support coverage test * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneSupportedDisplaysKHR (void) { deUint32 planeCountReported = 0u; deUint32 planeCountTested = 0u; VkResult result; DisplayVector displaysVector; DisplaySet displaySet; if (!getDisplays(displaysVector)) TCU_FAIL("Failed to retrieve displays"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No displays reported"); displaySet = DisplaySet(displaysVector.begin(), displaysVector.end()); result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties if ( result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY && result != VK_ERROR_OUT_OF_DEVICE_MEMORY ) { TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); } if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (planeCountReported == 0) TCU_THROW(ResourceError, "Cannot perform test: no planes supported"); planeCountTested = planeCountReported; if (planeCountReported > MAX_TESTED_PLANE_COUNT) { m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage; planeCountTested = MAX_TESTED_PLANE_COUNT; } for (deUint32 planeIndex = 0; planeIndex < planeCountTested; planeIndex++) { deUint32 displayCountReported = 0u; result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice planeIndex, // uint32_t planeIndex &displayCountReported, // uint32_t* pDisplayCount DE_NULL); // VkDisplayKHR* pDisplays if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); // Test the call correctly writes data in various size arrays for (deUint32 displayCountRequested = 0; displayCountRequested < displayCountReported + 2; displayCountRequested++) { const deUint32 displayCountExpected = std::min(displayCountRequested, displayCountReported); const VkDisplayKHR nullDisplay = DE_NULL; const VkDisplayKHR canaryDisplay = static_cast(0xABCDEF11); const deUint32 canaryItemCount = 1; std::vector displaysForPlane (displayCountRequested + canaryItemCount, nullDisplay); deUint32 displayCountRetrieved = displayCountRequested; displaysForPlane[displayCountExpected] = canaryDisplay; result = m_vki.getDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice planeIndex, // uint32_t planeIndex &displayCountRetrieved, // uint32_t* pDisplayCount &displaysForPlane[0]); // VkDisplayKHR* pDisplays // Check amount of data written equals to expected if (displayCountRetrieved != displayCountExpected) TCU_FAIL_STR( string("displayCountRetrieved != displayCountExpected, ") + de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected)); if (displayCountRequested >= displayCountReported) { if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); } else { if (result != VK_INCOMPLETE) TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); } // Check the driver has written something for (deUint32 displayIndex = 0; displayIndex < displayCountExpected; displayIndex++) { const VkDisplayKHR display = displaysForPlane[displayIndex]; if (display != nullDisplay) { if (!de::contains(displaySet, display)) { TCU_FAIL_STR("Invalid display handle " + de::toString(display)); } } } // Check the driver has not written more than requested if (displaysForPlane[displayCountExpected] != canaryDisplay) TCU_FAIL("Memory damage detected: driver has written more than expected"); } } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Display mode properties coverage test * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModePropertiesKHR (void) { VkResult result; DisplayVector displaysVector; if (!getDisplays(displaysVector)) TCU_FAIL("Failed to retrieve displays list"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No displays reported"); for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++) { VkDisplayKHR display = *it; deUint32 modesCountReported = 0u; result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &modesCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayModePropertiesKHR* pProperties // Test the call correctly writes data in various size arrays for (deUint32 modesCountRequested = 0; modesCountRequested < modesCountReported + 2; modesCountRequested = nextTestNumber(modesCountRequested, modesCountReported + 2)) { const deUint32 modesCountExpected = std::min(modesCountRequested, modesCountReported); const VkDisplayModeKHR nullDisplayMode = DE_NULL; const VkDisplayModePropertiesKHR nullMode = { nullDisplayMode, // VkDisplayModeKHR displayMode { // VkDisplayModeParametersKHR parameters {0, 0}, // VkExtent2D visibleRegion 0 // uint32_t refreshRate } }; const VkDisplayModeKHR canaryDisplayMode = static_cast(0xABCDEF11); const deUint32 canaryItemCount = 1; std::vector modesForDisplay (modesCountRequested + canaryItemCount, nullMode); deUint32 modesCountRetrieved = modesCountRequested; modesForDisplay[modesCountExpected].displayMode = canaryDisplayMode; result = m_vki.getDisplayModePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &modesCountRetrieved, // uint32_t* pPropertyCount &modesForDisplay[0]); // VkDisplayModePropertiesKHR* pProperties // Check amount of data written equals to expected if (modesCountRetrieved != modesCountExpected) TCU_FAIL_STR( string("modesCountRetrieved != modesCountExpected, ") + de::toString(modesCountRetrieved) + " != " + de::toString(modesCountExpected)); if (modesCountRequested >= modesCountReported) { if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); } else { if (result != VK_INCOMPLETE) TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); } // Check the driver has written something for (deUint32 modeIndex = 0; modeIndex < modesCountExpected; modeIndex++) { const VkDisplayModePropertiesKHR theModeProperties = modesForDisplay[modeIndex]; if (theModeProperties.displayMode == nullMode.displayMode) TCU_FAIL_STR("Invalid mode display handle reported for display " + de::toString(display)); } // Check the driver has not written more than requested if (modesForDisplay[modesCountExpected].displayMode != canaryDisplayMode) TCU_FAIL("Memory damage detected: driver has written more than expected"); } } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Create display mode coverage test * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testCreateDisplayModeKHR (void) { DisplayVector displaysVector; VkResult result; if (!getDisplays(displaysVector)) TCU_FAIL("Failed to retrieve displays"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No displays reported"); for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++) { const VkDisplayKHR display = *it; DisplayModePropertiesVector::size_type builtinModesCount = 0u; VkDisplayModePropertiesKHR validModeProperties; VkDisplayModeKHR mode = DE_NULL; DisplayModePropertiesVector modes; VkDisplayModeCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR, // VkStructureType sType DE_NULL, // const void* pNext 0, // VkDisplayModeCreateFlagsKHR flags { // VkDisplayModeParametersKHR parameters {0, 0}, // VkExtent2D visibleRegion 0 // uint32_t refreshRate } }; if (!getDisplayModeProperties(display, modes)) TCU_FAIL("Failed to retrieve display mode properties"); if (modes.size() < 1) TCU_FAIL("At least one mode expected to be returned"); // Builtin mode count should not be updated with a new mode. Get initial builtin mode count builtinModesCount = modes.size(); // Assume first available builtin mode as a valid mode sample validModeProperties = modes[0]; // Do negative test by making one of parameters unacceptable for (deUint32 testIndex = 0; testIndex < 3; testIndex++) { VkDisplayModeCreateInfoKHR createInfoFail (createInfo); VkDisplayModeKHR modeFail = DE_NULL; createInfoFail.parameters = validModeProperties.parameters; switch (testIndex) { case 0: createInfoFail.parameters.refreshRate = 0; break; case 1: createInfoFail.parameters.visibleRegion.width = 0; break; case 2: createInfoFail.parameters.visibleRegion.height = 0; break; default: DE_FATAL("Impossible"); break; } result = m_vki.createDisplayModeKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &createInfoFail, // const VkDisplayModeCreateInfoKHR* pCreateInfo DE_NULL, // const VkAllocationCallbacks* pAllocator &modeFail); // VkDisplayModeKHR* pMode if (result != VK_ERROR_INITIALIZATION_FAILED) TCU_FAIL_STR(string("Expected VK_ERROR_INITIALIZATION_FAILED. Have ") + getResultAsString(result)); if (modeFail != DE_NULL) TCU_FAIL("Mode should be kept invalid on fail"); } // At last create valid display mode createInfo.parameters = validModeProperties.parameters; result = m_vki.createDisplayModeKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &createInfo, // const VkDisplayModeCreateInfoKHR* pCreateInfo DE_NULL, // const VkAllocationCallbacks* pAllocator &mode); // VkDisplayModeKHR* pMode if (result != VK_SUCCESS) TCU_FAIL_STR("Expected VK_SUCCESS. Have " + getResultAsString(result)); if (mode == DE_NULL) TCU_FAIL("Valid handle expected"); // Builtin mode count should not be updated with a new mode modes.clear(); if (!getDisplayModeProperties(display, modes)) TCU_FAIL("Failed to retrieve display mode properties"); if (builtinModesCount != modes.size()) TCU_FAIL_STR( string("Mode count has changed from ") + de::toString(builtinModesCount) + string(" to ") + de::toString(modes.size())); } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Display-plane capabilities coverage test * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneCapabilitiesKHR (void) { deUint32 planeCountReported = 0u; VkResult result; result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (planeCountReported == 0) { DisplayVector displaysVector; // If we don't have any displays then it's alright to have no planes, as // per the Vulkan Spec: // Devices must support at least one plane on each display if (!getDisplays(displaysVector)) TCU_FAIL("Failed to retrieve displays"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No display planes reported"); TCU_FAIL("No planes defined"); } if (planeCountReported > MAX_TESTED_PLANE_COUNT) { m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage; planeCountReported = MAX_TESTED_PLANE_COUNT; } for (deUint32 planeIndex = 0; planeIndex < planeCountReported; planeIndex++) { std::vector displaysForPlane; if (!getDisplaysForPlane(planeIndex, displaysForPlane)) TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex)); if (displaysForPlane.empty()) continue; // Check the driver has written something for (deUint32 displayIndex = 0; displayIndex < displaysForPlane.size(); displayIndex++) { const VkDisplayKHR display = displaysForPlane[displayIndex]; std::vector modesPropertiesForDisplay; if (!getDisplayModeProperties(display, modesPropertiesForDisplay)) TCU_FAIL("Failed to retrieve display mode properties"); for (deUint32 modeIndex = 0; modeIndex < modesPropertiesForDisplay.size(); modeIndex++) { const VkDisplayModeKHR theDisplayMode = modesPropertiesForDisplay[modeIndex].displayMode; const deUint32 unrecognizedAlphaFlags = ~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS; VkDisplayPlaneCapabilitiesKHR planeCapabilities = { unrecognizedAlphaFlags, // VkDisplayPlaneAlphaFlagsKHR supportedAlpha; { -1, -1 }, // VkOffset2D minSrcPosition; { -1, -1 }, // VkOffset2D maxSrcPosition; { 1, 1 }, // VkExtent2D minSrcExtent; { 0, 0 }, // VkExtent2D maxSrcExtent; { 1, 1 }, // VkOffset2D minDstPosition; { 0, 0 }, // VkOffset2D maxDstPosition; { 1, 1 }, // VkExtent2D minDstExtent; { 0, 0 }, // VkExtent2D maxDstExtent; }; tcu::ResultCollector results (m_log); result = m_vki.getDisplayPlaneCapabilitiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice theDisplayMode, // VkDisplayModeKHR mode planeIndex, // uint32_t planeIndex &planeCapabilities); // VkDisplayPlaneCapabilitiesKHR* pCapabilities results.check( result == VK_SUCCESS, string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); results.check( (planeCapabilities.supportedAlpha & unrecognizedAlphaFlags) == 0, "supportedAlpha contains unrecognized value"); results.check( (planeCapabilities.supportedAlpha & RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS) != 0u, "supportedAlpha contains no known flags"); results.check( planeCapabilities.minSrcPosition.x >= 0, "minSrcPosition.x >= 0"); results.check( planeCapabilities.minSrcPosition.y >= 0, "minSrcPosition.y >= 0"); results.check( planeCapabilities.maxSrcPosition.x >= 0, "maxSrcPosition.x >= 0"); results.check( planeCapabilities.maxSrcPosition.y >= 0, "maxSrcPosition.y >= 0"); results.check( planeCapabilities.minSrcPosition.x <= planeCapabilities.maxSrcPosition.x, "minSrcPosition.x <= maxSrcPosition.x"); results.check( planeCapabilities.minSrcPosition.y <= planeCapabilities.maxSrcPosition.y, "minSrcPosition.y <= maxSrcPosition.y"); results.check( planeCapabilities.minDstPosition.x <= planeCapabilities.maxDstPosition.x, "minDstPosition.x <= maxDstPosition.x"); results.check( planeCapabilities.minDstPosition.y <= planeCapabilities.maxDstPosition.y, "minDstPosition.y <= maxDstPosition.y"); results.check( planeCapabilities.minSrcExtent.width <= planeCapabilities.maxSrcExtent.width, "minSrcExtent.width <= maxSrcExtent.width"); results.check( planeCapabilities.minSrcExtent.height <= planeCapabilities.maxSrcExtent.height, "minSrcExtent.height <= maxSrcExtent.height"); results.check( planeCapabilities.minDstExtent.width <= planeCapabilities.maxDstExtent.width, "minDstExtent.width <= maxDstExtent.width"); results.check( planeCapabilities.minDstExtent.height <= planeCapabilities.maxDstExtent.height, "minDstExtent.height <= maxDstExtent.height"); if (results.getResult() != QP_TEST_RESULT_PASS) { m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane's " << planeIndex << " display " << displayIndex << " and mode " << modeIndex << " with capabilities " << planeCapabilities << tcu::TestLog::EndMessage; TCU_FAIL_STR(results.getMessage()); } } } } return tcu::TestStatus::pass("pass"); } namespace { struct SurfaceCountersError : public std::runtime_error { SurfaceCountersError(const std::string& what_) : std::runtime_error(what_) {} }; } /*--------------------------------------------------------------------*//*! * \brief Test display surface creation or counters. * * In the counter variant, it needs VK_EXT_display_surface_counter * and checks the available surface counters. * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testDisplaySurface (SurfaceTestKind testKind) { deUint32 planeCountReported = 0u; deUint32 planeCountTested = 0u; deUint32 planeCountRetrieved = 0u; std::vector planeProperties; bool testPerformed = false; DisplayVector displaysVector; VkResult result; std::string surfaceCountersErr; DE_ASSERT(testKind >= 0 && testKind < SURFACE_TEST_KIND_MAX_ENUM); // Check the needed extension. if (testKind == SURFACE_COUNTERS && (!isInstanceExtensionSupported(m_context.getUsedApiVersion(), m_context.getInstanceExtensions(), "VK_EXT_display_surface_counter"))) TCU_THROW(NotSupportedError, "VK_EXT_display_surface_counter not supported"); // Get displays if (!getDisplays(displaysVector)) TCU_FAIL("Failed to retrieve displays"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No displays reported"); // Get planes result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPlanePropertiesKHR* pProperties if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (planeCountReported == 0) TCU_FAIL("No planes defined"); planeCountTested = planeCountReported; if (planeCountReported > MAX_TESTED_PLANE_COUNT) { m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage; planeCountTested = MAX_TESTED_PLANE_COUNT; } planeProperties.resize(planeCountTested); planeCountRetrieved = planeCountTested; result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountRetrieved, // uint32_t* pPropertyCount &planeProperties[0]); // VkDisplayPlanePropertiesKHR* pProperties if (result != VK_SUCCESS && result != VK_INCOMPLETE ) TCU_FAIL_STR(string("Expected VK_SUCCESS or VK_INCOMPLETE expected. Have ") + getResultAsString(result)); if (planeCountRetrieved != planeCountTested) TCU_FAIL_STR( string("Number of planes requested (") + de::toString(planeCountTested) + ") does not match retrieved (" + de::toString(planeCountRetrieved) + ")"); // Iterate through displays-modes for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++) { const VkDisplayKHR display = *it; std::vector modesPropertiesForDisplay; if (!getDisplayModeProperties(display, modesPropertiesForDisplay)) TCU_FAIL("Failed to retrieve display mode properties"); for (deUint32 modeIndex = 0; modeIndex < modesPropertiesForDisplay.size(); modeIndex++) { const VkDisplayModeKHR displayMode = modesPropertiesForDisplay[modeIndex].displayMode; const VkDisplayModePropertiesKHR& modeProperties = modesPropertiesForDisplay[modeIndex]; for (deUint32 planeIndex = 0; planeIndex < planeCountTested; planeIndex++) { std::vector displaysForPlane; if (!getDisplaysForPlane(planeIndex, displaysForPlane)) TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex)); if (displaysForPlane.empty()) continue; // Iterate through displays supported by the plane for (deUint32 displayIndex = 0; displayIndex < displaysForPlane.size(); displayIndex++) { const VkDisplayKHR planeDisplay = displaysForPlane[displayIndex]; VkDisplayPlaneCapabilitiesKHR planeCapabilities; bool fullDisplayPlane; if (display == planeDisplay) { deMemset(&planeCapabilities, 0, sizeof(planeCapabilities)); result = m_vki.getDisplayPlaneCapabilitiesKHR( m_physicalDevice, // VkPhysicalDevice physicalDevice displayMode, // VkDisplayModeKHR mode planeIndex, // uint32_t planeIndex &planeCapabilities); // VkDisplayPlaneCapabilitiesKHR* pCapabilities if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); fullDisplayPlane = planeCapabilities.minDstExtent.height == modeProperties.parameters.visibleRegion.height && planeCapabilities.minDstExtent.width == modeProperties.parameters.visibleRegion.width; if (fullDisplayPlane && (planeCapabilities.supportedAlpha & VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR) != 0) { const VkDisplayPlaneAlphaFlagBitsKHR alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; const VkInstance instance = m_context.getInstance(); const VkDisplaySurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, // VkStructureType sType DE_NULL, // const void* pNext 0, // VkDisplaySurfaceCreateFlagsKHR flags displayMode, // VkDisplayModeKHR displayMode planeIndex, // uint32_t planeIndex planeProperties[planeIndex].currentStackIndex, // uint32_t planeStackIndex VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, // VkSurfaceTransformFlagBitsKHR transform 1.0f, // float globalAlpha alphaMode, // VkDisplayPlaneAlphaFlagBitsKHR alphaMode { // VkExtent2D imageExtent planeCapabilities.minDstExtent.width, planeCapabilities.minDstExtent.height } }; VkSurfaceKHR surface = DE_NULL; result = m_vki.createDisplayPlaneSurfaceKHR( instance, // VkInstance instance &createInfo, // const VkDisplaySurfaceCreateInfoKHR* pCreateInfo DE_NULL, // const VkAllocationCallbacks* pAllocator &surface); // VkSurfaceKHR* pSurface if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (surface == DE_NULL) TCU_FAIL("Invalid surface handle returned"); if (testKind == SURFACE_COUNTERS) { // Check surface counters. try { const vk::VkSurfaceCapabilities2EXT capsExt = vk::wsi::getPhysicalDeviceSurfaceCapabilities2EXT (m_vki, m_physicalDevice, surface); const vk::VkSurfaceCapabilitiesKHR capsKhr = vk::wsi::getPhysicalDeviceSurfaceCapabilities (m_vki, m_physicalDevice, surface); if (!vk::wsi::sameSurfaceCapabilities(capsKhr, capsExt)) { throw SurfaceCountersError("KHR and EXT surface capabilities do not match"); } for (deUint32 i = 0; i < sizeof(capsExt.supportedSurfaceCounters) * 8; ++i) { deUint32 mask = (1<(VK_SURFACE_COUNTER_VBLANK_EXT)) { std::ostringstream msg; msg << "Invalid bit set in supportedSurfaceCounters: 0x" << std::hex << mask; throw SurfaceCountersError(msg.str()); } } } } catch(const SurfaceCountersError& err) { surfaceCountersErr = err.what(); } } m_vki.destroySurfaceKHR( instance, // VkInstance instance surface, // VkSurfaceKHR* pSurface DE_NULL); // const VkAllocationCallbacks* pAllocator testPerformed = true; } } } } } } if (!testPerformed) TCU_THROW(NotSupportedError, "Cannot find suitable parameters for the test"); return ((surfaceCountersErr.empty()) ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail(surfaceCountersErr)); } /*--------------------------------------------------------------------*//*! * \brief Display enumeration coverage test using VK_KHR_get_display_properties2 * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayProperties2KHR (void) { deUint32 displayCountReported = 0u; deUint32 displayCountToTest = 0u; tcu::ResultCollector results (m_log); VkResult result; result = m_vki.getPhysicalDeviceDisplayProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &displayCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayProperties2KHR* pProperties if ( result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY && result != VK_ERROR_OUT_OF_DEVICE_MEMORY ) { TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); } if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (displayCountReported == 0) TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str()); displayCountToTest = displayCountReported; if (displayCountReported > MAX_TESTED_DISPLAY_COUNT) { m_log << tcu::TestLog::Message << "Number of displays reported is too high " << displayCountReported << ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT << tcu::TestLog::EndMessage; displayCountToTest = MAX_TESTED_DISPLAY_COUNT; } // Test the call correctly writes data in various size arrays for (deUint32 displayCountRequested = 0; displayCountRequested < displayCountToTest + 2; displayCountRequested++) { const deUint32 displayCountExpected = std::min(displayCountRequested, displayCountReported); const VkDisplayPropertiesKHR nonUpdatedDisplayProperties = { // Most values are set to fail the test to make sure driver updates them DE_NULL, // VkDisplayKHR display DE_NULL, // const char* displayName {0, 0}, // VkExtent2D physicalDimensions {0, 0}, // VkExtent2D physicalResolution ~RECOGNIZED_SURFACE_TRANSFORM_FLAGS, // VkSurfaceTransformFlagsKHR supportedTransforms (vk::VkBool32)(VK_TRUE + 1), // VkBool32 planeReorderPossible (vk::VkBool32)(VK_TRUE + 1) // VkBool32 persistentContent }; const VkStructureType queryStructureType = VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR; const VkDisplayProperties2KHR nonUpdatedDisplayProperties2 = { queryStructureType, // VkStructureType sType DE_NULL, // void* pNext nonUpdatedDisplayProperties // VkDisplayPropertiesKHR displayProperties }; const VkDisplayKHR canaryDisplay = static_cast(0xABCDEF11); const deUint32 canaryItemCount = 1; std::vector displaysProps2 (displayCountRequested + canaryItemCount, nonUpdatedDisplayProperties2); deUint32 displayCountRetrieved = displayCountRequested; DisplaySet displaySet; displaysProps2[displayCountExpected].displayProperties.display = canaryDisplay; result = m_vki.getPhysicalDeviceDisplayProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &displayCountRetrieved, // uint32_t* pPropertyCount &displaysProps2[0]); // VkDisplayProperties2KHR* pProperties // Check amount of data written equals to expected if (displayCountRetrieved != displayCountExpected) TCU_FAIL_STR( string("displayCountRetrieved != displayCountExpected, ") + de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected)); if (displayCountRequested >= displayCountReported) { if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); } else { if (result != VK_INCOMPLETE) TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); } // Check the driver has written something for (deUint32 displayIndex = 0; displayIndex < displayCountRetrieved; displayIndex++) { const VkDisplayProperties2KHR& properties2 = displaysProps2[displayIndex]; const VkDisplayPropertiesKHR& properties = properties2.displayProperties; displaySet.insert(properties.display); results.check( properties2.sType == queryStructureType, "sType has changed to " + de::toString(properties2.sType)); results.check( properties2.pNext == DE_NULL, "pNext has changed to " + de::toString(properties2.pNext)); validateDisplayProperties(results, properties, nonUpdatedDisplayProperties); if (results.getResult() != QP_TEST_RESULT_PASS) { m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for display " << displayIndex << " with properties " << properties2 << " non updated display properties are " << nonUpdatedDisplayProperties2 << tcu::TestLog::EndMessage; TCU_FAIL_STR(results.getMessage()); } } // Check the driver has not written more than requested if (displaysProps2[displayCountExpected].displayProperties.display != canaryDisplay) TCU_FAIL("Memory damage detected: driver has written more than expected"); // Check display handle uniqueness if (displaySet.size() != displayCountRetrieved) TCU_FAIL("Display handle duplication detected"); } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Plane enumeration coverage test using VK_KHR_get_display_properties2 * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlaneProperties2KHR (void) { DisplayVector displaysVector; DisplaySet displaySet; deUint32 planeCountReported = 0u; deUint32 planeCountTested = 0u; tcu::ResultCollector results (m_log); VkResult result; // Create a list of displays available if (!getDisplays2(displaysVector)) TCU_FAIL("Failed to retrieve displays"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No displays reported"); displaySet = DisplaySet(displaysVector.begin(), displaysVector.end()); // Get planes to test result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPlaneProperties2KHR* pProperties if ( result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY && result != VK_ERROR_OUT_OF_DEVICE_MEMORY ) { TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result)); } if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (planeCountReported == 0) TCU_THROW(ResourceError, "Cannot perform test: no planes found"); planeCountTested = planeCountReported; if (planeCountReported > MAX_TESTED_PLANE_COUNT) { m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage; planeCountTested = MAX_TESTED_PLANE_COUNT; } // Test the call correctly writes data in various size arrays for (deUint32 planeCountRequested = 0; planeCountRequested < planeCountTested + 2; planeCountRequested++) { const deUint32 planeCountExpected = std::min(planeCountRequested, planeCountReported); const VkDisplayPlanePropertiesKHR nonUpdatedPlaneProperties = { // Most values are set to fail the test to make sure driver updates them DE_NULL, // VkDisplayKHR currentDisplay planeCountReported // deUint32 currentStackIndex }; const VkStructureType queryStructureType = VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR; const VkDisplayPlaneProperties2KHR nonUpdatedPlaneProperties2 = { queryStructureType, // VkStructureType sType DE_NULL, // void* pNext nonUpdatedPlaneProperties // VkDisplayPlanePropertiesKHR displayPlaneProperties }; const VkDisplayKHR canaryDisplay = static_cast(0xABCDEF11); const deUint32 canaryItemCount = 1; std::vector planeProps2 (planeCountRequested + canaryItemCount, nonUpdatedPlaneProperties2); deUint32 planeCountRetrieved = planeCountRequested; planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay = canaryDisplay; result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountRetrieved, // uint32_t* pPropertyCount &planeProps2[0]); // VkDisplayPlaneProperties2KHR* pProperties // Check amount of data written equals to expected if (planeCountRetrieved != planeCountExpected) TCU_FAIL_STR( string("planeCountRetrieved != planeCountExpected, ") + de::toString(planeCountRetrieved) + " != " + de::toString(planeCountExpected)); if (planeCountRequested >= planeCountReported) { if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); } else { if (result != VK_INCOMPLETE) TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); } // Check the driver has written something for (deUint32 planeIndex = 0; planeIndex < planeCountRetrieved; planeIndex++) { const VkDisplayPlaneProperties2KHR& properties2 = planeProps2[planeIndex]; const VkDisplayPlanePropertiesKHR& properties = properties2.displayPlaneProperties; results.check( properties2.sType == queryStructureType, "sType has changed to " + de::toString(properties2.sType)); results.check( properties2.pNext == DE_NULL, "pNext has changed to " + de::toString(properties2.pNext)); validateDisplayPlaneProperties(results, properties, nonUpdatedPlaneProperties, displaySet); if (results.getResult() != QP_TEST_RESULT_PASS) { m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane " << planeIndex << " with properties " << properties2 << tcu::TestLog::EndMessage; TCU_FAIL_STR(results.getMessage()); } } // Check the driver has not written more than requested if (planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay != canaryDisplay) TCU_FAIL("Memory damage detected: driver has written more than expected"); } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Display-plane capabilities coverage test using VK_KHR_get_display_properties2 * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneCapabilities2KHR (void) { deUint32 planeCountReported = 0u; VkResult result; result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayPlaneProperties2KHR* pProperties if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); if (planeCountReported == 0) TCU_THROW(NotSupportedError, "No display plane reported"); if (planeCountReported > MAX_TESTED_PLANE_COUNT) { m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage; planeCountReported = MAX_TESTED_PLANE_COUNT; } for (deUint32 planeIndex = 0; planeIndex < planeCountReported; planeIndex++) { std::vector displaysForPlane; if (!getDisplaysForPlane(planeIndex, displaysForPlane)) TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex)); if (displaysForPlane.empty()) continue; // Check the driver has written something for (deUint32 displayIndex = 0; displayIndex < displaysForPlane.size(); displayIndex++) { const VkDisplayKHR display = displaysForPlane[displayIndex]; std::vector modesPropertiesForDisplay; if (!getDisplayModeProperties2(display, modesPropertiesForDisplay)) TCU_FAIL("Failed to retrieve display mode properties"); for (deUint32 modeIndex = 0; modeIndex < modesPropertiesForDisplay.size(); modeIndex++) { const VkDisplayModeKHR displayMode = modesPropertiesForDisplay[modeIndex].displayModeProperties.displayMode; const deUint32 unrecognizedAlphaFlags = ~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS; const VkDisplayPlaneInfo2KHR planeInfo2 = { VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR, // VkStructureType sType DE_NULL, // const void* pNext displayMode, // VkDisplayModeKHR mode planeIndex // uint32_t planeIndex }; VkDisplayPlaneCapabilitiesKHR planeCapabilities = { unrecognizedAlphaFlags, // VkDisplayPlaneAlphaFlagsKHR supportedAlpha { -1, -1 }, // VkOffset2D minSrcPosition { -1, -1 }, // VkOffset2D maxSrcPosition { 1, 1 }, // VkExtent2D minSrcExtent { 0, 0 }, // VkExtent2D maxSrcExtent { 1, 1 }, // VkOffset2D minDstPosition { 0, 0 }, // VkOffset2D maxDstPosition { 1, 1 }, // VkExtent2D minDstExtent { 0, 0 }, // VkExtent2D maxDstExtent }; const VkStructureType queryStructureType = VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR; VkDisplayPlaneCapabilities2KHR planeCapabilities2 = { queryStructureType, // VkStructureType sType DE_NULL, // void* pNext planeCapabilities // VkDisplayPlaneCapabilitiesKHR capabilities }; tcu::ResultCollector results (m_log); result = m_vki.getDisplayPlaneCapabilities2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice &planeInfo2, // const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo &planeCapabilities2); // VkDisplayPlaneCapabilities2KHR* pCapabilities results.check( result == VK_SUCCESS, string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); results.check( planeCapabilities2.sType == queryStructureType, "sType has changed to " + de::toString(planeCapabilities2.sType)); results.check( planeCapabilities2.pNext == DE_NULL, "pNext has changed to " + de::toString(planeCapabilities2.pNext)); // Validate results returned by driver in planeCapabilities2 using non-updated planeCapabilities validateDisplayPlaneCapabilities(results, planeCapabilities2.capabilities, planeCapabilities); if (results.getResult() != QP_TEST_RESULT_PASS) { m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane's " << planeIndex << " display " << displayIndex << " and mode " << modeIndex << " with capabilities " << planeCapabilities2 << tcu::TestLog::EndMessage; TCU_FAIL_STR(results.getMessage()); } } } } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Display mode properties coverage test using VK_KHR_get_display_properties2 * * Throws an exception on fail. * * \return tcu::TestStatus::pass on success *//*--------------------------------------------------------------------*/ tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModeProperties2KHR (void) { VkResult result; tcu::ResultCollector results (m_log); DisplayVector displaysVector; if (!getDisplays2(displaysVector)) TCU_FAIL("Failed to retrieve displays list"); if (displaysVector.empty()) TCU_THROW(NotSupportedError, "No displays reported"); for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++) { VkDisplayKHR display = *it; deUint32 modesCountReported = 0u; result = m_vki.getDisplayModeProperties2KHR( m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &modesCountReported, // uint32_t* pPropertyCount DE_NULL); // VkDisplayModeProperties2KHR* pProperties // Test the call correctly writes data in various size arrays for (deUint32 modesCountRequested = 0; modesCountRequested < modesCountReported + 2; modesCountRequested = nextTestNumber(modesCountRequested, modesCountReported + 2)) { const deUint32 modesCountExpected = std::min(modesCountRequested, modesCountReported); const VkDisplayModeKHR nullDisplayMode = DE_NULL; const VkDisplayModePropertiesKHR nonUpdatedModeProperties = { nullDisplayMode, // VkDisplayModeKHR displayMode { // VkDisplayModeParametersKHR parameters {0, 0}, // VkExtent2D visibleRegion 0 // uint32_t refreshRate } }; const VkStructureType queryStructureType = VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR; const VkDisplayModeProperties2KHR nonUpdatedModeProperties2 = { queryStructureType, // VkStructureType sType DE_NULL, // void* pNext nonUpdatedModeProperties // VkDisplayModePropertiesKHR displayModeProperties }; const VkDisplayModeKHR canaryDisplayMode = static_cast(0xABCDEF11); const deUint32 canaryItemCount = 1; std::vector modesProperties2 (modesCountRequested + canaryItemCount, nonUpdatedModeProperties2); deUint32 modesCountRetrieved = modesCountRequested; modesProperties2[modesCountExpected].displayModeProperties.displayMode = canaryDisplayMode; result = m_vki.getDisplayModeProperties2KHR(m_physicalDevice, // VkPhysicalDevice physicalDevice display, // VkDisplayKHR display &modesCountRetrieved, // uint32_t* pPropertyCount &modesProperties2[0]); // VkDisplayModeProperties2KHR* pProperties // Check amount of data written equals to expected if (modesCountRetrieved != modesCountExpected) TCU_FAIL_STR( string("modesCountRetrieved != modesCountExpected, ") + de::toString(modesCountRetrieved) + " != " + de::toString(modesCountExpected)); if (modesCountRequested >= modesCountReported) { if (result != VK_SUCCESS) TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result)); } else { if (result != VK_INCOMPLETE) TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result)); } // Check the driver has written something for (deUint32 modeIndex = 0; modeIndex < modesCountExpected; modeIndex++) { const VkDisplayModeProperties2KHR& properties2 = modesProperties2[modeIndex]; const VkDisplayModePropertiesKHR& properties = properties2.displayModeProperties; results.check( properties2.sType == queryStructureType, "sType has changed to " + de::toString(properties2.sType)); results.check( properties2.pNext == DE_NULL, "pNext has changed to " + de::toString(properties2.pNext)); validateDisplayModeProperties(results, properties, nonUpdatedModeProperties); if (results.getResult() != QP_TEST_RESULT_PASS) { m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for mode " << modeIndex << " with properties " << properties2 << " non updated mode properties are " << nonUpdatedModeProperties2 << tcu::TestLog::EndMessage; TCU_FAIL_STR(results.getMessage()); } } // Check the driver has not written more than requested if (modesProperties2[modesCountExpected].displayModeProperties.displayMode != canaryDisplayMode) TCU_FAIL("Memory damage detected: driver has written more than expected"); } } return tcu::TestStatus::pass("pass"); } /*--------------------------------------------------------------------*//*! * \brief Display coverage tests case class *//*--------------------------------------------------------------------*/ class DisplayCoverageTestsCase : public vkt::TestCase { public: DisplayCoverageTestsCase (tcu::TestContext &context, const char *name, const char *description, const DisplayIndexTest testId) : TestCase (context, name, description) , m_testId (testId) { } private: const DisplayIndexTest m_testId; vkt::TestInstance* createInstance (vkt::Context& context) const { return new DisplayCoverageTestInstance(context, m_testId); } }; /*--------------------------------------------------------------------*//*! * \brief Adds a test into group *//*--------------------------------------------------------------------*/ static void addTest (tcu::TestCaseGroup* group, const DisplayIndexTest testId, const char* name, const char* description) { tcu::TestContext& testCtx = group->getTestContext(); group->addChild(new DisplayCoverageTestsCase(testCtx, name, description, testId)); } /*--------------------------------------------------------------------*//*! * \brief Adds VK_KHR_display and VK_KHR_display_swapchain extension tests into group *//*--------------------------------------------------------------------*/ void createDisplayCoverageTests (tcu::TestCaseGroup* group) { // VK_KHR_display extension tests addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES, "get_display_properties", "Display enumeration coverage test"); addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES, "get_display_plane_properties", "Planes enumeration coverage test"); addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY, "get_display_plane_supported_displays", "Display plane support coverage test"); addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE, "get_display_mode_properties", "Display mode properties coverage test"); addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE, "create_display_mode", "Create display mode coverage test"); addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES, "get_display_plane_capabilities", "Display-plane capabilities coverage test"); addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE, "create_display_plane_surface", "Create display plane surface coverage test"); addTest(group, DISPLAY_TEST_INDEX_SURFACE_COUNTERS, "surface_counters", "Display plane surface counters test"); // VK_KHR_get_display_properties2 extension tests addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2, "get_display_properties2", "Display enumeration coverage test using VK_KHR_get_display_properties2"); addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2, "get_display_plane_properties2", "Planes enumeration coverage test using VK_KHR_get_display_properties2"); addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2, "get_display_mode_properties2", "Display mode properties coverage test using VK_KHR_get_display_properties2"); addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2, "get_display_plane_capabilities2", "Display-plane capabilities coverage test using VK_KHR_get_display_properties2"); } } //wsi } //vkt