| /*------------------------------------------------------------------------ |
| * 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 <set> |
| #include <map> |
| #include <limits> |
| #include <sstream> |
| #include <stdexcept> |
| |
| 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 <typename Type> |
| class BinaryCompare |
| { |
| public: |
| bool operator() (const Type& a, const Type& b) const |
| { |
| return deMemCmp(&a, &b, sizeof(Type)) < 0; |
| } |
| }; |
| |
| typedef std::set<vk::VkDisplayKHR, BinaryCompare<vk::VkDisplayKHR> > DisplaySet; |
| typedef std::vector<vk::VkDisplayKHR> DisplayVector; |
| typedef std::vector<vk::VkDisplayModePropertiesKHR> DisplayModePropertiesVector; |
| typedef std::vector<vk::VkDisplayModeProperties2KHR> DisplayModeProperties2Vector; |
| |
| const deUint32 DEUINT32_MAX = std::numeric_limits<deUint32>::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<endIndex; nextTestNumber(i, endIndex)) |
| * with endIndex = 4 generates 0,1,2,3 |
| * with endIndex = 9 generates 0,1,2,6,7,8 |
| * |
| * \param index Current iterator value |
| * \param endIndex First number out of iteration sequence |
| * \return new iterator value |
| *//*--------------------------------------------------------------------*/ |
| deUint32 nextTestNumber (deUint32 index, deUint32 endIndex) |
| { |
| deUint32 result; |
| |
| if (endIndex > 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<VkDisplayPropertiesKHR> 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<VkDisplayProperties2KHR> 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<VkDisplayKHR>(0xABCDEF11); |
| const deUint32 canaryItemCount = 1; |
| std::vector<VkDisplayPropertiesKHR> 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<VkDisplayKHR>(0xABCDEF11); |
| const deUint32 canaryItemCount = 1; |
| std::vector<VkDisplayPlanePropertiesKHR> 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<VkDisplayKHR>(0xABCDEF11); |
| const deUint32 canaryItemCount = 1; |
| std::vector<VkDisplayKHR> 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<VkDisplayModeKHR>(0xABCDEF11); |
| const deUint32 canaryItemCount = 1; |
| std::vector<VkDisplayModePropertiesKHR> 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<VkDisplayKHR> 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<VkDisplayModePropertiesKHR> 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<VkDisplayPlanePropertiesKHR> 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<VkDisplayModePropertiesKHR> 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<VkDisplayKHR> 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<<i); |
| if (capsExt.supportedSurfaceCounters & mask) |
| { |
| if (mask != static_cast<deUint32>(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<VkDisplayKHR>(0xABCDEF11); |
| const deUint32 canaryItemCount = 1; |
| std::vector<VkDisplayProperties2KHR> 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<VkDisplayKHR>(0xABCDEF11); |
| const deUint32 canaryItemCount = 1; |
| std::vector<VkDisplayPlaneProperties2KHR> 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<VkDisplayKHR> 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<VkDisplayModeProperties2KHR> 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<VkDisplayModeKHR>(0xABCDEF11); |
| const deUint32 canaryItemCount = 1; |
| std::vector<VkDisplayModeProperties2KHR> 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 |
| |