/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Vulkan coverage tests for extensions VK_KHR_display,
 *        VK_KHR_get_display_properties2
 *//*--------------------------------------------------------------------*/

#include "vktWsiDisplayTests.hpp"

#include "vktTestCase.hpp"
#include "vkStrUtil.hpp"
#include "vkPrograms.hpp"
#include "vkRef.hpp"

#include "tcuDefs.hpp"
#include "tcuTestLog.hpp"
#include "tcuResultCollector.hpp"

#include "deMemory.h"
#include "deSTLUtil.hpp"
#include "deStringUtil.hpp"

#include <set>
#include <map>
#include <limits>

namespace vkt
{
namespace wsi
{
using namespace vk;
using std::vector;
using std::map;
using std::set;
using std::string;

#ifndef TCU_FAIL_STR
	#define TCU_FAIL_STR(MSG) TCU_FAIL(string(MSG).c_str())
#endif

enum DisplayIndexTest
{
	DISPLAY_TEST_INDEX_START,
	DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES,
	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES,
	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY,
	DISPLAY_TEST_INDEX_GET_DISPLAY_MODE,
	DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE,
	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES,
	DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE,
	DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2,
	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2,
	DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2,
	DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2,
	DISPLAY_TEST_INDEX_LAST
};

template <typename Type>
class BinaryCompare
{
public:
	bool operator() (const Type& a, const Type& b) const
	{
		return deMemCmp(&a, &b, sizeof(Type)) < 0;
	}
};

typedef std::set<vk::VkDisplayKHR, BinaryCompare<vk::VkDisplayKHR> >	DisplaySet;
typedef std::vector<vk::VkDisplayKHR>									DisplayVector;
typedef std::vector<vk::VkDisplayModePropertiesKHR>						DisplayModePropertiesVector;
typedef std::vector<vk::VkDisplayModeProperties2KHR>					DisplayModeProperties2Vector;

const deUint32 DEUINT32_MAX = std::numeric_limits<deUint32>::max();

const deUint32 RECOGNIZED_SURFACE_TRANSFORM_FLAGS =
														  vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR
														| vk::VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;

const deUint32 RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS =
														  VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR
														| VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR
														| VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR
														| VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR;
enum DisplayMaxTestedConsts
{
	MAX_TESTED_DISPLAY_COUNT	= 16,
	MAX_TESTED_PLANE_COUNT		= 16,
};

/*--------------------------------------------------------------------*//*!
 * \brief Return Vulkan result name or code as std::string.
 *
 * \param result Vulkan code to convert to string
 * \return Vulkun result code name or code number as std::string
 *//*--------------------------------------------------------------------*/
std::string getResultAsString (vk::VkResult result)
{
	const char* resultAsChar = vk::getResultName(result);

	if (resultAsChar != DE_NULL)
		return std::string(resultAsChar);
	else
		return de::toString(result);
}

/*--------------------------------------------------------------------*//*!
 * \brief Moves test index to next test skipping middle tests.
 *
 * Gets first 3 tests and last 3 tests on long sequences.
 * After test number 2 moves index value to endIndex - 3.
 * Shortens the number of tests executed by skipping middle tests.
 *
 * Example:
 * for (i=0; i<endIndex; nextTestNumber(i, endIndex))
 * with endIndex = 4 generates 0,1,2,3
 * with endIndex = 9 generates 0,1,2,6,7,8
 *
 * \param index    Current iterator value
 * \param endIndex First number out of iteration sequence
 * \return new iterator value
 *//*--------------------------------------------------------------------*/
deUint32 nextTestNumber (deUint32 index, deUint32 endIndex)
{
	deUint32 result;

	if (endIndex > 6 && index == 2)
		result = endIndex - 3;
	else
		result = index + 1;

	return result;
}

/*--------------------------------------------------------------------*//*!
 * \brief Vulkan VK_KHR_display extensions coverage tests
 *//*--------------------------------------------------------------------*/
class DisplayCoverageTestInstance : public TestInstance
{
public:
								DisplayCoverageTestInstance						(Context& context, const DisplayIndexTest testId);
private:
	typedef void				(DisplayCoverageTestInstance::*EachSurfaceFunctionPtr)
																				(VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties);

	bool						getDisplays										(DisplayVector& displays);
	bool						getDisplaysForPlane								(deUint32 plane, DisplayVector& displays);
	bool						getDisplayModeProperties						(VkDisplayKHR display, DisplayModePropertiesVector& modeProperties);

	bool						getDisplays2									(DisplayVector& displays);
	bool						getDisplayModeProperties2						(VkDisplayKHR display, DisplayModeProperties2Vector& modeProperties);

	void						validateDisplayProperties						(	tcu::ResultCollector&					results,
																					const VkDisplayPropertiesKHR&			toValidate,
																					const VkDisplayPropertiesKHR&			nonUpdated);

	void						validateDisplayPlaneProperties					(	tcu::ResultCollector&					results,
																					const VkDisplayPlanePropertiesKHR&		toValidate,
																					const VkDisplayPlanePropertiesKHR&		nonUpdated,
																					DisplaySet&								displaySet);

	void						validateDisplayPlaneCapabilities				(	tcu::ResultCollector&					results,
																					const VkDisplayPlaneCapabilitiesKHR&	toValidate,
																					const VkDisplayPlaneCapabilitiesKHR&	nonUpdated);

	void						validateDisplayModeProperties					(	tcu::ResultCollector&					results,
																					const VkDisplayModePropertiesKHR&		toValidate,
																					const VkDisplayModePropertiesKHR&		nonUpdated);

	// VK_KHR_display extension tests
	tcu::TestStatus				testGetPhysicalDeviceDisplayPropertiesKHR		(void);
	tcu::TestStatus				testGetPhysicalDeviceDisplayPlanePropertiesKHR	(void);
	tcu::TestStatus				testGetDisplayPlaneSupportedDisplaysKHR			(void);
	tcu::TestStatus				testGetDisplayModePropertiesKHR					(void);
	tcu::TestStatus				testCreateDisplayModeKHR						(void);
	tcu::TestStatus				testGetDisplayPlaneCapabilitiesKHR				(void);
	tcu::TestStatus				testCreateDisplayPlaneSurfaceKHR				(void);

	// VK_KHR_get_display_properties2 extension tests
	tcu::TestStatus				testGetPhysicalDeviceDisplayProperties2KHR		(void);
	tcu::TestStatus				testGetPhysicalDeviceDisplayPlaneProperties2KHR	(void);
	tcu::TestStatus				testGetDisplayModeProperties2KHR				(void);
	tcu::TestStatus				testGetDisplayPlaneCapabilities2KHR				(void);

	tcu::TestStatus				iterate											(void);

	void						testCreateSharedSwapchainsKHRforSurface			(VkSurfaceKHR& surface, VkDisplayModePropertiesKHR& modeProperties);

	const InstanceInterface&	m_vki;
	const DeviceInterface&		m_vkd;
	tcu::TestLog&				m_log;
	const VkPhysicalDevice		m_physicalDevice;
	const DisplayIndexTest		m_testId;
};


/*--------------------------------------------------------------------*//*!
 * \brief DisplayCoverageTestInstance constructor
 *
 * Initializes DisplayCoverageTestInstance object
 *
 * \param context    Context object
 * \param parameters Test parameters structure
 *//*--------------------------------------------------------------------*/
DisplayCoverageTestInstance::DisplayCoverageTestInstance (Context& context, const DisplayIndexTest testId)
	: TestInstance		(context)
	, m_vki				(m_context.getInstanceInterface())
	, m_vkd				(m_context.getDeviceInterface())
	, m_log				(m_context.getTestContext().getLog())
	, m_physicalDevice	(m_context.getPhysicalDevice())
	, m_testId			(testId)
{
	const std::string extensionName("VK_KHR_display");

	if(!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionName))
		TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());

	switch (m_testId)
	{
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2:
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2:
		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2:
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2:
		{
			const std::string extensionNameAddition("VK_KHR_get_display_properties2");

			if(!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionNameAddition))
				TCU_THROW(NotSupportedError, std::string(extensionNameAddition + " is not supported").c_str());

			break;
		}

		default:
		{
			break;
		}
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Step forward test execution
 *
 * \return true if application should call iterate() again and false
 *         if test execution session is complete.
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::iterate (void)
{
	switch (m_testId)
	{
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES:					return testGetPhysicalDeviceDisplayPropertiesKHR();			break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES:						return testGetPhysicalDeviceDisplayPlanePropertiesKHR();	break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY:	return testGetDisplayPlaneSupportedDisplaysKHR();			break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE:						return testGetDisplayModePropertiesKHR();					break;
		case DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE:					return testCreateDisplayModeKHR();							break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES:			return testGetDisplayPlaneCapabilitiesKHR();				break;
		case DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE:			return testCreateDisplayPlaneSurfaceKHR();					break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2:				return testGetPhysicalDeviceDisplayProperties2KHR();		break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2:					return testGetPhysicalDeviceDisplayPlaneProperties2KHR();	break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2:						return testGetDisplayModeProperties2KHR();					break;
		case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2:		return testGetDisplayPlaneCapabilities2KHR();				break;
		default:
		{
			DE_FATAL("Impossible");
		}
	}

	TCU_FAIL("Invalid test identifier");
}

/*--------------------------------------------------------------------*//*!
 * \brief Fills vector with available displays. Clears passed vector at start.
 *
 * \param displays The vector filled with display handles
 * \return true on success, false on error
 *//*--------------------------------------------------------------------*/
bool DisplayCoverageTestInstance::getDisplays (DisplayVector& displays)
{
	deUint32							countReported	=	0u;
	deUint32							countRetrieved	=	0u;
	std::vector<VkDisplayPropertiesKHR>	displaysProps;
	VkResult							result;

	displays.clear();

	result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
															&countReported,		// uint32_t*				pPropertyCount
															DE_NULL);			// VkDisplayPropertiesKHR*	pProperties

