/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 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.
 *
 *//*!
 * \brief VK_EXT_display_control tests
 *//*--------------------------------------------------------------------*/

#include "vkRefUtil.hpp"
#include "vkWsiPlatform.hpp"
#include "vkWsiUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkPlatform.hpp"
#include "vkTypeUtil.hpp"
#include "vkPrograms.hpp"
#include "vkCmdUtil.hpp"
#include "vkWsiUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "vktWsiDisplayControlTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktCustomInstancesDevices.hpp"

#include "tcuPlatform.hpp"
#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuCommandLine.hpp"

#include "deClock.h"

#include <vector>
#include <string>

using std::vector;
using std::string;

using tcu::Maybe;
using tcu::UVec2;
using tcu::TestLog;

namespace vkt
{
namespace wsi
{
namespace
{

using namespace vk;
using namespace vk::wsi;

typedef vector<VkExtensionProperties> Extensions;

CustomInstance createInstance (Context& context)
{
	vector<string> extensions =
	{
		"VK_KHR_surface",
		"VK_KHR_display",
		"VK_EXT_display_surface_counter",
	};

	return vkt::createCustomInstanceWithExtensions(context, extensions);
}

deUint32 chooseQueueFamilyIndex (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
{
	deUint32 numTotalFamilyIndices;
	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numTotalFamilyIndices, DE_NULL);

	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
	{
		if (wsi::getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) == VK_TRUE)
			return queueFamilyNdx;
	}

	TCU_THROW(NotSupportedError, "Device doesn't support presentation");
	return 0;
}

Move<VkDevice> createTestDevice (const vk::Platform&			platform,
								 const PlatformInterface&		vkp,
								 const VkInstance				instance,
								 const InstanceInterface&		vki,
								 VkPhysicalDevice				physicalDevice,
								 const Extensions&				supportedExtensions,
								 const deUint32					queueFamilyIndex,
								 bool							validationEnabled,
								 const VkAllocationCallbacks*	pAllocator = DE_NULL)
{
	const float queuePriorities[] = { 1.0f };
	bool displayAvailable = true;
	const VkDeviceQueueCreateInfo queueInfos[] =
	{
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
			DE_NULL,
			(VkDeviceQueueCreateFlags)0,
			queueFamilyIndex,
			DE_LENGTH_OF_ARRAY(queuePriorities),
			&queuePriorities[0]
		}
	};

	VkPhysicalDeviceFeatures features;
	deMemset(&features, 0, sizeof(features));

	const char* extensions[] =
	{
		"VK_KHR_swapchain",
		"VK_EXT_display_control"
	};

	const VkDeviceCreateInfo deviceParams =
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
		DE_NULL,
		(VkDeviceCreateFlags)0,
		DE_LENGTH_OF_ARRAY(queueInfos),
		&queueInfos[0],
		0u,
		DE_NULL,
		DE_LENGTH_OF_ARRAY(extensions),
		&extensions[0],
		&features
	};

	for (auto ext: extensions)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(ext)))
			TCU_THROW(NotSupportedError, (string(ext) + " is not supported").c_str());
	}

	for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
	{
		vk::wsi::Type	wsiType = (vk::wsi::Type)typeNdx;
		if (platform.hasDisplay(wsiType))
		{
			displayAvailable = false;
			break;
		}
	}

	if (!displayAvailable)
		TCU_THROW(NotSupportedError, "Display is unavailable as windowing system has access");

	return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
}

VkDisplayKHR getDisplayAndDisplayPlane(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 *pPlaneIndex)
{
	deUint32 countDisplays = 0;
	VkResult result = vki.getPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &countDisplays, DE_NULL);
	if (result != VK_SUCCESS)
		TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceDisplayPropertiesKHR failed");

	if (countDisplays == 0)
		TCU_THROW(NotSupportedError, "No displays available");

	deUint32 countDisplayPlanes = 0;
	result = vki.getPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &countDisplayPlanes, DE_NULL);
	if (result != VK_SUCCESS || !countDisplayPlanes)
		TCU_FAIL("GetPhysicalDeviceDisplayPlanePropertiesKHR failed");

	for (deUint32 p = 0; p < countDisplayPlanes; p++)
	{
		deUint32 count = 0u;
		result = vki.getDisplayPlaneSupportedDisplaysKHR(physicalDevice, p, &count, DE_NULL);
		if (result != VK_SUCCESS)
			TCU_FAIL("GetDisplayPlaneSupportedDisplaysKHR failed");

		// No displays that can make use of this plane are available.
		if (!count)
			continue;

		std::vector<VkDisplayKHR> displays(count);
		result = vki.getDisplayPlaneSupportedDisplaysKHR(physicalDevice, p, &count, &displays[0]);
		if (result != VK_SUCCESS)
			TCU_FAIL("GetDisplayPlaneSupportedDisplaysKHR failed");

		// return first plane with an available display
		*pPlaneIndex = p;
		return displays[0];
	}

	TCU_FAIL("No intersection between displays and display planes");

	// Unreachable.
	return DE_NULL;
}

