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