	if (result != VK_SUCCESS)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result)
				<< " reported items count " << countReported
				<< tcu::TestLog::EndMessage;

		return false;
	}

	displaysProps.resize(countReported);

	countRetrieved = countReported;

	result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
															&countRetrieved,	// uint32_t*				pPropertyCount
															&displaysProps[0]);	// VkDisplayPropertiesKHR*	pProperties

	if (result != VK_SUCCESS || countRetrieved > countReported)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetPhysicalDeviceDisplayPropertiesKHR failed with " << getResultAsString(result)
				<< " reported items count " << countReported
				<< " retrieved items count " << countRetrieved
				<< tcu::TestLog::EndMessage;

		return false;
	}

	displays.reserve(countRetrieved);

	for (deUint32	displayIndex = 0;
					displayIndex < countRetrieved;
					displayIndex++)
	{
		const VkDisplayKHR display = displaysProps[displayIndex].display;

		if (display == DE_NULL)
		{
			displays.clear();

			return false;
		}

		displays.push_back(display);
	}

	return true;
}

/*--------------------------------------------------------------------*//*!
 * \brief Fills vector with available displays for plane specified.
 *
 * Clears passed vector at start and on error.
 *
 * \param plane		The plane to get displays for
 * \param displays	The vector filled with display handles
 * \return true on success, false on error
 *//*--------------------------------------------------------------------*/
bool DisplayCoverageTestInstance::getDisplaysForPlane(deUint32 plane, DisplayVector& displays)
{
	deUint32	countReported	=	0u;
	deUint32	countRetrieved	=	0u;
	VkResult	result;

	displays.clear();

	result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,	// VkPhysicalDevice	physicalDevice
														plane,				// uint32_t			planeIndex
														&countReported,		// uint32_t*		pDisplayCount
														DE_NULL);			// VkDisplayKHR*	pDisplays

	if (result != VK_SUCCESS)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result)
				<< " for plane " << plane
				<< " reported items count " << countReported
				<< tcu::TestLog::EndMessage;

		return false;
	}

	displays.resize(countReported);

	countRetrieved = countReported;

	result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,	// VkPhysicalDevice	physicalDevice
														plane,				// uint32_t			planeIndex
														&countRetrieved,	// uint32_t*		pDisplayCount
														&displays[0]);		// VkDisplayKHR*	pDisplays

	if (result != VK_SUCCESS || countRetrieved > countReported)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetDisplayPlaneSupportedDisplaysKHR failed with " << getResultAsString(result)
				<< " for plane " << plane
				<< " reported items count " << countReported
				<< " retrieved items count " << countRetrieved
				<< tcu::TestLog::EndMessage;

		displays.clear();

		return false;
	}

	if (countRetrieved < countReported)
		displays.resize(countRetrieved);

	return true;
}

/*--------------------------------------------------------------------*//*!
 * \brief Fills vector with available modes properties for display specified.
 *
 * Clears passed vector at start and on error.
 *
 * \param display	The display to get modes for
 * \param modes		The vector filled with display mode properties structures
 * \return true on success, false on error
 *//*--------------------------------------------------------------------*/
bool DisplayCoverageTestInstance::getDisplayModeProperties(VkDisplayKHR display, DisplayModePropertiesVector& modeProperties)
{
	deUint32	countReported	=	0u;
	deUint32	countRetrieved	=	0u;
	VkResult	result;

	modeProperties.clear();

	result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
												display,				// VkDisplayKHR					display
												&countReported,			// uint32_t*					pPropertyCount
												DE_NULL);				// VkDisplayModePropertiesKHR*	pProperties

	if (result != VK_SUCCESS)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result)
				<< " for display " << display
				<< " reported items count " << countReported
				<< tcu::TestLog::EndMessage;

		return false;
	}

	modeProperties.resize(countReported);

	countRetrieved = countReported;

	result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
												display,				// VkDisplayKHR					display
												&countRetrieved,		// uint32_t*					pPropertyCount
												&modeProperties[0]);	// VkDisplayModePropertiesKHR*	pProperties

	if (result != VK_SUCCESS || countRetrieved > countReported)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result)
				<< " for display " << display
				<< " reported items count " << countReported
				<< " retrieved items count " << countReported
				<< tcu::TestLog::EndMessage;

		modeProperties.clear();

		return false;
	}

	if (countRetrieved < countReported)
		modeProperties.resize(countRetrieved);

	return true;
}

/*--------------------------------------------------------------------*//*!
 * \brief Fills vector with available displays. Clears passed vector at start.
 *
 * Uses VK_KHR_get_display_properties2 extension API.
 * Clears passed vector at start.
 *
 * \param displays The vector filled with display handles
 * \return true on success, false on error
 *//*--------------------------------------------------------------------*/
bool DisplayCoverageTestInstance::getDisplays2 (DisplayVector& displays)
{
	deUint32								countReported		=	0u;
	deUint32								countRetrieved		=	0u;
	const VkDisplayPropertiesKHR			displayProperties	=	{
																		DE_NULL,										// VkDisplayKHR					display
																		DE_NULL,										// const char*					displayName
																		{0, 0},											// VkExtent2D					physicalDimensions
																		{0, 0},											// VkExtent2D					physicalResolution
																		0,												// VkSurfaceTransformFlagsKHR	supportedTransforms
																		VK_FALSE,										// VkBool32						planeReorderPossible
																		VK_FALSE										// VkBool32						persistentContent
																	};
	const VkDisplayProperties2KHR			displayProperties2	=	{
																		VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR,		// VkStructureType			sType
																		DE_NULL,										// void*					pNext
																		displayProperties								// VkDisplayPropertiesKHR	displayProperties
																	};

	std::vector<VkDisplayProperties2KHR>	displaysProps;
	VkResult								result;

	displays.clear();

	result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
															&countReported,		// uint32_t*				pPropertyCount
															DE_NULL);			// VkDisplayProperties2KHR*	pProperties

	if (result != VK_SUCCESS)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetPhysicalDeviceDisplayProperties2KHR failed with " << getResultAsString(result)
				<< " reported items count " << countReported
				<< tcu::TestLog::EndMessage;

		return false;
	}

	displaysProps.resize(countReported, displayProperties2);

	countRetrieved = countReported;

	result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,	// VkPhysicalDevice			physicalDevice
															&countRetrieved,	// uint32_t*				pPropertyCount
															&displaysProps[0]);	// VkDisplayPropertiesKHR*	pProperties

	if (result != VK_SUCCESS || countRetrieved > countReported)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetPhysicalDeviceDisplayProperties2KHR failed with " << getResultAsString(result)
				<< " reported items count " << countReported
				<< " retrieved items count " << countRetrieved
				<< tcu::TestLog::EndMessage;

		return false;
	}

	displays.reserve(countRetrieved);

	for (deUint32	displayIndex = 0;
					displayIndex < countRetrieved;
					displayIndex++)
	{
		const VkDisplayKHR display = displaysProps[displayIndex].displayProperties.display;

		if (display == DE_NULL)
		{
			displays.clear();

			return false;
		}

		displays.push_back(display);
	}

	return true;
}

/*--------------------------------------------------------------------*//*!
 * \brief Fills vector with available modes properties for display specified.
 *
 * Uses VK_KHR_get_display_properties2 extension API.
 * Clears passed vector at start and on error.
 *
 * \param display	The display to get modes for
 * \param modes		The vector filled with display mode properties structures
 * \return true on success, false on error
 *//*--------------------------------------------------------------------*/
bool DisplayCoverageTestInstance::getDisplayModeProperties2 (VkDisplayKHR display, DisplayModeProperties2Vector& modeProperties)
{
	deUint32							countReported			=	0u;
	deUint32							countRetrieved			=	0u;
	const VkDisplayModePropertiesKHR	displayModeProperties	=	{
																		DE_NULL,											// VkDisplayModeKHR				displayMode
																		{													// VkDisplayModeParametersKHR	parameters
																			{0, 0},											// VkExtent2D					visibleRegion
																			0												// uint32_t						refreshRate
																		}
																	};
	const VkDisplayModeProperties2KHR	displayModeProperties2	=	{
																		VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR,	// VkStructureType				sType
																		DE_NULL,											// void*						pNext
																		displayModeProperties								// VkDisplayModePropertiesKHR	displayModeProperties
																	};
	VkResult							result;

	modeProperties.clear();

	result = m_vki.getDisplayModeProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
													display,				// VkDisplayKHR					display
													&countReported,			// uint32_t*					pPropertyCount
													DE_NULL);				// VkDisplayModeProperties2KHR*	pProperties

	if (result != VK_SUCCESS)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result)
				<< " for display " << display
				<< " reported items count " << countReported
				<< tcu::TestLog::EndMessage;

		return false;
	}

	modeProperties.resize(countReported, displayModeProperties2);

	countRetrieved = countReported;

	result = m_vki.getDisplayModeProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
													display,				// VkDisplayKHR					display
													&countRetrieved,		// uint32_t*					pPropertyCount
													&modeProperties[0]);	// VkDisplayModeProperties2KHR*	pProperties

	if (result != VK_SUCCESS || countRetrieved > countReported)
	{
		m_log	<< tcu::TestLog::Message
				<< "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result)
				<< " for display " << display
				<< " reported items count " << countReported
				<< " retrieved items count " << countReported
				<< tcu::TestLog::EndMessage;

		modeProperties.clear();

		return false;
	}

	if (countRetrieved < countReported)
		modeProperties.resize(countRetrieved);

	return true;
}