VkSurfaceKHR createSurface(const InstanceInterface& vki, VkInstance instance, VkPhysicalDevice physicalDevice, VkDisplayKHR display, deUint32 planeIndex)
{
	// get number of display modes for this display
	deUint32 displayModesCount = 0;
	VkResult result = vki.getDisplayModePropertiesKHR(physicalDevice, display, &displayModesCount, DE_NULL);
	if (result != VK_SUCCESS)
		TCU_FAIL("GetDisplayModePropertiesKHR failed");

	// get first display mode of this display
	std::vector<vk::VkDisplayModePropertiesKHR> modeProperties(displayModesCount);
	result = vki.getDisplayModePropertiesKHR(physicalDevice, display, &displayModesCount, &modeProperties[0]);
	if (result != VK_SUCCESS)
		TCU_FAIL("GetDisplayModePropertiesKHR failed");
	VkDisplayModeKHR displayMode = modeProperties[0].displayMode;

	// get capabielieties for first plane of this display
	VkDisplayPlaneCapabilitiesKHR planeCapabilities;
	result = vki.getDisplayPlaneCapabilitiesKHR(physicalDevice, displayMode, planeIndex, &planeCapabilities);
	if (result != VK_SUCCESS)
		TCU_FAIL("GetDisplayPlaneCapabilitiesKHR failed");

	// get plane properties count
	deUint32 planePropertiesCount = 0;
	result = vki.getPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &planePropertiesCount, DE_NULL);
	if (result != VK_SUCCESS || !planePropertiesCount)
		TCU_FAIL("GetPhysicalDeviceDisplayPlanePropertiesKHR failed");

	// get plane properties
	std::vector <VkDisplayPlanePropertiesKHR> planeProperties(planePropertiesCount);
	result = vki.getPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &planePropertiesCount, &planeProperties[0]);
	if (result != VK_SUCCESS)
		TCU_FAIL("GetPhysicalDeviceDisplayPlanePropertiesKHR failed");

	// define surface create info
	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
		VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR,				// VkDisplayPlaneAlphaFlagBitsKHR	alphaMode
		{													// VkExtent2D						imageExtent
			planeCapabilities.minDstExtent.width,
			planeCapabilities.minDstExtent.height
		}
	};

	VkSurfaceKHR surface = DE_NULL;
	result = vki.createDisplayPlaneSurfaceKHR(instance, &createInfo, DE_NULL, &surface);
	if (result != VK_SUCCESS)
		TCU_FAIL("CreateDisplayPlaneSurfaceKHR failed");

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

	return surface;
}

void initSemaphores (const DeviceInterface&		vkd,
					 VkDevice					device,
					 std::vector<VkSemaphore>&	semaphores)
{
	for (VkSemaphore& semaphore : semaphores)
		semaphore = createSemaphore(vkd, device).disown();
}

void deinitSemaphores (const DeviceInterface&	vkd,
					 VkDevice					device,
					 std::vector<VkSemaphore>&	semaphores)
{
	for (VkSemaphore& semaphore : semaphores)
	{
		if (semaphore == (VkSemaphore)0)
			continue;

		vkd.destroySemaphore(device, semaphore, DE_NULL);
		semaphore = (VkSemaphore)0;
	}

	semaphores.clear();
}

void initFences (const DeviceInterface&	vkd,
				 VkDevice				device,
				 std::vector<VkFence>&	fences)
{
	for (VkFence& fence : fences)
		fence = createFence(vkd, device).disown();
}

void deinitFences (const DeviceInterface&	vkd,
				   VkDevice					device,
				   std::vector<VkFence>&	fences)
{
	for (VkFence& fence : fences)
	{
		if (fence == (VkFence)0)
			continue;

		vkd.destroyFence(device, fence, DE_NULL);
		fence = (VkFence)0;
	}

	fences.clear();
}

Move<VkCommandBuffer> createCommandBuffer (const DeviceInterface&	vkd,
										   VkDevice					device,
										   VkCommandPool			commandPool,
										   VkRenderPass				renderPass,
										   VkImage					image,
										   VkFramebuffer			framebuffer,
										   VkPipeline				pipeline,
										   deUint32					imageWidth,
										   deUint32					imageHeight)
{
	const VkCommandBufferAllocateInfo allocateInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
		DE_NULL,

		commandPool,
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,
		1
	};

	VkImageMemoryBarrier imageBarrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		0u,											// VkAccessFlags			srcAccessMask;
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		image,										// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags		aspectMask;
			0u,										// deUint32					baseMipLevel;
			1u,										// deUint32					mipLevels;
			0u,										// deUint32					baseArraySlice;
			1u										// deUint32					arraySize;
		}
	};

	Move<VkCommandBuffer>	commandBuffer	(allocateCommandBuffer(vkd, device, &allocateInfo));
	beginCommandBuffer(vkd, *commandBuffer, 0u);

	vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
		(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);

	beginRenderPass(vkd, *commandBuffer, renderPass, framebuffer, makeRect2D(0, 0, imageWidth, imageHeight), tcu::Vec4(0.25f, 0.5f, 0.75f, 1.0f));

	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
	vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);

	endRenderPass(vkd, *commandBuffer);

	endCommandBuffer(vkd, *commandBuffer);
	return commandBuffer;
}

