• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 coverage tests for extensions VK_KHR_display,
22  *        VK_KHR_get_display_properties2
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktWsiDisplayTests.hpp"
26 
27 #include "vktTestCase.hpp"
28 #include "vkStrUtil.hpp"
29 #include "vkPrograms.hpp"
30 #include "vkRef.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkWsiUtil.hpp"
33 
34 #include "tcuDefs.hpp"
35 #include "tcuTestLog.hpp"
36 #include "tcuResultCollector.hpp"
37 
38 #include "deMemory.h"
39 #include "deSTLUtil.hpp"
40 #include "deStringUtil.hpp"
41 
42 #include <set>
43 #include <map>
44 #include <limits>
45 #include <sstream>
46 #include <stdexcept>
47 
48 namespace vkt
49 {
50 namespace wsi
51 {
52 using namespace vk;
53 using std::vector;
54 using std::map;
55 using std::set;
56 using std::string;
57 
58 #ifndef TCU_FAIL_STR
59 	#define TCU_FAIL_STR(MSG) TCU_FAIL(string(MSG).c_str())
60 #endif
61 
62 enum DisplayIndexTest
63 {
64 	DISPLAY_TEST_INDEX_START,
65 	DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES,
66 	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES,
67 	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY,
68 	DISPLAY_TEST_INDEX_GET_DISPLAY_MODE,
69 	DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE,
70 	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES,
71 	DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE,
72 	DISPLAY_TEST_INDEX_SURFACE_COUNTERS,
73 	DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2,
74 	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2,
75 	DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2,
76 	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2,
77 	DISPLAY_TEST_INDEX_LAST
78 };
79 
80 template <typename Type>
81 class BinaryCompare
82 {
83 public:
operator ()(const Type & a,const Type & b) const84 	bool operator() (const Type& a, const Type& b) const
85 	{
86 		return deMemCmp(&a, &b, sizeof(Type)) < 0;
87 	}
88 };
89 
90 typedef std::set<vk::VkDisplayKHR, BinaryCompare<vk::VkDisplayKHR> >	DisplaySet;
91 typedef std::vector<vk::VkDisplayKHR>									DisplayVector;
92 typedef std::vector<vk::VkDisplayModePropertiesKHR>						DisplayModePropertiesVector;
93 typedef std::vector<vk::VkDisplayModeProperties2KHR>					DisplayModeProperties2Vector;
94 
95 const deUint32 DEUINT32_MAX = std::numeric_limits<deUint32>::max();
96 
97 const deUint32 RECOGNIZED_SURFACE_TRANSFORM_FLAGS =
98 														  vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
99 														| vk::VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR
100 														| vk::VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR
101 														| vk::VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR
102 														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR
103 														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR
104 														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR
105 														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR
106 														| vk::VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
107 
108 const deUint32 RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS =
109 														  VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR
110 														| VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR
111 														| VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR
112 														| VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR;
113 enum DisplayMaxTestedConsts
114 {
115 	MAX_TESTED_DISPLAY_COUNT	= 16,
116 	MAX_TESTED_PLANE_COUNT		= 16,
117 };
118 
119 /*--------------------------------------------------------------------*//*!
120  * \brief Return Vulkan result name or code as std::string.
121  *
122  * \param result Vulkan code to convert to string
123  * \return Vulkun result code name or code number as std::string
124  *//*--------------------------------------------------------------------*/
getResultAsString(vk::VkResult result)125 std::string getResultAsString (vk::VkResult result)
126 {
127 	const char* resultAsChar = vk::getResultName(result);
128 
129 	if (resultAsChar != DE_NULL)
130 		return std::string(resultAsChar);
131 	else
132 		return de::toString(result);
133 }
134 
135 /*--------------------------------------------------------------------*//*!
136  * \brief Moves test index to next test skipping middle tests.
137  *
138  * Gets first 3 tests and last 3 tests on long sequences.
139  * After test number 2 moves index value to endIndex - 3.
140  * Shortens the number of tests executed by skipping middle tests.
141  *
142  * Example:
143  * for (i=0; i<endIndex; nextTestNumber(i, endIndex))
144  * with endIndex = 4 generates 0,1,2,3
145  * with endIndex = 9 generates 0,1,2,6,7,8
146  *
147  * \param index    Current iterator value
148  * \param endIndex First number out of iteration sequence
149  * \return new iterator value
150  *//*--------------------------------------------------------------------*/
nextTestNumber(deUint32 index,deUint32 endIndex)151 deUint32 nextTestNumber (deUint32 index, deUint32 endIndex)
152 {
153 	deUint32 result;
154 
155 	if (endIndex > 6 && index == 2)
156 		result = endIndex - 3;
157 	else
158 		result = index + 1;
159 
160 	return result;
161 }
162 
163 /*--------------------------------------------------------------------*//*!
164  * \brief Vulkan VK_KHR_display extensions coverage tests
165  *//*--------------------------------------------------------------------*/
166 class DisplayCoverageTestInstance : public TestInstance
167 {
168 public:
169 								DisplayCoverageTestInstance						(Context& context, const DisplayIndexTest testId);
170 private:
171 	typedef void				(DisplayCoverageTestInstance::*EachSurfaceFunctionPtr)
172 																				(VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties);
173 
174 	bool						getDisplays										(DisplayVector& displays);
175 	bool						getDisplaysForPlane								(deUint32 plane, DisplayVector& displays);
176 	bool						getDisplayModeProperties						(VkDisplayKHR display, DisplayModePropertiesVector& modeProperties);
177 
178 	bool						getDisplays2									(DisplayVector& displays);
179 	bool						getDisplayModeProperties2						(VkDisplayKHR display, DisplayModeProperties2Vector& modeProperties);
180 
181 	void						validateDisplayProperties						(	tcu::ResultCollector&					results,
182 																					const VkDisplayPropertiesKHR&			toValidate,
183 																					const VkDisplayPropertiesKHR&			nonUpdated);
184 
185 	void						validateDisplayPlaneProperties					(	tcu::ResultCollector&					results,
186 																					const VkDisplayPlanePropertiesKHR&		toValidate,
187 																					const VkDisplayPlanePropertiesKHR&		nonUpdated,
188 																					DisplaySet&								displaySet);
189 
190 	void						validateDisplayPlaneCapabilities				(	tcu::ResultCollector&					results,
191 																					const VkDisplayPlaneCapabilitiesKHR&	toValidate,
192 																					const VkDisplayPlaneCapabilitiesKHR&	nonUpdated);
193 
194 	void						validateDisplayModeProperties					(	tcu::ResultCollector&					results,
195 																					const VkDisplayModePropertiesKHR&		toValidate,
196 																					const VkDisplayModePropertiesKHR&		nonUpdated);
197 
198 	// VK_KHR_display extension tests
199 	tcu::TestStatus				testGetPhysicalDeviceDisplayPropertiesKHR		(void);
200 	tcu::TestStatus				testGetPhysicalDeviceDisplayPlanePropertiesKHR	(void);
201 	tcu::TestStatus				testGetDisplayPlaneSupportedDisplaysKHR			(void);
202 	tcu::TestStatus				testGetDisplayModePropertiesKHR					(void);
203 	tcu::TestStatus				testCreateDisplayModeKHR						(void);
204 	tcu::TestStatus				testGetDisplayPlaneCapabilitiesKHR				(void);
205 
206 	enum SurfaceTestKind
207 	{
208 		SURFACE_CREATE = 0,
209 		SURFACE_COUNTERS,
210 		SURFACE_TEST_KIND_MAX_ENUM
211 	};
212 
213 	tcu::TestStatus				testDisplaySurface								(SurfaceTestKind testKind);
214 
215 	// VK_KHR_get_display_properties2 extension tests
216 	tcu::TestStatus				testGetPhysicalDeviceDisplayProperties2KHR		(void);
217 	tcu::TestStatus				testGetPhysicalDeviceDisplayPlaneProperties2KHR	(void);
218 	tcu::TestStatus				testGetDisplayModeProperties2KHR				(void);
219 	tcu::TestStatus				testGetDisplayPlaneCapabilities2KHR				(void);
220 
221 	tcu::TestStatus				iterate											(void);
222 
223 	void						testCreateSharedSwapchainsKHRforSurface			(VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties);
224 
225 	const InstanceInterface&	m_vki;
226 	const DeviceInterface&		m_vkd;
227 	tcu::TestLog&				m_log;
228 	const VkPhysicalDevice		m_physicalDevice;
229 	const DisplayIndexTest		m_testId;
230 };
231 
232 
233 /*--------------------------------------------------------------------*//*!
234  * \brief DisplayCoverageTestInstance constructor
235  *
236  * Initializes DisplayCoverageTestInstance object
237  *
238  * \param context    Context object
239  * \param parameters Test parameters structure
240  *//*--------------------------------------------------------------------*/
DisplayCoverageTestInstance(Context & context,const DisplayIndexTest testId)241 DisplayCoverageTestInstance::DisplayCoverageTestInstance (Context& context, const DisplayIndexTest testId)
242 	: TestInstance		(context)
243 	, m_vki				(m_context.getInstanceInterface())
244 	, m_vkd				(m_context.getDeviceInterface())
245 	, m_log				(m_context.getTestContext().getLog())
246 	, m_physicalDevice	(m_context.getPhysicalDevice())
247 	, m_testId			(testId)
248 {
249 	const std::string extensionName("VK_KHR_display");
250 
251 	if(!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionName))
252 		TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
253 
254 	switch (m_testId)
255 	{
256 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2:
257 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2:
258 		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2:
259 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2:
260 		{
261 			const std::string extensionNameAddition("VK_KHR_get_display_properties2");
262 
263 			if(!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionNameAddition))
264 				TCU_THROW(NotSupportedError, std::string(extensionNameAddition + " is not supported").c_str());
265 
266 			break;
267 		}
268 
269 		default:
270 		{
271 			break;
272 		}
273 	}
274 }
275 
276 /*--------------------------------------------------------------------*//*!
277  * \brief Step forward test execution
278  *
279  * \return true if application should call iterate() again and false
280  *         if test execution session is complete.
281  *//*--------------------------------------------------------------------*/
iterate(void)282 tcu::TestStatus DisplayCoverageTestInstance::iterate (void)
283 {
284 	switch (m_testId)
285 	{
286 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES:					return testGetPhysicalDeviceDisplayPropertiesKHR();			break;
287 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES:						return testGetPhysicalDeviceDisplayPlanePropertiesKHR();	break;
288 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY:	return testGetDisplayPlaneSupportedDisplaysKHR();			break;
289 		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE:						return testGetDisplayModePropertiesKHR();					break;
290 		case DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE:					return testCreateDisplayModeKHR();							break;
291 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES:			return testGetDisplayPlaneCapabilitiesKHR();				break;
292 		case DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE:			return testDisplaySurface(SURFACE_CREATE);					break;
293 		case DISPLAY_TEST_INDEX_SURFACE_COUNTERS:						return testDisplaySurface(SURFACE_COUNTERS);				break;
294 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2:				return testGetPhysicalDeviceDisplayProperties2KHR();		break;
295 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2:					return testGetPhysicalDeviceDisplayPlaneProperties2KHR();	break;
296 		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2:						return testGetDisplayModeProperties2KHR();					break;
297 		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2:		return testGetDisplayPlaneCapabilities2KHR();				break;
298 		default:
299 		{
300 			DE_FATAL("Impossible");
301 		}
302 	}
303 
304 	TCU_FAIL("Invalid test identifier");
305 }
306 
307 /*--------------------------------------------------------------------*//*!
308  * \brief Fills vector with available displays. Clears passed vector at start.
309  *
310  * \param displays The vector filled with display handles
311  * \return true on success, false on error
312  *//*--------------------------------------------------------------------*/
getDisplays(DisplayVector & displays)313 bool DisplayCoverageTestInstance::getDisplays (DisplayVector& displays)
314 {
315 	deUint32							countReported	=	0u;
316 	deUint32							countRetrieved	=	0u;
317 	std::vector<VkDisplayPropertiesKHR>	displaysProps;
318 	VkResult							result;
319 
320 	displays.clear();
321 
322 	result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
323 															&countReported,		// uint32_t*				pPropertyCount
324 															DE_NULL);			// VkDisplayPropertiesKHR*	pProperties
325 
326 	if (result != VK_SUCCESS)
327 	{
328 		m_log	<< tcu::TestLog::Message
329 				<< "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result)
330 				<< " reported items count " << countReported
331 				<< tcu::TestLog::EndMessage;
332 
333 		return false;
334 	}
335 
336 	if (!countReported)
337 		TCU_THROW(NotSupportedError, "No displays reported");
338 
339 	displaysProps.resize(countReported);
340 
341 	countRetrieved = countReported;
342 
343 	result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
344 															&countRetrieved,	// uint32_t*				pPropertyCount
345 															&displaysProps[0]);	// VkDisplayPropertiesKHR*	pProperties
346 
347 	if (result != VK_SUCCESS || countRetrieved > countReported)
348 	{
349 		m_log	<< tcu::TestLog::Message
350 				<< "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result)
351 				<< " reported items count " << countReported
352 				<< " retrieved items count " << countRetrieved
353 				<< tcu::TestLog::EndMessage;
354 
355 		return false;
356 	}
357 
358 	displays.reserve(countRetrieved);
359 
360 	for (deUint32	displayIndex = 0;
361 					displayIndex < countRetrieved;
362 					displayIndex++)
363 	{
364 		const VkDisplayKHR display = displaysProps[displayIndex].display;
365 
366 		if (display == DE_NULL)
367 		{
368 			displays.clear();
369 
370 			return false;
371 		}
372 
373 		displays.push_back(display);
374 	}
375 
376 	return true;
377 }
378 
379 /*--------------------------------------------------------------------*//*!
380  * \brief Fills vector with available displays for plane specified.
381  *
382  * Clears passed vector at start and on error.
383  *
384  * \param plane		The plane to get displays for
385  * \param displays	The vector filled with display handles
386  * \return true on success, false on error
387  *//*--------------------------------------------------------------------*/
getDisplaysForPlane(deUint32 plane,DisplayVector & displays)388 bool DisplayCoverageTestInstance::getDisplaysForPlane(deUint32 plane, DisplayVector& displays)
389 {
390 	deUint32	countReported	=	0u;
391 	deUint32	countRetrieved	=	0u;
392 	VkResult	result;
393 
394 	displays.clear();
395 
396 	result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,	// VkPhysicalDevice	physicalDevice
397 														plane,				// uint32_t			planeIndex
398 														&countReported,		// uint32_t*		pDisplayCount
399 														DE_NULL);			// VkDisplayKHR*	pDisplays
400 
401 	if (result != VK_SUCCESS)
402 	{
403 		m_log	<< tcu::TestLog::Message
404 				<< "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result)
405 				<< " for plane " << plane
406 				<< " reported items count " << countReported
407 				<< tcu::TestLog::EndMessage;
408 
409 		return false;
410 	}
411 
412 	displays.resize(countReported);
413 
414 	countRetrieved = countReported;
415 
416 	result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,	// VkPhysicalDevice	physicalDevice
417 														plane,				// uint32_t			planeIndex
418 														&countRetrieved,	// uint32_t*		pDisplayCount
419 														&displays[0]);		// VkDisplayKHR*	pDisplays
420 
421 	if (result != VK_SUCCESS || countRetrieved > countReported)
422 	{
423 		m_log	<< tcu::TestLog::Message
424 				<< "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result)
425 				<< " for plane " << plane
426 				<< " reported items count " << countReported
427 				<< " retrieved items count " << countRetrieved
428 				<< tcu::TestLog::EndMessage;
429 
430 		displays.clear();
431 
432 		return false;
433 	}
434 
435 	if (countRetrieved < countReported)
436 		displays.resize(countRetrieved);
437 
438 	return true;
439 }
440 
441 /*--------------------------------------------------------------------*//*!
442  * \brief Fills vector with available modes properties for display specified.
443  *
444  * Clears passed vector at start and on error.
445  *
446  * \param display	The display to get modes for
447  * \param modes		The vector filled with display mode properties structures
448  * \return true on success, false on error
449  *//*--------------------------------------------------------------------*/
getDisplayModeProperties(VkDisplayKHR display,DisplayModePropertiesVector & modeProperties)450 bool DisplayCoverageTestInstance::getDisplayModeProperties(VkDisplayKHR display, DisplayModePropertiesVector& modeProperties)
451 {
452 	deUint32	countReported	=	0u;
453 	deUint32	countRetrieved	=	0u;
454 	VkResult	result;
455 
456 	modeProperties.clear();
457 
458 	result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
459 												display,				// VkDisplayKHR					display
460 												&countReported,			// uint32_t*					pPropertyCount
461 												DE_NULL);				// VkDisplayModePropertiesKHR*	pProperties
462 
463 	if (result != VK_SUCCESS)
464 	{
465 		m_log	<< tcu::TestLog::Message
466 				<< "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result)
467 				<< " for display " << display
468 				<< " reported items count " << countReported
469 				<< tcu::TestLog::EndMessage;
470 
471 		return false;
472 	}
473 
474 	modeProperties.resize(countReported);
475 
476 	countRetrieved = countReported;
477 
478 	result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
479 												display,				// VkDisplayKHR					display
480 												&countRetrieved,		// uint32_t*					pPropertyCount
481 												&modeProperties[0]);	// VkDisplayModePropertiesKHR*	pProperties
482 
483 	if (result != VK_SUCCESS || countRetrieved > countReported)
484 	{
485 		m_log	<< tcu::TestLog::Message
486 				<< "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result)
487 				<< " for display " << display
488 				<< " reported items count " << countReported
489 				<< " retrieved items count " << countReported
490 				<< tcu::TestLog::EndMessage;
491 
492 		modeProperties.clear();
493 
494 		return false;
495 	}
496 
497 	if (countRetrieved < countReported)
498 		modeProperties.resize(countRetrieved);
499 
500 	return true;
501 }
502 
503 /*--------------------------------------------------------------------*//*!
504  * \brief Fills vector with available displays. Clears passed vector at start.
505  *
506  * Uses VK_KHR_get_display_properties2 extension API.
507  * Clears passed vector at start.
508  *
509  * \param displays The vector filled with display handles
510  * \return true on success, false on error
511  *//*--------------------------------------------------------------------*/
getDisplays2(DisplayVector & displays)512 bool DisplayCoverageTestInstance::getDisplays2 (DisplayVector& displays)
513 {
514 	deUint32								countReported		=	0u;
515 	deUint32								countRetrieved		=	0u;
516 	const VkDisplayPropertiesKHR			displayProperties	=	{
517 																		DE_NULL,										// VkDisplayKHR					display
518 																		DE_NULL,										// const char*					displayName
519 																		{0, 0},											// VkExtent2D					physicalDimensions
520 																		{0, 0},											// VkExtent2D					physicalResolution
521 																		0,												// VkSurfaceTransformFlagsKHR	supportedTransforms
522 																		VK_FALSE,										// VkBool32						planeReorderPossible
523 																		VK_FALSE										// VkBool32						persistentContent
524 																	};
525 	const VkDisplayProperties2KHR			displayProperties2	=	{
526 																		VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR,		// VkStructureType			sType
527 																		DE_NULL,										// void*					pNext
528 																		displayProperties								// VkDisplayPropertiesKHR	displayProperties
529 																	};
530 
531 	std::vector<VkDisplayProperties2KHR>	displaysProps;
532 	VkResult								result;
533 
534 	displays.clear();
535 
536 	result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
537 															&countReported,		// uint32_t*				pPropertyCount
538 															DE_NULL);			// VkDisplayProperties2KHR*	pProperties
539 
540 	if (result != VK_SUCCESS)
541 	{
542 		m_log	<< tcu::TestLog::Message
543 				<< "vkGetPhysicalDeviceDisplayProperties2KHR failed with " << getResultAsString(result)
544 				<< " reported items count " << countReported
545 				<< tcu::TestLog::EndMessage;
546 
547 		return false;
548 	}
549 
550 	if (!countReported)
551 		TCU_THROW(NotSupportedError, "No displays reported");
552 
553 	displaysProps.resize(countReported, displayProperties2);
554 
555 	countRetrieved = countReported;
556 
557 	result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
558 															&countRetrieved,	// uint32_t*				pPropertyCount
559 															&displaysProps[0]);	// VkDisplayPropertiesKHR*	pProperties
560 
561 	if (result != VK_SUCCESS || countRetrieved > countReported)
562 	{
563 		m_log	<< tcu::TestLog::Message
564 				<< "vkGetPhysicalDeviceDisplayProperties2KHR failed with " << getResultAsString(result)
565 				<< " reported items count " << countReported
566 				<< " retrieved items count " << countRetrieved
567 				<< tcu::TestLog::EndMessage;
568 
569 		return false;
570 	}
571 
572 	displays.reserve(countRetrieved);
573 
574 	for (deUint32	displayIndex = 0;
575 					displayIndex < countRetrieved;
576 					displayIndex++)
577 	{
578 		const VkDisplayKHR display = displaysProps[displayIndex].displayProperties.display;
579 
580 		if (display == DE_NULL)
581 		{
582 			displays.clear();
583 
584 			return false;
585 		}
586 
587 		displays.push_back(display);
588 	}
589 
590 	return true;
591 }
592 
593 /*--------------------------------------------------------------------*//*!
594  * \brief Fills vector with available modes properties for display specified.
595  *
596  * Uses VK_KHR_get_display_properties2 extension API.
597  * Clears passed vector at start and on error.
598  *
599  * \param display	The display to get modes for
600  * \param modes		The vector filled with display mode properties structures
601  * \return true on success, false on error
602  *//*--------------------------------------------------------------------*/
getDisplayModeProperties2(VkDisplayKHR display,DisplayModeProperties2Vector & modeProperties)603 bool DisplayCoverageTestInstance::getDisplayModeProperties2 (VkDisplayKHR display, DisplayModeProperties2Vector& modeProperties)
604 {
605 	deUint32							countReported			=	0u;
606 	deUint32							countRetrieved			=	0u;
607 	const VkDisplayModePropertiesKHR	displayModeProperties	=	{
608 																		DE_NULL,											// VkDisplayModeKHR				displayMode
609 																		{													// VkDisplayModeParametersKHR	parameters
610 																			{0, 0},											// VkExtent2D					visibleRegion
611 																			0												// uint32_t						refreshRate
612 																		}
613 																	};
614 	const VkDisplayModeProperties2KHR	displayModeProperties2	=	{
615 																		VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR,	// VkStructureType				sType
616 																		DE_NULL,											// void*						pNext
617 																		displayModeProperties								// VkDisplayModePropertiesKHR	displayModeProperties
618 																	};
619 	VkResult							result;
620 
621 	modeProperties.clear();
622 
623 	result = m_vki.getDisplayModeProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
624 													display,				// VkDisplayKHR					display
625 													&countReported,			// uint32_t*					pPropertyCount
626 													DE_NULL);				// VkDisplayModeProperties2KHR*	pProperties
627 
628 	if (result != VK_SUCCESS)
629 	{
630 		m_log	<< tcu::TestLog::Message
631 				<< "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result)
632 				<< " for display " << display
633 				<< " reported items count " << countReported
634 				<< tcu::TestLog::EndMessage;
635 
636 		return false;
637 	}
638 
639 	modeProperties.resize(countReported, displayModeProperties2);
640 
641 	countRetrieved = countReported;
642 
643 	result = m_vki.getDisplayModeProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
644 													display,				// VkDisplayKHR					display
645 													&countRetrieved,		// uint32_t*					pPropertyCount
646 													&modeProperties[0]);	// VkDisplayModeProperties2KHR*	pProperties
647 
648 	if (result != VK_SUCCESS || countRetrieved > countReported)
649 	{
650 		m_log	<< tcu::TestLog::Message
651 				<< "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result)
652 				<< " for display " << display
653 				<< " reported items count " << countReported
654 				<< " retrieved items count " << countReported
655 				<< tcu::TestLog::EndMessage;
656 
657 		modeProperties.clear();
658 
659 		return false;
660 	}
661 
662 	if (countRetrieved < countReported)
663 		modeProperties.resize(countRetrieved);
664 
665 	return true;
666 }
667 
668 /*--------------------------------------------------------------------*//*!
669  * \brief Validate display properties and report failures
670  *        into results collector
671  *
672  * \param results		Results collector
673  * \param toValidate	Display properties to validate
674  * \param nonUpdated	Display properties to compare with
675  *//*--------------------------------------------------------------------*/
validateDisplayProperties(tcu::ResultCollector & results,const VkDisplayPropertiesKHR & toValidate,const VkDisplayPropertiesKHR & nonUpdated)676 void DisplayCoverageTestInstance::validateDisplayProperties (	tcu::ResultCollector&			results,
677 																const VkDisplayPropertiesKHR&	toValidate,
678 																const VkDisplayPropertiesKHR&	nonUpdated)
679 {
680 	results.check(	toValidate.display != nonUpdated.display,
681 					"Invalid display handle");
682 
683 	results.check(	toValidate.planeReorderPossible == VK_TRUE || toValidate.planeReorderPossible == VK_FALSE,
684 					"planeReorderPossible neither VK_TRUE, nor VK_FALSE");
685 
686 	results.check(	toValidate.persistentContent == VK_TRUE || toValidate.persistentContent == VK_FALSE,
687 					"persistentContent neither VK_TRUE, nor VK_FALSE");
688 
689 	results.check(	(toValidate.supportedTransforms & nonUpdated.supportedTransforms) == 0,
690 					"supportedTransforms contains unrecognized flags");
691 
692 	// Outside specification, but resolution 0x0 pixels will break many applications
693 	results.check(	toValidate.physicalResolution.height != 0,
694 					"physicalResolution.height cannot be zero");
695 
696 	// Outside specification, but resolution 0x0 pixels will break many applications
697 	results.check(	toValidate.physicalResolution.width != 0,
698 					"physicalResolution.width cannot be zero");
699 }
700 
701 /*--------------------------------------------------------------------*//*!
702  * \brief Validates display plane properties and report failures
703  *        into results collector
704  *
705  * \param results		Results collector
706  * \param toValidate	Display plane properties to validate
707  * \param nonUpdated	Display plane properties to compare with
708  * \param displaySet	Set of valid display handles
709  *//*--------------------------------------------------------------------*/
validateDisplayPlaneProperties(tcu::ResultCollector & results,const VkDisplayPlanePropertiesKHR & toValidate,const VkDisplayPlanePropertiesKHR & nonUpdated,DisplaySet & displaySet)710 void DisplayCoverageTestInstance::validateDisplayPlaneProperties (	tcu::ResultCollector&				results,
711 																	const VkDisplayPlanePropertiesKHR&	toValidate,
712 																	const VkDisplayPlanePropertiesKHR&	nonUpdated,
713 																	DisplaySet&							displaySet)
714 {
715 	const VkDisplayKHR currentDisplay = toValidate.currentDisplay;
716 
717 	results.check(	toValidate.currentStackIndex < nonUpdated.currentStackIndex,
718 					"CurrentStackIndex must be less than the number of planes reported " + de::toString(nonUpdated.currentStackIndex));
719 
720 	results.check(	currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay),
721 					"Plane bound to invalid handle " + de::toString(toValidate.currentDisplay));
722 }
723 
724 /*--------------------------------------------------------------------*//*!
725  * \brief Validate display plane capabilities and report failures
726  *        into results collector
727  *
728  * \param results		Results collector
729  * \param toValidate	Display plane capabilities to validate
730  * \param nonUpdated	Display plane capabilities to compare with
731  *//*--------------------------------------------------------------------*/
validateDisplayPlaneCapabilities(tcu::ResultCollector & results,const VkDisplayPlaneCapabilitiesKHR & toValidate,const VkDisplayPlaneCapabilitiesKHR & nonUpdated)732 void DisplayCoverageTestInstance::validateDisplayPlaneCapabilities (	tcu::ResultCollector&					results,
733 																		const VkDisplayPlaneCapabilitiesKHR&	toValidate,
734 																		const VkDisplayPlaneCapabilitiesKHR&	nonUpdated)
735 {
736 	results.check(	(toValidate.supportedAlpha & nonUpdated.supportedAlpha) == 0,
737 					"supportedAlpha contains unrecognized value");
738 
739 	results.check(	toValidate.minSrcPosition.x >= 0,
740 					"minSrcPosition.x >= 0");
741 
742 	results.check(	toValidate.minSrcPosition.y >= 0,
743 					"minSrcPosition.y >= 0");
744 
745 	results.check(	toValidate.maxSrcPosition.x >= 0,
746 					"maxSrcPosition.x >= 0");
747 
748 	results.check(	toValidate.maxSrcPosition.y >= 0,
749 					"maxSrcPosition.y >= 0");
750 
751 	results.check(	toValidate.minSrcPosition.x <= toValidate.maxSrcPosition.x,
752 					"minSrcPosition.x <= maxSrcPosition.x");
753 
754 	results.check(	toValidate.minSrcPosition.y <= toValidate.maxSrcPosition.y,
755 					"minSrcPosition.y <= maxSrcPosition.y");
756 
757 	results.check(	toValidate.minDstPosition.x <= toValidate.maxDstPosition.x,
758 					"minDstPosition.x <= maxDstPosition.x");
759 
760 	results.check(	toValidate.minDstPosition.y <= toValidate.maxDstPosition.y,
761 					"minDstPosition.y <= maxDstPosition.y");
762 
763 	results.check(	toValidate.minSrcExtent.width <= toValidate.maxSrcExtent.width,
764 					"minSrcExtent.width <= maxSrcExtent.width");
765 
766 	results.check(	toValidate.minSrcExtent.height <= toValidate.maxSrcExtent.height,
767 					"minSrcExtent.height <= maxSrcExtent.height");
768 
769 	results.check(	toValidate.minDstExtent.width <= toValidate.maxDstExtent.width,
770 					"minDstExtent.width <= maxDstExtent.width");
771 
772 	results.check(	toValidate.minDstExtent.height <= toValidate.maxDstExtent.height,
773 					"minDstExtent.height <= maxDstExtent.height");
774 }
775 
776 /*--------------------------------------------------------------------*//*!
777  * \brief Validate display mode properties and report failures
778  *        into results collector
779  *
780  * \param results		Results collector
781  * \param toValidate	Display mode properties to validate
782  * \param nonUpdated	Display mode properties to compare with
783  *//*--------------------------------------------------------------------*/
validateDisplayModeProperties(tcu::ResultCollector & results,const VkDisplayModePropertiesKHR & toValidate,const VkDisplayModePropertiesKHR & nonUpdated)784 void DisplayCoverageTestInstance::validateDisplayModeProperties (	tcu::ResultCollector&				results,
785 																	const VkDisplayModePropertiesKHR&	toValidate,
786 																	const VkDisplayModePropertiesKHR&	nonUpdated)
787 {
788 	results.check(	toValidate.displayMode != nonUpdated.displayMode,
789 					"Invalid mode display handle reported");
790 }
791 
792 /*--------------------------------------------------------------------*//*!
793  * \brief Display enumeration coverage test
794  *
795  * Throws ResourceError exception in case no displays available.
796  * Throws an exception on fail.
797  *
798  * \return tcu::TestStatus::pass on success
799  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayPropertiesKHR(void)800 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPropertiesKHR (void)
801 {
802 	deUint32				displayCountReported	=	0u;
803 	deUint32				displayCountToTest		=	0u;
804 	tcu::ResultCollector	results						(m_log);
805 	VkResult				result;
806 
807 	result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
808 															&displayCountReported,	// uint32_t*				pPropertyCount
809 															DE_NULL);				// VkDisplayPropertiesKHR*	pProperties
810 
811 	if (   result != VK_SUCCESS
812 		&& result != VK_INCOMPLETE
813 		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
814 		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
815 		)
816 	{
817 		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
818 	}
819 
820 	if (result != VK_SUCCESS)
821 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
822 
823 	if (displayCountReported == 0)
824 		TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str());
825 
826 	displayCountToTest = displayCountReported;
827 	if (displayCountReported > MAX_TESTED_DISPLAY_COUNT)
828 	{
829 		m_log	<< tcu::TestLog::Message
830 				<< "Number of displays reported is too high " << displayCountReported
831 				<< ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT
832 				<< tcu::TestLog::EndMessage;
833 
834 		displayCountToTest = MAX_TESTED_DISPLAY_COUNT;
835 	}
836 
837 	// Test the call correctly writes data in various size arrays
838 	for (deUint32	displayCountRequested = 0;
839 					displayCountRequested < displayCountToTest + 2;
840 					displayCountRequested++)
841 	{
842 		const deUint32						displayCountExpected	=	std::min(displayCountRequested, displayCountReported);
843 		const VkDisplayPropertiesKHR		invalidDisplayProps		=	{	// Most values are set to fail the test to make sure driver updates these
844 																			DE_NULL,								// VkDisplayKHR					display;
845 																			DE_NULL,								// const char*					displayName;
846 																			{0, 0},									// VkExtent2D					physicalDimensions;
847 																			{0, 0},									// VkExtent2D					physicalResolution;
848 																			~RECOGNIZED_SURFACE_TRANSFORM_FLAGS,	// VkSurfaceTransformFlagsKHR	supportedTransforms;
849 																			(vk::VkBool32)(VK_TRUE + 1),			// VkBool32						planeReorderPossible;
850 																			(vk::VkBool32)(VK_TRUE + 1)				// VkBool32						persistentContent;
851 																		};
852 		const VkDisplayKHR					canaryDisplay			=	static_cast<VkDisplayKHR>(0xABCDEF11);
853 		const deUint32						canaryItemCount			=	1;
854 		std::vector<VkDisplayPropertiesKHR>	displaysProps				(displayCountRequested + canaryItemCount, invalidDisplayProps);
855 		deUint32							displayCountRetrieved	=	displayCountRequested;
856 		DisplaySet							displaySet;
857 
858 		displaysProps[displayCountExpected].display = canaryDisplay;
859 
860 		result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
861 																&displayCountRetrieved,	// uint32_t*				pPropertyCount
862 																&displaysProps[0]);		// VkDisplayPropertiesKHR*	pProperties
863 
864 		// Check amount of data written equals to expected
865 		if (displayCountRetrieved != displayCountExpected)
866 			TCU_FAIL_STR(	string("displayCountRetrieved != displayCountExpected, ") +
867 							de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));
868 
869 		if (displayCountRequested >= displayCountReported)
870 		{
871 			if (result != VK_SUCCESS)
872 				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
873 		}
874 		else
875 		{
876 			if (result != VK_INCOMPLETE)
877 				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
878 		}
879 
880 		// Check the driver has written something
881 		for (deUint32	displayIndex = 0;
882 						displayIndex < displayCountRetrieved;
883 						displayIndex++)
884 		{
885 			displaySet.insert(displaysProps[displayIndex].display);
886 
887 			results.check(	displaysProps[displayIndex].display != invalidDisplayProps.display,
888 							"Invalid display handle for display number " + de::toString(displayIndex));
889 
890 			results.check(	displaysProps[displayIndex].planeReorderPossible == VK_TRUE || displaysProps[displayIndex].planeReorderPossible == VK_FALSE,
891 							"planeReorderPossible neither VK_TRUE, nor VK_FALSE");
892 
893 			results.check(	displaysProps[displayIndex].persistentContent == VK_TRUE || displaysProps[displayIndex].persistentContent == VK_FALSE,
894 							"persistentContent neither VK_TRUE, nor VK_FALSE");
895 
896 			results.check(	(displaysProps[displayIndex].supportedTransforms & invalidDisplayProps.supportedTransforms) == 0,
897 							"supportedTransforms contains unrecognized flags");
898 
899 			// Outside specification, but resolution 0x0 pixels will break many applications
900 			results.check(	displaysProps[displayIndex].physicalResolution.height != 0,
901 							"physicalResolution.height cannot be zero");
902 
903 			// Outside specification, but resolution 0x0 pixels will break many applications
904 			results.check(	displaysProps[displayIndex].physicalResolution.width != 0,
905 							"physicalResolution.width cannot be zero");
906 
907 			if (results.getResult() != QP_TEST_RESULT_PASS)
908 			{
909 				m_log	<< tcu::TestLog::Message
910 						<< "Error detected " << results.getMessage()
911 						<< " for display " << displayIndex << " with properties " << displaysProps[displayIndex]
912 						<< " invalid display properties are " << invalidDisplayProps
913 						<< tcu::TestLog::EndMessage;
914 
915 				TCU_FAIL_STR(results.getMessage());
916 			}
917 		}
918 
919 		// Check the driver has not written more than requested
920 		if (displaysProps[displayCountExpected].display != canaryDisplay)
921 			TCU_FAIL("Memory damage detected: driver has written more than expected");
922 
923 		// Check display handle uniqueness
924 		if (displaySet.size() != displayCountRetrieved)
925 			TCU_FAIL("Display handle duplication detected");
926 	}
927 
928 	return tcu::TestStatus::pass("pass");
929 }
930 
931 /*--------------------------------------------------------------------*//*!
932  * \brief Plane enumeration coverage test
933  *
934  * Throws an exception on fail.
935  *
936  * \return tcu::TestStatus::pass on success
937  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayPlanePropertiesKHR(void)938 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlanePropertiesKHR (void)
939 {
940 	DisplayVector			displaysVector;
941 	DisplaySet				displaySet;
942 	deUint32				planeCountReported	=	0u;
943 	deUint32				planeCountTested	=	0u;
944 	tcu::ResultCollector	results					(m_log);
945 	VkResult				result;
946 
947 	// Create a list of displays available
948 	if (!getDisplays(displaysVector))
949 		TCU_FAIL("Failed to retrieve displays");
950 
951 	if (displaysVector.empty())
952 		TCU_THROW(NotSupportedError, "No displays reported");
953 
954 	displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());
955 
956 	// Get planes to test
957 	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
958 																&planeCountReported,	// uint32_t*					pPropertyCount
959 																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties
960 
961 	if (   result != VK_SUCCESS
962 		&& result != VK_INCOMPLETE
963 		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
964 		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
965 		)
966 	{
967 		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
968 	}
969 
970 	if (result != VK_SUCCESS)
971 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
972 
973 	if (planeCountReported == 0)
974 		TCU_THROW(ResourceError, "Cannot perform test: no planes found");
975 
976 	planeCountTested = planeCountReported;
977 	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
978 	{
979 		m_log	<< tcu::TestLog::Message
980 				<< "Number of planes reported is too high " << planeCountReported
981 				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
982 				<< tcu::TestLog::EndMessage;
983 
984 		planeCountTested = MAX_TESTED_PLANE_COUNT;
985 	}
986 
987 	// Test the call correctly writes data in various size arrays
988 	for (deUint32	planeCountRequested = 0;
989 					planeCountRequested < planeCountTested + 2;
990 					planeCountRequested++)
991 	{
992 		const deUint32								planeCountExpected	=	std::min(planeCountRequested, planeCountReported);
993 		const VkDisplayPlanePropertiesKHR			invalidPlaneProps	=	{	// Most values are set to fail the test to make sure driver updates these
994 																				DE_NULL,		// VkDisplayKHR	currentDisplay
995 																				DEUINT32_MAX	// deUint32		currentStackIndex
996 																			};
997 		const VkDisplayKHR							canaryDisplay		=	static_cast<VkDisplayKHR>(0xABCDEF11);
998 		const deUint32								canaryItemCount		=	1;
999 		std::vector<VkDisplayPlanePropertiesKHR>	planeProps				(planeCountRequested + canaryItemCount, invalidPlaneProps);
1000 		deUint32									planeCountRetrieved	=	planeCountRequested;
1001 
1002 		planeProps[planeCountExpected].currentDisplay = canaryDisplay;
1003 
1004 		result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
1005 																	&planeCountRetrieved,	// uint32_t*					pPropertyCount
1006 																	&planeProps[0]);		// VkDisplayPlanePropertiesKHR*	pProperties
1007 
1008 		// Check amount of data written equals to expected
1009 		if (planeCountRetrieved != planeCountExpected)
1010 			TCU_FAIL_STR(	string("planeCountRetrieved != planeCountExpected, ") +
1011 							de::toString(planeCountRetrieved) + " != " + de::toString(planeCountExpected));
1012 
1013 		if (planeCountRequested >= planeCountReported)
1014 		{
1015 			if (result != VK_SUCCESS)
1016 				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1017 		}
1018 		else
1019 		{
1020 			if (result != VK_INCOMPLETE)
1021 				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1022 		}
1023 
1024 		// Check the driver has written something
1025 		for (deUint32	planeIndex = 0;
1026 						planeIndex < planeCountRetrieved;
1027 						planeIndex++)
1028 		{
1029 			const VkDisplayKHR currentDisplay = planeProps[planeIndex].currentDisplay;
1030 
1031 			results.check(	planeProps[planeIndex].currentStackIndex < planeCountReported,
1032 							"CurrentStackIndex must be less than the number of planes reported " + de::toString(planeCountReported));
1033 
1034 			results.check(	currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay),
1035 							"Plane bound to invalid handle " + de::toString(currentDisplay));
1036 
1037 			if (results.getResult() != QP_TEST_RESULT_PASS)
1038 			{
1039 				m_log	<< tcu::TestLog::Message
1040 						<< "Error detected " << results.getMessage()
1041 						<< " for plane " << planeIndex << " with properties " << planeProps[planeIndex]
1042 						<< tcu::TestLog::EndMessage;
1043 
1044 				TCU_FAIL_STR(results.getMessage());
1045 			}
1046 		}
1047 
1048 		// Check the driver has not written more than requested
1049 		if (planeProps[planeCountExpected].currentDisplay != canaryDisplay)
1050 			TCU_FAIL("Memory damage detected: driver has written more than expected");
1051 	}
1052 
1053 	return tcu::TestStatus::pass("pass");
1054 }
1055 
1056 /*--------------------------------------------------------------------*//*!
1057  * \brief Display plane support coverage test
1058  *
1059  * Throws an exception on fail.
1060  *
1061  * \return tcu::TestStatus::pass on success
1062  *//*--------------------------------------------------------------------*/
testGetDisplayPlaneSupportedDisplaysKHR(void)1063 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneSupportedDisplaysKHR (void)
1064 {
1065 	deUint32		planeCountReported	=	0u;
1066 	deUint32		planeCountTested	=	0u;
1067 	VkResult		result;
1068 	DisplayVector	displaysVector;
1069 	DisplaySet		displaySet;
1070 
1071 	if (!getDisplays(displaysVector))
1072 		TCU_FAIL("Failed to retrieve displays");
1073 
1074 	if (displaysVector.empty())
1075 		TCU_THROW(NotSupportedError, "No displays reported");
1076 
1077 	displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());
1078 
1079 	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
1080 																&planeCountReported,	// uint32_t*					pPropertyCount
1081 																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties
1082 
1083 	if (   result != VK_SUCCESS
1084 		&& result != VK_INCOMPLETE
1085 		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
1086 		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
1087 		)
1088 	{
1089 		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
1090 	}
1091 
1092 	if (result != VK_SUCCESS)
1093 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1094 
1095 	if (planeCountReported == 0)
1096 		TCU_THROW(ResourceError, "Cannot perform test: no planes supported");
1097 
1098 	planeCountTested = planeCountReported;
1099 	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1100 	{
1101 		m_log	<< tcu::TestLog::Message
1102 				<< "Number of planes reported is too high " << planeCountReported
1103 				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
1104 				<< tcu::TestLog::EndMessage;
1105 
1106 		planeCountTested = MAX_TESTED_PLANE_COUNT;
1107 	}
1108 
1109 	for (deUint32	planeIndex = 0;
1110 					planeIndex < planeCountTested;
1111 					planeIndex++)
1112 	{
1113 		deUint32 displayCountReported = 0u;
1114 
1115 		result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,		// VkPhysicalDevice	physicalDevice
1116 															planeIndex,				// uint32_t			planeIndex
1117 															&displayCountReported,	// uint32_t*		pDisplayCount
1118 															DE_NULL);				// VkDisplayKHR*	pDisplays
1119 
1120 		if (result != VK_SUCCESS)
1121 			TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1122 
1123 		// Test the call correctly writes data in various size arrays
1124 		for (deUint32	displayCountRequested = 0;
1125 						displayCountRequested < displayCountReported + 2;
1126 						displayCountRequested++)
1127 		{
1128 			const deUint32				displayCountExpected	=	std::min(displayCountRequested, displayCountReported);
1129 			const VkDisplayKHR			nullDisplay				=	DE_NULL;
1130 			const VkDisplayKHR			canaryDisplay			=	static_cast<VkDisplayKHR>(0xABCDEF11);
1131 			const deUint32				canaryItemCount			=	1;
1132 			std::vector<VkDisplayKHR>	displaysForPlane			(displayCountRequested + canaryItemCount, nullDisplay);
1133 			deUint32					displayCountRetrieved	=	displayCountRequested;
1134 
1135 			displaysForPlane[displayCountExpected] = canaryDisplay;
1136 
1137 			result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,		// VkPhysicalDevice	physicalDevice
1138 																planeIndex,				// uint32_t			planeIndex
1139 																&displayCountRetrieved,	// uint32_t*		pDisplayCount
1140 																&displaysForPlane[0]);	// VkDisplayKHR*	pDisplays
1141 
1142 			// Check amount of data written equals to expected
1143 			if (displayCountRetrieved != displayCountExpected)
1144 				TCU_FAIL_STR(	string("displayCountRetrieved != displayCountExpected, ") +
1145 								de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));
1146 
1147 			if (displayCountRequested >= displayCountReported)
1148 			{
1149 				if (result != VK_SUCCESS)
1150 					TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1151 			}
1152 			else
1153 			{
1154 				if (result != VK_INCOMPLETE)
1155 					TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1156 			}
1157 
1158 			// Check the driver has written something
1159 			for (deUint32	displayIndex = 0;
1160 							displayIndex < displayCountExpected;
1161 							displayIndex++)
1162 			{
1163 				const VkDisplayKHR display = displaysForPlane[displayIndex];
1164 
1165 				if (display != nullDisplay)
1166 				{
1167 					if (!de::contains(displaySet, display))
1168 					{
1169 						TCU_FAIL_STR("Invalid display handle " + de::toString(display));
1170 					}
1171 				}
1172 			}
1173 
1174 			// Check the driver has not written more than requested
1175 			if (displaysForPlane[displayCountExpected] != canaryDisplay)
1176 				TCU_FAIL("Memory damage detected: driver has written more than expected");
1177 		}
1178 	}
1179 
1180 	return tcu::TestStatus::pass("pass");
1181 }
1182 
1183 /*--------------------------------------------------------------------*//*!
1184  * \brief Display mode properties coverage test
1185  *
1186  * Throws an exception on fail.
1187  *
1188  * \return tcu::TestStatus::pass on success
1189  *//*--------------------------------------------------------------------*/
testGetDisplayModePropertiesKHR(void)1190 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModePropertiesKHR (void)
1191 {
1192 	VkResult		result;
1193 	DisplayVector	displaysVector;
1194 
1195 	if (!getDisplays(displaysVector))
1196 		TCU_FAIL("Failed to retrieve displays list");
1197 
1198 	if (displaysVector.empty())
1199 		TCU_THROW(NotSupportedError, "No displays reported");
1200 
1201 	for (DisplayVector::iterator	it =  displaysVector.begin();
1202 									it != displaysVector.end();
1203 									it++)
1204 	{
1205 		VkDisplayKHR	display				= *it;
1206 		deUint32		modesCountReported	= 0u;
1207 
1208 		result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
1209 													display,				// VkDisplayKHR					display
1210 													&modesCountReported,	// uint32_t*					pPropertyCount
1211 													DE_NULL);				// VkDisplayModePropertiesKHR*	pProperties
1212 
1213 		// Test the call correctly writes data in various size arrays
1214 		for (deUint32	modesCountRequested = 0;
1215 						modesCountRequested < modesCountReported + 2;
1216 						modesCountRequested = nextTestNumber(modesCountRequested, modesCountReported + 2))
1217 		{
1218 			const deUint32							modesCountExpected	=	std::min(modesCountRequested, modesCountReported);
1219 			const VkDisplayModeKHR					nullDisplayMode		=	DE_NULL;
1220 			const VkDisplayModePropertiesKHR		nullMode			=	{
1221 																				nullDisplayMode,	// VkDisplayModeKHR				displayMode
1222 																				{					// VkDisplayModeParametersKHR	parameters
1223 																					{0, 0},			// VkExtent2D					visibleRegion
1224 																					0				// uint32_t						refreshRate
1225 																				}
1226 																			};
1227 			const VkDisplayModeKHR					canaryDisplayMode	=	static_cast<VkDisplayModeKHR>(0xABCDEF11);
1228 			const deUint32							canaryItemCount		=	1;
1229 			std::vector<VkDisplayModePropertiesKHR>	modesForDisplay			(modesCountRequested + canaryItemCount, nullMode);
1230 			deUint32								modesCountRetrieved	=	modesCountRequested;
1231 
1232 			modesForDisplay[modesCountExpected].displayMode = canaryDisplayMode;
1233 
1234 			result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
1235 														display,				// VkDisplayKHR					display
1236 														&modesCountRetrieved,	// uint32_t*					pPropertyCount
1237 														&modesForDisplay[0]);	// VkDisplayModePropertiesKHR*	pProperties
1238 
1239 			// Check amount of data written equals to expected
1240 			if (modesCountRetrieved != modesCountExpected)
1241 				TCU_FAIL_STR(	string("modesCountRetrieved != modesCountExpected, ") +
1242 								de::toString(modesCountRetrieved) + " != " + de::toString(modesCountExpected));
1243 
1244 			if (modesCountRequested >= modesCountReported)
1245 			{
1246 				if (result != VK_SUCCESS)
1247 					TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1248 			}
1249 			else
1250 			{
1251 				if (result != VK_INCOMPLETE)
1252 					TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1253 			}
1254 
1255 			// Check the driver has written something
1256 			for (deUint32	modeIndex = 0;
1257 							modeIndex < modesCountExpected;
1258 							modeIndex++)
1259 			{
1260 				const VkDisplayModePropertiesKHR theModeProperties = modesForDisplay[modeIndex];
1261 
1262 				if (theModeProperties.displayMode == nullMode.displayMode)
1263 					TCU_FAIL_STR("Invalid mode display handle reported for display " + de::toString(display));
1264 			}
1265 
1266 			// Check the driver has not written more than requested
1267 			if (modesForDisplay[modesCountExpected].displayMode != canaryDisplayMode)
1268 				TCU_FAIL("Memory damage detected: driver has written more than expected");
1269 		}
1270 	}
1271 
1272 	return tcu::TestStatus::pass("pass");
1273 }
1274 
1275 /*--------------------------------------------------------------------*//*!
1276  * \brief Create display mode coverage test
1277  *
1278  * Throws an exception on fail.
1279  *
1280  * \return tcu::TestStatus::pass on success
1281  *//*--------------------------------------------------------------------*/
testCreateDisplayModeKHR(void)1282 tcu::TestStatus	DisplayCoverageTestInstance::testCreateDisplayModeKHR (void)
1283 {
1284 	DisplayVector	displaysVector;
1285 	VkResult		result;
1286 
1287 	if (!getDisplays(displaysVector))
1288 		TCU_FAIL("Failed to retrieve displays");
1289 
1290 	if (displaysVector.empty())
1291 		TCU_THROW(NotSupportedError, "No displays reported");
1292 
1293 	for (DisplayVector::iterator	it =  displaysVector.begin();
1294 									it != displaysVector.end();
1295 									it++)
1296 	{
1297 		const VkDisplayKHR						display				=	*it;
1298 		DisplayModePropertiesVector::size_type	builtinModesCount	=	0u;
1299 		VkDisplayModePropertiesKHR				validModeProperties;
1300 		VkDisplayModeKHR						mode				=	DE_NULL;
1301 		DisplayModePropertiesVector				modes;
1302 		VkDisplayModeCreateInfoKHR				createInfo			=	{
1303 																			VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR,	// VkStructureType				sType
1304 																			DE_NULL,										// const void*					pNext
1305 																			0,												// VkDisplayModeCreateFlagsKHR	flags
1306 																			{												// VkDisplayModeParametersKHR	parameters
1307 																				{0, 0},										// VkExtent2D					visibleRegion
1308 																				0											// uint32_t						refreshRate
1309 																			}
1310 																		};
1311 
1312 		if (!getDisplayModeProperties(display, modes))
1313 			TCU_FAIL("Failed to retrieve display mode properties");
1314 
1315 		if (modes.size() < 1)
1316 			TCU_FAIL("At least one mode expected to be returned");
1317 
1318 		// Builtin mode count should not be updated with a new mode. Get initial builtin mode count
1319 		builtinModesCount = modes.size();
1320 
1321 		// Assume first available builtin mode as a valid mode sample
1322 		validModeProperties = modes[0];
1323 
1324 		// Do negative test by making one of parameters unacceptable
1325 		for (deUint32	testIndex = 0;
1326 						testIndex < 3;
1327 						testIndex++)
1328 		{
1329 			VkDisplayModeCreateInfoKHR	createInfoFail		(createInfo);
1330 			VkDisplayModeKHR			modeFail		=	DE_NULL;
1331 
1332 			createInfoFail.parameters = validModeProperties.parameters;
1333 
1334 			switch (testIndex)
1335 			{
1336 				case 0:		createInfoFail.parameters.refreshRate			= 0;	break;
1337 				case 1:		createInfoFail.parameters.visibleRegion.width	= 0;	break;
1338 				case 2:		createInfoFail.parameters.visibleRegion.height	= 0;	break;
1339 				default:	DE_FATAL("Impossible");									break;
1340 			}
1341 
1342 			result = m_vki.createDisplayModeKHR(	m_physicalDevice,	// VkPhysicalDevice						physicalDevice
1343 													display,			// VkDisplayKHR							display
1344 													&createInfoFail,	// const VkDisplayModeCreateInfoKHR*	pCreateInfo
1345 													DE_NULL,			// const VkAllocationCallbacks*			pAllocator
1346 													&modeFail);			// VkDisplayModeKHR*					pMode
1347 
1348 			if (result != VK_ERROR_INITIALIZATION_FAILED)
1349 				TCU_FAIL_STR(string("Expected VK_ERROR_INITIALIZATION_FAILED. Have ") + getResultAsString(result));
1350 
1351 			if (modeFail != DE_NULL)
1352 				TCU_FAIL("Mode should be kept invalid on fail");
1353 		}
1354 
1355 		// At last create valid display mode
1356 		createInfo.parameters = validModeProperties.parameters;
1357 
1358 		result = m_vki.createDisplayModeKHR(	m_physicalDevice,	// VkPhysicalDevice						physicalDevice
1359 												display,			// VkDisplayKHR							display
1360 												&createInfo,		// const VkDisplayModeCreateInfoKHR*	pCreateInfo
1361 												DE_NULL,			// const VkAllocationCallbacks*			pAllocator
1362 												&mode);				// VkDisplayModeKHR*					pMode
1363 
1364 		if (result != VK_SUCCESS)
1365 			TCU_FAIL_STR("Expected VK_SUCCESS. Have " + getResultAsString(result));
1366 
1367 		if (mode == DE_NULL)
1368 			TCU_FAIL("Valid handle expected");
1369 
1370 		// Builtin mode count should not be updated with a new mode
1371 		modes.clear();
1372 
1373 		if (!getDisplayModeProperties(display, modes))
1374 			TCU_FAIL("Failed to retrieve display mode properties");
1375 
1376 		if (builtinModesCount != modes.size())
1377 			TCU_FAIL_STR(	string("Mode count has changed from ") + de::toString(builtinModesCount) +
1378 							string(" to ") + de::toString(modes.size()));
1379 	}
1380 
1381 	return tcu::TestStatus::pass("pass");
1382 }
1383 
1384 /*--------------------------------------------------------------------*//*!
1385  * \brief Display-plane capabilities coverage test
1386  *
1387  * Throws an exception on fail.
1388  *
1389  * \return tcu::TestStatus::pass on success
1390  *//*--------------------------------------------------------------------*/
testGetDisplayPlaneCapabilitiesKHR(void)1391 tcu::TestStatus	DisplayCoverageTestInstance::testGetDisplayPlaneCapabilitiesKHR (void)
1392 {
1393 	deUint32	planeCountReported	=	0u;
1394 	VkResult	result;
1395 
1396 	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
1397 																&planeCountReported,	// uint32_t*					pPropertyCount
1398 																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties
1399 
1400 	if (result != VK_SUCCESS)
1401 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1402 
1403 	if (planeCountReported == 0)
1404 	{
1405 		DisplayVector	displaysVector;
1406 
1407 		// If we don't have any displays then it's alright to have no planes, as
1408 		// per the Vulkan Spec:
1409 		//		Devices must support at least one plane on each display
1410 		if (!getDisplays(displaysVector))
1411 			TCU_FAIL("Failed to retrieve displays");
1412 
1413 		if (displaysVector.empty())
1414 			TCU_THROW(NotSupportedError, "No display planes reported");
1415 
1416 		TCU_FAIL("No planes defined");
1417 	}
1418 
1419 	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1420 	{
1421 		m_log	<< tcu::TestLog::Message
1422 				<< "Number of planes reported is too high " << planeCountReported
1423 				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
1424 				<< tcu::TestLog::EndMessage;
1425 
1426 		planeCountReported = MAX_TESTED_PLANE_COUNT;
1427 	}
1428 
1429 	for (deUint32	planeIndex = 0;
1430 					planeIndex < planeCountReported;
1431 					planeIndex++)
1432 	{
1433 		std::vector<VkDisplayKHR> displaysForPlane;
1434 
1435 		if (!getDisplaysForPlane(planeIndex, displaysForPlane))
1436 			TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));
1437 
1438 		if (displaysForPlane.empty())
1439 			continue;
1440 
1441 		// Check the driver has written something
1442 		for (deUint32	displayIndex = 0;
1443 						displayIndex < displaysForPlane.size();
1444 						displayIndex++)
1445 		{
1446 			const VkDisplayKHR						display						=	displaysForPlane[displayIndex];
1447 			std::vector<VkDisplayModePropertiesKHR>	modesPropertiesForDisplay;
1448 
1449 			if (!getDisplayModeProperties(display, modesPropertiesForDisplay))
1450 				TCU_FAIL("Failed to retrieve display mode properties");
1451 
1452 			for (deUint32	modeIndex = 0;
1453 							modeIndex < modesPropertiesForDisplay.size();
1454 							modeIndex++)
1455 			{
1456 				const VkDisplayModeKHR			theDisplayMode			=	modesPropertiesForDisplay[modeIndex].displayMode;
1457 				const deUint32					unrecognizedAlphaFlags	=	~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS;
1458 				VkDisplayPlaneCapabilitiesKHR	planeCapabilities		=	{
1459 																				unrecognizedAlphaFlags,	// VkDisplayPlaneAlphaFlagsKHR	supportedAlpha;
1460 																				{ -1, -1 },				// VkOffset2D					minSrcPosition;
1461 																				{ -1, -1 },				// VkOffset2D					maxSrcPosition;
1462 																				{ 1, 1 },				// VkExtent2D					minSrcExtent;
1463 																				{ 0, 0 },				// VkExtent2D					maxSrcExtent;
1464 																				{ 1, 1 },				// VkOffset2D					minDstPosition;
1465 																				{ 0, 0 },				// VkOffset2D					maxDstPosition;
1466 																				{ 1, 1 },				// VkExtent2D					minDstExtent;
1467 																				{ 0, 0 },				// VkExtent2D					maxDstExtent;
1468 																			};
1469 				tcu::ResultCollector			results						(m_log);
1470 
1471 				result = m_vki.getDisplayPlaneCapabilitiesKHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
1472 																theDisplayMode,			// VkDisplayModeKHR					mode
1473 																planeIndex,				// uint32_t							planeIndex
1474 																&planeCapabilities);	// VkDisplayPlaneCapabilitiesKHR*	pCapabilities
1475 
1476 				results.check(	result == VK_SUCCESS,
1477 								string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1478 
1479 				results.check(	(planeCapabilities.supportedAlpha & unrecognizedAlphaFlags) == 0,
1480 								"supportedAlpha contains unrecognized value");
1481 
1482 				results.check(	planeCapabilities.minSrcPosition.x >= 0,
1483 								"minSrcPosition.x >= 0");
1484 
1485 				results.check(	planeCapabilities.minSrcPosition.y >= 0,
1486 								"minSrcPosition.y >= 0");
1487 
1488 				results.check(	planeCapabilities.maxSrcPosition.x >= 0,
1489 								"maxSrcPosition.x >= 0");
1490 
1491 				results.check(	planeCapabilities.maxSrcPosition.y >= 0,
1492 								"maxSrcPosition.y >= 0");
1493 
1494 				results.check(	planeCapabilities.minSrcPosition.x <= planeCapabilities.maxSrcPosition.x,
1495 								"minSrcPosition.x <= maxSrcPosition.x");
1496 
1497 				results.check(	planeCapabilities.minSrcPosition.y <= planeCapabilities.maxSrcPosition.y,
1498 								"minSrcPosition.y <= maxSrcPosition.y");
1499 
1500 				results.check(	planeCapabilities.minDstPosition.x <= planeCapabilities.maxDstPosition.x,
1501 								"minDstPosition.x <= maxDstPosition.x");
1502 
1503 				results.check(	planeCapabilities.minDstPosition.y <= planeCapabilities.maxDstPosition.y,
1504 								"minDstPosition.y <= maxDstPosition.y");
1505 
1506 				results.check(	planeCapabilities.minSrcExtent.width <= planeCapabilities.maxSrcExtent.width,
1507 								"minSrcExtent.width <= maxSrcExtent.width");
1508 
1509 				results.check(	planeCapabilities.minSrcExtent.height <= planeCapabilities.maxSrcExtent.height,
1510 								"minSrcExtent.height <= maxSrcExtent.height");
1511 
1512 				results.check(	planeCapabilities.minDstExtent.width <= planeCapabilities.maxDstExtent.width,
1513 								"minDstExtent.width <= maxDstExtent.width");
1514 
1515 				results.check(	planeCapabilities.minDstExtent.height <= planeCapabilities.maxDstExtent.height,
1516 								"minDstExtent.height <= maxDstExtent.height");
1517 
1518 				if (results.getResult() != QP_TEST_RESULT_PASS)
1519 				{
1520 					m_log	<< tcu::TestLog::Message
1521 							<< "Error detected " << results.getMessage()
1522 							<< " for plane's " << planeIndex
1523 							<< " display " << displayIndex
1524 							<< " and mode " << modeIndex
1525 							<< " with capabilities " << planeCapabilities
1526 							<< tcu::TestLog::EndMessage;
1527 
1528 					TCU_FAIL_STR(results.getMessage());
1529 				}
1530 
1531 			}
1532 		}
1533 	}
1534 
1535 	return tcu::TestStatus::pass("pass");
1536 }
1537 
1538 namespace
1539 {
1540 	struct SurfaceCountersError : public std::runtime_error
1541 	{
SurfaceCountersErrorvkt::wsi::__anon466b28b90111::SurfaceCountersError1542 		SurfaceCountersError(const std::string& what_) : std::runtime_error(what_) {}
1543 	};
1544 }
1545 
1546 /*--------------------------------------------------------------------*//*!
1547  * \brief Test display surface creation or counters.
1548  *
1549  * In the counter variant, it needs VK_EXT_display_surface_counter
1550  * and checks the available surface counters.
1551  *
1552  * Throws an exception on fail.
1553  *
1554  * \return tcu::TestStatus::pass on success
1555  *//*--------------------------------------------------------------------*/
testDisplaySurface(SurfaceTestKind testKind)1556 tcu::TestStatus	DisplayCoverageTestInstance::testDisplaySurface (SurfaceTestKind testKind)
1557 {
1558 	deUint32									planeCountReported	=	0u;
1559 	deUint32									planeCountTested	=	0u;
1560 	deUint32									planeCountRetrieved	=	0u;
1561 	std::vector<VkDisplayPlanePropertiesKHR>	planeProperties;
1562 	bool										testPerformed		=	false;
1563 	DisplayVector								displaysVector;
1564 	VkResult									result;
1565 	std::string									surfaceCountersErr;
1566 
1567 	DE_ASSERT(testKind >= 0 && testKind < SURFACE_TEST_KIND_MAX_ENUM);
1568 
1569 	// Check the needed extension.
1570 	if (testKind == SURFACE_COUNTERS && (!isInstanceExtensionSupported(m_context.getUsedApiVersion(), m_context.getInstanceExtensions(), "VK_EXT_display_surface_counter")))
1571 		TCU_THROW(NotSupportedError, "VK_EXT_display_surface_counter not supported");
1572 
1573 	// Get displays
1574 	if (!getDisplays(displaysVector))
1575 		TCU_FAIL("Failed to retrieve displays");
1576 
1577 	if (displaysVector.empty())
1578 		TCU_THROW(NotSupportedError, "No displays reported");
1579 
1580 	// Get planes
1581 	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
1582 																&planeCountReported,	// uint32_t*					pPropertyCount
1583 																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties
1584 
1585 	if (result != VK_SUCCESS)
1586 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1587 
1588 	if (planeCountReported == 0)
1589 		TCU_FAIL("No planes defined");
1590 
1591 	planeCountTested = planeCountReported;
1592 	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1593 	{
1594 		m_log	<< tcu::TestLog::Message
1595 				<< "Number of planes reported is too high " << planeCountReported
1596 				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
1597 				<< tcu::TestLog::EndMessage;
1598 
1599 		planeCountTested = MAX_TESTED_PLANE_COUNT;
1600 	}
1601 
1602 	planeProperties.resize(planeCountTested);
1603 	planeCountRetrieved = planeCountTested;
1604 
1605 	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
1606 																&planeCountRetrieved,	// uint32_t*					pPropertyCount
1607 																&planeProperties[0]);	// VkDisplayPlanePropertiesKHR*	pProperties
1608 
1609 	if (result != VK_SUCCESS && result != VK_INCOMPLETE )
1610 		TCU_FAIL_STR(string("Expected VK_SUCCESS or VK_INCOMPLETE expected. Have ") + getResultAsString(result));
1611 
1612 	if (planeCountRetrieved != planeCountTested)
1613 		TCU_FAIL_STR(	string("Number of planes requested (") + de::toString(planeCountTested) +
1614 						") does not match retrieved (" + de::toString(planeCountRetrieved) + ")");
1615 
1616 	// Iterate through displays-modes
1617 	for (DisplayVector::iterator	it =  displaysVector.begin();
1618 									it != displaysVector.end();
1619 									it++)
1620 	{
1621 		const VkDisplayKHR						display						=	*it;
1622 		std::vector<VkDisplayModePropertiesKHR>	modesPropertiesForDisplay;
1623 
1624 		if (!getDisplayModeProperties(display, modesPropertiesForDisplay))
1625 			TCU_FAIL("Failed to retrieve display mode properties");
1626 
1627 		for (deUint32	modeIndex = 0;
1628 						modeIndex < modesPropertiesForDisplay.size();
1629 						modeIndex++)
1630 		{
1631 			const VkDisplayModeKHR				displayMode		=	modesPropertiesForDisplay[modeIndex].displayMode;
1632 			const VkDisplayModePropertiesKHR&	modeProperties	=	modesPropertiesForDisplay[modeIndex];
1633 
1634 			for (deUint32	planeIndex = 0;
1635 							planeIndex < planeCountTested;
1636 							planeIndex++)
1637 			{
1638 				std::vector<VkDisplayKHR>	displaysForPlane;
1639 
1640 				if (!getDisplaysForPlane(planeIndex, displaysForPlane))
1641 					TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));
1642 
1643 				if (displaysForPlane.empty())
1644 					continue;
1645 
1646 				// Iterate through displays supported by the plane
1647 				for (deUint32	displayIndex = 0;
1648 								displayIndex < displaysForPlane.size();
1649 								displayIndex++)
1650 				{
1651 					const VkDisplayKHR				planeDisplay		=	displaysForPlane[displayIndex];
1652 					VkDisplayPlaneCapabilitiesKHR	planeCapabilities;
1653 					bool							fullDisplayPlane;
1654 
1655 					if (display == planeDisplay)
1656 					{
1657 						deMemset(&planeCapabilities, 0, sizeof(planeCapabilities));
1658 
1659 						result = m_vki.getDisplayPlaneCapabilitiesKHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
1660 																		displayMode,			// VkDisplayModeKHR					mode
1661 																		planeIndex,				// uint32_t							planeIndex
1662 																		&planeCapabilities);	// VkDisplayPlaneCapabilitiesKHR*	pCapabilities
1663 
1664 						if (result != VK_SUCCESS)
1665 							TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1666 
1667 						fullDisplayPlane	=	   planeCapabilities.minDstExtent.height == modeProperties.parameters.visibleRegion.height
1668 												&& planeCapabilities.minDstExtent.width  == modeProperties.parameters.visibleRegion.width;
1669 
1670 						if (fullDisplayPlane && (planeCapabilities.supportedAlpha & VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR) != 0)
1671 						{
1672 							const VkDisplayPlaneAlphaFlagBitsKHR	alphaMode	=	VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
1673 							const VkInstance						instance	=	m_context.getInstance();
1674 							const VkDisplaySurfaceCreateInfoKHR		createInfo	=	{
1675 																						VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR,	// VkStructureType					sType
1676 																						DE_NULL,											// const void*						pNext
1677 																						0,													// VkDisplaySurfaceCreateFlagsKHR	flags
1678 																						displayMode,										// VkDisplayModeKHR					displayMode
1679 																						planeIndex,											// uint32_t							planeIndex
1680 																						planeProperties[planeIndex].currentStackIndex,		// uint32_t							planeStackIndex
1681 																						VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,				// VkSurfaceTransformFlagBitsKHR	transform
1682 																						1.0f,												// float							globalAlpha
1683 																						alphaMode,											// VkDisplayPlaneAlphaFlagBitsKHR	alphaMode
1684 																						{													// VkExtent2D						imageExtent
1685 																							planeCapabilities.minDstExtent.width,
1686 																							planeCapabilities.minDstExtent.height
1687 																						}
1688 																					};
1689 							VkSurfaceKHR							surface		=	DE_NULL;
1690 
1691 							result = m_vki.createDisplayPlaneSurfaceKHR(	instance,		// VkInstance							instance
1692 																			&createInfo,	// const VkDisplaySurfaceCreateInfoKHR*	pCreateInfo
1693 																			DE_NULL,		// const VkAllocationCallbacks*			pAllocator
1694 																			&surface);		// VkSurfaceKHR*						pSurface
1695 
1696 							if (result != VK_SUCCESS)
1697 								TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1698 
1699 							if (surface == DE_NULL)
1700 								TCU_FAIL("Invalid surface handle returned");
1701 
1702 							if (testKind == SURFACE_COUNTERS)
1703 							{
1704 								// Check surface counters.
1705 								try
1706 								{
1707 									const vk::VkSurfaceCapabilities2EXT	capsExt = vk::wsi::getPhysicalDeviceSurfaceCapabilities2EXT	(m_vki, m_physicalDevice, surface);
1708 									const vk::VkSurfaceCapabilitiesKHR	capsKhr = vk::wsi::getPhysicalDeviceSurfaceCapabilities		(m_vki, m_physicalDevice, surface);
1709 
1710 									if (!vk::wsi::sameSurfaceCapabilities(capsKhr, capsExt))
1711 									{
1712 										throw SurfaceCountersError("KHR and EXT surface capabilities do not match");
1713 									}
1714 
1715 									for (deUint32 i = 0; i < sizeof(capsExt.supportedSurfaceCounters) * 8; ++i)
1716 									{
1717 										deUint32 mask = (1<<i);
1718 										if (capsExt.supportedSurfaceCounters & mask)
1719 										{
1720 											if (mask != static_cast<deUint32>(VK_SURFACE_COUNTER_VBLANK_EXT))
1721 											{
1722 												std::ostringstream msg;
1723 												msg << "Invalid bit set in supportedSurfaceCounters: 0x" << std::hex << mask;
1724 												throw SurfaceCountersError(msg.str());
1725 											}
1726 										}
1727 									}
1728 								}
1729 								catch(const SurfaceCountersError& err)
1730 								{
1731 									surfaceCountersErr = err.what();
1732 								}
1733 							}
1734 
1735 							m_vki.destroySurfaceKHR(	instance,	// VkInstance							instance
1736 														surface,	// VkSurfaceKHR*						pSurface
1737 														DE_NULL);	// const VkAllocationCallbacks*			pAllocator
1738 
1739 							testPerformed = true;
1740 						}
1741 					}
1742 				}
1743 			}
1744 		}
1745 	}
1746 
1747 	if (!testPerformed)
1748 		TCU_THROW(NotSupportedError, "Cannot find suitable parameters for the test");
1749 
1750 	return ((surfaceCountersErr.empty()) ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail(surfaceCountersErr));
1751 }
1752 
1753 /*--------------------------------------------------------------------*//*!
1754  * \brief Display enumeration coverage test using VK_KHR_get_display_properties2
1755  *
1756  * Throws an exception on fail.
1757  *
1758  * \return tcu::TestStatus::pass on success
1759  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayProperties2KHR(void)1760 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayProperties2KHR (void)
1761 {
1762 	deUint32				displayCountReported	=	0u;
1763 	deUint32				displayCountToTest		=	0u;
1764 	tcu::ResultCollector	results						(m_log);
1765 	VkResult				result;
1766 
1767 	result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
1768 															&displayCountReported,	// uint32_t*				pPropertyCount
1769 															DE_NULL);				// VkDisplayProperties2KHR*	pProperties
1770 
1771 	if (   result != VK_SUCCESS
1772 		&& result != VK_INCOMPLETE
1773 		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
1774 		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
1775 		)
1776 	{
1777 		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
1778 	}
1779 
1780 	if (result != VK_SUCCESS)
1781 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1782 
1783 	if (displayCountReported == 0)
1784 		TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str());
1785 
1786 	displayCountToTest = displayCountReported;
1787 	if (displayCountReported > MAX_TESTED_DISPLAY_COUNT)
1788 	{
1789 		m_log	<< tcu::TestLog::Message
1790 				<< "Number of displays reported is too high " << displayCountReported
1791 				<< ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT
1792 				<< tcu::TestLog::EndMessage;
1793 
1794 		displayCountToTest = MAX_TESTED_DISPLAY_COUNT;
1795 	}
1796 
1797 	// Test the call correctly writes data in various size arrays
1798 	for (deUint32	displayCountRequested = 0;
1799 					displayCountRequested < displayCountToTest + 2;
1800 					displayCountRequested++)
1801 	{
1802 		const deUint32							displayCountExpected			=	std::min(displayCountRequested, displayCountReported);
1803 		const VkDisplayPropertiesKHR			nonUpdatedDisplayProperties		=	{	// Most values are set to fail the test to make sure driver updates them
1804 																						DE_NULL,								// VkDisplayKHR					display
1805 																						DE_NULL,								// const char*					displayName
1806 																						{0, 0},									// VkExtent2D					physicalDimensions
1807 																						{0, 0},									// VkExtent2D					physicalResolution
1808 																						~RECOGNIZED_SURFACE_TRANSFORM_FLAGS,	// VkSurfaceTransformFlagsKHR	supportedTransforms
1809 																						(vk::VkBool32)(VK_TRUE + 1),			// VkBool32						planeReorderPossible
1810 																						(vk::VkBool32)(VK_TRUE + 1)				// VkBool32						persistentContent
1811 																					};
1812 		const VkStructureType					queryStructureType				=	VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR;
1813 		const VkDisplayProperties2KHR			nonUpdatedDisplayProperties2	=	{
1814 																						queryStructureType,			// VkStructureType			sType
1815 																						DE_NULL,					// void*					pNext
1816 																						nonUpdatedDisplayProperties	// VkDisplayPropertiesKHR	displayProperties
1817 																					};
1818 		const VkDisplayKHR						canaryDisplay					=	static_cast<VkDisplayKHR>(0xABCDEF11);
1819 		const deUint32							canaryItemCount					=	1;
1820 		std::vector<VkDisplayProperties2KHR>	displaysProps2						(displayCountRequested + canaryItemCount, nonUpdatedDisplayProperties2);
1821 		deUint32								displayCountRetrieved			=	displayCountRequested;
1822 		DisplaySet								displaySet;
1823 
1824 		displaysProps2[displayCountExpected].displayProperties.display = canaryDisplay;
1825 
1826 		result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
1827 																&displayCountRetrieved,	// uint32_t*				pPropertyCount
1828 																&displaysProps2[0]);	// VkDisplayProperties2KHR*	pProperties
1829 
1830 		// Check amount of data written equals to expected
1831 		if (displayCountRetrieved != displayCountExpected)
1832 			TCU_FAIL_STR(	string("displayCountRetrieved != displayCountExpected, ") +
1833 							de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));
1834 
1835 		if (displayCountRequested >= displayCountReported)
1836 		{
1837 			if (result != VK_SUCCESS)
1838 				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1839 		}
1840 		else
1841 		{
1842 			if (result != VK_INCOMPLETE)
1843 				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1844 		}
1845 
1846 		// Check the driver has written something
1847 		for (deUint32	displayIndex = 0;
1848 						displayIndex < displayCountRetrieved;
1849 						displayIndex++)
1850 		{
1851 			const VkDisplayProperties2KHR&	properties2 = displaysProps2[displayIndex];
1852 			const VkDisplayPropertiesKHR&	properties	= properties2.displayProperties;
1853 
1854 			displaySet.insert(properties.display);
1855 
1856 			results.check(	properties2.sType == queryStructureType,
1857 							"sType has changed to " + de::toString(properties2.sType));
1858 
1859 			results.check(	properties2.pNext == DE_NULL,
1860 							"pNext has changed to " + de::toString(properties2.pNext));
1861 
1862 			validateDisplayProperties(results, properties, nonUpdatedDisplayProperties);
1863 
1864 			if (results.getResult() != QP_TEST_RESULT_PASS)
1865 			{
1866 				m_log	<< tcu::TestLog::Message
1867 						<< "Error detected " << results.getMessage()
1868 						<< " for display " << displayIndex << " with properties " << properties2
1869 						<< " non updated display properties are " << nonUpdatedDisplayProperties2
1870 						<< tcu::TestLog::EndMessage;
1871 
1872 				TCU_FAIL_STR(results.getMessage());
1873 			}
1874 		}
1875 
1876 		// Check the driver has not written more than requested
1877 		if (displaysProps2[displayCountExpected].displayProperties.display != canaryDisplay)
1878 			TCU_FAIL("Memory damage detected: driver has written more than expected");
1879 
1880 		// Check display handle uniqueness
1881 		if (displaySet.size() != displayCountRetrieved)
1882 			TCU_FAIL("Display handle duplication detected");
1883 	}
1884 
1885 	return tcu::TestStatus::pass("pass");
1886 }
1887 
1888 /*--------------------------------------------------------------------*//*!
1889  * \brief Plane enumeration coverage test using VK_KHR_get_display_properties2
1890  *
1891  * Throws an exception on fail.
1892  *
1893  * \return tcu::TestStatus::pass on success
1894  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayPlaneProperties2KHR(void)1895 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlaneProperties2KHR (void)
1896 {
1897 	DisplayVector			displaysVector;
1898 	DisplaySet				displaySet;
1899 	deUint32				planeCountReported	=	0u;
1900 	deUint32				planeCountTested	=	0u;
1901 	tcu::ResultCollector	results					(m_log);
1902 	VkResult				result;
1903 
1904 	// Create a list of displays available
1905 	if (!getDisplays2(displaysVector))
1906 		TCU_FAIL("Failed to retrieve displays");
1907 
1908 	if (displaysVector.empty())
1909 		TCU_THROW(NotSupportedError, "No displays reported");
1910 
1911 	displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());
1912 
1913 	// Get planes to test
1914 	result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
1915 																&planeCountReported,	// uint32_t*						pPropertyCount
1916 																DE_NULL);				// VkDisplayPlaneProperties2KHR*	pProperties
1917 
1918 	if (   result != VK_SUCCESS
1919 		&& result != VK_INCOMPLETE
1920 		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
1921 		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
1922 		)
1923 	{
1924 		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
1925 	}
1926 
1927 	if (result != VK_SUCCESS)
1928 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1929 
1930 	if (planeCountReported == 0)
1931 		TCU_THROW(ResourceError, "Cannot perform test: no planes found");
1932 
1933 	planeCountTested = planeCountReported;
1934 	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1935 	{
1936 		m_log	<< tcu::TestLog::Message
1937 				<< "Number of planes reported is too high " << planeCountReported
1938 				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
1939 				<< tcu::TestLog::EndMessage;
1940 
1941 		planeCountTested = MAX_TESTED_PLANE_COUNT;
1942 	}
1943 
1944 	// Test the call correctly writes data in various size arrays
1945 	for (deUint32	planeCountRequested = 0;
1946 					planeCountRequested < planeCountTested + 2;
1947 					planeCountRequested++)
1948 	{
1949 		const deUint32								planeCountExpected			=	std::min(planeCountRequested, planeCountReported);
1950 		const VkDisplayPlanePropertiesKHR			nonUpdatedPlaneProperties	=	{	// Most values are set to fail the test to make sure driver updates them
1951 																						DE_NULL,			// VkDisplayKHR	currentDisplay
1952 																						planeCountReported	// deUint32		currentStackIndex
1953 																					};
1954 		const VkStructureType						queryStructureType			=	VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR;
1955 		const VkDisplayPlaneProperties2KHR			nonUpdatedPlaneProperties2	=	{
1956 																						queryStructureType,			// VkStructureType				sType
1957 																						DE_NULL,					// void*						pNext
1958 																						nonUpdatedPlaneProperties	// VkDisplayPlanePropertiesKHR	displayPlaneProperties
1959 																					};
1960 		const VkDisplayKHR							canaryDisplay				=	static_cast<VkDisplayKHR>(0xABCDEF11);
1961 		const deUint32								canaryItemCount				=	1;
1962 		std::vector<VkDisplayPlaneProperties2KHR>	planeProps2						(planeCountRequested + canaryItemCount, nonUpdatedPlaneProperties2);
1963 		deUint32									planeCountRetrieved			=	planeCountRequested;
1964 
1965 		planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay = canaryDisplay;
1966 
1967 		result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
1968 																	&planeCountRetrieved,	// uint32_t*						pPropertyCount
1969 																	&planeProps2[0]);		// VkDisplayPlaneProperties2KHR*	pProperties
1970 
1971 		// Check amount of data written equals to expected
1972 		if (planeCountRetrieved != planeCountExpected)
1973 			TCU_FAIL_STR(	string("planeCountRetrieved != planeCountExpected, ") +
1974 							de::toString(planeCountRetrieved) + " != " + de::toString(planeCountExpected));
1975 
1976 		if (planeCountRequested >= planeCountReported)
1977 		{
1978 			if (result != VK_SUCCESS)
1979 				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1980 		}
1981 		else
1982 		{
1983 			if (result != VK_INCOMPLETE)
1984 				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1985 		}
1986 
1987 		// Check the driver has written something
1988 		for (deUint32	planeIndex = 0;
1989 						planeIndex < planeCountRetrieved;
1990 						planeIndex++)
1991 		{
1992 			const VkDisplayPlaneProperties2KHR&	properties2		= planeProps2[planeIndex];
1993 			const VkDisplayPlanePropertiesKHR&	properties		= properties2.displayPlaneProperties;
1994 
1995 			results.check(	properties2.sType == queryStructureType,
1996 							"sType has changed to " + de::toString(properties2.sType));
1997 
1998 			results.check(	properties2.pNext == DE_NULL,
1999 							"pNext has changed to " + de::toString(properties2.pNext));
2000 
2001 			validateDisplayPlaneProperties(results, properties, nonUpdatedPlaneProperties, displaySet);
2002 
2003 			if (results.getResult() != QP_TEST_RESULT_PASS)
2004 			{
2005 				m_log	<< tcu::TestLog::Message
2006 						<< "Error detected " << results.getMessage()
2007 						<< " for plane " << planeIndex << " with properties " << properties2
2008 						<< tcu::TestLog::EndMessage;
2009 
2010 				TCU_FAIL_STR(results.getMessage());
2011 			}
2012 		}
2013 
2014 		// Check the driver has not written more than requested
2015 		if (planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay != canaryDisplay)
2016 			TCU_FAIL("Memory damage detected: driver has written more than expected");
2017 	}
2018 
2019 	return tcu::TestStatus::pass("pass");
2020 }
2021 
2022 /*--------------------------------------------------------------------*//*!
2023  * \brief Display-plane capabilities coverage test using VK_KHR_get_display_properties2
2024  *
2025  * Throws an exception on fail.
2026  *
2027  * \return tcu::TestStatus::pass on success
2028  *//*--------------------------------------------------------------------*/
testGetDisplayPlaneCapabilities2KHR(void)2029 tcu::TestStatus	DisplayCoverageTestInstance::testGetDisplayPlaneCapabilities2KHR (void)
2030 {
2031 	deUint32	planeCountReported	=	0u;
2032 	VkResult	result;
2033 
2034 	result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
2035 																&planeCountReported,	// uint32_t*						pPropertyCount
2036 																DE_NULL);				// VkDisplayPlaneProperties2KHR*	pProperties
2037 
2038 	if (result != VK_SUCCESS)
2039 		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
2040 
2041 	if (planeCountReported == 0)
2042 		TCU_THROW(NotSupportedError, "No display plane reported");
2043 
2044 	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
2045 	{
2046 		m_log	<< tcu::TestLog::Message
2047 				<< "Number of planes reported is too high " << planeCountReported
2048 				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
2049 				<< tcu::TestLog::EndMessage;
2050 
2051 		planeCountReported = MAX_TESTED_PLANE_COUNT;
2052 	}
2053 
2054 	for (deUint32	planeIndex = 0;
2055 					planeIndex < planeCountReported;
2056 					planeIndex++)
2057 	{
2058 		std::vector<VkDisplayKHR> displaysForPlane;
2059 
2060 		if (!getDisplaysForPlane(planeIndex, displaysForPlane))
2061 			TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));
2062 
2063 		if (displaysForPlane.empty())
2064 			continue;
2065 
2066 		// Check the driver has written something
2067 		for (deUint32	displayIndex = 0;
2068 						displayIndex < displaysForPlane.size();
2069 						displayIndex++)
2070 		{
2071 			const VkDisplayKHR							display						=	displaysForPlane[displayIndex];
2072 			std::vector<VkDisplayModeProperties2KHR>	modesPropertiesForDisplay;
2073 
2074 			if (!getDisplayModeProperties2(display, modesPropertiesForDisplay))
2075 				TCU_FAIL("Failed to retrieve display mode properties");
2076 
2077 			for (deUint32	modeIndex = 0;
2078 							modeIndex < modesPropertiesForDisplay.size();
2079 							modeIndex++)
2080 			{
2081 				const VkDisplayModeKHR			displayMode				=	modesPropertiesForDisplay[modeIndex].displayModeProperties.displayMode;
2082 				const deUint32					unrecognizedAlphaFlags	=	~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS;
2083 				const VkDisplayPlaneInfo2KHR	planeInfo2				=	{
2084 																				VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR, // VkStructureType	sType
2085 																				DE_NULL,									// const void*		pNext
2086 																				displayMode,								// VkDisplayModeKHR	mode
2087 																				planeIndex									// uint32_t			planeIndex
2088 																			};
2089 				VkDisplayPlaneCapabilitiesKHR	planeCapabilities		=	{
2090 																				unrecognizedAlphaFlags,	// VkDisplayPlaneAlphaFlagsKHR	supportedAlpha
2091 																				{ -1, -1 },				// VkOffset2D					minSrcPosition
2092 																				{ -1, -1 },				// VkOffset2D					maxSrcPosition
2093 																				{ 1, 1 },				// VkExtent2D					minSrcExtent
2094 																				{ 0, 0 },				// VkExtent2D					maxSrcExtent
2095 																				{ 1, 1 },				// VkOffset2D					minDstPosition
2096 																				{ 0, 0 },				// VkOffset2D					maxDstPosition
2097 																				{ 1, 1 },				// VkExtent2D					minDstExtent
2098 																				{ 0, 0 },				// VkExtent2D					maxDstExtent
2099 																			};
2100 				const VkStructureType			queryStructureType		=	VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR;
2101 				VkDisplayPlaneCapabilities2KHR	planeCapabilities2		=	{
2102 																				queryStructureType,	// VkStructureType					sType
2103 																				DE_NULL,			// void*							pNext
2104 																				planeCapabilities	// VkDisplayPlaneCapabilitiesKHR	capabilities
2105 																			};
2106 				tcu::ResultCollector			results						(m_log);
2107 
2108 				result = m_vki.getDisplayPlaneCapabilities2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
2109 																&planeInfo2,			// const VkDisplayPlaneInfo2KHR*	pDisplayPlaneInfo
2110 																&planeCapabilities2);	// VkDisplayPlaneCapabilities2KHR*	pCapabilities
2111 
2112 				results.check(	result == VK_SUCCESS,
2113 								string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
2114 
2115 				results.check(	planeCapabilities2.sType == queryStructureType,
2116 								"sType has changed to " + de::toString(planeCapabilities2.sType));
2117 
2118 				results.check(	planeCapabilities2.pNext == DE_NULL,
2119 								"pNext has changed to " + de::toString(planeCapabilities2.pNext));
2120 
2121 				// Validate results returned by driver in planeCapabilities2 using non-updated planeCapabilities
2122 				validateDisplayPlaneCapabilities(results, planeCapabilities2.capabilities, planeCapabilities);
2123 
2124 				if (results.getResult() != QP_TEST_RESULT_PASS)
2125 				{
2126 					m_log	<< tcu::TestLog::Message
2127 							<< "Error detected " << results.getMessage()
2128 							<< " for plane's " << planeIndex
2129 							<< " display " << displayIndex
2130 							<< " and mode " << modeIndex
2131 							<< " with capabilities " << planeCapabilities2
2132 							<< tcu::TestLog::EndMessage;
2133 
2134 					TCU_FAIL_STR(results.getMessage());
2135 				}
2136 			}
2137 		}
2138 	}
2139 
2140 	return tcu::TestStatus::pass("pass");
2141 }
2142 
2143 /*--------------------------------------------------------------------*//*!
2144  * \brief Display mode properties coverage test using VK_KHR_get_display_properties2
2145  *
2146  * Throws an exception on fail.
2147  *
2148  * \return tcu::TestStatus::pass on success
2149  *//*--------------------------------------------------------------------*/
testGetDisplayModeProperties2KHR(void)2150 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModeProperties2KHR (void)
2151 {
2152 	VkResult				result;
2153 	tcu::ResultCollector	results			(m_log);
2154 	DisplayVector			displaysVector;
2155 
2156 	if (!getDisplays2(displaysVector))
2157 		TCU_FAIL("Failed to retrieve displays list");
2158 
2159 	if (displaysVector.empty())
2160 		TCU_THROW(NotSupportedError, "No displays reported");
2161 
2162 	for (DisplayVector::iterator	it =  displaysVector.begin();
2163 									it != displaysVector.end();
2164 									it++)
2165 	{
2166 		VkDisplayKHR	display				= *it;
2167 		deUint32		modesCountReported	= 0u;
2168 
2169 		result = m_vki.getDisplayModeProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
2170 														display,				// VkDisplayKHR					display
2171 														&modesCountReported,	// uint32_t*					pPropertyCount
2172 														DE_NULL);				// VkDisplayModeProperties2KHR*	pProperties
2173 
2174 		// Test the call correctly writes data in various size arrays
2175 		for (deUint32	modesCountRequested = 0;
2176 						modesCountRequested < modesCountReported + 2;
2177 						modesCountRequested = nextTestNumber(modesCountRequested, modesCountReported + 2))
2178 		{
2179 			const deUint32								modesCountExpected			=	std::min(modesCountRequested, modesCountReported);
2180 			const VkDisplayModeKHR						nullDisplayMode				=	DE_NULL;
2181 			const VkDisplayModePropertiesKHR			nonUpdatedModeProperties	=	{
2182 																							nullDisplayMode,	// VkDisplayModeKHR				displayMode
2183 																							{					// VkDisplayModeParametersKHR	parameters
2184 																								{0, 0},			// VkExtent2D					visibleRegion
2185 																								0				// uint32_t						refreshRate
2186 																							}
2187 																						};
2188 			const VkStructureType						queryStructureType			=	VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR;
2189 			const VkDisplayModeProperties2KHR			nonUpdatedModeProperties2	=	{
2190 																							queryStructureType,			// VkStructureType				sType
2191 																							DE_NULL,					// void*						pNext
2192 																							nonUpdatedModeProperties	// VkDisplayModePropertiesKHR	displayModeProperties
2193 																						};
2194 			const VkDisplayModeKHR						canaryDisplayMode			=	static_cast<VkDisplayModeKHR>(0xABCDEF11);
2195 			const deUint32								canaryItemCount				=	1;
2196 			std::vector<VkDisplayModeProperties2KHR>	modesProperties2				(modesCountRequested + canaryItemCount, nonUpdatedModeProperties2);
2197 			deUint32									modesCountRetrieved			=	modesCountRequested;
2198 
2199 			modesProperties2[modesCountExpected].displayModeProperties.displayMode = canaryDisplayMode;
2200 
2201 			result = m_vki.getDisplayModeProperties2KHR(m_physicalDevice,		// VkPhysicalDevice				physicalDevice
2202 														display,				// VkDisplayKHR					display
2203 														&modesCountRetrieved,	// uint32_t*					pPropertyCount
2204 														&modesProperties2[0]);	// VkDisplayModeProperties2KHR*	pProperties
2205 
2206 			// Check amount of data written equals to expected
2207 			if (modesCountRetrieved != modesCountExpected)
2208 				TCU_FAIL_STR(	string("modesCountRetrieved != modesCountExpected, ") +
2209 								de::toString(modesCountRetrieved) + " != " + de::toString(modesCountExpected));
2210 
2211 			if (modesCountRequested >= modesCountReported)
2212 			{
2213 				if (result != VK_SUCCESS)
2214 					TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
2215 			}
2216 			else
2217 			{
2218 				if (result != VK_INCOMPLETE)
2219 					TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
2220 			}
2221 
2222 			// Check the driver has written something
2223 			for (deUint32	modeIndex = 0;
2224 							modeIndex < modesCountExpected;
2225 							modeIndex++)
2226 			{
2227 				const VkDisplayModeProperties2KHR&	properties2	= modesProperties2[modeIndex];
2228 				const VkDisplayModePropertiesKHR&	properties	= properties2.displayModeProperties;
2229 
2230 				results.check(	properties2.sType == queryStructureType,
2231 								"sType has changed to " + de::toString(properties2.sType));
2232 
2233 				results.check(	properties2.pNext == DE_NULL,
2234 								"pNext has changed to " + de::toString(properties2.pNext));
2235 
2236 				validateDisplayModeProperties(results, properties, nonUpdatedModeProperties);
2237 
2238 				if (results.getResult() != QP_TEST_RESULT_PASS)
2239 				{
2240 					m_log	<< tcu::TestLog::Message
2241 							<< "Error detected " << results.getMessage()
2242 							<< " for mode " << modeIndex << " with properties " << properties2
2243 							<< " non updated mode properties are " << nonUpdatedModeProperties2
2244 							<< tcu::TestLog::EndMessage;
2245 
2246 					TCU_FAIL_STR(results.getMessage());
2247 				}
2248 			}
2249 
2250 			// Check the driver has not written more than requested
2251 			if (modesProperties2[modesCountExpected].displayModeProperties.displayMode != canaryDisplayMode)
2252 				TCU_FAIL("Memory damage detected: driver has written more than expected");
2253 		}
2254 	}
2255 
2256 	return tcu::TestStatus::pass("pass");
2257 }
2258 
2259 
2260 /*--------------------------------------------------------------------*//*!
2261  * \brief Display coverage tests case class
2262  *//*--------------------------------------------------------------------*/
2263 class DisplayCoverageTestsCase : public vkt::TestCase
2264 {
2265 public:
DisplayCoverageTestsCase(tcu::TestContext & context,const char * name,const char * description,const DisplayIndexTest testId)2266 	DisplayCoverageTestsCase (tcu::TestContext &context, const char *name, const char *description, const DisplayIndexTest testId)
2267 		: TestCase	(context, name, description)
2268 		, m_testId	(testId)
2269 	{
2270 	}
2271 private:
2272 	const DisplayIndexTest	m_testId;
2273 
createInstance(vkt::Context & context) const2274 	vkt::TestInstance*	createInstance	(vkt::Context& context) const
2275 	{
2276 		return new DisplayCoverageTestInstance(context, m_testId);
2277 	}
2278 };
2279 
2280 
2281 /*--------------------------------------------------------------------*//*!
2282  * \brief Adds a test into group
2283  *//*--------------------------------------------------------------------*/
addTest(tcu::TestCaseGroup * group,const DisplayIndexTest testId,const char * name,const char * description)2284 static void addTest (tcu::TestCaseGroup* group, const DisplayIndexTest testId, const char* name, const char* description)
2285 {
2286 	tcu::TestContext&	testCtx	= group->getTestContext();
2287 
2288 	group->addChild(new DisplayCoverageTestsCase(testCtx, name, description, testId));
2289 }
2290 
2291 /*--------------------------------------------------------------------*//*!
2292  * \brief Adds VK_KHR_display and VK_KHR_display_swapchain extension tests into group
2293  *//*--------------------------------------------------------------------*/
createDisplayCoverageTests(tcu::TestCaseGroup * group)2294 void createDisplayCoverageTests (tcu::TestCaseGroup* group)
2295 {
2296 	// VK_KHR_display extension tests
2297 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES,				"get_display_properties",				"Display enumeration coverage test");
2298 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES,					"get_display_plane_properties",			"Planes enumeration coverage test");
2299 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY,	"get_display_plane_supported_displays", "Display plane support coverage test");
2300 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE,						"get_display_mode_properties",			"Display mode properties coverage test");
2301 	addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE,					"create_display_mode",					"Create display mode coverage test");
2302 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES,		"get_display_plane_capabilities",		"Display-plane capabilities coverage test");
2303 	addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE,			"create_display_plane_surface",			"Create display plane surface coverage test");
2304 	addTest(group, DISPLAY_TEST_INDEX_SURFACE_COUNTERS,						"surface_counters",						"Display plane surface counters test");
2305 
2306 	// VK_KHR_get_display_properties2 extension tests
2307 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2,				"get_display_properties2",				"Display enumeration coverage test using VK_KHR_get_display_properties2");
2308 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2,					"get_display_plane_properties2",		"Planes enumeration coverage test using VK_KHR_get_display_properties2");
2309 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2,					"get_display_mode_properties2",			"Display mode properties coverage test using VK_KHR_get_display_properties2");
2310 	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2,		"get_display_plane_capabilities2",		"Display-plane capabilities coverage test using VK_KHR_get_display_properties2");
2311 }
2312 
2313 } //wsi
2314 } //vkt
2315 
2316