/*--------------------------------------------------------------------*//*!
 * \brief Validate display properties and report failures
 *        into results collector
 *
 * \param results		Results collector
 * \param toValidate	Display properties to validate
 * \param nonUpdated	Display properties to compare with
 *//*--------------------------------------------------------------------*/
void DisplayCoverageTestInstance::validateDisplayProperties (	tcu::ResultCollector&			results,
																const VkDisplayPropertiesKHR&	toValidate,
																const VkDisplayPropertiesKHR&	nonUpdated)
{
	results.check(	toValidate.display != nonUpdated.display,
					"Invalid display handle");

	results.check(	toValidate.planeReorderPossible == VK_TRUE || toValidate.planeReorderPossible == VK_FALSE,
					"planeReorderPossible neither VK_TRUE, nor VK_FALSE");

	results.check(	toValidate.persistentContent == VK_TRUE || toValidate.persistentContent == VK_FALSE,
					"persistentContent neither VK_TRUE, nor VK_FALSE");

	results.check(	(toValidate.supportedTransforms & nonUpdated.supportedTransforms) == 0,
					"supportedTransforms contains unrecognized flags");

	// Outside specification, but resolution 0x0 pixels will break many applications
	results.check(	toValidate.physicalResolution.height != 0,
					"physicalResolution.height cannot be zero");

	// Outside specification, but resolution 0x0 pixels will break many applications
	results.check(	toValidate.physicalResolution.width != 0,
					"physicalResolution.width cannot be zero");
}

/*--------------------------------------------------------------------*//*!
 * \brief Validates display plane properties and report failures
 *        into results collector
 *
 * \param results		Results collector
 * \param toValidate	Display plane properties to validate
 * \param nonUpdated	Display plane properties to compare with
 * \param displaySet	Set of valid display handles
 *//*--------------------------------------------------------------------*/
void DisplayCoverageTestInstance::validateDisplayPlaneProperties (	tcu::ResultCollector&				results,
																	const VkDisplayPlanePropertiesKHR&	toValidate,
																	const VkDisplayPlanePropertiesKHR&	nonUpdated,
																	DisplaySet&							displaySet)
{
	const VkDisplayKHR currentDisplay = toValidate.currentDisplay;

	results.check(	toValidate.currentStackIndex < nonUpdated.currentStackIndex,
					"CurrentStackIndex must be less than the number of planes reported " + de::toString(nonUpdated.currentStackIndex));

	results.check(	currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay),
					"Plane bound to invalid handle " + de::toString(toValidate.currentDisplay));
}

/*--------------------------------------------------------------------*//*!
 * \brief Validate display plane capabilities and report failures
 *        into results collector
 *
 * \param results		Results collector
 * \param toValidate	Display plane capabilities to validate
 * \param nonUpdated	Display plane capabilities to compare with
 *//*--------------------------------------------------------------------*/
void DisplayCoverageTestInstance::validateDisplayPlaneCapabilities (	tcu::ResultCollector&					results,
																		const VkDisplayPlaneCapabilitiesKHR&	toValidate,
																		const VkDisplayPlaneCapabilitiesKHR&	nonUpdated)
{
	results.check(	(toValidate.supportedAlpha & nonUpdated.supportedAlpha) == 0,
					"supportedAlpha contains unrecognized value");

	results.check(	toValidate.minSrcPosition.x >= 0,
					"minSrcPosition.x >= 0");

	results.check(	toValidate.minSrcPosition.y >= 0,
					"minSrcPosition.y >= 0");

	results.check(	toValidate.maxSrcPosition.x >= 0,
					"maxSrcPosition.x >= 0");

	results.check(	toValidate.maxSrcPosition.y >= 0,
					"maxSrcPosition.y >= 0");

	results.check(	toValidate.minSrcPosition.x <= toValidate.maxSrcPosition.x,
					"minSrcPosition.x <= maxSrcPosition.x");

	results.check(	toValidate.minSrcPosition.y <= toValidate.maxSrcPosition.y,
					"minSrcPosition.y <= maxSrcPosition.y");

	results.check(	toValidate.minDstPosition.x <= toValidate.maxDstPosition.x,
					"minDstPosition.x <= maxDstPosition.x");

	results.check(	toValidate.minDstPosition.y <= toValidate.maxDstPosition.y,
					"minDstPosition.y <= maxDstPosition.y");

	results.check(	toValidate.minSrcExtent.width <= toValidate.maxSrcExtent.width,
					"minSrcExtent.width <= maxSrcExtent.width");

	results.check(	toValidate.minSrcExtent.height <= toValidate.maxSrcExtent.height,
					"minSrcExtent.height <= maxSrcExtent.height");

	results.check(	toValidate.minDstExtent.width <= toValidate.maxDstExtent.width,
					"minDstExtent.width <= maxDstExtent.width");

	results.check(	toValidate.minDstExtent.height <= toValidate.maxDstExtent.height,
					"minDstExtent.height <= maxDstExtent.height");
}

/*--------------------------------------------------------------------*//*!
 * \brief Validate display mode properties and report failures
 *        into results collector
 *
 * \param results		Results collector
 * \param toValidate	Display mode properties to validate
 * \param nonUpdated	Display mode properties to compare with
 *//*--------------------------------------------------------------------*/
void DisplayCoverageTestInstance::validateDisplayModeProperties (	tcu::ResultCollector&				results,
																	const VkDisplayModePropertiesKHR&	toValidate,
																	const VkDisplayModePropertiesKHR&	nonUpdated)
{
	results.check(	toValidate.displayMode != nonUpdated.displayMode,
					"Invalid mode display handle reported");
}