void deinitCommandBuffers (const DeviceInterface&			vkd,
						   VkDevice							device,
						   VkCommandPool					commandPool,
						   std::vector<VkCommandBuffer>&	commandBuffers)
{
	for (size_t ndx = 0; ndx < commandBuffers.size(); ndx++)
	{
		if (commandBuffers[ndx] != (VkCommandBuffer)0)
			vkd.freeCommandBuffers(device, commandPool, 1u,  &commandBuffers[ndx]);

		commandBuffers[ndx] = (VkCommandBuffer)0;
	}

	commandBuffers.clear();
}

Move<VkCommandPool> createCommandPool (const DeviceInterface&	vkd,
									   VkDevice					device,
									   deUint32					queueFamilyIndex)
{
	const VkCommandPoolCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
		DE_NULL,
		0u,
		queueFamilyIndex
	};

	return createCommandPool(vkd, device, &createInfo);
}

void initFramebuffers (const DeviceInterface&		vkd,
					   VkDevice						device,
					   VkRenderPass					renderPass,
					   std::vector<VkImageView>		imageViews,
					   deUint32						width,
					   deUint32						height,
					   std::vector<VkFramebuffer>&	framebuffers)
{
	DE_ASSERT(framebuffers.size() == imageViews.size());

	for (size_t ndx = 0; ndx < framebuffers.size(); ndx++)
	{
		const VkFramebufferCreateInfo createInfo =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
			DE_NULL,

			0u,
			renderPass,
			1u,
			&imageViews[ndx],
			width,
			height,
			1u
		};

		framebuffers[ndx] = createFramebuffer(vkd, device, &createInfo).disown();
	}
}

void deinitFramebuffers (const DeviceInterface&			vkd,
						 VkDevice						device,
						 std::vector<VkFramebuffer>&	framebuffers)
{
	for (size_t ndx = 0; ndx < framebuffers.size(); ndx++)
	{
		if (framebuffers[ndx] != (VkFramebuffer)0)
			vkd.destroyFramebuffer(device, framebuffers[ndx], DE_NULL);

		framebuffers[ndx] = (VkFramebuffer)0;
	}

	framebuffers.clear();
}

Move<VkImageView> createImageView (const DeviceInterface&	vkd,
								   VkDevice					device,
								   VkImage					image,
								   VkFormat					format)
{
	const VkImageViewCreateInfo	createInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
		DE_NULL,

		0u,
		image,
		VK_IMAGE_VIEW_TYPE_2D,
		format,
		makeComponentMappingRGBA(),
		{
			VK_IMAGE_ASPECT_COLOR_BIT,
			0u,
			1u,
			0u,
			1u
		}
	};

	return createImageView(vkd, device, &createInfo, DE_NULL);
}

void initImageViews (const DeviceInterface&			vkd,
					 VkDevice						device,
					 const std::vector<VkImage>&	images,
					 VkFormat						format,
					 std::vector<VkImageView>&		imageViews)
{
	DE_ASSERT(images.size() == imageViews.size());

	for (size_t ndx = 0; ndx < imageViews.size(); ndx++)
		imageViews[ndx] = createImageView(vkd, device, images[ndx], format).disown();
}

void deinitImageViews (const DeviceInterface&		vkd,
					   VkDevice						device,
					   std::vector<VkImageView>&	imageViews)
{
	for (size_t ndx = 0; ndx < imageViews.size(); ndx++)
	{
		if (imageViews[ndx] != (VkImageView)0)
			vkd.destroyImageView(device, imageViews[ndx], DE_NULL);

		imageViews[ndx] = (VkImageView)0;
	}

	imageViews.clear();
}