/*--------------------------------------------------------------------*//*!
 * \brief Display enumeration coverage test
 *
 * Throws ResourceError exception in case no displays available.
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPropertiesKHR (void)
{
	deUint32				displayCountReported	=	0u;
	deUint32				displayCountToTest		=	0u;
	tcu::ResultCollector	results						(m_log);
	VkResult				result;

	result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
															&displayCountReported,	// uint32_t*				pPropertyCount
															DE_NULL);				// VkDisplayPropertiesKHR*	pProperties

	if (   result != VK_SUCCESS
		&& result != VK_INCOMPLETE
		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
		)
	{
		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
	}

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (displayCountReported == 0)
		TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str());

	displayCountToTest = displayCountReported;
	if (displayCountReported > MAX_TESTED_DISPLAY_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of displays reported is too high " << displayCountReported
				<< ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT
				<< tcu::TestLog::EndMessage;

		displayCountToTest = MAX_TESTED_DISPLAY_COUNT;
	}

	// Test the call correctly writes data in various size arrays
	for (deUint32	displayCountRequested = 0;
					displayCountRequested < displayCountToTest + 2;
					displayCountRequested++)
	{
		const deUint32						displayCountExpected	=	std::min(displayCountRequested, displayCountReported);
		const VkDisplayPropertiesKHR		invalidDisplayProps		=	{	// Most values are set to fail the test to make sure driver updates these
																			DE_NULL,								// VkDisplayKHR					display;
																			DE_NULL,								// const char*					displayName;
																			{0, 0},									// VkExtent2D					physicalDimensions;
																			{0, 0},									// VkExtent2D					physicalResolution;
																			~RECOGNIZED_SURFACE_TRANSFORM_FLAGS,	// VkSurfaceTransformFlagsKHR	supportedTransforms;
																			(vk::VkBool32)(VK_TRUE + 1),			// VkBool32						planeReorderPossible;
																			(vk::VkBool32)(VK_TRUE + 1)				// VkBool32						persistentContent;
																		};
		const VkDisplayKHR					canaryDisplay			=	static_cast<VkDisplayKHR>(0xABCDEF11);
		const deUint32						canaryItemCount			=	1;
		std::vector<VkDisplayPropertiesKHR>	displaysProps				(displayCountRequested + canaryItemCount, invalidDisplayProps);
		deUint32							displayCountRetrieved	=	displayCountRequested;
		DisplaySet							displaySet;

		displaysProps[displayCountExpected].display = canaryDisplay;

		result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
																&displayCountRetrieved,	// uint32_t*				pPropertyCount
																&displaysProps[0]);		// VkDisplayPropertiesKHR*	pProperties

		// Check amount of data written equals to expected
		if (displayCountRetrieved != displayCountExpected)
			TCU_FAIL_STR(	string("displayCountRetrieved != displayCountExpected, ") +
							de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));

		if (displayCountRequested >= displayCountReported)
		{
			if (result != VK_SUCCESS)
				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
		}
		else
		{
			if (result != VK_INCOMPLETE)
				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
		}

		// Check the driver has written something
		for (deUint32	displayIndex = 0;
						displayIndex < displayCountRetrieved;
						displayIndex++)
		{
			displaySet.insert(displaysProps[displayIndex].display);

			results.check(	displaysProps[displayIndex].display != invalidDisplayProps.display,
							"Invalid display handle for display number " + de::toString(displayIndex));

			results.check(	displaysProps[displayIndex].planeReorderPossible == VK_TRUE || displaysProps[displayIndex].planeReorderPossible == VK_FALSE,
							"planeReorderPossible neither VK_TRUE, nor VK_FALSE");

			results.check(	displaysProps[displayIndex].persistentContent == VK_TRUE || displaysProps[displayIndex].persistentContent == VK_FALSE,
							"persistentContent neither VK_TRUE, nor VK_FALSE");

			results.check(	(displaysProps[displayIndex].supportedTransforms & invalidDisplayProps.supportedTransforms) == 0,
							"supportedTransforms contains unrecognized flags");

			// Outside specification, but resolution 0x0 pixels will break many applications
			results.check(	displaysProps[displayIndex].physicalResolution.height != 0,
							"physicalResolution.height cannot be zero");

			// Outside specification, but resolution 0x0 pixels will break many applications
			results.check(	displaysProps[displayIndex].physicalResolution.width != 0,
							"physicalResolution.width cannot be zero");

			if (results.getResult() != QP_TEST_RESULT_PASS)
			{
				m_log	<< tcu::TestLog::Message
						<< "Error detected " << results.getMessage()
						<< " for display " << displayIndex << " with properties " << displaysProps[displayIndex]
						<< " invalid display properties are " << invalidDisplayProps
						<< tcu::TestLog::EndMessage;

				TCU_FAIL_STR(results.getMessage());
			}
		}

		// Check the driver has not written more than requested
		if (displaysProps[displayCountExpected].display != canaryDisplay)
			TCU_FAIL("Memory damage detected: driver has written more than expected");

		// Check display handle uniqueness
		if (displaySet.size() != displayCountRetrieved)
			TCU_FAIL("Display handle duplication detected");
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Plane enumeration coverage test
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlanePropertiesKHR (void)
{
	DisplayVector			displaysVector;
	DisplaySet				displaySet;
	deUint32				planeCountReported	=	0u;
	deUint32				planeCountTested	=	0u;
	tcu::ResultCollector	results					(m_log);
	VkResult				result;

	// Create a list of displays available
	if (!getDisplays(displaysVector))
		TCU_FAIL("Failed to retrieve displays");

	if (displaysVector.empty())
		TCU_THROW(NotSupportedError, "No displays reported");

	displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());

	// Get planes to test
	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
																&planeCountReported,	// uint32_t*					pPropertyCount
																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties

	if (   result != VK_SUCCESS
		&& result != VK_INCOMPLETE
		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
		)
	{
		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
	}

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (planeCountReported == 0)
		TCU_THROW(ResourceError, "Cannot perform test: no planes found");

	planeCountTested = planeCountReported;
	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of planes reported is too high " << planeCountReported
				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
				<< tcu::TestLog::EndMessage;

		planeCountTested = MAX_TESTED_PLANE_COUNT;
	}

	// Test the call correctly writes data in various size arrays
	for (deUint32	planeCountRequested = 0;
					planeCountRequested < planeCountTested + 2;
					planeCountRequested++)
	{
		const deUint32								planeCountExpected	=	std::min(planeCountRequested, planeCountReported);
		const VkDisplayPlanePropertiesKHR			invalidPlaneProps	=	{	// Most values are set to fail the test to make sure driver updates these
																				DE_NULL,		// VkDisplayKHR	currentDisplay
																				DEUINT32_MAX	// deUint32		currentStackIndex
																			};
		const VkDisplayKHR							canaryDisplay		=	static_cast<VkDisplayKHR>(0xABCDEF11);
		const deUint32								canaryItemCount		=	1;
		std::vector<VkDisplayPlanePropertiesKHR>	planeProps				(planeCountRequested + canaryItemCount, invalidPlaneProps);
		deUint32									planeCountRetrieved	=	planeCountRequested;

		planeProps[planeCountExpected].currentDisplay = canaryDisplay;

		result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
																	&planeCountRetrieved,	// uint32_t*					pPropertyCount
																	&planeProps[0]);		// VkDisplayPlanePropertiesKHR*	pProperties

		// Check amount of data written equals to expected
		if (planeCountRetrieved != planeCountExpected)
			TCU_FAIL_STR(	string("planeCountRetrieved != planeCountExpected, ") +
							de::toString(planeCountRetrieved) + " != " + de::toString(planeCountExpected));

		if (planeCountRequested >= planeCountReported)
		{
			if (result != VK_SUCCESS)
				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
		}
		else
		{
			if (result != VK_INCOMPLETE)
				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
		}

		// Check the driver has written something
		for (deUint32	planeIndex = 0;
						planeIndex < planeCountRetrieved;
						planeIndex++)
		{
			const VkDisplayKHR currentDisplay = planeProps[planeIndex].currentDisplay;

			results.check(	planeProps[planeIndex].currentStackIndex < planeCountReported,
							"CurrentStackIndex must be less than the number of planes reported " + de::toString(planeCountReported));

			results.check(	currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay),
							"Plane bound to invalid handle " + de::toString(currentDisplay));

			if (results.getResult() != QP_TEST_RESULT_PASS)
			{
				m_log	<< tcu::TestLog::Message
						<< "Error detected " << results.getMessage()
						<< " for plane " << planeIndex << " with properties " << planeProps[planeIndex]
						<< tcu::TestLog::EndMessage;

				TCU_FAIL_STR(results.getMessage());
			}
		}

		// Check the driver has not written more than requested
		if (planeProps[planeCountExpected].currentDisplay != canaryDisplay)
			TCU_FAIL("Memory damage detected: driver has written more than expected");
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Display plane support coverage test
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneSupportedDisplaysKHR (void)
{
	deUint32		planeCountReported	=	0u;
	deUint32		planeCountTested	=	0u;
	VkResult		result;
	DisplayVector	displaysVector;
	DisplaySet		displaySet;

	if (!getDisplays(displaysVector))
		TCU_FAIL("Failed to retrieve displays");

	if (displaysVector.empty())
		TCU_THROW(NotSupportedError, "No displays reported");

	displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());

	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
																&planeCountReported,	// uint32_t*					pPropertyCount
																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties

	if (   result != VK_SUCCESS
		&& result != VK_INCOMPLETE
		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
		)
	{
		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
	}

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (planeCountReported == 0)
		TCU_THROW(ResourceError, "Cannot perform test: no planes supported");

	planeCountTested = planeCountReported;
	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of planes reported is too high " << planeCountReported
				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
				<< tcu::TestLog::EndMessage;

		planeCountTested = MAX_TESTED_PLANE_COUNT;
	}

	for (deUint32	planeIndex = 0;
					planeIndex < planeCountTested;
					planeIndex++)
	{
		deUint32 displayCountReported = 0u;

		result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,		// VkPhysicalDevice	physicalDevice
															planeIndex,				// uint32_t			planeIndex
															&displayCountReported,	// uint32_t*		pDisplayCount
															DE_NULL);				// VkDisplayKHR*	pDisplays

		if (result != VK_SUCCESS)
			TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

		// Test the call correctly writes data in various size arrays
		for (deUint32	displayCountRequested = 0;
						displayCountRequested < displayCountReported + 2;
						displayCountRequested++)
		{
			const deUint32				displayCountExpected	=	std::min(displayCountRequested, displayCountReported);
			const VkDisplayKHR			nullDisplay				=	DE_NULL;
			const VkDisplayKHR			canaryDisplay			=	static_cast<VkDisplayKHR>(0xABCDEF11);
			const deUint32				canaryItemCount			=	1;
			std::vector<VkDisplayKHR>	displaysForPlane			(displayCountRequested + canaryItemCount, nullDisplay);
			deUint32					displayCountRetrieved	=	displayCountRequested;

			displaysForPlane[displayCountExpected] = canaryDisplay;

			result = m_vki.getDisplayPlaneSupportedDisplaysKHR(	m_physicalDevice,		// VkPhysicalDevice	physicalDevice
																planeIndex,				// uint32_t			planeIndex
																&displayCountRetrieved,	// uint32_t*		pDisplayCount
																&displaysForPlane[0]);	// VkDisplayKHR*	pDisplays

			// Check amount of data written equals to expected
			if (displayCountRetrieved != displayCountExpected)
				TCU_FAIL_STR(	string("displayCountRetrieved != displayCountExpected, ") +
								de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));

			if (displayCountRequested >= displayCountReported)
			{
				if (result != VK_SUCCESS)
					TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
			}
			else
			{
				if (result != VK_INCOMPLETE)
					TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
			}

			// Check the driver has written something
			for (deUint32	displayIndex = 0;
							displayIndex < displayCountExpected;
							displayIndex++)
			{
				const VkDisplayKHR display = displaysForPlane[displayIndex];

				if (display != nullDisplay)
				{
					if (!de::contains(displaySet, display))
					{
						TCU_FAIL_STR("Invalid display handle " + de::toString(display));
					}
				}
			}

			// Check the driver has not written more than requested
			if (displaysForPlane[displayCountExpected] != canaryDisplay)
				TCU_FAIL("Memory damage detected: driver has written more than expected");
		}
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Display mode properties coverage test
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModePropertiesKHR (void)
{
	VkResult		result;
	DisplayVector	displaysVector;

	if (!getDisplays(displaysVector))
		TCU_FAIL("Failed to retrieve displays list");

	if (displaysVector.empty())
		TCU_THROW(NotSupportedError, "No displays reported");

	for (DisplayVector::iterator	it =  displaysVector.begin();
									it != displaysVector.end();
									it++)
	{
		VkDisplayKHR	display				= *it;
		deUint32		modesCountReported	= 0u;

		result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
													display,				// VkDisplayKHR					display
													&modesCountReported,	// uint32_t*					pPropertyCount
													DE_NULL);				// VkDisplayModePropertiesKHR*	pProperties

		// Test the call correctly writes data in various size arrays
		for (deUint32	modesCountRequested = 0;
						modesCountRequested < modesCountReported + 2;
						modesCountRequested = nextTestNumber(modesCountRequested, modesCountReported + 2))
		{
			const deUint32							modesCountExpected	=	std::min(modesCountRequested, modesCountReported);
			const VkDisplayModeKHR					nullDisplayMode		=	DE_NULL;
			const VkDisplayModePropertiesKHR		nullMode			=	{
																				nullDisplayMode,	// VkDisplayModeKHR				displayMode
																				{					// VkDisplayModeParametersKHR	parameters
																					{0, 0},			// VkExtent2D					visibleRegion
																					0				// uint32_t						refreshRate
																				}
																			};
			const VkDisplayModeKHR					canaryDisplayMode	=	static_cast<VkDisplayModeKHR>(0xABCDEF11);
			const deUint32							canaryItemCount		=	1;
			std::vector<VkDisplayModePropertiesKHR>	modesForDisplay			(modesCountRequested + canaryItemCount, nullMode);
			deUint32								modesCountRetrieved	=	modesCountRequested;

			modesForDisplay[modesCountExpected].displayMode = canaryDisplayMode;

			result = m_vki.getDisplayModePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
														display,				// VkDisplayKHR					display
														&modesCountRetrieved,	// uint32_t*					pPropertyCount
														&modesForDisplay[0]);	// VkDisplayModePropertiesKHR*	pProperties

			// Check amount of data written equals to expected
			if (modesCountRetrieved != modesCountExpected)
				TCU_FAIL_STR(	string("modesCountRetrieved != modesCountExpected, ") +
								de::toString(modesCountRetrieved) + " != " + de::toString(modesCountExpected));

			if (modesCountRequested >= modesCountReported)
			{
				if (result != VK_SUCCESS)
					TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
			}
			else
			{
				if (result != VK_INCOMPLETE)
					TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
			}

			// Check the driver has written something
			for (deUint32	modeIndex = 0;
							modeIndex < modesCountExpected;
							modeIndex++)
			{
				const VkDisplayModePropertiesKHR theModeProperties = modesForDisplay[modeIndex];

				if (theModeProperties.displayMode == nullMode.displayMode)
					TCU_FAIL_STR("Invalid mode display handle reported for display " + de::toString(display));
			}

			// Check the driver has not written more than requested
			if (modesForDisplay[modesCountExpected].displayMode != canaryDisplayMode)
				TCU_FAIL("Memory damage detected: driver has written more than expected");
		}
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Create display mode coverage test
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus	DisplayCoverageTestInstance::testCreateDisplayModeKHR (void)
{
	DisplayVector	displaysVector;
	VkResult		result;

	if (!getDisplays(displaysVector))
		TCU_FAIL("Failed to retrieve displays");

	if (displaysVector.empty())
		TCU_THROW(NotSupportedError, "No displays reported");

	for (DisplayVector::iterator	it =  displaysVector.begin();
									it != displaysVector.end();
									it++)
	{
		const VkDisplayKHR						display				=	*it;
		DisplayModePropertiesVector::size_type	builtinModesCount	=	0u;
		VkDisplayModePropertiesKHR				validModeProperties;
		VkDisplayModeKHR						mode				=	DE_NULL;
		DisplayModePropertiesVector				modes;
		VkDisplayModeCreateInfoKHR				createInfo			=	{
																			VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR,	// VkStructureType				sType
																			DE_NULL,										// const void*					pNext
																			0,												// VkDisplayModeCreateFlagsKHR	flags
																			{												// VkDisplayModeParametersKHR	parameters
																				{0, 0},										// VkExtent2D					visibleRegion
																				0											// uint32_t						refreshRate
																			}
																		};

		if (!getDisplayModeProperties(display, modes))
			TCU_FAIL("Failed to retrieve display mode properties");

		if (modes.size() < 1)
			TCU_FAIL("At least one mode expected to be returned");

		// Builtin mode count should not be updated with a new mode. Get initial builtin mode count
		builtinModesCount = modes.size();

		// Assume first available builtin mode as a valid mode sample
		validModeProperties = modes[0];

		// Do negative test by making one of parameters unacceptable
		for (deUint32	testIndex = 0;
						testIndex < 3;
						testIndex++)
		{
			VkDisplayModeCreateInfoKHR	createInfoFail		(createInfo);
			VkDisplayModeKHR			modeFail		=	DE_NULL;

			createInfoFail.parameters = validModeProperties.parameters;

			switch (testIndex)
			{
				case 0:		createInfoFail.parameters.refreshRate			= 0;	break;
				case 1:		createInfoFail.parameters.visibleRegion.width	= 0;	break;
				case 2:		createInfoFail.parameters.visibleRegion.height	= 0;	break;
				default:	DE_FATAL("Impossible");									break;
			}

			result = m_vki.createDisplayModeKHR(	m_physicalDevice,	// VkPhysicalDevice						physicalDevice
													display,			// VkDisplayKHR							display
													&createInfoFail,	// const VkDisplayModeCreateInfoKHR*	pCreateInfo
													DE_NULL,			// const VkAllocationCallbacks*			pAllocator
													&modeFail);			// VkDisplayModeKHR*					pMode

			if (result != VK_ERROR_INITIALIZATION_FAILED)
				TCU_FAIL_STR(string("Expected VK_ERROR_INITIALIZATION_FAILED. Have ") + getResultAsString(result));

			if (modeFail != DE_NULL)
				TCU_FAIL("Mode should be kept invalid on fail");
		}

		// At last create valid display mode
		createInfo.parameters = validModeProperties.parameters;

		result = m_vki.createDisplayModeKHR(	m_physicalDevice,	// VkPhysicalDevice						physicalDevice
												display,			// VkDisplayKHR							display
												&createInfo,		// const VkDisplayModeCreateInfoKHR*	pCreateInfo
												DE_NULL,			// const VkAllocationCallbacks*			pAllocator
												&mode);				// VkDisplayModeKHR*					pMode

		if (result != VK_SUCCESS)
			TCU_FAIL_STR("Expected VK_SUCCESS. Have " + getResultAsString(result));

		if (mode == DE_NULL)
			TCU_FAIL("Valid handle expected");

		// Builtin mode count should not be updated with a new mode
		modes.clear();

		if (!getDisplayModeProperties(display, modes))
			TCU_FAIL("Failed to retrieve display mode properties");

		if (builtinModesCount != modes.size())
			TCU_FAIL_STR(	string("Mode count has changed from ") + de::toString(builtinModesCount) +
							string(" to ") + de::toString(modes.size()));
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Display-plane capabilities coverage test
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus	DisplayCoverageTestInstance::testGetDisplayPlaneCapabilitiesKHR (void)
{
	deUint32	planeCountReported	=	0u;
	VkResult	result;

	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
																&planeCountReported,	// uint32_t*					pPropertyCount
																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (planeCountReported == 0)
	{
		DisplayVector	displaysVector;

		// If we don't have any displays then it's alright to have no planes, as
		// per the Vulkan Spec:
		//		Devices must support at least one plane on each display
		if (!getDisplays(displaysVector))
			TCU_FAIL("Failed to retrieve displays");

		if (displaysVector.empty())
			TCU_THROW(NotSupportedError, "No display planes reported");

		TCU_FAIL("No planes defined");
	}

	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of planes reported is too high " << planeCountReported
				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
				<< tcu::TestLog::EndMessage;

		planeCountReported = MAX_TESTED_PLANE_COUNT;
	}

	for (deUint32	planeIndex = 0;
					planeIndex < planeCountReported;
					planeIndex++)
	{
		std::vector<VkDisplayKHR> displaysForPlane;

		if (!getDisplaysForPlane(planeIndex, displaysForPlane))
			TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));

		if (displaysForPlane.empty())
			continue;

		// Check the driver has written something
		for (deUint32	displayIndex = 0;
						displayIndex < displaysForPlane.size();
						displayIndex++)
		{
			const VkDisplayKHR						display						=	displaysForPlane[displayIndex];
			std::vector<VkDisplayModePropertiesKHR>	modesPropertiesForDisplay;

			if (!getDisplayModeProperties(display, modesPropertiesForDisplay))
				TCU_FAIL("Failed to retrieve display mode properties");

			for (deUint32	modeIndex = 0;
							modeIndex < modesPropertiesForDisplay.size();
							modeIndex++)
			{
				const VkDisplayModeKHR			theDisplayMode			=	modesPropertiesForDisplay[modeIndex].displayMode;
				const deUint32					unrecognizedAlphaFlags	=	~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS;
				VkDisplayPlaneCapabilitiesKHR	planeCapabilities		=	{
																				unrecognizedAlphaFlags,	// VkDisplayPlaneAlphaFlagsKHR	supportedAlpha;
																				{ -1, -1 },				// VkOffset2D					minSrcPosition;
																				{ -1, -1 },				// VkOffset2D					maxSrcPosition;
																				{ 1, 1 },				// VkExtent2D					minSrcExtent;
																				{ 0, 0 },				// VkExtent2D					maxSrcExtent;
																				{ 1, 1 },				// VkOffset2D					minDstPosition;
																				{ 0, 0 },				// VkOffset2D					maxDstPosition;
																				{ 1, 1 },				// VkExtent2D					minDstExtent;
																				{ 0, 0 },				// VkExtent2D					maxDstExtent;
																			};
				tcu::ResultCollector			results						(m_log);

				result = m_vki.getDisplayPlaneCapabilitiesKHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
																theDisplayMode,			// VkDisplayModeKHR					mode
																planeIndex,				// uint32_t							planeIndex
																&planeCapabilities);	// VkDisplayPlaneCapabilitiesKHR*	pCapabilities

				results.check(	result == VK_SUCCESS,
								string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

				results.check(	(planeCapabilities.supportedAlpha & unrecognizedAlphaFlags) == 0,
								"supportedAlpha contains unrecognized value");

				results.check(	planeCapabilities.minSrcPosition.x >= 0,
								"minSrcPosition.x >= 0");

				results.check(	planeCapabilities.minSrcPosition.y >= 0,
								"minSrcPosition.y >= 0");

				results.check(	planeCapabilities.maxSrcPosition.x >= 0,
								"maxSrcPosition.x >= 0");

				results.check(	planeCapabilities.maxSrcPosition.y >= 0,
								"maxSrcPosition.y >= 0");

				results.check(	planeCapabilities.minSrcPosition.x <= planeCapabilities.maxSrcPosition.x,
								"minSrcPosition.x <= maxSrcPosition.x");

				results.check(	planeCapabilities.minSrcPosition.y <= planeCapabilities.maxSrcPosition.y,
								"minSrcPosition.y <= maxSrcPosition.y");

				results.check(	planeCapabilities.minDstPosition.x <= planeCapabilities.maxDstPosition.x,
								"minDstPosition.x <= maxDstPosition.x");

				results.check(	planeCapabilities.minDstPosition.y <= planeCapabilities.maxDstPosition.y,
								"minDstPosition.y <= maxDstPosition.y");

				results.check(	planeCapabilities.minSrcExtent.width <= planeCapabilities.maxSrcExtent.width,
								"minSrcExtent.width <= maxSrcExtent.width");

				results.check(	planeCapabilities.minSrcExtent.height <= planeCapabilities.maxSrcExtent.height,
								"minSrcExtent.height <= maxSrcExtent.height");

				results.check(	planeCapabilities.minDstExtent.width <= planeCapabilities.maxDstExtent.width,
								"minDstExtent.width <= maxDstExtent.width");

				results.check(	planeCapabilities.minDstExtent.height <= planeCapabilities.maxDstExtent.height,
								"minDstExtent.height <= maxDstExtent.height");

				if (results.getResult() != QP_TEST_RESULT_PASS)
				{
					m_log	<< tcu::TestLog::Message
							<< "Error detected " << results.getMessage()
							<< " for plane's " << planeIndex
							<< " display " << displayIndex
							<< " and mode " << modeIndex
							<< " with capabilities " << planeCapabilities
							<< tcu::TestLog::EndMessage;

					TCU_FAIL_STR(results.getMessage());
				}

			}
		}
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Create display plane surface coverage test
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus	DisplayCoverageTestInstance::testCreateDisplayPlaneSurfaceKHR (void)
{
	deUint32									planeCountReported	=	0u;
	deUint32									planeCountTested	=	0u;
	deUint32									planeCountRetrieved	=	0u;
	std::vector<VkDisplayPlanePropertiesKHR>	planeProperties;
	bool										testPerformed		=	false;
	DisplayVector								displaysVector;
	VkResult									result;

	// Get displays
	if (!getDisplays(displaysVector))
		TCU_FAIL("Failed to retrieve displays");

	if (displaysVector.empty())
		TCU_THROW(NotSupportedError, "No displays reported");

	// Get planes
	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
																&planeCountReported,	// uint32_t*					pPropertyCount
																DE_NULL);				// VkDisplayPlanePropertiesKHR*	pProperties

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (planeCountReported == 0)
		TCU_FAIL("No planes defined");

	planeCountTested = planeCountReported;
	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of planes reported is too high " << planeCountReported
				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
				<< tcu::TestLog::EndMessage;

		planeCountTested = MAX_TESTED_PLANE_COUNT;
	}

	planeProperties.resize(planeCountTested);
	planeCountRetrieved = planeCountTested;

	result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
																&planeCountRetrieved,	// uint32_t*					pPropertyCount
																&planeProperties[0]);	// VkDisplayPlanePropertiesKHR*	pProperties

	if (result != VK_SUCCESS && result != VK_INCOMPLETE )
		TCU_FAIL_STR(string("Expected VK_SUCCESS or VK_INCOMPLETE expected. Have ") + getResultAsString(result));

	if (planeCountRetrieved != planeCountTested)
		TCU_FAIL_STR(	string("Number of planes requested (") + de::toString(planeCountTested) +
						") does not match retrieved (" + de::toString(planeCountRetrieved) + ")");

	// Iterate through displays-modes
	for (DisplayVector::iterator	it =  displaysVector.begin();
									it != displaysVector.end();
									it++)
	{
		const VkDisplayKHR						display						=	*it;
		std::vector<VkDisplayModePropertiesKHR>	modesPropertiesForDisplay;

		if (!getDisplayModeProperties(display, modesPropertiesForDisplay))
			TCU_FAIL("Failed to retrieve display mode properties");

		for (deUint32	modeIndex = 0;
						modeIndex < modesPropertiesForDisplay.size();
						modeIndex++)
		{
			const VkDisplayModeKHR				displayMode		=	modesPropertiesForDisplay[modeIndex].displayMode;
			const VkDisplayModePropertiesKHR&	modeProperties	=	modesPropertiesForDisplay[modeIndex];

			for (deUint32	planeIndex = 0;
							planeIndex < planeCountTested;
							planeIndex++)
			{
				std::vector<VkDisplayKHR>	displaysForPlane;

				if (!getDisplaysForPlane(planeIndex, displaysForPlane))
					TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));

				if (displaysForPlane.empty())
					continue;

				// Iterate through displays supported by the plane
				for (deUint32	displayIndex = 0;
								displayIndex < displaysForPlane.size();
								displayIndex++)
				{
					const VkDisplayKHR				planeDisplay		=	displaysForPlane[displayIndex];
					VkDisplayPlaneCapabilitiesKHR	planeCapabilities;
					bool							fullDisplayPlane;

					if (display == planeDisplay)
					{
						deMemset(&planeCapabilities, 0, sizeof(planeCapabilities));

						result = m_vki.getDisplayPlaneCapabilitiesKHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
																		displayMode,			// VkDisplayModeKHR					mode
																		planeIndex,				// uint32_t							planeIndex
																		&planeCapabilities);	// VkDisplayPlaneCapabilitiesKHR*	pCapabilities

						if (result != VK_SUCCESS)
							TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

						fullDisplayPlane	=	   planeCapabilities.minDstExtent.height == modeProperties.parameters.visibleRegion.height
												&& planeCapabilities.minDstExtent.width  == modeProperties.parameters.visibleRegion.width;

						if (fullDisplayPlane && (planeCapabilities.supportedAlpha & VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR) != 0)
						{
							const VkDisplayPlaneAlphaFlagBitsKHR	alphaMode	=	VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
							const VkInstance						instance	=	m_context.getInstance();
							const VkDisplaySurfaceCreateInfoKHR		createInfo	=	{
																						VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR,	// VkStructureType					sType
																						DE_NULL,											// const void*						pNext
																						0,													// VkDisplaySurfaceCreateFlagsKHR	flags
																						displayMode,										// VkDisplayModeKHR					displayMode
																						planeIndex,											// uint32_t							planeIndex
																						planeProperties[planeIndex].currentStackIndex,		// uint32_t							planeStackIndex
																						VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,				// VkSurfaceTransformFlagBitsKHR	transform
																						1.0f,												// float							globalAlpha
																						alphaMode,											// VkDisplayPlaneAlphaFlagBitsKHR	alphaMode
																						{													// VkExtent2D						imageExtent
																							planeCapabilities.minDstExtent.width,
																							planeCapabilities.minDstExtent.height
																						}
																					};
							VkSurfaceKHR							surface		=	DE_NULL;

							result = m_vki.createDisplayPlaneSurfaceKHR(	instance,		// VkInstance							instance
																			&createInfo,	// const VkDisplaySurfaceCreateInfoKHR*	pCreateInfo
																			DE_NULL,		// const VkAllocationCallbacks*			pAllocator
																			&surface);		// VkSurfaceKHR*						pSurface

							if (result != VK_SUCCESS)
								TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

							if (surface == DE_NULL)
								TCU_FAIL("Invalid surface handle returned");

							m_vki.destroySurfaceKHR(	instance,	// VkInstance							instance
														surface,	// VkSurfaceKHR*						pSurface
														DE_NULL);	// const VkAllocationCallbacks*			pAllocator

							testPerformed = true;
						}
					}
				}
			}
		}
	}

	if (!testPerformed)
		TCU_THROW(NotSupportedError, "Cannot find suitable parameters for the test");

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Display enumeration coverage test using VK_KHR_get_display_properties2
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayProperties2KHR (void)
{
	deUint32				displayCountReported	=	0u;
	deUint32				displayCountToTest		=	0u;
	tcu::ResultCollector	results						(m_log);
	VkResult				result;

	result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
															&displayCountReported,	// uint32_t*				pPropertyCount
															DE_NULL);				// VkDisplayProperties2KHR*	pProperties

	if (   result != VK_SUCCESS
		&& result != VK_INCOMPLETE
		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
		)
	{
		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
	}

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (displayCountReported == 0)
		TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str());

	displayCountToTest = displayCountReported;
	if (displayCountReported > MAX_TESTED_DISPLAY_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of displays reported is too high " << displayCountReported
				<< ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT
				<< tcu::TestLog::EndMessage;

		displayCountToTest = MAX_TESTED_DISPLAY_COUNT;
	}

	// Test the call correctly writes data in various size arrays
	for (deUint32	displayCountRequested = 0;
					displayCountRequested < displayCountToTest + 2;
					displayCountRequested++)
	{
		const deUint32							displayCountExpected			=	std::min(displayCountRequested, displayCountReported);
		const VkDisplayPropertiesKHR			nonUpdatedDisplayProperties		=	{	// Most values are set to fail the test to make sure driver updates them
																						DE_NULL,								// VkDisplayKHR					display
																						DE_NULL,								// const char*					displayName
																						{0, 0},									// VkExtent2D					physicalDimensions
																						{0, 0},									// VkExtent2D					physicalResolution
																						~RECOGNIZED_SURFACE_TRANSFORM_FLAGS,	// VkSurfaceTransformFlagsKHR	supportedTransforms
																						(vk::VkBool32)(VK_TRUE + 1),			// VkBool32						planeReorderPossible
																						(vk::VkBool32)(VK_TRUE + 1)				// VkBool32						persistentContent
																					};
		const VkStructureType					queryStructureType				=	VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR;
		const VkDisplayProperties2KHR			nonUpdatedDisplayProperties2	=	{
																						queryStructureType,			// VkStructureType			sType
																						DE_NULL,					// void*					pNext
																						nonUpdatedDisplayProperties	// VkDisplayPropertiesKHR	displayProperties
																					};
		const VkDisplayKHR						canaryDisplay					=	static_cast<VkDisplayKHR>(0xABCDEF11);
		const deUint32							canaryItemCount					=	1;
		std::vector<VkDisplayProperties2KHR>	displaysProps2						(displayCountRequested + canaryItemCount, nonUpdatedDisplayProperties2);
		deUint32								displayCountRetrieved			=	displayCountRequested;
		DisplaySet								displaySet;

		displaysProps2[displayCountExpected].displayProperties.display = canaryDisplay;

		result = m_vki.getPhysicalDeviceDisplayProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice			physicalDevice
																&displayCountRetrieved,	// uint32_t*				pPropertyCount
																&displaysProps2[0]);	// VkDisplayProperties2KHR*	pProperties

		// Check amount of data written equals to expected
		if (displayCountRetrieved != displayCountExpected)
			TCU_FAIL_STR(	string("displayCountRetrieved != displayCountExpected, ") +
							de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));

		if (displayCountRequested >= displayCountReported)
		{
			if (result != VK_SUCCESS)
				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
		}
		else
		{
			if (result != VK_INCOMPLETE)
				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
		}

		// Check the driver has written something
		for (deUint32	displayIndex = 0;
						displayIndex < displayCountRetrieved;
						displayIndex++)
		{
			const VkDisplayProperties2KHR&	properties2 = displaysProps2[displayIndex];
			const VkDisplayPropertiesKHR&	properties	= properties2.displayProperties;

			displaySet.insert(properties.display);

			results.check(	properties2.sType == queryStructureType,
							"sType has changed to " + de::toString(properties2.sType));

			results.check(	properties2.pNext == DE_NULL,
							"pNext has changed to " + de::toString(properties2.pNext));

			validateDisplayProperties(results, properties, nonUpdatedDisplayProperties);

			if (results.getResult() != QP_TEST_RESULT_PASS)
			{
				m_log	<< tcu::TestLog::Message
						<< "Error detected " << results.getMessage()
						<< " for display " << displayIndex << " with properties " << properties2
						<< " non updated display properties are " << nonUpdatedDisplayProperties2
						<< tcu::TestLog::EndMessage;

				TCU_FAIL_STR(results.getMessage());
			}
		}

		// Check the driver has not written more than requested
		if (displaysProps2[displayCountExpected].displayProperties.display != canaryDisplay)
			TCU_FAIL("Memory damage detected: driver has written more than expected");

		// Check display handle uniqueness
		if (displaySet.size() != displayCountRetrieved)
			TCU_FAIL("Display handle duplication detected");
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Plane enumeration coverage test using VK_KHR_get_display_properties2
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlaneProperties2KHR (void)
{
	DisplayVector			displaysVector;
	DisplaySet				displaySet;
	deUint32				planeCountReported	=	0u;
	deUint32				planeCountTested	=	0u;
	tcu::ResultCollector	results					(m_log);
	VkResult				result;

	// Create a list of displays available
	if (!getDisplays2(displaysVector))
		TCU_FAIL("Failed to retrieve displays");

	if (displaysVector.empty())
		TCU_THROW(NotSupportedError, "No displays reported");

	displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());

	// Get planes to test
	result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
																&planeCountReported,	// uint32_t*						pPropertyCount
																DE_NULL);				// VkDisplayPlaneProperties2KHR*	pProperties

	if (   result != VK_SUCCESS
		&& result != VK_INCOMPLETE
		&& result != VK_ERROR_OUT_OF_HOST_MEMORY
		&& result != VK_ERROR_OUT_OF_DEVICE_MEMORY
		)
	{
		TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
	}

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (planeCountReported == 0)
		TCU_THROW(ResourceError, "Cannot perform test: no planes found");

	planeCountTested = planeCountReported;
	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of planes reported is too high " << planeCountReported
				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
				<< tcu::TestLog::EndMessage;

		planeCountTested = MAX_TESTED_PLANE_COUNT;
	}

	// Test the call correctly writes data in various size arrays
	for (deUint32	planeCountRequested = 0;
					planeCountRequested < planeCountTested + 2;
					planeCountRequested++)
	{
		const deUint32								planeCountExpected			=	std::min(planeCountRequested, planeCountReported);
		const VkDisplayPlanePropertiesKHR			nonUpdatedPlaneProperties	=	{	// Most values are set to fail the test to make sure driver updates them
																						DE_NULL,			// VkDisplayKHR	currentDisplay
																						planeCountReported	// deUint32		currentStackIndex
																					};
		const VkStructureType						queryStructureType			=	VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR;
		const VkDisplayPlaneProperties2KHR			nonUpdatedPlaneProperties2	=	{
																						queryStructureType,			// VkStructureType				sType
																						DE_NULL,					// void*						pNext
																						nonUpdatedPlaneProperties	// VkDisplayPlanePropertiesKHR	displayPlaneProperties
																					};
		const VkDisplayKHR							canaryDisplay				=	static_cast<VkDisplayKHR>(0xABCDEF11);
		const deUint32								canaryItemCount				=	1;
		std::vector<VkDisplayPlaneProperties2KHR>	planeProps2						(planeCountRequested + canaryItemCount, nonUpdatedPlaneProperties2);
		deUint32									planeCountRetrieved			=	planeCountRequested;

		planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay = canaryDisplay;

		result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
																	&planeCountRetrieved,	// uint32_t*						pPropertyCount
																	&planeProps2[0]);		// VkDisplayPlaneProperties2KHR*	pProperties

		// Check amount of data written equals to expected
		if (planeCountRetrieved != planeCountExpected)
			TCU_FAIL_STR(	string("planeCountRetrieved != planeCountExpected, ") +
							de::toString(planeCountRetrieved) + " != " + de::toString(planeCountExpected));

		if (planeCountRequested >= planeCountReported)
		{
			if (result != VK_SUCCESS)
				TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
		}
		else
		{
			if (result != VK_INCOMPLETE)
				TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
		}

		// Check the driver has written something
		for (deUint32	planeIndex = 0;
						planeIndex < planeCountRetrieved;
						planeIndex++)
		{
			const VkDisplayPlaneProperties2KHR&	properties2		= planeProps2[planeIndex];
			const VkDisplayPlanePropertiesKHR&	properties		= properties2.displayPlaneProperties;

			results.check(	properties2.sType == queryStructureType,
							"sType has changed to " + de::toString(properties2.sType));

			results.check(	properties2.pNext == DE_NULL,
							"pNext has changed to " + de::toString(properties2.pNext));

			validateDisplayPlaneProperties(results, properties, nonUpdatedPlaneProperties, displaySet);

			if (results.getResult() != QP_TEST_RESULT_PASS)
			{
				m_log	<< tcu::TestLog::Message
						<< "Error detected " << results.getMessage()
						<< " for plane " << planeIndex << " with properties " << properties2
						<< tcu::TestLog::EndMessage;

				TCU_FAIL_STR(results.getMessage());
			}
		}

		// Check the driver has not written more than requested
		if (planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay != canaryDisplay)
			TCU_FAIL("Memory damage detected: driver has written more than expected");
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Display-plane capabilities coverage test using VK_KHR_get_display_properties2
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus	DisplayCoverageTestInstance::testGetDisplayPlaneCapabilities2KHR (void)
{
	deUint32	planeCountReported	=	0u;
	VkResult	result;

	result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
																&planeCountReported,	// uint32_t*						pPropertyCount
																DE_NULL);				// VkDisplayPlaneProperties2KHR*	pProperties

	if (result != VK_SUCCESS)
		TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

	if (planeCountReported == 0)
		TCU_THROW(NotSupportedError, "No display plane reported");

	if (planeCountReported > MAX_TESTED_PLANE_COUNT)
	{
		m_log	<< tcu::TestLog::Message
				<< "Number of planes reported is too high " << planeCountReported
				<< ". Test is limited to " << MAX_TESTED_PLANE_COUNT
				<< tcu::TestLog::EndMessage;

		planeCountReported = MAX_TESTED_PLANE_COUNT;
	}

	for (deUint32	planeIndex = 0;
					planeIndex < planeCountReported;
					planeIndex++)
	{
		std::vector<VkDisplayKHR> displaysForPlane;

		if (!getDisplaysForPlane(planeIndex, displaysForPlane))
			TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));

		if (displaysForPlane.empty())
			continue;

		// Check the driver has written something
		for (deUint32	displayIndex = 0;
						displayIndex < displaysForPlane.size();
						displayIndex++)
		{
			const VkDisplayKHR							display						=	displaysForPlane[displayIndex];
			std::vector<VkDisplayModeProperties2KHR>	modesPropertiesForDisplay;

			if (!getDisplayModeProperties2(display, modesPropertiesForDisplay))
				TCU_FAIL("Failed to retrieve display mode properties");

			for (deUint32	modeIndex = 0;
							modeIndex < modesPropertiesForDisplay.size();
							modeIndex++)
			{
				const VkDisplayModeKHR			displayMode				=	modesPropertiesForDisplay[modeIndex].displayModeProperties.displayMode;
				const deUint32					unrecognizedAlphaFlags	=	~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS;
				const VkDisplayPlaneInfo2KHR	planeInfo2				=	{
																				VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR, // VkStructureType	sType
																				DE_NULL,									// const void*		pNext
																				displayMode,								// VkDisplayModeKHR	mode
																				planeIndex									// uint32_t			planeIndex
																			};
				VkDisplayPlaneCapabilitiesKHR	planeCapabilities		=	{
																				unrecognizedAlphaFlags,	// VkDisplayPlaneAlphaFlagsKHR	supportedAlpha
																				{ -1, -1 },				// VkOffset2D					minSrcPosition
																				{ -1, -1 },				// VkOffset2D					maxSrcPosition
																				{ 1, 1 },				// VkExtent2D					minSrcExtent
																				{ 0, 0 },				// VkExtent2D					maxSrcExtent
																				{ 1, 1 },				// VkOffset2D					minDstPosition
																				{ 0, 0 },				// VkOffset2D					maxDstPosition
																				{ 1, 1 },				// VkExtent2D					minDstExtent
																				{ 0, 0 },				// VkExtent2D					maxDstExtent
																			};
				const VkStructureType			queryStructureType		=	VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR;
				VkDisplayPlaneCapabilities2KHR	planeCapabilities2		=	{
																				queryStructureType,	// VkStructureType					sType
																				DE_NULL,			// void*							pNext
																				planeCapabilities	// VkDisplayPlaneCapabilitiesKHR	capabilities
																			};
				tcu::ResultCollector			results						(m_log);

				result = m_vki.getDisplayPlaneCapabilities2KHR(	m_physicalDevice,		// VkPhysicalDevice					physicalDevice
																&planeInfo2,			// const VkDisplayPlaneInfo2KHR*	pDisplayPlaneInfo
																&planeCapabilities2);	// VkDisplayPlaneCapabilities2KHR*	pCapabilities

				results.check(	result == VK_SUCCESS,
								string("Expected VK_SUCCESS. Have ") + getResultAsString(result));

				results.check(	planeCapabilities2.sType == queryStructureType,
								"sType has changed to " + de::toString(planeCapabilities2.sType));

				results.check(	planeCapabilities2.pNext == DE_NULL,
								"pNext has changed to " + de::toString(planeCapabilities2.pNext));

				// Validate results returned by driver in planeCapabilities2 using non-updated planeCapabilities
				validateDisplayPlaneCapabilities(results, planeCapabilities2.capabilities, planeCapabilities);

				if (results.getResult() != QP_TEST_RESULT_PASS)
				{
					m_log	<< tcu::TestLog::Message
							<< "Error detected " << results.getMessage()
							<< " for plane's " << planeIndex
							<< " display " << displayIndex
							<< " and mode " << modeIndex
							<< " with capabilities " << planeCapabilities2
							<< tcu::TestLog::EndMessage;

					TCU_FAIL_STR(results.getMessage());
				}
			}
		}
	}

	return tcu::TestStatus::pass("pass");
}

/*--------------------------------------------------------------------*//*!
 * \brief Display mode properties coverage test using VK_KHR_get_display_properties2
 *
 * Throws an exception on fail.
 *
 * \return tcu::TestStatus::pass on success
 *//*--------------------------------------------------------------------*/
tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModeProperties2KHR (void)
{
	VkResult				result;
	tcu::ResultCollector	results			(m_log);
	DisplayVector			displaysVector;

	if (!getDisplays2(displaysVector))
		TCU_FAIL("Failed to retrieve displays list");

	if (displaysVector.empty())
		TCU_THROW(NotSupportedError, "No displays reported");

	for (DisplayVector::iterator	it =  displaysVector.begin();
									it != displaysVector.end();
									it++)
	{
		VkDisplayKHR	display				= *it;
		deUint32		modesCountReported	= 0u;

		result = m_vki.getDisplayModeProperties2KHR(	m_physicalDevice,		// VkPhysicalDevice				physicalDevice
														display,				// VkDisplayKHR					display
														&modesCountReported,	// uint32_t*					pPropertyCount
														DE_NULL);				// VkDisplayModeProperties2KHR*	pProperties

		// Test the call correctly writes data in various size arrays
		for (deUint32	modesCountRequested = 0;
						modesCountRequested < modesCountReported + 2;
						modesCountRequested = nextTestNumber(modesCountRequested, modesCountReported + 2))
		{
			const deUint32								modesCountExpected			=	std::min(modesCountRequested, modesCountReported);
			const VkDisplayModeKHR						nullDisplayMode				=	DE_NULL;
			const VkDisplayModePropertiesKHR			nonUpdatedModeProperties	=	{
																							nullDisplayMode,	// VkDisplayModeKHR				displayMode
																							{					// VkDisplayModeParametersKHR	parameters
																								{0, 0},			// VkExtent2D					visibleRegion
																								0				// uint32_t						refreshRate
																							}
																						};
			const VkStructureType						queryStructureType			=	VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR;
			const VkDisplayModeProperties2KHR			nonUpdatedModeProperties2	=	{
																							queryStructureType,			// VkStructureType				sType
																							DE_NULL,					// void*						pNext
																							nonUpdatedModeProperties	// VkDisplayModePropertiesKHR	displayModeProperties
																						};
			const VkDisplayModeKHR						canaryDisplayMode			=	static_cast<VkDisplayModeKHR>(0xABCDEF11);
			const deUint32								canaryItemCount				=	1;
			std::vector<VkDisplayModeProperties2KHR>	modesProperties2				(modesCountRequested + canaryItemCount, nonUpdatedModeProperties2);
			deUint32									modesCountRetrieved			=	modesCountRequested;

			modesProperties2[modesCountExpected].displayModeProperties.displayMode = canaryDisplayMode;

			result = m_vki.getDisplayModeProperties2KHR(m_physicalDevice,		// VkPhysicalDevice				physicalDevice
														display,				// VkDisplayKHR					display
														&modesCountRetrieved,	// uint32_t*					pPropertyCount
														&modesProperties2[0]);	// VkDisplayModeProperties2KHR*	pProperties

			// Check amount of data written equals to expected
			if (modesCountRetrieved != modesCountExpected)
				TCU_FAIL_STR(	string("modesCountRetrieved != modesCountExpected, ") +
								de::toString(modesCountRetrieved) + " != " + de::toString(modesCountExpected));

			if (modesCountRequested >= modesCountReported)
			{
				if (result != VK_SUCCESS)
					TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
			}
			else
			{
				if (result != VK_INCOMPLETE)
					TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
			}

			// Check the driver has written something
			for (deUint32	modeIndex = 0;
							modeIndex < modesCountExpected;
							modeIndex++)
			{
				const VkDisplayModeProperties2KHR&	properties2	= modesProperties2[modeIndex];
				const VkDisplayModePropertiesKHR&	properties	= properties2.displayModeProperties;

				results.check(	properties2.sType == queryStructureType,
								"sType has changed to " + de::toString(properties2.sType));

				results.check(	properties2.pNext == DE_NULL,
								"pNext has changed to " + de::toString(properties2.pNext));

				validateDisplayModeProperties(results, properties, nonUpdatedModeProperties);

				if (results.getResult() != QP_TEST_RESULT_PASS)
				{
					m_log	<< tcu::TestLog::Message
							<< "Error detected " << results.getMessage()
							<< " for mode " << modeIndex << " with properties " << properties2
							<< " non updated mode properties are " << nonUpdatedModeProperties2
							<< tcu::TestLog::EndMessage;

					TCU_FAIL_STR(results.getMessage());
				}
			}

			// Check the driver has not written more than requested
			if (modesProperties2[modesCountExpected].displayModeProperties.displayMode != canaryDisplayMode)
				TCU_FAIL("Memory damage detected: driver has written more than expected");
		}
	}

	return tcu::TestStatus::pass("pass");
}