Move<VkPipeline> createPipeline (const DeviceInterface&	vkd,
								 VkDevice				device,
								 VkRenderPass			renderPass,
								 VkPipelineLayout		layout,
								 VkShaderModule			vertexShaderModule,
								 VkShaderModule			fragmentShaderModule,
								 deUint32				width,
								 deUint32				height)
{
	const VkPipelineVertexInputStateCreateInfo	vertexInputState	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
		DE_NULL,
		0u,
		0u,
		DE_NULL,
		0u,
		DE_NULL
	};
	const std::vector<VkViewport>	viewports	(1, makeViewport(tcu::UVec2(width, height)));
	const std::vector<VkRect2D>		scissors	(1, makeRect2D(tcu::UVec2(width, height)));

	return makeGraphicsPipeline(vkd,										// const DeviceInterface&                        vk
								device,										// const VkDevice                                device
								layout,										// const VkPipelineLayout                        pipelineLayout
								vertexShaderModule,							// const VkShaderModule                          vertexShaderModule
								DE_NULL,									// const VkShaderModule                          tessellationControlShaderModule
								DE_NULL,									// const VkShaderModule                          tessellationEvalShaderModule
								DE_NULL,									// const VkShaderModule                          geometryShaderModule
								fragmentShaderModule,						// const VkShaderModule                          fragmentShaderModule
								renderPass,									// const VkRenderPass                            renderPass
								viewports,									// const std::vector<VkViewport>&                viewports
								scissors,									// const std::vector<VkRect2D>&                  scissors
								VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,		// const VkPrimitiveTopology                     topology
								0u,											// const deUint32                                subpass
								0u,											// const deUint32                                patchControlPoints
								&vertexInputState);							// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
}

Move<VkPipelineLayout> createPipelineLayout (const DeviceInterface&	vkd,
												   VkDevice			device)
{
	const VkPipelineLayoutCreateInfo createInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
		DE_NULL,
		0u,
		0u,
		DE_NULL,
		0u,
		DE_NULL,
	};

	return createPipelineLayout(vkd, device, &createInfo);
}

VkSwapchainCounterCreateInfoEXT createSwapchainCounterConfig()
{
	const VkSwapchainCounterCreateInfoEXT swapchainCounterConfig =
	{
		VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT,
		DE_NULL,
		VK_SURFACE_COUNTER_VBLANK_EXT
	};
	return swapchainCounterConfig;
}

VkSwapchainCreateInfoKHR createSwapchainConfig (VkSurfaceKHR						surface,
												deUint32							queueFamilyIndex,
												const VkSurfaceCapabilities2EXT&	properties,
												const vector<VkSurfaceFormatKHR>&	formats,
												const vector<VkPresentModeKHR>&		presentModes,
												VkPresentModeKHR					presentMode,
												VkSwapchainCounterCreateInfoEXT *swapchainCounterInfo)
{
	if ((properties.supportedSurfaceCounters & VK_SURFACE_COUNTER_VBLANK_EXT) == 0)
		TCU_THROW(NotSupportedError, "vblank counter not supported");

	const deUint32				imageLayers		= 1u;
	const VkImageUsageFlags		imageUsage		= properties.supportedUsageFlags;
	const VkBool32				clipped			= VK_FALSE;

	const deUint32				imageWidth		= (properties.currentExtent.width != 0xFFFFFFFFu)
													? properties.currentExtent.width
													: de::min(1024u, properties.minImageExtent.width + ((properties.maxImageExtent.width - properties.minImageExtent.width) / 2));
	const deUint32				imageHeight		= (properties.currentExtent.height != 0xFFFFFFFFu)
													? properties.currentExtent.height
													: de::min(1024u, properties.minImageExtent.height + ((properties.maxImageExtent.height - properties.minImageExtent.height) / 2));
	const VkExtent2D			imageSize		= { imageWidth, imageHeight };

	if (std::find(presentModes.begin(), presentModes.end(), presentMode) == presentModes.end())
		TCU_THROW(NotSupportedError, "Present mode not supported");

	// Pick the first supported transform, alpha, and format:
	VkSurfaceTransformFlagsKHR transform;
	for (transform = 1u; transform <= properties.supportedTransforms; transform = transform << 1u)
	{
		if ((properties.supportedTransforms & transform) != 0)
			break;
	}

	VkCompositeAlphaFlagsKHR alpha;
	for (alpha = 1u; alpha <= properties.supportedCompositeAlpha; alpha = alpha << 1u)
	{
		if ((alpha & properties.supportedCompositeAlpha) != 0)
			break;
	}

	{
		const VkSurfaceTransformFlagBitsKHR	preTransform	= (VkSurfaceTransformFlagBitsKHR)transform;
		const VkCompositeAlphaFlagBitsKHR	compositeAlpha	= (VkCompositeAlphaFlagBitsKHR)alpha;
		const VkFormat						imageFormat		= formats[0].format;
		const VkColorSpaceKHR				imageColorSpace	= formats[0].colorSpace;
		const VkSwapchainCreateInfoKHR		createInfo		=
		{
			VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
			swapchainCounterInfo,
			0u,
			surface,
			properties.minImageCount,
			imageFormat,
			imageColorSpace,
			imageSize,
			imageLayers,
			imageUsage,
			VK_SHARING_MODE_EXCLUSIVE,
			1u,
			&queueFamilyIndex,
			preTransform,
			compositeAlpha,
			presentMode,
			clipped,
			(VkSwapchainKHR)0
		};

		return createInfo;
	}
}