/*--------------------------------------------------------------------*//*!
 * \brief Display coverage tests case class
 *//*--------------------------------------------------------------------*/
class DisplayCoverageTestsCase : public vkt::TestCase
{
public:
	DisplayCoverageTestsCase (tcu::TestContext &context, const char *name, const char *description, const DisplayIndexTest testId)
		: TestCase	(context, name, description)
		, m_testId	(testId)
	{
	}
private:
	const DisplayIndexTest	m_testId;

	vkt::TestInstance*	createInstance	(vkt::Context& context) const
	{
		return new DisplayCoverageTestInstance(context, m_testId);
	}
};


/*--------------------------------------------------------------------*//*!
 * \brief Adds a test into group
 *//*--------------------------------------------------------------------*/
static void addTest (tcu::TestCaseGroup* group, const DisplayIndexTest testId, const char* name, const char* description)
{
	tcu::TestContext&	testCtx	= group->getTestContext();

	group->addChild(new DisplayCoverageTestsCase(testCtx, name, description, testId));
}

/*--------------------------------------------------------------------*//*!
 * \brief Adds VK_KHR_display and VK_KHR_display_swapchain extension tests into group
 *//*--------------------------------------------------------------------*/
void createDisplayCoverageTests (tcu::TestCaseGroup* group)
{
	// VK_KHR_display extension tests
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES,				"get_display_properties",				"Display enumeration coverage test");
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES,					"get_display_plane_properties",			"Planes enumeration coverage test");
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY,	"get_display_plane_supported_displays", "Display plane support coverage test");
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE,						"get_display_mode_properties",			"Display mode properties coverage test");
	addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE,					"create_display_mode",					"Create display mode coverage test");
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES,		"get_display_plane_capabilities",		"Display-plane capabilities coverage test");
	addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE,			"create_display_plane_surface",			"Create display plane surface coverage test");

	// VK_KHR_get_display_properties2 extension tests
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2,				"get_display_properties2",				"Display enumeration coverage test using VK_KHR_get_display_properties2");
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2,					"get_display_plane_properties2",		"Planes enumeration coverage test using VK_KHR_get_display_properties2");
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2,					"get_display_mode_properties2",			"Display mode properties coverage test using VK_KHR_get_display_properties2");
	addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2,		"get_display_plane_capabilities2",		"Display-plane capabilities coverage test using VK_KHR_get_display_properties2");
}

} //wsi
} //vkt