class SwapchainCounterTestInstance : public TestInstance
{
public:
						SwapchainCounterTestInstance	(Context& context);
						~SwapchainCounterTestInstance	(void);

	tcu::TestStatus		iterate							(void);

private:
	void				initSwapchainResources			(void);
	void				deinitSwapchainResources		(void);
	void				render							(void);

private:
	const PlatformInterface&			m_vkp;
	const CustomInstance				m_instance;
	const InstanceDriver&				m_vki;
	const VkPhysicalDevice				m_physicalDevice;
	deUint32							m_planeIndex;
	const VkDisplayKHR					m_display;
	const VkSurfaceKHR					m_surface;

	const deUint32						m_queueFamilyIndex;
	const Extensions					m_deviceExtensions;
	const Unique<VkDevice>				m_device;
	const DeviceDriver					m_vkd;
	const VkQueue						m_queue;

	const Unique<VkCommandPool>			m_commandPool;
	const Unique<VkShaderModule>		m_vertexShaderModule;
	const Unique<VkShaderModule>		m_fragmentShaderModule;
	const Unique<VkPipelineLayout>		m_pipelineLayout;

	const VkSurfaceCapabilities2EXT		m_surfaceProperties;
	const vector<VkSurfaceFormatKHR>	m_surfaceFormats;
	const vector<VkPresentModeKHR>		m_presentModes;

	tcu::ResultCollector				m_resultCollector;

	Move<VkSwapchainKHR>				m_swapchain;
	std::vector<VkImage>				m_swapchainImages;

	Move<VkRenderPass>					m_renderPass;
	Move<VkPipeline>					m_pipeline;

	std::vector<VkImageView>			m_swapchainImageViews;
	std::vector<VkFramebuffer>			m_framebuffers;
	std::vector<VkCommandBuffer>		m_commandBuffers;
	std::vector<VkSemaphore>			m_acquireSemaphores;
	std::vector<VkSemaphore>			m_renderSemaphores;
	std::vector<VkFence>				m_fences;

	VkSwapchainCounterCreateInfoEXT		m_swapchainCounterConfig;
	VkSwapchainCreateInfoKHR			m_swapchainConfig;

	const size_t						m_frameCount;
	size_t								m_frameNdx;

	const size_t						m_maxOutOfDateCount;
	size_t								m_outOfDateCount;
};

SwapchainCounterTestInstance::SwapchainCounterTestInstance (Context& context)
	: TestInstance				(context)
	, m_vkp						(context.getPlatformInterface())
	, m_instance				(createInstance(context))
	, m_vki						(m_instance.getDriver())
	, m_physicalDevice			(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
	, m_planeIndex				(0)
	, m_display					(getDisplayAndDisplayPlane(m_vki, m_physicalDevice, &m_planeIndex))
	, m_surface					(createSurface(m_vki, m_instance, m_physicalDevice, m_display, m_planeIndex))

	, m_queueFamilyIndex		(chooseQueueFamilyIndex(m_vki, m_physicalDevice, m_surface))
	, m_deviceExtensions		(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
	, m_device					(createTestDevice(context.getTestContext().getPlatform().getVulkanPlatform(), m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, context.getTestContext().getCommandLine().isValidationEnabled()))
	, m_vkd						(m_vkp, m_instance, *m_device)
	, m_queue					(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))

	, m_commandPool				(createCommandPool(m_vkd, *m_device, m_queueFamilyIndex))
	, m_vertexShaderModule		(createShaderModule(m_vkd, *m_device, context.getBinaryCollection().get("quad-vert"), 0u))
	, m_fragmentShaderModule	(createShaderModule(m_vkd, *m_device, context.getBinaryCollection().get("quad-frag"), 0u))
	, m_pipelineLayout			(createPipelineLayout(m_vkd, *m_device))

	, m_surfaceProperties		(wsi::getPhysicalDeviceSurfaceCapabilities2EXT(m_vki, m_physicalDevice, m_surface))
	, m_surfaceFormats			(wsi::getPhysicalDeviceSurfaceFormats(m_vki, m_physicalDevice, m_surface))
	, m_presentModes			(wsi::getPhysicalDeviceSurfacePresentModes(m_vki, m_physicalDevice, m_surface))

	, m_swapchainCounterConfig	(createSwapchainCounterConfig())
	, m_swapchainConfig			(createSwapchainConfig(m_surface, m_queueFamilyIndex, m_surfaceProperties, m_surfaceFormats, m_presentModes, VK_PRESENT_MODE_FIFO_KHR, &m_swapchainCounterConfig))

	, m_frameCount				(20u)
	, m_frameNdx				(0u)

	, m_maxOutOfDateCount		(10u)
	, m_outOfDateCount			(0u)
{
}

SwapchainCounterTestInstance::~SwapchainCounterTestInstance (void)
{
	deinitSwapchainResources();

	m_vki.destroySurfaceKHR(m_instance, m_surface, DE_NULL);
}

void SwapchainCounterTestInstance::initSwapchainResources (void)
{
	const deUint32		imageWidth	= m_swapchainConfig.imageExtent.width;
	const deUint32		imageHeight	= m_swapchainConfig.imageExtent.height;
	const VkFormat		imageFormat	= m_swapchainConfig.imageFormat;

	m_swapchain			= createSwapchainKHR(m_vkd, *m_device, &m_swapchainConfig);
	m_swapchainImages	= wsi::getSwapchainImages(m_vkd, *m_device, *m_swapchain);

	m_renderPass		= makeRenderPass(m_vkd, *m_device, imageFormat, VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
	m_pipeline			= createPipeline(m_vkd, *m_device, *m_renderPass, *m_pipelineLayout, *m_vertexShaderModule, *m_fragmentShaderModule, imageWidth, imageHeight);

	const size_t swapchainImagesCount	= m_swapchainImages.size();
	const size_t fenceCount				= swapchainImagesCount * 2;

	m_swapchainImageViews	= std::vector<VkImageView>(swapchainImagesCount, (VkImageView)0);
	m_framebuffers			= std::vector<VkFramebuffer>(swapchainImagesCount, (VkFramebuffer)0);
	m_acquireSemaphores		= std::vector<VkSemaphore>(swapchainImagesCount+1, (VkSemaphore)0);
	m_renderSemaphores		= std::vector<VkSemaphore>(swapchainImagesCount+1, (VkSemaphore)0);

	m_fences				= std::vector<VkFence>(fenceCount, (VkFence)0);
	m_commandBuffers		= std::vector<VkCommandBuffer>(fenceCount, (VkCommandBuffer)0);

	initImageViews(m_vkd, *m_device, m_swapchainImages, imageFormat, m_swapchainImageViews);
	initFramebuffers(m_vkd, *m_device, *m_renderPass, m_swapchainImageViews, imageWidth, imageHeight, m_framebuffers);
	initSemaphores(m_vkd, *m_device, m_acquireSemaphores);
	initSemaphores(m_vkd, *m_device, m_renderSemaphores);

	initFences(m_vkd, *m_device, m_fences);
}

void SwapchainCounterTestInstance::deinitSwapchainResources (void)
{
	VK_CHECK(m_vkd.queueWaitIdle(m_queue));

	deinitSemaphores(m_vkd, *m_device, m_acquireSemaphores);
	deinitSemaphores(m_vkd, *m_device, m_renderSemaphores);
	deinitFences(m_vkd, *m_device, m_fences);
	deinitCommandBuffers(m_vkd, *m_device, *m_commandPool, m_commandBuffers);
	deinitFramebuffers(m_vkd, *m_device, m_framebuffers);
	deinitImageViews(m_vkd, *m_device, m_swapchainImageViews);

	m_swapchainImages.clear();

	m_swapchain		= Move<VkSwapchainKHR>();
	m_renderPass	= Move<VkRenderPass>();
	m_pipeline		= Move<VkPipeline>();
}

void SwapchainCounterTestInstance::render (void)
{
	const deUint64		foreverNs		= ~0x0ull;
	VkCommandBuffer&	commandBuffer	= m_commandBuffers[m_frameNdx % m_commandBuffers.size()];
	const VkFence		fence			= m_fences[m_frameNdx % m_fences.size()];
	const deUint32		width			= m_swapchainConfig.imageExtent.width;
	const deUint32		height			= m_swapchainConfig.imageExtent.height;

	if (m_frameNdx >= m_fences.size())
		VK_CHECK(m_vkd.waitForFences(*m_device, 1u, &fence, VK_TRUE, foreverNs));
	VK_CHECK(m_vkd.resetFences(*m_device, 1u, &fence));

	VkSemaphore currentAcquireSemaphore	= m_acquireSemaphores[m_frameNdx % m_acquireSemaphores.size()];
	VkSemaphore currentRenderSemaphore	= m_renderSemaphores[m_frameNdx % m_renderSemaphores.size()];

	// Acquire next image
	deUint32 imageIndex;
	VK_CHECK(m_vkd.acquireNextImageKHR(*m_device, *m_swapchain, foreverNs, currentAcquireSemaphore, (VkFence)0, &imageIndex));

	// Create command buffer
	commandBuffer = createCommandBuffer(m_vkd, *m_device, *m_commandPool, *m_renderPass, m_swapchainImages[imageIndex],
										m_framebuffers[imageIndex], *m_pipeline, width, height).disown();

	// Submit command buffer
	{
		const VkPipelineStageFlags	dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
		const VkSubmitInfo			submitInfo =
		{
			VK_STRUCTURE_TYPE_SUBMIT_INFO,
			DE_NULL,
			1u,
			&currentAcquireSemaphore,
			&dstStageMask,
			1u,
			&commandBuffer,
			1u,
			&currentRenderSemaphore
		};

		VK_CHECK(m_vkd.queueSubmit(m_queue, 1u, &submitInfo, fence));
	}

	VkResult result;
	const VkPresentInfoKHR presentInfo =
	{
		VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
		DE_NULL,
		1u,
		&currentRenderSemaphore,
		1u,
		&*m_swapchain,
		&imageIndex,
		&result
	};

	VK_CHECK_WSI(m_vkd.queuePresentKHR(m_queue, &presentInfo));
	VK_CHECK_WSI(result);

	// verify counter on last frame - we know that we must have presented as meny frames
	// as we rendered minus the number of images in swapchain - that may not have been presented yet
	if (m_frameNdx >= m_frameCount)
	{
		deUint64 counter = 0;
		m_vkd.getSwapchainCounterEXT(*m_device, *m_swapchain, VK_SURFACE_COUNTER_VBLANK_EXT, &counter);
		if ((counter < (m_frameCount - m_swapchainImages.size())) || (counter > m_frameCount))
		{
			deinitSwapchainResources();
			m_resultCollector.fail("Invalid surface counter value");
		}
	}
}

tcu::TestStatus SwapchainCounterTestInstance::iterate (void)
{
	try
	{
		// Initialize swapchain specific resources
		if (m_frameNdx == 0)
			initSwapchainResources();

		// Render frame
		render();
	}
	catch (const Error& error)
	{
		if (error.getError() == VK_ERROR_OUT_OF_DATE_KHR)
		{
			if (m_outOfDateCount < m_maxOutOfDateCount)
			{
				m_context.getTestContext().getLog() << TestLog::Message << "Frame " << m_frameNdx
					<< ": Swapchain out of date. Recreating resources." << TestLog::EndMessage;
				deinitSwapchainResources();
				m_outOfDateCount++;
				m_frameNdx = 0;

				return tcu::TestStatus::incomplete();
			}

			m_context.getTestContext().getLog() << TestLog::Message << "Frame " << m_frameNdx
				<< ": Swapchain out of date." << TestLog::EndMessage;
			return tcu::TestStatus::fail("Received too many VK_ERROR_OUT_OF_DATE_KHR errors.");
		}

		deinitSwapchainResources();
		return tcu::TestStatus::fail(error.what());
	}

	m_frameNdx++;
	if (m_frameNdx < m_frameCount)
		return tcu::TestStatus::incomplete();

	deinitSwapchainResources();
	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
}

class SwapchainCounterTestCase : public TestCase
{
public:

	SwapchainCounterTestCase(tcu::TestContext& context, const char* name);
	~SwapchainCounterTestCase() = default;

	void					initPrograms(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance(Context& context) const;
	virtual void			checkSupport(Context& context) const;
};

SwapchainCounterTestCase::SwapchainCounterTestCase(tcu::TestContext& context, const char* name)
	: vkt::TestCase(context, name, name)
{
}

void SwapchainCounterTestCase::initPrograms(SourceCollections& dst) const
{
	dst.glslSources.add("quad-vert") << glu::VertexSource(
		"#version 450\n"
		"out gl_PerVertex {\n"
		"    vec4 gl_Position;\n"
		"};\n"
		"highp float;\n"
		"void main (void) {\n"
		"    gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
		"                       ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
		"}\n");
	dst.glslSources.add("quad-frag") << glu::FragmentSource(
		"#version 450\n"
		"layout(location = 0) out highp vec4 o_color;\n"
		"void main (void)\n"
		"{\n"
		"    o_color = vec4(1.0, 0.5, 0.0, 1.0);\n"
		"}\n");
}

TestInstance* SwapchainCounterTestCase::createInstance(Context& context) const
{
	return new SwapchainCounterTestInstance(context);
}

void SwapchainCounterTestCase::checkSupport(Context& context) const
{
	context.requireInstanceFunctionality("VK_KHR_display");
	context.requireDeviceFunctionality("VK_EXT_display_control");
}

void getDisplays(Context& context, std::vector<VkDisplayKHR>& availableDisplays)
{
	// get number of displays
	deUint32					countReported		= 0u;
	VkPhysicalDevice			physicalDevice		= context.getPhysicalDevice();
	const InstanceInterface&	vki					= context.getInstanceInterface();

	VkResult result = vki.getPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &countReported, DE_NULL);
	if (result != VK_SUCCESS)
		TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceDisplayPropertiesKHR failed");

	if (countReported == 0)
		TCU_THROW(NotSupportedError, "No displays available");

	// get display properties
	std::vector<VkDisplayPropertiesKHR> displaysProperties(countReported);
	result = vki.getPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &countReported, &displaysProperties[0]);

	if (result != VK_SUCCESS)
		TCU_THROW(NotSupportedError, "vkGetPhysicalDeviceDisplayPropertiesKHR failed");

	availableDisplays.clear();
	for (const auto& dp : displaysProperties)
		availableDisplays.push_back(dp.display);
}

tcu::TestStatus testDisplayPowerControl(Context& context)
{
	// make sure VK_EXT_display_control is available
	context.requireDeviceFunctionality("VK_EXT_display_control");

	// get all connected displays
	std::vector<VkDisplayKHR> availableDisplays;
	getDisplays(context, availableDisplays);

	struct PowerStateData
	{
		VkDisplayPowerStateEXT	state;
		deUint32				waitMs;
	};
	vector<PowerStateData> powerStateDataVect =
	{
		{ VK_DISPLAY_POWER_STATE_ON_EXT,		1000 },
		{ VK_DISPLAY_POWER_STATE_SUSPEND_EXT,	1000 },
		{ VK_DISPLAY_POWER_STATE_OFF_EXT,		1000 },
		{ VK_DISPLAY_POWER_STATE_ON_EXT,		1000 },
	};

	// iterate over all displays
	VkDevice						device	= context.getDevice();
	const vk::DeviceInterface&		vkd		= context.getDeviceInterface();
	for (const auto& display : availableDisplays)
	{
		// iterate over tested sequence of power states
		for (const auto& psd : powerStateDataVect)
		{
			VkDisplayPowerInfoEXT displayPowerInfo =
			{
				VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT,
				DE_NULL,
				psd.state
			};

			VkResult result = vkd.displayPowerControlEXT(device, display, &displayPowerInfo);
			if (result != VK_SUCCESS)
				return tcu::TestStatus::fail(std::string("vkDisplayPowerControlEXT returned invalid result for ") + de::toString(psd.state));

			deSleep(psd.waitMs);
		}
	}

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

tcu::TestStatus testDisplayEvent(Context& context)
{
	// make sure VK_EXT_display_control is available
	context.requireDeviceFunctionality("VK_EXT_display_control");

	// get all connected displays
	std::vector<vk::VkDisplayKHR> availableDisplays;
	getDisplays(context, availableDisplays);

	VkDevice				device	= context.getDevice();
	const DeviceInterface&	vkd		= context.getDeviceInterface();
	std::vector<VkFence>	fences	= std::vector<VkFence>(availableDisplays.size(), (VkFence)0);

	// iterate over all displays
	for (size_t i = 0 ; i < availableDisplays.size() ; ++i)
	{
		VkDisplayEventInfoEXT displayEventInfo =
		{
			VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT,
			DE_NULL,
			VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT
		};

		VkFence&		fence		= fences[i];
		VkDisplayKHR&	display		= availableDisplays[i];
		VkResult		result		= vkd.registerDisplayEventEXT(device, display, &displayEventInfo, DE_NULL, &fence);
		if (result != VK_SUCCESS)
			return tcu::TestStatus::fail(std::string("vkRegisterDisplayEventEXT returned invalid result"));
	}

	// deinit fence
	deinitFences (vkd, device, fences);

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

tcu::TestStatus testDeviceEvent(Context& context)
{
	// make sure VK_EXT_display_control is available
	context.requireDeviceFunctionality("VK_EXT_display_control");

	VkDevice				device = context.getDevice();
	const DeviceInterface&	vkd = context.getDeviceInterface();
	std::vector<VkFence>	fences = std::vector<VkFence>(1, (VkFence)0);

	vk::VkDeviceEventInfoEXT deviceEventInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT,
		DE_NULL,
		VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT
	};

	VkResult result = vkd.registerDeviceEventEXT(device, &deviceEventInfo, DE_NULL, &fences[0]);
	if (result != VK_SUCCESS)
		return tcu::TestStatus::fail(std::string("vkRegisterDeviceEventEXT returned invalid result"));

	// deinit fence
	deinitFences(vkd, device, fences);

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

} // anonymous

void createDisplayControlTests (tcu::TestCaseGroup* testGroup)
{
	testGroup->addChild(new SwapchainCounterTestCase(testGroup->getTestContext(), "swapchain_counter"));
	addFunctionCase(testGroup, "display_power_control",		"Test display power control",	testDisplayPowerControl);
	addFunctionCase(testGroup, "register_display_event",	"Test register display event",	testDisplayEvent);
	addFunctionCase(testGroup, "register_device_event",		"Test register device event",	testDeviceEvent);
}

} // wsi
} // vkt
