/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 Google 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 VkSwapchain Tests
 *//*--------------------------------------------------------------------*/

#include "vktWsiSwapchainTests.hpp"

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

#include "vkDefs.hpp"
#include "vkPlatform.hpp"
#include "vkStrUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkPrograms.hpp"
#include "vkTypeUtil.hpp"
#include "vkWsiPlatform.hpp"
#include "vkWsiUtil.hpp"
#include "vkAllocationCallbackUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

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

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"
#include "deArrayUtil.hpp"
#include "deSharedPtr.hpp"

#include <limits>
#include <algorithm>

namespace vkt
{
namespace wsi
{

namespace
{

using namespace vk;
using namespace vk::wsi;

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

using de::MovePtr;
using de::UniquePtr;

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

typedef vector<VkExtensionProperties> Extensions;

void checkAllSupported (const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
{
	for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
		 requiredExtName != requiredExtensions.end();
		 ++requiredExtName)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
			TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
	}
}

CustomInstance createInstanceWithWsi (Context&						context,
									  const Extensions&				supportedExtensions,
									  Type							wsiType,
									  const vector<string>			extraExtensions,
									  const VkAllocationCallbacks*	pAllocator	= DE_NULL)
{
	vector<string>	extensions = extraExtensions;

	extensions.push_back("VK_KHR_surface");
	extensions.push_back(getExtensionName(wsiType));

	// VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
	// the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
	// but using them without enabling the extension is not allowed. Thus we have
	// two options:
	//
	// 1) Filter out non-core formats to stay within valid usage.
	//
	// 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
	//
	// We opt for (2) as it provides basic coverage for the extension as a bonus.
	if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
		extensions.push_back("VK_EXT_swapchain_colorspace");

	checkAllSupported(supportedExtensions, extensions);

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

VkPhysicalDeviceFeatures getDeviceFeaturesForWsi (void)
{
	VkPhysicalDeviceFeatures features;
	deMemset(&features, 0, sizeof(features));
	return features;
}

Move<VkDevice> createDeviceWithWsi (const PlatformInterface&		vkp,
									VkInstance						instance,
									const InstanceInterface&		vki,
									VkPhysicalDevice				physicalDevice,
									const Extensions&				supportedExtensions,
									const vector<deUint32>&			queueFamilyIndices,
									bool							validationEnabled,
									const VkAllocationCallbacks*	pAllocator = DE_NULL)
{
	const float						queuePriorities[]	= { 1.0f };

	vector<VkDeviceQueueCreateInfo>	queueInfos;
	for (const auto familyIndex : queueFamilyIndices)
	{
		const VkDeviceQueueCreateInfo info =
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
			nullptr,
			(VkDeviceQueueCreateFlags)0,
			familyIndex,
			DE_LENGTH_OF_ARRAY(queuePriorities),
			&queuePriorities[0],
		};

		queueInfos.push_back(info);
	}

	const VkPhysicalDeviceFeatures	features		= getDeviceFeaturesForWsi();
	const char* const				extensions[]	= { "VK_KHR_swapchain" };

	const VkDeviceCreateInfo		deviceParams	=
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
		DE_NULL,
		(VkDeviceCreateFlags)0,
		static_cast<deUint32>(queueInfos.size()),
		queueInfos.data(),
		0u,									// enabledLayerCount
		DE_NULL,							// ppEnabledLayerNames
		DE_LENGTH_OF_ARRAY(extensions),		// enabledExtensionCount
		DE_ARRAY_BEGIN(extensions),			// ppEnabledExtensionNames
		&features
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
			TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
	}

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

Move<VkDevice> createDeviceWithWsi (const PlatformInterface&		vkp,
									VkInstance						instance,
									const InstanceInterface&		vki,
									VkPhysicalDevice				physicalDevice,
									const Extensions&				supportedExtensions,
									const deUint32					queueFamilyIndex,
									bool							validationEnabled,
									const VkAllocationCallbacks*	pAllocator = DE_NULL)
{
	return createDeviceWithWsi(vkp, instance, vki, physicalDevice, supportedExtensions, vector<deUint32>(1u, queueFamilyIndex), validationEnabled, pAllocator);
}

struct InstanceHelper
{
	const vector<VkExtensionProperties>	supportedExtensions;
	const CustomInstance				instance;
	const InstanceDriver&				vki;

	InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
		: supportedExtensions	(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
																	  DE_NULL))
		, instance				(createInstanceWithWsi(context,
													   supportedExtensions,
													   wsiType,
													   vector<string>(),
													   pAllocator))
		, vki					(instance.getDriver())
	{}

	InstanceHelper (Context& context, Type wsiType, const vector<string>& extensions, const VkAllocationCallbacks* pAllocator = DE_NULL)
		: supportedExtensions	(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
																	  DE_NULL))
		, instance				(createInstanceWithWsi(context,
													   supportedExtensions,
													   wsiType,
													   extensions,
													   pAllocator))
		, vki					(instance.getDriver())
	{}
};

struct DeviceHelper
{
	const VkPhysicalDevice	physicalDevice;
	const deUint32			queueFamilyIndex;
	const Unique<VkDevice>	device;
	const DeviceDriver		vkd;
	const VkQueue			queue;

	DeviceHelper (Context&						context,
				  const InstanceInterface&		vki,
				  VkInstance					instance,
				  const vector<VkSurfaceKHR>&	surface,
				  const VkAllocationCallbacks*	pAllocator = DE_NULL)
		: physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
		, queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, surface))
		, device			(createDeviceWithWsi(context.getPlatformInterface(),
												 context.getInstance(),
												 vki,
												 physicalDevice,
												 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
												 queueFamilyIndex,
												 context.getTestContext().getCommandLine().isValidationEnabled(),
												 pAllocator))
		, vkd				(context.getPlatformInterface(), context.getInstance(), *device)
		, queue				(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
	{
	}

	// Single-surface shortcut.
	DeviceHelper (Context&						context,
				  const InstanceInterface&		vki,
				  VkInstance					instance,
				  VkSurfaceKHR					surface,
				  const VkAllocationCallbacks*	pAllocator = DE_NULL)
		: DeviceHelper(context, vki, instance, vector<VkSurfaceKHR>(1u, surface), pAllocator)
	{
	}
};

// Similar to the one above with no queues and multiple queue families.
struct MultiQueueDeviceHelper
{
	const VkPhysicalDevice	physicalDevice;
	const vector<deUint32>	queueFamilyIndices;
	const Unique<VkDevice>	device;
	const DeviceDriver		vkd;

	MultiQueueDeviceHelper (Context&						context,
							const InstanceInterface&		vki,
							VkInstance						instance,
							const vector<VkSurfaceKHR>&		surface,
							const VkAllocationCallbacks*	pAllocator = DE_NULL)
		: physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
		, queueFamilyIndices(getCompatibleQueueFamilyIndices(vki, physicalDevice, surface))
		, device			(createDeviceWithWsi(context.getPlatformInterface(),
												 context.getInstance(),
												 vki,
												 physicalDevice,
												 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
												 queueFamilyIndices,
												 context.getTestContext().getCommandLine().isValidationEnabled(),
												 pAllocator))
		, vkd				(context.getPlatformInterface(), context.getInstance(), *device)
	{
	}

	// Single-surface shortcut.
	MultiQueueDeviceHelper (Context&						context,
							const InstanceInterface&		vki,
							VkInstance						instance,
							VkSurfaceKHR					surface,
							const VkAllocationCallbacks*	pAllocator = DE_NULL)
		: MultiQueueDeviceHelper(context, vki, instance, vector<VkSurfaceKHR>(1u, surface), pAllocator)
	{
	}
};

MovePtr<Display> createDisplay (const vk::Platform&	platform,
								const Extensions&	supportedExtensions,
								Type				wsiType)
{
	try
	{
		return MovePtr<Display>(platform.createWsiDisplay(wsiType));
	}
	catch (const tcu::NotSupportedError& e)
	{
		if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
		    platform.hasDisplay(wsiType))
		{
			// If VK_KHR_{platform}_surface was supported, vk::Platform implementation
			// must support creating native display & window for that WSI type.
			throw tcu::TestError(e.getMessage());
		}
		else
			throw;
	}
}

MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
{
	try
	{
		return MovePtr<Window>(display.createWindow(initialSize));
	}
	catch (const tcu::NotSupportedError& e)
	{
		// See createDisplay - assuming that wsi::Display was supported platform port
		// should also support creating a window.
		throw tcu::TestError(e.getMessage());
	}
}

class NativeObjects
{
private:
	UniquePtr<Display>		display;
	vector<MovePtr<Window>>	windows;

public:
	NativeObjects (Context&				context,
				   const Extensions&	supportedExtensions,
				   Type					wsiType,
				   size_t				windowCount = 1u,
				   const Maybe<UVec2>&	initialWindowSize = tcu::nothing<UVec2>())
		: display	(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
	{
		DE_ASSERT(windowCount > 0u);
		for (size_t i = 0; i < windowCount; ++i)
			windows.emplace_back(createWindow(*display, initialWindowSize));
	}

	NativeObjects (NativeObjects&& other)
		: display	(other.display.move())
		, windows	()
	{
		windows.swap(other.windows);
	}

	Display&	getDisplay	() const
	{
		return *display;
	}

	Window&		getWindow	(size_t index = 0u) const
	{
		DE_ASSERT(index < windows.size());
		return *windows[index];
	}
};

enum TestDimension
{
	TEST_DIMENSION_MIN_IMAGE_COUNT = 0,	//!< Test all supported image counts
	TEST_DIMENSION_IMAGE_FORMAT,		//!< Test all supported formats
	TEST_DIMENSION_IMAGE_EXTENT,		//!< Test various (supported) extents
	TEST_DIMENSION_IMAGE_ARRAY_LAYERS,
	TEST_DIMENSION_IMAGE_USAGE,
	TEST_DIMENSION_IMAGE_SHARING_MODE,
	TEST_DIMENSION_PRE_TRANSFORM,
	TEST_DIMENSION_COMPOSITE_ALPHA,
	TEST_DIMENSION_PRESENT_MODE,
	TEST_DIMENSION_CLIPPED,

	TEST_DIMENSION_LAST
};

const char* getTestDimensionName (TestDimension dimension)
{
	static const char* const s_names[] =
	{
		"min_image_count",
		"image_format",
		"image_extent",
		"image_array_layers",
		"image_usage",
		"image_sharing_mode",
		"pre_transform",
		"composite_alpha",
		"present_mode",
		"clipped"
	};
	return de::getSizedArrayElement<TEST_DIMENSION_LAST>(s_names, dimension);
}

struct TestParameters
{
	Type			wsiType;
	TestDimension	dimension;

	TestParameters (Type wsiType_, TestDimension dimension_)
		: wsiType	(wsiType_)
		, dimension	(dimension_)
	{}

	TestParameters (void)
		: wsiType	(TYPE_LAST)
		, dimension	(TEST_DIMENSION_LAST)
	{}
};

vector<VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (Type								wsiType,
																  TestDimension						dimension,
																  const VkSurfaceCapabilitiesKHR&	capabilities,
																  const vector<VkSurfaceFormatKHR>&	formats,
																  const vector<VkPresentModeKHR>&	presentModes)
{
	const PlatformProperties&			platformProperties	= getPlatformProperties(wsiType);
	vector<VkSwapchainCreateInfoKHR>	cases;
	const VkSurfaceTransformFlagBitsKHR defaultTransform	= (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
	const VkSwapchainCreateInfoKHR		baseParameters		=
	{
		VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
		DE_NULL,
		(VkSwapchainCreateFlagsKHR)0,
		(VkSurfaceKHR)0,
		capabilities.minImageCount,
		formats[0].format,
		formats[0].colorSpace,
		(platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE
			? capabilities.minImageExtent : capabilities.currentExtent),
		1u,									// imageArrayLayers
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		defaultTransform,
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
		VK_PRESENT_MODE_FIFO_KHR,
		VK_FALSE,							// clipped
		(VkSwapchainKHR)0					// oldSwapchain
	};

	switch (dimension)
	{
		case TEST_DIMENSION_MIN_IMAGE_COUNT:
		{
			const deUint32	maxImageCountToTest	= de::clamp(16u, capabilities.minImageCount, (capabilities.maxImageCount > 0) ? capabilities.maxImageCount : capabilities.minImageCount + 16u);

			for (deUint32 imageCount = capabilities.minImageCount; imageCount <= maxImageCountToTest; ++imageCount)
			{
				cases.push_back(baseParameters);
				cases.back().minImageCount = imageCount;
			}

			break;
		}

		case TEST_DIMENSION_IMAGE_FORMAT:
		{
			for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
			{
				cases.push_back(baseParameters);
				cases.back().imageFormat		= curFmt->format;
				cases.back().imageColorSpace	= curFmt->colorSpace;
			}

			break;
		}

		case TEST_DIMENSION_IMAGE_EXTENT:
		{
			static const VkExtent2D	s_testSizes[]	=
			{
				{ 1, 1 },
				{ 16, 32 },
				{ 32, 16 },
				{ 632, 231 },
				{ 117, 998 },
			};

			if (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE ||
				platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE)
			{
				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_testSizes); ++ndx)
				{
					cases.push_back(baseParameters);
					cases.back().imageExtent.width	= de::clamp(s_testSizes[ndx].width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
					cases.back().imageExtent.height	= de::clamp(s_testSizes[ndx].height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
				}
			}

			if (platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE)
			{
				cases.push_back(baseParameters);
				cases.back().imageExtent = capabilities.currentExtent;
			}

			if (platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE)
			{
				cases.push_back(baseParameters);
				cases.back().imageExtent = capabilities.minImageExtent;

				cases.push_back(baseParameters);
				cases.back().imageExtent = capabilities.maxImageExtent;
			}

			break;
		}

		case TEST_DIMENSION_IMAGE_ARRAY_LAYERS:
		{
			const deUint32	maxLayers	= de::min(capabilities.maxImageArrayLayers, 16u);

			for (deUint32 numLayers = 1; numLayers <= maxLayers; ++numLayers)
			{
				cases.push_back(baseParameters);
				cases.back().imageArrayLayers = numLayers;
			}

			break;
		}

		case TEST_DIMENSION_IMAGE_USAGE:
		{
			for (deUint32 flags = 1u; flags <= capabilities.supportedUsageFlags; ++flags)
			{
				if ((flags & ~capabilities.supportedUsageFlags) == 0)
				{
					cases.push_back(baseParameters);
					cases.back().imageUsage = flags;
				}
			}

			break;
		}

		case TEST_DIMENSION_IMAGE_SHARING_MODE:
		{
#if 0
			// Skipping since this matches the base parameters.
			cases.push_back(baseParameters);
			cases.back().imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
#endif

			cases.push_back(baseParameters);
			cases.back().imageSharingMode = VK_SHARING_MODE_CONCURRENT;

			break;
		}

		case TEST_DIMENSION_PRE_TRANSFORM:
		{
			for (deUint32 transform = 1u;
				 transform <= capabilities.supportedTransforms;
				 transform = transform<<1u)
			{
				if ((transform & capabilities.supportedTransforms) != 0)
				{
					cases.push_back(baseParameters);
					cases.back().preTransform = (VkSurfaceTransformFlagBitsKHR)transform;
				}
			}

			break;
		}

		case TEST_DIMENSION_COMPOSITE_ALPHA:
		{
			for (deUint32 alphaMode = 1u;
				 alphaMode <= capabilities.supportedCompositeAlpha;
				 alphaMode = alphaMode<<1u)
			{
				if ((alphaMode & capabilities.supportedCompositeAlpha) != 0)
				{
					cases.push_back(baseParameters);
					cases.back().compositeAlpha = (VkCompositeAlphaFlagBitsKHR)alphaMode;
				}
			}

			break;
		}

		case TEST_DIMENSION_PRESENT_MODE:
		{
			for (vector<VkPresentModeKHR>::const_iterator curMode = presentModes.begin(); curMode != presentModes.end(); ++curMode)
			{
				cases.push_back(baseParameters);
				cases.back().presentMode = *curMode;
			}

			break;
		}

		case TEST_DIMENSION_CLIPPED:
		{
			cases.push_back(baseParameters);
			cases.back().clipped = VK_FALSE;

			cases.push_back(baseParameters);
			cases.back().clipped = VK_TRUE;

			break;
		}

		default:
			DE_FATAL("Impossible");
	}

	DE_ASSERT(!cases.empty());
	return cases;
}

vector<VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (Type								wsiType,
																  TestDimension						dimension,
																  const InstanceInterface&			vki,
																  VkPhysicalDevice					physicalDevice,
																  VkSurfaceKHR						surface)
{
	const VkSurfaceCapabilitiesKHR		capabilities	= getPhysicalDeviceSurfaceCapabilities(vki,
																							   physicalDevice,
																							   surface);
	const vector<VkSurfaceFormatKHR>	formats			= getPhysicalDeviceSurfaceFormats(vki,
																						  physicalDevice,
																						  surface);
	const vector<VkPresentModeKHR>		presentModes	= getPhysicalDeviceSurfacePresentModes(vki,
																							   physicalDevice,
																							   surface);

	return generateSwapchainParameterCases(wsiType, dimension, capabilities, formats, presentModes);
}

tcu::TestStatus createSwapchainTest (Context& context, TestParameters params)
{
	tcu::TestLog&							log			= context.getTestContext().getLog();
	const InstanceHelper					instHelper	(context, params.wsiType);
	const NativeObjects						native		(context, instHelper.supportedExtensions, params.wsiType);
	const Unique<VkSurfaceKHR>				surface		(createSurface(instHelper.vki, instHelper.instance, params.wsiType, native.getDisplay(), native.getWindow()));
	const MultiQueueDeviceHelper			devHelper	(context, instHelper.vki, instHelper.instance, *surface);
	const vector<VkSwapchainCreateInfoKHR>	cases		(generateSwapchainParameterCases(params.wsiType, params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));
	const VkSurfaceCapabilitiesKHR			capabilities(getPhysicalDeviceSurfaceCapabilities(instHelper.vki, devHelper.physicalDevice, *surface));

	for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
	{
		std::ostringstream subcase;
		subcase << "Sub-case " << (caseNdx+1) << " / " << cases.size() << ": ";

		VkSwapchainCreateInfoKHR	curParams	= cases[caseNdx];

		if (curParams.imageSharingMode == VK_SHARING_MODE_CONCURRENT)
		{
			const deUint32 numFamilies = static_cast<deUint32>(devHelper.queueFamilyIndices.size());
			if (numFamilies < 2u)
				TCU_THROW(NotSupportedError, "Only " + de::toString(numFamilies) + " queue families available for VK_SHARING_MODE_CONCURRENT");
			curParams.queueFamilyIndexCount	= numFamilies;
		}
		else
		{
			// Take only the first queue.
			if (devHelper.queueFamilyIndices.empty())
				TCU_THROW(NotSupportedError, "No queue families compatible with the given surface");
			curParams.queueFamilyIndexCount	= 1u;
		}
		curParams.pQueueFamilyIndices	= devHelper.queueFamilyIndices.data();
		curParams.surface				= *surface;

		log << TestLog::Message << subcase.str() << curParams << TestLog::EndMessage;

		// The Vulkan 1.1.87 spec contains the following VU for VkSwapchainCreateInfoKHR:
		//
		//     * imageFormat, imageUsage, imageExtent, and imageArrayLayers must be supported for VK_IMAGE_TYPE_2D
		//     VK_IMAGE_TILING_OPTIMAL images as reported by vkGetPhysicalDeviceImageFormatProperties.
		VkImageFormatProperties properties;
		const VkResult propertiesResult = instHelper.vki.getPhysicalDeviceImageFormatProperties(devHelper.physicalDevice,
																								curParams.imageFormat,
																								VK_IMAGE_TYPE_2D,
																								VK_IMAGE_TILING_OPTIMAL,
																								curParams.imageUsage,
																								0, // flags
																								&properties);

		log << TestLog::Message << subcase.str()
			<< "vkGetPhysicalDeviceImageFormatProperties => "
			<< getResultStr(propertiesResult) << TestLog::EndMessage;

		switch (propertiesResult) {
		case VK_SUCCESS:
			{
				// The maxExtents case might not be able to create the requested surface due to insufficient
				// memory, so in this case *only* we handle the OOM exception.
				if (params.dimension == TEST_DIMENSION_IMAGE_EXTENT &&
					capabilities.maxImageExtent.width == curParams.imageExtent.width &&
					capabilities.maxImageExtent.height == curParams.imageExtent.height)
				{
					try
					{
						const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(devHelper.vkd, *devHelper.device, &curParams));

						log << TestLog::Message << subcase.str()
							<< "Creating swapchain succeeded" << TestLog::EndMessage;
					}
					catch (const OutOfMemoryError& e)
					{
						log << TestLog::Message << subcase.str() << "vkCreateSwapchainKHR with maxImageExtent encountered " << e.getError() << TestLog::EndMessage;
					}
				}
				else
				{
					const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(devHelper.vkd, *devHelper.device, &curParams));

					log << TestLog::Message << subcase.str()
						<< "Creating swapchain succeeded" << TestLog::EndMessage;
				}
			}
			break;
		case VK_ERROR_FORMAT_NOT_SUPPORTED:
			log << TestLog::Message << subcase.str()
				<< "Skip because vkGetPhysicalDeviceImageFormatProperties returned VK_ERROR_FORMAT_NOT_SUPPORTED" << TestLog::EndMessage;
			break;
		default:
			log << TestLog::Message << subcase.str()
				<< "Fail because vkGetPhysicalDeviceImageFormatProperties returned "
				<< getResultStr(propertiesResult) << TestLog::EndMessage;
			return tcu::TestStatus::fail("Unexpected result from vkGetPhysicalDeviceImageFormatProperties");
		}
	}

	return tcu::TestStatus::pass("No sub-case failed");
}

tcu::TestStatus createSwapchainSimulateOOMTest (Context& context, TestParameters params)
{
	const size_t				maxCases			= 300u;
	const deUint32				maxAllocs			= 1024u;

	tcu::TestLog&				log					= context.getTestContext().getLog();
	tcu::ResultCollector		results				(log);

	AllocationCallbackRecorder	allocationRecorder	(getSystemAllocator());
	DeterministicFailAllocator	failingAllocator	(allocationRecorder.getCallbacks(),
													 DeterministicFailAllocator::MODE_DO_NOT_COUNT,
													 0);
	{
		const InstanceHelper					instHelper	(context, params.wsiType, failingAllocator.getCallbacks());
		const NativeObjects						native		(context, instHelper.supportedExtensions, params.wsiType);
		const Unique<VkSurfaceKHR>				surface		(createSurface(instHelper.vki,
																			instHelper.instance,
																			params.wsiType,
																			native.getDisplay(),
																			native.getWindow(),
																			failingAllocator.getCallbacks()));
		const DeviceHelper						devHelper	(context, instHelper.vki, instHelper.instance, *surface, failingAllocator.getCallbacks());
		const vector<VkSwapchainCreateInfoKHR>	allCases	(generateSwapchainParameterCases(params.wsiType, params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));

		if (maxCases < allCases.size())
			log << TestLog::Message << "Note: Will only test first " << maxCases << " cases out of total of " << allCases.size() << " parameter combinations" << TestLog::EndMessage;

		for (size_t caseNdx = 0; caseNdx < de::min(maxCases, allCases.size()); ++caseNdx)
		{
			log << TestLog::Message << "Testing parameter case " << caseNdx << ": " << allCases[caseNdx] << TestLog::EndMessage;

			for (deUint32 numPassingAllocs = 0; numPassingAllocs <= maxAllocs; ++numPassingAllocs)
			{
				bool	gotOOM	= false;

				failingAllocator.reset(DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs);

				log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;

				try
				{
					VkSwapchainCreateInfoKHR	curParams	= allCases[caseNdx];

					curParams.surface				= *surface;
					curParams.queueFamilyIndexCount	= 1u;
					curParams.pQueueFamilyIndices	= &devHelper.queueFamilyIndex;

					{
						const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(devHelper.vkd, *devHelper.device, &curParams, failingAllocator.getCallbacks()));
					}
				}
				catch (const OutOfMemoryError& e)
				{
					log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
					gotOOM = true;
				}

				if (!gotOOM)
				{
					log << TestLog::Message << "Creating swapchain succeeded!" << TestLog::EndMessage;

					if (numPassingAllocs == 0)
						results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");

					break;
				}
				else if (numPassingAllocs == maxAllocs)
					results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Creating swapchain did not succeed, callback limit exceeded");
			}

			context.getTestContext().touchWatchdog();
		}
	}

	if (!validateAndLog(log, allocationRecorder, 0u))
		results.fail("Detected invalid system allocation callback");

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

tcu::TestStatus testImageSwapchainCreateInfo (Context& context, Type wsiType)
{
	const tcu::UVec2			desiredSize			(256, 256);
	const InstanceHelper		instHelper			(context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
	const NativeObjects			native				(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>	surface				(createSurface(instHelper.vki,
																   instHelper.instance,
																   wsiType,
																   native.getDisplay(),
																   native.getWindow()));
	const DeviceHelper			devHelper			(context, instHelper.vki, instHelper.instance, *surface);
	const Extensions&			deviceExtensions	= enumerateDeviceExtensionProperties(instHelper.vki, devHelper.physicalDevice, DE_NULL);

	// structures this tests checks were added in revision 69
	if (!isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_swapchain", 69)))
		TCU_THROW(NotSupportedError, "Required extension revision is not supported");

	const VkSurfaceCapabilitiesKHR		capabilities		= getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
																								   devHelper.physicalDevice,
																								   *surface);
	const vector<VkSurfaceFormatKHR>	formats				= getPhysicalDeviceSurfaceFormats(instHelper.vki,
																							  devHelper.physicalDevice,
																							  *surface);
	const PlatformProperties&			platformProperties	= getPlatformProperties(wsiType);
	const VkSurfaceTransformFlagBitsKHR transform			= (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
	const deUint32						desiredImageCount	= 2;
	const VkSwapchainCreateInfoKHR		swapchainInfo		=
	{
		VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
		DE_NULL,
		(VkSwapchainCreateFlagsKHR)0,
		*surface,
		de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount),
		formats[0].format,
		formats[0].colorSpace,
		(platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
			? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),
		1u,
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		transform,
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
		VK_PRESENT_MODE_FIFO_KHR,
		VK_FALSE,							// clipped
		(VkSwapchainKHR)0					// oldSwapchain
	};

	const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));
	deUint32						numImages	= 0;
	VK_CHECK(devHelper.vkd.getSwapchainImagesKHR(*devHelper.device, *swapchain, &numImages, DE_NULL));
	if (numImages == 0)
		return tcu::TestStatus::pass("Pass");

	VkImageSwapchainCreateInfoKHR imageSwapchainCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR,
		DE_NULL,
		*swapchain
	};

	VkImageCreateInfo imageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		&imageSwapchainCreateInfo,
		(VkImageCreateFlags)0u,					// flags
		VK_IMAGE_TYPE_2D,						// imageType
		formats[0].format,						// format
		{										// extent
			desiredSize.x(),					//   width
			desiredSize.y(),					//   height
			1u									//   depth
		},
		1u,										// mipLevels
		1u,										// arrayLayers
		VK_SAMPLE_COUNT_1_BIT,					// samples
		VK_IMAGE_TILING_OPTIMAL,				// tiling
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,	// usage
		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
		0u,										// queueFamilyIndexCount
		DE_NULL,								// pQueueFamilyIndices
		VK_IMAGE_LAYOUT_UNDEFINED				// initialLayout
	};

	typedef vk::Unique<VkImage>			UniqueImage;
	typedef de::SharedPtr<UniqueImage>	ImageSp;

	std::vector<ImageSp>							images						(numImages);
	std::vector<VkBindImageMemorySwapchainInfoKHR>	bindImageMemorySwapchainInfo(numImages);
	std::vector<VkBindImageMemoryInfo>				bindImageMemoryInfos		(numImages);

	for (deUint32 idx = 0; idx < numImages; ++idx)
	{
		// Create image
		images[idx] = ImageSp(new UniqueImage(createImage(devHelper.vkd, *devHelper.device, &imageCreateInfo)));

		VkBindImageMemorySwapchainInfoKHR bimsInfo =
		{
			VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
			DE_NULL,
			*swapchain,
			idx
		};
		bindImageMemorySwapchainInfo[idx] = bimsInfo;

		VkBindImageMemoryInfo bimInfo =
		{
			VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
			&bindImageMemorySwapchainInfo[idx],
			**images[idx],
			DE_NULL,				// If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
			0u						// If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
		};

		bindImageMemoryInfos[idx] = bimInfo;
	}

	VK_CHECK(devHelper.vkd.bindImageMemory2(*devHelper.device, numImages, &bindImageMemoryInfos[0]));

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

struct GroupParameters
{
	typedef FunctionInstance1<TestParameters>::Function	Function;

	Type		wsiType;
	Function	function;

	GroupParameters (Type wsiType_, Function function_)
		: wsiType	(wsiType_)
		, function	(function_)
	{}

	GroupParameters (void)
		: wsiType	(TYPE_LAST)
		, function	((Function)DE_NULL)
	{}
};

void populateSwapchainGroup (tcu::TestCaseGroup* testGroup, GroupParameters params)
{
	for (int dimensionNdx = 0; dimensionNdx < TEST_DIMENSION_LAST; ++dimensionNdx)
	{
		const TestDimension		testDimension	= (TestDimension)dimensionNdx;

		addFunctionCase(testGroup, getTestDimensionName(testDimension), "", params.function, TestParameters(params.wsiType, testDimension));
	}

	addFunctionCase(testGroup, "image_swapchain_create_info", "Test VkImageSwapchainCreateInfoKHR", testImageSwapchainCreateInfo, params.wsiType);
}

VkSwapchainCreateInfoKHR getBasicSwapchainParameters (Type						wsiType,
													  const InstanceInterface&	vki,
													  VkPhysicalDevice			physicalDevice,
													  VkSurfaceKHR				surface,
													  const tcu::UVec2&			desiredSize,
													  deUint32					desiredImageCount)
{
	const VkSurfaceCapabilitiesKHR		capabilities		= getPhysicalDeviceSurfaceCapabilities(vki,
																								   physicalDevice,
																								   surface);
	const vector<VkSurfaceFormatKHR>	formats				= getPhysicalDeviceSurfaceFormats(vki,
																							  physicalDevice,
																							  surface);
	const PlatformProperties&			platformProperties	= getPlatformProperties(wsiType);
	const VkSurfaceTransformFlagBitsKHR transform			= (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
	const VkSwapchainCreateInfoKHR		parameters			=
	{
		VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
		DE_NULL,
		(VkSwapchainCreateFlagsKHR)0,
		surface,
		de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount),
		formats[0].format,
		formats[0].colorSpace,
		(platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
			? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),
		1u,									// imageArrayLayers
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		transform,
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
		VK_PRESENT_MODE_FIFO_KHR,
		VK_FALSE,							// clipped
		(VkSwapchainKHR)0					// oldSwapchain
	};

	return parameters;
}

typedef de::SharedPtr<Unique<VkCommandBuffer> >	CommandBufferSp;
typedef de::SharedPtr<Unique<VkFence> >			FenceSp;
typedef de::SharedPtr<Unique<VkSemaphore> >		SemaphoreSp;

vector<FenceSp> createFences (const DeviceInterface&	vkd,
							  const VkDevice			device,
							  size_t					numFences)
{
	vector<FenceSp> fences(numFences);

	for (size_t ndx = 0; ndx < numFences; ++ndx)
		fences[ndx] = FenceSp(new Unique<VkFence>(createFence(vkd, device, vk::VK_FENCE_CREATE_SIGNALED_BIT)));

	return fences;
}

vector<SemaphoreSp> createSemaphores (const DeviceInterface&	vkd,
									  const VkDevice			device,
									  size_t					numSemaphores)
{
	vector<SemaphoreSp> semaphores(numSemaphores);

	for (size_t ndx = 0; ndx < numSemaphores; ++ndx)
		semaphores[ndx] = SemaphoreSp(new Unique<VkSemaphore>(createSemaphore(vkd, device)));

	return semaphores;
}

vector<CommandBufferSp> allocateCommandBuffers (const DeviceInterface&		vkd,
												const VkDevice				device,
												const VkCommandPool			commandPool,
												const VkCommandBufferLevel	level,
												const size_t				numCommandBuffers)
{
	vector<CommandBufferSp>				buffers		(numCommandBuffers);

	for (size_t ndx = 0; ndx < numCommandBuffers; ++ndx)
		buffers[ndx] = CommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(vkd, device, commandPool, level)));

	return buffers;
}

class AcquireNextImageWrapper
{
public:

	AcquireNextImageWrapper(const DeviceInterface&	vkd,
							VkDevice				device,
							deUint32				deviceMask,
							VkSwapchainKHR			swapchain,
							deUint64				timeout)
		: m_vkd			(vkd)
		, m_device		(device)
		, m_swapchain	(swapchain)
		, m_timeout		(timeout)
	{
		DE_UNREF(deviceMask);	// needed for compatibility with acquireNextImage2KHR
	}

	bool featureAvailable(Context&)
	{
		return true;			// needed for compatibility with acquireNextImage2KHR
	}

	VkResult call(VkSemaphore semaphore, VkFence fence, deUint32* imageIndex)
	{
		return m_vkd.acquireNextImageKHR(m_device,
										 m_swapchain,
										 m_timeout,
										 semaphore,
										 fence,
										 imageIndex);
	}

protected:

	const DeviceInterface&	m_vkd;
	VkDevice				m_device;
	VkSwapchainKHR			m_swapchain;
	deUint64				m_timeout;
};

class AcquireNextImage2Wrapper
{
public:

	AcquireNextImage2Wrapper(const DeviceInterface&	vkd,
							 VkDevice				device,
							 deUint32				deviceMask,
							 VkSwapchainKHR			swapchain,
							 deUint64				timeout)
		: m_vkd		(vkd)
		, m_device	(device)
	{
		m_info.sType		= VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR;
		m_info.pNext		= DE_NULL;
		m_info.swapchain	= swapchain;
		m_info.timeout		= timeout;
		m_info.semaphore	= DE_NULL;
		m_info.fence		= DE_NULL;
		m_info.deviceMask	= deviceMask;
	}

	bool featureAvailable(Context& context)
	{
		return context.isDeviceFunctionalitySupported("VK_KHR_device_group");
	}

	VkResult call(VkSemaphore semaphore, VkFence fence, deUint32* imageIndex)
	{
		m_info.semaphore	= semaphore;
		m_info.fence		= fence;
		return m_vkd.acquireNextImage2KHR(m_device,
										  &m_info,
										  imageIndex);
	}

protected:

	const DeviceInterface&		m_vkd;
	VkDevice					m_device;
	VkAcquireNextImageInfoKHR	m_info;
};


template <typename AcquireWrapperType>
tcu::TestStatus basicRenderTest (Context& context, Type wsiType)
{
	const tcu::UVec2				desiredSize					(256, 256);
	const InstanceHelper			instHelper					(context, wsiType);
	const NativeObjects				native						(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>		surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
	const DeviceHelper				devHelper					(context, instHelper.vki, instHelper.instance, *surface);
	const DeviceInterface&			vkd							= devHelper.vkd;
	const VkDevice					device						= *devHelper.device;
	SimpleAllocator					allocator					(vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
	const VkSwapchainCreateInfoKHR	swapchainInfo				= getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
	const Unique<VkSwapchainKHR>	swapchain					(createSwapchainKHR(vkd, device, &swapchainInfo));
	const vector<VkImage>			swapchainImages				= getSwapchainImages(vkd, device, *swapchain);

	AcquireWrapperType acquireImageWrapper(vkd, device, 1u, *swapchain, std::numeric_limits<deUint64>::max());
	if (!acquireImageWrapper.featureAvailable(context))
		TCU_THROW(NotSupportedError, "Required extension is not supported");

	const WsiTriangleRenderer		renderer					(vkd,
																 device,
																 allocator,
																 context.getBinaryCollection(),
																 false,
																 swapchainImages,
																 swapchainImages,
																 swapchainInfo.imageFormat,
																 tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));

	const Unique<VkCommandPool>		commandPool					(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));

	const size_t					maxQueuedFrames				= swapchainImages.size()*2;

	// We need to keep hold of fences from vkAcquireNextImage(2)KHR to actually
	// limit number of frames we allow to be queued.
	const vector<FenceSp>			imageReadyFences			(createFences(vkd, device, maxQueuedFrames));

	// We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to pass
	// the semaphore in same time as the fence we use to meter rendering.
	const vector<SemaphoreSp>		imageReadySemaphores		(createSemaphores(vkd, device, maxQueuedFrames+1));

	// For rest we simply need maxQueuedFrames as we will wait for image
	// from frameNdx-maxQueuedFrames to become available to us, guaranteeing that
	// previous uses must have completed.
	const vector<SemaphoreSp>		renderingCompleteSemaphores	(createSemaphores(vkd, device, maxQueuedFrames));
	const vector<CommandBufferSp>	commandBuffers				(allocateCommandBuffers(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));

	try
	{
		const deUint32	numFramesToRender	= 60*10;

		for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
		{
			const VkFence		imageReadyFence		= **imageReadyFences[frameNdx%imageReadyFences.size()];
			const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
			deUint32			imageNdx			= ~0u;

			VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
			VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));

			{
				const VkResult	acquireResult	= acquireImageWrapper.call(imageReadySemaphore, (VkFence)0, &imageNdx);

				if (acquireResult == VK_SUBOPTIMAL_KHR)
					context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
				else
					VK_CHECK(acquireResult);
			}

			TCU_CHECK((size_t)imageNdx < swapchainImages.size());

			{
				const VkSemaphore			renderingCompleteSemaphore	= **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
				const VkCommandBuffer		commandBuffer				= **commandBuffers[frameNdx%commandBuffers.size()];
				const VkPipelineStageFlags	waitDstStage				= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
				const VkSubmitInfo			submitInfo					=
				{
					VK_STRUCTURE_TYPE_SUBMIT_INFO,
					DE_NULL,
					1u,
					&imageReadySemaphore,
					&waitDstStage,
					1u,
					&commandBuffer,
					1u,
					&renderingCompleteSemaphore
				};
				const VkPresentInfoKHR		presentInfo					=
				{
					VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
					DE_NULL,
					1u,
					&renderingCompleteSemaphore,
					1u,
					&*swapchain,
					&imageNdx,
					(VkResult*)DE_NULL
				};

				renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
				VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, imageReadyFence));
				VK_CHECK_WSI(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
			}
		}

		VK_CHECK(vkd.deviceWaitIdle(device));
	}
	catch (...)
	{
		// Make sure device is idle before destroying resources
		vkd.deviceWaitIdle(device);
		throw;
	}

	return tcu::TestStatus::pass("Rendering tests succeeded");
}

class FrameStreamObjects
{
public:
	struct FrameObjects
	{
		const vk::VkFence&			renderCompleteFence;
		const vk::VkSemaphore&		renderCompleteSemaphore;
		const vk::VkSemaphore&		imageAvailableSemaphore;
		const vk::VkCommandBuffer&	commandBuffer;
	};

	FrameStreamObjects (const vk::DeviceInterface& vkd, vk::VkDevice device, vk::VkCommandPool cmdPool, size_t maxQueuedFrames)
		: renderingCompleteFences(createFences(vkd, device, maxQueuedFrames))
		, renderingCompleteSemaphores(createSemaphores(vkd, device, maxQueuedFrames))
		, imageAvailableSemaphores(createSemaphores(vkd, device, maxQueuedFrames))
		, commandBuffers(allocateCommandBuffers(vkd, device, cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames))
		, m_maxQueuedFrames(maxQueuedFrames)
		, m_nextFrame(0u)
	{}

	size_t frameNumber (void) const { DE_ASSERT(m_nextFrame > 0u); return m_nextFrame - 1u; }

	FrameObjects newFrame ()
	{
		const size_t mod = m_nextFrame % m_maxQueuedFrames;
		FrameObjects ret =
		{
			**renderingCompleteFences[mod],
			**renderingCompleteSemaphores[mod],
			**imageAvailableSemaphores[mod],
			**commandBuffers[mod],
		};
		++m_nextFrame;
		return ret;
	}

private:
	const vector<FenceSp>			renderingCompleteFences;
	const vector<SemaphoreSp>		renderingCompleteSemaphores;
	const vector<SemaphoreSp>		imageAvailableSemaphores;
	const vector<CommandBufferSp>	commandBuffers;

	const size_t	m_maxQueuedFrames;
	size_t			m_nextFrame;
};

struct MultiSwapchainParams
{
	Type	wsiType;
	size_t	swapchainCount;
};

struct AccumulatedPresentInfo
{
	vector<VkSemaphore>		semaphores;
	vector<VkSwapchainKHR>	swapchains;
	vector<deUint32>		imageIndices;

	AccumulatedPresentInfo ()
		: semaphores(), swapchains(), imageIndices()
	{
	}

	void push_back (VkSemaphore sem, VkSwapchainKHR sc, deUint32 index)
	{
		semaphores.push_back(sem);
		swapchains.push_back(sc);
		imageIndices.push_back(index);
	}

	void reset ()
	{
		semaphores.resize(0);
		swapchains.resize(0);
		imageIndices.resize(0);
	}

	size_t size () const
	{
		// Any of the vectors would do.
		return semaphores.size();
	}
};

template <typename AcquireWrapperType>
tcu::TestStatus multiSwapchainRenderTest (Context& context, MultiSwapchainParams params)
{
	DE_ASSERT(params.swapchainCount > 0);

	const tcu::UVec2		desiredSize	(256, 256);
	const InstanceHelper	instHelper	(context, params.wsiType);

	// Create native window system objects, surfaces and helper surface vector.
	std::unique_ptr<NativeObjects> native;
	try
	{
		native.reset(new NativeObjects(context, instHelper.supportedExtensions, params.wsiType, params.swapchainCount, tcu::just(desiredSize)));
	}
	catch(tcu::ResourceError&)
	{
		std::ostringstream msg;
		msg << "Unable to create " << params.swapchainCount << " windows";
		TCU_THROW(NotSupportedError, msg.str());
	}

	vector<Move<VkSurfaceKHR>>	surface;
	vector<VkSurfaceKHR>		surfaceKHR;	// The plain Vulkan objects from the vector above.

	for (size_t i = 0; i < params.swapchainCount; ++i)
	{
		surface.emplace_back(createSurface(instHelper.vki, instHelper.instance, params.wsiType, native->getDisplay(), native->getWindow(i)));
		surfaceKHR.push_back(surface.back().get());
	}

	// Create a device compatible with all surfaces.
	const DeviceHelper		devHelper	(context, instHelper.vki, instHelper.instance, surfaceKHR);
	const DeviceInterface&	vkd			= devHelper.vkd;
	const VkDevice			device		= *devHelper.device;
	SimpleAllocator			allocator	(vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));

	// Create several swapchains and images.
	vector<VkSwapchainCreateInfoKHR>	swapchainInfo;
	vector<Move<VkSwapchainKHR>>		swapchain;
	vector<vector<VkImage>>				swapchainImages;
	vector<AcquireWrapperType>			acquireImageWrapper;
	for (size_t i = 0; i < params.swapchainCount; ++i)
	{
		swapchainInfo.emplace_back(getBasicSwapchainParameters(params.wsiType, instHelper.vki, devHelper.physicalDevice, *surface[i], desiredSize, 2));
		swapchain.emplace_back(createSwapchainKHR(vkd, device, &swapchainInfo.back()));
		swapchainImages.emplace_back(getSwapchainImages(vkd, device, swapchain.back().get()));
		acquireImageWrapper.emplace_back(vkd, device, 1u, swapchain.back().get(), std::numeric_limits<deUint64>::max());
	}

	// Every acquire wrapper requires the same features, so we only check the first one.
	if (!acquireImageWrapper.front().featureAvailable(context))
		TCU_THROW(NotSupportedError, "Required extension is not supported");

	// Renderer per swapchain.
	vector<WsiTriangleRenderer> renderer;
	for (size_t i = 0; i < params.swapchainCount; ++i)
	{
		renderer.emplace_back(vkd,
							  device,
							  allocator,
							  context.getBinaryCollection(),
							  false,
							  swapchainImages[i],
							  swapchainImages[i],
							  swapchainInfo[i].imageFormat,
							  tcu::UVec2(swapchainInfo[i].imageExtent.width, swapchainInfo[i].imageExtent.height));
	}

	const Unique<VkCommandPool>	commandPool			(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
	const size_t				maxQueuedFrames		= swapchainImages.front().size()*2;	// Limit in-flight frames.

	vector<FrameStreamObjects>	frameStreamObjects;
	for (size_t i = 0; i < params.swapchainCount; ++i)
		frameStreamObjects.emplace_back(vkd, device, commandPool.get(), maxQueuedFrames);

	try
	{
		// 3 seconds for 60 Hz screens.
		const deUint32			kNumFramesToRender		= 60*3*static_cast<deUint32>(params.swapchainCount);
		AccumulatedPresentInfo	accumulatedPresentInfo;

		for (size_t frameNdx = 0; frameNdx < kNumFramesToRender; ++frameNdx)
		{
			size_t		swapchainIndex	= frameNdx % params.swapchainCount;
			auto&		fsObjects		= frameStreamObjects[swapchainIndex];
			auto		frameObjects	= fsObjects.newFrame();
			deUint32	imageNdx		= std::numeric_limits<deUint32>::max();

			VK_CHECK(vkd.waitForFences(device, 1u, &frameObjects.renderCompleteFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
			VK_CHECK(vkd.resetFences(device, 1u, &frameObjects.renderCompleteFence));

			{
				const VkResult acquireResult = acquireImageWrapper[swapchainIndex].call(frameObjects.imageAvailableSemaphore, (VkFence)DE_NULL, &imageNdx);
				if (acquireResult == VK_SUBOPTIMAL_KHR)
					context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
				else
					VK_CHECK(acquireResult);
			}

			TCU_CHECK(static_cast<size_t>(imageNdx) < swapchainImages[swapchainIndex].size());

			{
				const VkPipelineStageFlags	waitDstStage	= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
				const VkSubmitInfo			submitInfo		=
				{
					VK_STRUCTURE_TYPE_SUBMIT_INFO,
					DE_NULL,
					1u,
					&frameObjects.imageAvailableSemaphore,
					&waitDstStage,
					1u,
					&frameObjects.commandBuffer,
					1u,
					&frameObjects.renderCompleteSemaphore,
				};

				renderer[swapchainIndex].recordFrame(frameObjects.commandBuffer, imageNdx, static_cast<deUint32>(frameNdx));
				VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, frameObjects.renderCompleteFence));

				// Save present information for the current frame.
				accumulatedPresentInfo.push_back(frameObjects.renderCompleteSemaphore, swapchain[swapchainIndex].get(), imageNdx);

				// Present frames when we have accumulated one frame per swapchain.
				if (accumulatedPresentInfo.size() == params.swapchainCount)
				{
					DE_ASSERT(	accumulatedPresentInfo.semaphores.size() == accumulatedPresentInfo.swapchains.size()	&&
								accumulatedPresentInfo.semaphores.size() == accumulatedPresentInfo.imageIndices.size()	);

					vector<VkResult> results(params.swapchainCount, VK_ERROR_DEVICE_LOST);

					const VkPresentInfoKHR presentInfo =
					{
						VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
						DE_NULL,
						static_cast<deUint32>(accumulatedPresentInfo.semaphores.size()),
						accumulatedPresentInfo.semaphores.data(),
						static_cast<deUint32>(accumulatedPresentInfo.swapchains.size()),
						accumulatedPresentInfo.swapchains.data(),
						accumulatedPresentInfo.imageIndices.data(),
						results.data(),
					};

					// Check both the global result and the individual results.
					VK_CHECK_WSI(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
					for (const auto& result : results)
						VK_CHECK_WSI(result);

					accumulatedPresentInfo.reset();
				}
			}
		}

		VK_CHECK(vkd.deviceWaitIdle(device));
	}
	catch (...)
	{
		// Make sure device is idle before destroying resources
		vkd.deviceWaitIdle(device);
		throw;
	}

	return tcu::TestStatus::pass("Rendering tests succeeded");
}

tcu::TestStatus deviceGroupRenderTest (Context& context, Type wsiType)
{
	const InstanceHelper		instHelper			(context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
	const tcu::CommandLine&		cmdLine				= context.getTestContext().getCommandLine();
	VkPhysicalDevice			physicalDevice		= chooseDevice(instHelper.vki, instHelper.instance, cmdLine);
	const Extensions&			supportedExtensions	= enumerateDeviceExtensionProperties(instHelper.vki, physicalDevice, DE_NULL);

	std::vector<const char*> deviceExtensions;
	deviceExtensions.push_back("VK_KHR_swapchain");
	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
		deviceExtensions.push_back("VK_KHR_device_group");

	for (std::size_t ndx = 0; ndx < deviceExtensions.size(); ++ndx)
	{
		if (!isExtensionSupported(supportedExtensions, RequiredExtension(deviceExtensions[ndx])))
			TCU_THROW(NotSupportedError, (string(deviceExtensions[ndx]) + " is not supported").c_str());
	}

	const tcu::UVec2								desiredSize					(256, 256);
	const NativeObjects								native						(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>						surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));

	const deUint32									devGroupIdx					= cmdLine.getVKDeviceGroupId() - 1;
	const deUint32									deviceIdx					= context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
	const vector<VkPhysicalDeviceGroupProperties>	deviceGroupProps			= enumeratePhysicalDeviceGroups(instHelper.vki, instHelper.instance);
	deUint32										physicalDevicesInGroupCount	= deviceGroupProps[devGroupIdx].physicalDeviceCount;
	const VkPhysicalDevice*							physicalDevicesInGroup		= deviceGroupProps[devGroupIdx].physicalDevices;
	deUint32										queueFamilyIndex			= chooseQueueFamilyIndex(instHelper.vki, physicalDevicesInGroup[deviceIdx], *surface);
	const std::vector<VkQueueFamilyProperties>		queueProps					= getPhysicalDeviceQueueFamilyProperties(instHelper.vki, physicalDevicesInGroup[deviceIdx]);
	const float										queuePriority				= 1.0f;
	const deUint32									firstDeviceID				= 0;
	const deUint32									secondDeviceID				= 1;

	// create a device group
	const VkDeviceGroupDeviceCreateInfo groupDeviceInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR,			// stype
		DE_NULL,														// pNext
		physicalDevicesInGroupCount,									// physicalDeviceCount
		physicalDevicesInGroup											// physicalDevices
	};
	const VkDeviceQueueCreateInfo deviceQueueCreateInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// type
		DE_NULL,														// pNext
		(VkDeviceQueueCreateFlags)0u,									// flags
		queueFamilyIndex,												// queueFamilyIndex
		1u,																// queueCount
		&queuePriority,													// pQueuePriorities
	};

	const VkDeviceCreateInfo	deviceCreateInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// sType
		&groupDeviceInfo,												// pNext
		(VkDeviceCreateFlags)0u,										// flags
		1,																// queueRecordCount
		&deviceQueueCreateInfo,											// pRequestedQueues
		0,																// layerCount
		DE_NULL,														// ppEnabledLayerNames
		deUint32(deviceExtensions.size()),								// enabledExtensionCount
		&deviceExtensions[0],											// ppEnabledExtensionNames
		DE_NULL,														// pEnabledFeatures
	};

	Move<VkDevice>					groupDevice					= createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instHelper.instance, instHelper.vki, physicalDevicesInGroup[deviceIdx], &deviceCreateInfo);
	const DeviceDriver				vkd							(context.getPlatformInterface(), instHelper.instance, *groupDevice);
	VkQueue							queue						(getDeviceQueue(vkd, *groupDevice, queueFamilyIndex, 0));
	SimpleAllocator					allocator					(vkd, *groupDevice, getPhysicalDeviceMemoryProperties(instHelper.vki, physicalDevicesInGroup[deviceIdx]));

	// create swapchain for device group
	struct VkDeviceGroupSwapchainCreateInfoKHR deviceGroupSwapchainInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR,
		DE_NULL,
		VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR
	};
	VkSwapchainCreateInfoKHR swapchainInfo = getBasicSwapchainParameters(wsiType,
																		 instHelper.vki,
																		 physicalDevicesInGroup[deviceIdx],
																		 *surface,
																		 desiredSize,
																		 2);
	swapchainInfo.pNext = &deviceGroupSwapchainInfo;

	const Unique<VkSwapchainKHR>	swapchain					(createSwapchainKHR(vkd, *groupDevice, &swapchainInfo));
	const vector<VkImage>			swapchainImages				= getSwapchainImages(vkd, *groupDevice, *swapchain);

	const WsiTriangleRenderer		renderer					(vkd,
																 *groupDevice,
																 allocator,
																 context.getBinaryCollection(),
																 false,
																 swapchainImages,
																 swapchainImages,
																 swapchainInfo.imageFormat,
																 tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));

	const Unique<VkCommandPool>		commandPool					(createCommandPool(vkd, *groupDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));

	const size_t					maxQueuedFrames				= swapchainImages.size()*2;

	// We need to keep hold of fences from vkAcquireNextImage2KHR
	// to actually limit number of frames we allow to be queued.
	const vector<FenceSp>			imageReadyFences			(createFences(vkd, *groupDevice, maxQueuedFrames));

	// We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to
	// pass the semaphore in same time as the fence we use to meter rendering.
	const vector<SemaphoreSp>		imageReadySemaphores		(createSemaphores(vkd, *groupDevice, maxQueuedFrames+1));

	// For rest we simply need maxQueuedFrames as we will wait for image from frameNdx-maxQueuedFrames
	// to become available to us, guaranteeing that previous uses must have completed.
	const vector<SemaphoreSp>		renderingCompleteSemaphores	(createSemaphores(vkd, *groupDevice, maxQueuedFrames));
	const vector<CommandBufferSp>	commandBuffers				(allocateCommandBuffers(vkd, *groupDevice, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));

	try
	{
		const deUint32	numFramesToRender = 60*10;

		for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
		{
			const VkFence		imageReadyFence		= **imageReadyFences[frameNdx%imageReadyFences.size()];
			const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
			deUint32			imageNdx			= ~0u;

			VK_CHECK(vkd.waitForFences(*groupDevice, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
			VK_CHECK(vkd.resetFences(*groupDevice, 1, &imageReadyFence));

			{
				VkAcquireNextImageInfoKHR acquireNextImageInfo =
				{
					VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
					DE_NULL,
					*swapchain,
					std::numeric_limits<deUint64>::max(),
					imageReadySemaphore,
					(VkFence)0,
					(1 << firstDeviceID)
				};

				const VkResult acquireResult = vkd.acquireNextImage2KHR(*groupDevice, &acquireNextImageInfo, &imageNdx);

				if (acquireResult == VK_SUBOPTIMAL_KHR)
					context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
				else
					VK_CHECK(acquireResult);
			}

			TCU_CHECK((size_t)imageNdx < swapchainImages.size());

			{
				const VkSemaphore			renderingCompleteSemaphore	= **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
				const VkCommandBuffer		commandBuffer				= **commandBuffers[frameNdx%commandBuffers.size()];
				const VkPipelineStageFlags	waitDstStage				= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

				// render triangle using one or two subdevices when available
				renderer.recordDeviceGroupFrame(commandBuffer, firstDeviceID, secondDeviceID, physicalDevicesInGroupCount, imageNdx, frameNdx);

				// submit queue
				deUint32 deviceMask = (1 << firstDeviceID);
				std::vector<deUint32> deviceIndices(1, firstDeviceID);
				if (physicalDevicesInGroupCount > 1)
				{
					deviceMask |= (1 << secondDeviceID);
					deviceIndices.push_back(secondDeviceID);
				}
				const VkDeviceGroupSubmitInfo deviceGroupSubmitInfo =
				{
					VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR,		// sType
					DE_NULL,											// pNext
					deUint32(deviceIndices.size()),						// waitSemaphoreCount
					&deviceIndices[0],									// pWaitSemaphoreDeviceIndices
					1u,													// commandBufferCount
					&deviceMask,										// pCommandBufferDeviceMasks
					deUint32(deviceIndices.size()),						// signalSemaphoreCount
					&deviceIndices[0],									// pSignalSemaphoreDeviceIndices
				};
				const VkSubmitInfo submitInfo =
				{
					VK_STRUCTURE_TYPE_SUBMIT_INFO,						// sType
					&deviceGroupSubmitInfo,								// pNext
					1u,													// waitSemaphoreCount
					&imageReadySemaphore,								// pWaitSemaphores
					&waitDstStage,										// pWaitDstStageMask
					1u,													// commandBufferCount
					&commandBuffer,										// pCommandBuffers
					1u,													// signalSemaphoreCount
					&renderingCompleteSemaphore,						// pSignalSemaphores
				};
				VK_CHECK(vkd.queueSubmit(queue, 1u, &submitInfo, imageReadyFence));

				// present swapchain image
				deviceMask = (1 << firstDeviceID);
				const VkDeviceGroupPresentInfoKHR deviceGroupPresentInfo =
				{
					VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR,
					DE_NULL,
					1u,
					&deviceMask,
					VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR,
				};
				const VkPresentInfoKHR presentInfo =
				{
					VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
					&deviceGroupPresentInfo,
					1u,
					&renderingCompleteSemaphore,
					1u,
					&*swapchain,
					&imageNdx,
					(VkResult*)DE_NULL
				};
				VK_CHECK_WSI(vkd.queuePresentKHR(queue, &presentInfo));
			}
		}

		VK_CHECK(vkd.deviceWaitIdle(*groupDevice));
	}
	catch (...)
	{
		// Make sure device is idle before destroying resources
		vkd.deviceWaitIdle(*groupDevice);
		throw;
	}

	return tcu::TestStatus::pass("Rendering tests succeeded");
}

tcu::TestStatus deviceGroupRenderTest2 (Context& context, Type wsiType)
{
	const InstanceHelper		instHelper			(context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
	const tcu::CommandLine&		cmdLine				= context.getTestContext().getCommandLine();
	VkPhysicalDevice			physicalDevice		= chooseDevice(instHelper.vki, instHelper.instance, cmdLine);
	const Extensions&			deviceExtensions	= enumerateDeviceExtensionProperties(instHelper.vki, physicalDevice, DE_NULL);

	// structures this tests checks were added in revision 69
	if (!isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_swapchain", 69)))
		TCU_THROW(NotSupportedError, "Required extension revision is not supported");

	std::vector<const char*> requiredExtensions;
	requiredExtensions.push_back("VK_KHR_swapchain");
	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
	{
		requiredExtensions.push_back("VK_KHR_device_group");
		if (!isExtensionSupported(deviceExtensions, RequiredExtension("VK_KHR_device_group")))
			TCU_THROW(NotSupportedError, "VK_KHR_device_group is not supported");
	}

	const tcu::UVec2								desiredSize					(256, 256);
	const NativeObjects								native						(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>						surface						(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));

	const deUint32									devGroupIdx					= cmdLine.getVKDeviceGroupId() - 1;
	const deUint32									deviceIdx					= context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
	const vector<VkPhysicalDeviceGroupProperties>	deviceGroupProps			= enumeratePhysicalDeviceGroups(instHelper.vki, instHelper.instance);
	deUint32										physicalDevicesInGroupCount	= deviceGroupProps[devGroupIdx].physicalDeviceCount;
	const VkPhysicalDevice*							physicalDevicesInGroup		= deviceGroupProps[devGroupIdx].physicalDevices;
	deUint32										queueFamilyIndex			= chooseQueueFamilyIndex(instHelper.vki, physicalDevicesInGroup[deviceIdx], *surface);
	const std::vector<VkQueueFamilyProperties>		queueProps					= getPhysicalDeviceQueueFamilyProperties(instHelper.vki, physicalDevicesInGroup[deviceIdx]);
	const float										queuePriority				= 1.0f;
	const deUint32									firstDeviceID				= 0;
	const deUint32									secondDeviceID				= 1;
	const deUint32									deviceIndices[]				= { firstDeviceID, secondDeviceID };

	if (physicalDevicesInGroupCount < 2)
		TCU_THROW(NotSupportedError, "Test requires more then 1 device in device group");

	// create a device group
	const VkDeviceGroupDeviceCreateInfo groupDeviceInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR,			// stype
		DE_NULL,														// pNext
		physicalDevicesInGroupCount,									// physicalDeviceCount
		physicalDevicesInGroup											// physicalDevices
	};
	const VkDeviceQueueCreateInfo deviceQueueCreateInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// type
		DE_NULL,														// pNext
		(VkDeviceQueueCreateFlags)0u,									// flags
		queueFamilyIndex,												// queueFamilyIndex
		1u,																// queueCount
		&queuePriority,													// pQueuePriorities
	};

	const VkDeviceCreateInfo deviceCreateInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// sType
		&groupDeviceInfo,												// pNext
		(VkDeviceCreateFlags)0u,										// flags
		1,																// queueRecordCount
		&deviceQueueCreateInfo,											// pRequestedQueues
		0,																// layerCount
		DE_NULL,														// ppEnabledLayerNames
		deUint32(requiredExtensions.size()),							// enabledExtensionCount
		&requiredExtensions[0],											// ppEnabledExtensionNames
		DE_NULL,														// pEnabledFeatures
	};

	Move<VkDevice>						groupDevice			= createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instHelper.instance, instHelper.vki, physicalDevicesInGroup[deviceIdx], &deviceCreateInfo);
	const DeviceDriver					vkd					(context.getPlatformInterface(), instHelper.instance, *groupDevice);
	VkQueue								queue				(getDeviceQueue(vkd, *groupDevice, queueFamilyIndex, 0));
	SimpleAllocator						allocator			(vkd, *groupDevice, getPhysicalDeviceMemoryProperties(instHelper.vki, physicalDevicesInGroup[deviceIdx]));

	// create swapchain for device group
	const VkSurfaceCapabilitiesKHR		capabilities		= getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevice, *surface);
	const vector<VkSurfaceFormatKHR>	formats				= getPhysicalDeviceSurfaceFormats(instHelper.vki, physicalDevice, *surface);
	const PlatformProperties&			platformProperties	= getPlatformProperties(wsiType);
	const VkSurfaceTransformFlagBitsKHR transform			= (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
	const deUint32						desiredImageCount	= 2;

	struct VkDeviceGroupSwapchainCreateInfoKHR deviceGroupSwapchainInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR,
		DE_NULL,
		VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR
	};
	const VkSwapchainCreateInfoKHR swapchainInfo =
	{
		VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
		&deviceGroupSwapchainInfo,
		VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR,
		*surface,
		de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount),
		formats[0].format,
		formats[0].colorSpace,
		(platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
			? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),
		1u,
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		transform,
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
		VK_PRESENT_MODE_FIFO_KHR,
		VK_FALSE,
		(VkSwapchainKHR)0
	};

	const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(vkd, *groupDevice, &swapchainInfo));
	deUint32						numImages	= 0;
	VK_CHECK(vkd.getSwapchainImagesKHR(*groupDevice, *swapchain, &numImages, DE_NULL));
	if (numImages == 0)
		return tcu::TestStatus::pass("Pass");

	VkImageSwapchainCreateInfoKHR imageSwapchainCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR,
		DE_NULL,
		*swapchain
	};

	VkImageCreateInfo imageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		&imageSwapchainCreateInfo,
		VK_IMAGE_CREATE_ALIAS_BIT |
		VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR,		// flags
		VK_IMAGE_TYPE_2D,											// imageType
		formats[0].format,											// format
		{															// extent
			desiredSize.x(),										//   width
			desiredSize.y(),										//   height
			1u														//   depth
		},
		1u,															// mipLevels
		1u,															// arrayLayers
		VK_SAMPLE_COUNT_1_BIT,										// samples
		VK_IMAGE_TILING_OPTIMAL,									// tiling
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,						// usage
		VK_SHARING_MODE_EXCLUSIVE,									// sharingMode
		0u,															// queueFamilyIndexCount
		DE_NULL,													// pQueueFamilyIndices
		VK_IMAGE_LAYOUT_UNDEFINED									// initialLayout
	};

	typedef vk::Unique<VkImage>			UniqueImage;
	typedef de::SharedPtr<UniqueImage>	ImageSp;

	vector<ImageSp>								images							(numImages);
	vector<VkImage>								rawImages						(numImages);
	vector<ImageSp>								imagesSfr						(numImages);
	vector<VkImage>								rawImagesSfr					(numImages);
	vector<VkBindImageMemorySwapchainInfoKHR>	bindImageMemorySwapchainInfo	(numImages);

	// Create non-SFR image aliases for image layout transition
	{
		vector<VkBindImageMemoryInfo>				bindImageMemoryInfos			(numImages);

		for (deUint32 idx = 0; idx < numImages; ++idx)
		{
			// Create image
			images[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));

			VkBindImageMemorySwapchainInfoKHR bimsInfo =
			{
				VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
				DE_NULL,
				*swapchain,
				idx
			};
			bindImageMemorySwapchainInfo[idx] = bimsInfo;

			VkBindImageMemoryInfo bimInfo =
			{
				VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
				&bindImageMemorySwapchainInfo[idx],
				**images[idx],
				DE_NULL,				// If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
				0u						// If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
			};
			bindImageMemoryInfos[idx]	= bimInfo;
			rawImages[idx]				= **images[idx];
		}

		VK_CHECK(vkd.bindImageMemory2(*groupDevice, numImages, &bindImageMemoryInfos[0]));
	}

	// Create the SFR images
	{
		vector<VkBindImageMemoryDeviceGroupInfo	>	bindImageMemoryDeviceGroupInfo	(numImages);
		vector<VkBindImageMemoryInfo>				bindImageMemoryInfos			(numImages);
		for (deUint32 idx = 0; idx < numImages; ++idx)
		{
			// Create image
			imagesSfr[idx] = ImageSp(new UniqueImage(createImage(vkd, *groupDevice, &imageCreateInfo)));

		// Split into 2 vertical halves
		// NOTE: the same split has to be done also in WsiTriangleRenderer::recordDeviceGroupFrame
		const deUint32	halfWidth			= desiredSize.x() / 2;
		const deUint32	height				= desiredSize.y();
		const VkRect2D	sfrRects[] =
		{
			{	{ 0, 0 },					{ halfWidth, height }	},		// offset, extent
			{	{ (deInt32)halfWidth, 0 },	{ halfWidth, height }	},		// offset, extent
			{	{ 0, 0 },					{ halfWidth, height }	},		// offset, extent
			{	{ (deInt32)halfWidth, 0 },	{ halfWidth, height }	}		// offset, extent
		};

		VkBindImageMemoryDeviceGroupInfo bimdgInfo =
		{
			VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
			&bindImageMemorySwapchainInfo[idx],
			DE_LENGTH_OF_ARRAY(deviceIndices),
			deviceIndices,
			DE_LENGTH_OF_ARRAY(sfrRects),
			sfrRects
		};
		bindImageMemoryDeviceGroupInfo[idx] = bimdgInfo;

		VkBindImageMemoryInfo bimInfo =
		{
			VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
			&bindImageMemoryDeviceGroupInfo[idx],
				**imagesSfr[idx],
			DE_NULL,				// If the pNext chain includes an instance of VkBindImageMemorySwapchainInfoKHR, memory must be VK_NULL_HANDLE
			0u						// If swapchain <in VkBindImageMemorySwapchainInfoKHR> is not NULL, the swapchain and imageIndex are used to determine the memory that the image is bound to, instead of memory and memoryOffset.
		};
		bindImageMemoryInfos[idx]	= bimInfo;
			rawImagesSfr[idx]			= **imagesSfr[idx];
	}

	VK_CHECK(vkd.bindImageMemory2(*groupDevice, numImages, &bindImageMemoryInfos[0]));
	}

	VkPeerMemoryFeatureFlags peerMemoryFeatures = 0u;
	vkd.getDeviceGroupPeerMemoryFeatures(*groupDevice, 0, firstDeviceID, secondDeviceID, &peerMemoryFeatures);
	bool explicitLayoutTransitions = !(peerMemoryFeatures & VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT) ||
									 !(peerMemoryFeatures & VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT);

	const WsiTriangleRenderer			renderer					(vkd,
																 *groupDevice,
																 allocator,
																 context.getBinaryCollection(),
																 explicitLayoutTransitions,
																 rawImagesSfr,
																 rawImages,
																 swapchainInfo.imageFormat,
																 tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));

	const Unique<VkCommandPool>		commandPool					(createCommandPool(vkd, *groupDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));

	const size_t					maxQueuedFrames				= rawImagesSfr.size()*2;

	// We need to keep hold of fences from vkAcquireNextImage2KHR
	// to actually limit number of frames we allow to be queued.
	const vector<FenceSp>			imageReadyFences			(createFences(vkd, *groupDevice, maxQueuedFrames));

	// We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to
	// pass the semaphore in same time as the fence we use to meter rendering.
	const vector<SemaphoreSp>		imageReadySemaphores		(createSemaphores(vkd, *groupDevice, maxQueuedFrames+1));

	// For rest we simply need maxQueuedFrames as we will wait for image from frameNdx-maxQueuedFrames
	// to become available to us, guaranteeing that previous uses must have completed.
	const vector<SemaphoreSp>		renderingCompleteSemaphores	(createSemaphores(vkd, *groupDevice, maxQueuedFrames));
	const vector<CommandBufferSp>	commandBuffers				(allocateCommandBuffers(vkd, *groupDevice, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));

	try
	{
		const deUint32	numFramesToRender = 60*10;

		for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
		{
			const VkFence		imageReadyFence		= **imageReadyFences[frameNdx%imageReadyFences.size()];
			const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
			deUint32			imageNdx			= ~0u;

			VK_CHECK(vkd.waitForFences(*groupDevice, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
			VK_CHECK(vkd.resetFences(*groupDevice, 1, &imageReadyFence));

			{
				VkAcquireNextImageInfoKHR acquireNextImageInfo =
				{
					VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
					DE_NULL,
					*swapchain,
					std::numeric_limits<deUint64>::max(),
					imageReadySemaphore,
					(VkFence)0,
					(1 << firstDeviceID)
				};

				const VkResult acquireResult = vkd.acquireNextImage2KHR(*groupDevice, &acquireNextImageInfo, &imageNdx);

				if (acquireResult == VK_SUBOPTIMAL_KHR)
					context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
				else
					VK_CHECK(acquireResult);
			}

			TCU_CHECK((size_t)imageNdx < rawImagesSfr.size());

			{
				const VkSemaphore			renderingCompleteSemaphore	= **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
				const VkCommandBuffer		commandBuffer				= **commandBuffers[frameNdx%commandBuffers.size()];
				const VkPipelineStageFlags	waitDstStage				= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

				// render triangle using one or two subdevices when available
				renderer.recordDeviceGroupFrame(commandBuffer, firstDeviceID, secondDeviceID, physicalDevicesInGroupCount, imageNdx, frameNdx);

				// submit queue
				deUint32 deviceMask = (1 << firstDeviceID) | (1 << secondDeviceID);
				const VkDeviceGroupSubmitInfo deviceGroupSubmitInfo =
				{
					VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR,		// sType
					DE_NULL,											// pNext
					DE_LENGTH_OF_ARRAY(deviceIndices),					// waitSemaphoreCount
					deviceIndices,										// pWaitSemaphoreDeviceIndices
					1u,													// commandBufferCount
					&deviceMask,										// pCommandBufferDeviceMasks
					DE_LENGTH_OF_ARRAY(deviceIndices),					// signalSemaphoreCount
					deviceIndices,										// pSignalSemaphoreDeviceIndices
				};
				const VkSubmitInfo submitInfo =
				{
					VK_STRUCTURE_TYPE_SUBMIT_INFO,						// sType
					&deviceGroupSubmitInfo,								// pNext
					1u,													// waitSemaphoreCount
					&imageReadySemaphore,								// pWaitSemaphores
					&waitDstStage,										// pWaitDstStageMask
					1u,													// commandBufferCount
					&commandBuffer,										// pCommandBuffers
					1u,													// signalSemaphoreCount
					&renderingCompleteSemaphore,						// pSignalSemaphores
				};
				VK_CHECK(vkd.queueSubmit(queue, 1u, &submitInfo, imageReadyFence));

				// present swapchain image -  asume that first device has a presentation engine
				deviceMask = (1 << firstDeviceID);
				const VkDeviceGroupPresentInfoKHR deviceGroupPresentInfo =
				{
					VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR,
					DE_NULL,
					1u,
					&deviceMask,
					VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR,
				};
				const VkPresentInfoKHR presentInfo =
				{
					VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
					&deviceGroupPresentInfo,
					1u,
					&renderingCompleteSemaphore,
					1u,
					&*swapchain,
					&imageNdx,
					(VkResult*)DE_NULL
				};
				VK_CHECK(vkd.queuePresentKHR(queue, &presentInfo));
			}
		}

		VK_CHECK(vkd.deviceWaitIdle(*groupDevice));
	}
	catch (...)
	{
		// Make sure device is idle before destroying resources
		vkd.deviceWaitIdle(*groupDevice);
		throw;
	}

	return tcu::TestStatus::pass("Rendering tests succeeded");
}

vector<tcu::UVec2> getSwapchainSizeSequence (const VkSurfaceCapabilitiesKHR& capabilities, const tcu::UVec2& defaultSize)
{
	vector<tcu::UVec2> sizes(3);
	sizes[0] = defaultSize / 2u;
	sizes[1] = defaultSize;
	sizes[2] = defaultSize * 2u;

	for (deUint32 i = 0; i < sizes.size(); ++i)
	{
		sizes[i].x() = de::clamp(sizes[i].x(), capabilities.minImageExtent.width,  capabilities.maxImageExtent.width);
		sizes[i].y() = de::clamp(sizes[i].y(), capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
	}

	return sizes;
}

tcu::TestStatus resizeSwapchainTest (Context& context, Type wsiType)
{
	const tcu::UVec2				desiredSize			(256, 256);
	const InstanceHelper			instHelper			(context, wsiType);
	const NativeObjects				native				(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>		surface				(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
	const DeviceHelper				devHelper			(context, instHelper.vki, instHelper.instance, *surface);
	const PlatformProperties&		platformProperties	= getPlatformProperties(wsiType);
	const VkSurfaceCapabilitiesKHR	capabilities		= getPhysicalDeviceSurfaceCapabilities(instHelper.vki, devHelper.physicalDevice, *surface);
	const DeviceInterface&			vkd					= devHelper.vkd;
	const VkDevice					device				= *devHelper.device;
	SimpleAllocator					allocator			(vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
	vector<tcu::UVec2>				sizes				= getSwapchainSizeSequence(capabilities, desiredSize);
	Move<VkSwapchainKHR>			prevSwapchain;

	DE_ASSERT(platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE);
	DE_UNREF(platformProperties);

	for (deUint32 sizeNdx = 0; sizeNdx < sizes.size(); ++sizeNdx)
	{
		// \todo [2016-05-30 jesse] This test currently waits for idle and
		// recreates way more than necessary when recreating the swapchain. Make
		// it match expected real app behavior better by smoothly switching from
		// old to new swapchain. Once that is done, it will also be possible to
		// test creating a new swapchain while images from the previous one are
		// still acquired.

		VkSwapchainCreateInfoKHR		swapchainInfo				= getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, sizes[sizeNdx], 2);
		swapchainInfo.oldSwapchain = *prevSwapchain;

		Move<VkSwapchainKHR>			swapchain					(createSwapchainKHR(vkd, device, &swapchainInfo));
		const vector<VkImage>			swapchainImages				= getSwapchainImages(vkd, device, *swapchain);
		const WsiTriangleRenderer		renderer					(vkd,
																	device,
																	allocator,
																	context.getBinaryCollection(),
																	false,
																	swapchainImages,
																	swapchainImages,
																	swapchainInfo.imageFormat,
																	tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
		const Unique<VkCommandPool>		commandPool					(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
		const size_t					maxQueuedFrames				= swapchainImages.size()*2;

		// We need to keep hold of fences from vkAcquireNextImageKHR to actually
		// limit number of frames we allow to be queued.
		const vector<FenceSp>			imageReadyFences			(createFences(vkd, device, maxQueuedFrames));

		// We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to pass
		// the semaphore in same time as the fence we use to meter rendering.
		const vector<SemaphoreSp>		imageReadySemaphores		(createSemaphores(vkd, device, maxQueuedFrames+1));

		// For rest we simply need maxQueuedFrames as we will wait for image
		// from frameNdx-maxQueuedFrames to become available to us, guaranteeing that
		// previous uses must have completed.
		const vector<SemaphoreSp>		renderingCompleteSemaphores	(createSemaphores(vkd, device, maxQueuedFrames));
		const vector<CommandBufferSp>	commandBuffers				(allocateCommandBuffers(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));

		try
		{
			const deUint32	numFramesToRender	= 60;

			for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
			{
				const VkFence		imageReadyFence		= **imageReadyFences[frameNdx%imageReadyFences.size()];
				const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
				deUint32			imageNdx			= ~0u;

				VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
				VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));

				{
					const VkResult	acquireResult	= vkd.acquireNextImageKHR(device,
																			  *swapchain,
																			  std::numeric_limits<deUint64>::max(),
																			  imageReadySemaphore,
																			  imageReadyFence,
																			  &imageNdx);

					if (acquireResult == VK_SUBOPTIMAL_KHR)
						context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
					else
						VK_CHECK(acquireResult);
				}

				TCU_CHECK((size_t)imageNdx < swapchainImages.size());

				{
					const VkSemaphore			renderingCompleteSemaphore	= **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
					const VkCommandBuffer		commandBuffer				= **commandBuffers[frameNdx%commandBuffers.size()];
					const VkPipelineStageFlags	waitDstStage				= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
					const VkSubmitInfo			submitInfo					=
					{
						VK_STRUCTURE_TYPE_SUBMIT_INFO,
						DE_NULL,
						1u,
						&imageReadySemaphore,
						&waitDstStage,
						1u,
						&commandBuffer,
						1u,
						&renderingCompleteSemaphore
					};
					const VkPresentInfoKHR		presentInfo					=
					{
						VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
						DE_NULL,
						1u,
						&renderingCompleteSemaphore,
						1u,
						&*swapchain,
						&imageNdx,
						(VkResult*)DE_NULL
					};

					renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
					VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, (VkFence)0));
					VK_CHECK_WSI(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
				}
			}

			VK_CHECK(vkd.deviceWaitIdle(device));

			prevSwapchain = swapchain;
		}
		catch (...)
		{
			// Make sure device is idle before destroying resources
			vkd.deviceWaitIdle(device);
			throw;
		}
	}

	return tcu::TestStatus::pass("Resizing tests succeeded");
}

tcu::TestStatus getImagesIncompleteResultTest (Context& context, Type wsiType)
{
	const tcu::UVec2				desiredSize		(256, 256);
	const InstanceHelper			instHelper		(context, wsiType);
	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
	const DeviceHelper				devHelper		(context, instHelper.vki, instHelper.instance, *surface);
	const VkSwapchainCreateInfoKHR	swapchainInfo	= getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
	const Unique<VkSwapchainKHR>	swapchain		(createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));

	vector<VkImage>		swapchainImages	= getSwapchainImages(devHelper.vkd, *devHelper.device, *swapchain);

	ValidateQueryBits::fillBits(swapchainImages.begin(), swapchainImages.end());

	const deUint32		usedCount		= static_cast<deUint32>(swapchainImages.size() / 2);
	deUint32			count			= usedCount;
	const VkResult		result			= devHelper.vkd.getSwapchainImagesKHR(*devHelper.device, *swapchain, &count, &swapchainImages[0]);

	if (count != usedCount || result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(swapchainImages.begin() + count, swapchainImages.end()))
		return tcu::TestStatus::fail("Get swapchain images didn't return VK_INCOMPLETE");
	else
		return tcu::TestStatus::pass("Get swapchain images tests succeeded");
}

tcu::TestStatus getImagesResultsCountTest (Context& context, Type wsiType)
{
	const tcu::UVec2				desiredSize(256, 256);
	const InstanceHelper			instHelper(context, wsiType);
	const NativeObjects				native(context, instHelper.supportedExtensions, wsiType, 1u, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>		surface(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
	const DeviceHelper				devHelper(context, instHelper.vki, instHelper.instance, *surface);
	const VkSwapchainCreateInfoKHR	swapchainInfo = getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
	const Unique<VkSwapchainKHR>	swapchain(createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));

	deUint32	numImages = 0;

	VK_CHECK(devHelper.vkd.getSwapchainImagesKHR(*devHelper.device, *swapchain, &numImages, DE_NULL));

	if (numImages > 0)
	{
		std::vector<VkImage>	images			(numImages + 1);
		const deUint32			numImagesOrig	= numImages;

		// check if below call properly overwrites formats count
		numImages++;

		VK_CHECK(devHelper.vkd.getSwapchainImagesKHR(*devHelper.device, *swapchain, &numImages, &images[0]));

		if ((size_t)numImages != numImagesOrig)
			TCU_FAIL("Image count changed between calls");
	}
	return tcu::TestStatus::pass("Get swapchain images tests succeeded");
}

tcu::TestStatus destroyNullHandleSwapchainTest (Context& context, Type wsiType)
{
	const InstanceHelper		instHelper	(context, wsiType);
	const NativeObjects			native		(context, instHelper.supportedExtensions, wsiType);
	const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
	const DeviceHelper			devHelper	(context, instHelper.vki, instHelper.instance, *surface);
	const VkSwapchainKHR		nullHandle	= DE_NULL;

	// Default allocator
	devHelper.vkd.destroySwapchainKHR(*devHelper.device, nullHandle, DE_NULL);

	// Custom allocator
	{
		AllocationCallbackRecorder	recordingAllocator	(getSystemAllocator(), 1u);

		devHelper.vkd.destroySwapchainKHR(*devHelper.device, nullHandle, recordingAllocator.getCallbacks());

		if (recordingAllocator.getNumRecords() != 0u)
			return tcu::TestStatus::fail("Implementation allocated/freed the memory");
	}

	return tcu::TestStatus::pass("Destroying a VK_NULL_HANDLE surface has no effect");
}

tcu::TestStatus acquireTooManyTest (Context& context, Type wsiType)
{
	const tcu::UVec2               desiredSize     (256, 256);
	const InstanceHelper           instHelper      (context, wsiType);
	const NativeObjects            native          (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>     surface         (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
	const DeviceHelper             devHelper       (context, instHelper.vki, instHelper.instance, *surface);
	const VkSwapchainCreateInfoKHR swapchainInfo = getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
	const Unique<VkSwapchainKHR>   swapchain       (createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));

	deUint32 numImages;
	VK_CHECK(devHelper.vkd.getSwapchainImagesKHR(*devHelper.device, *swapchain, &numImages, DE_NULL));
	const deUint32 minImageCount = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, devHelper.physicalDevice, *surface).minImageCount;
	if (numImages < minImageCount) return tcu::TestStatus::fail("Get swapchain images returned less than minImageCount images");
	const deUint32 numAcquirableImages = numImages - minImageCount + 1;

	const auto fences = createFences(devHelper.vkd, *devHelper.device, numAcquirableImages + 1);
	deUint32 dummy;
	for (deUint32 i = 0; i < numAcquirableImages; ++i) {
		VK_CHECK_WSI(devHelper.vkd.acquireNextImageKHR(*devHelper.device, *swapchain, std::numeric_limits<deUint64>::max(), (VkSemaphore)0, **fences[i], &dummy));
	}

	const auto result = devHelper.vkd.acquireNextImageKHR(*devHelper.device, *swapchain, 0, (VkSemaphore)0, **fences[numAcquirableImages], &dummy);

	if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR && result != VK_NOT_READY ){
		return tcu::TestStatus::fail("Implementation failed to respond well acquiring too many images with 0 timeout");
	}

	// cleanup
	const deUint32 numFences = (result == VK_NOT_READY) ? static_cast<deUint32>(fences.size() - 1) : static_cast<deUint32>(fences.size());
	vector<vk::VkFence> fencesRaw(numFences);
	std::transform(fences.begin(), fences.begin() + numFences, fencesRaw.begin(), [](const FenceSp& f) -> vk::VkFence{ return **f; });
	VK_CHECK(devHelper.vkd.waitForFences(*devHelper.device, numFences, fencesRaw.data(), VK_TRUE, std::numeric_limits<deUint64>::max()));

	return tcu::TestStatus::pass("Acquire too many swapchain images test succeeded");
}

tcu::TestStatus acquireTooManyTimeoutTest (Context& context, Type wsiType)
{
	const tcu::UVec2               desiredSize     (256, 256);
	const InstanceHelper           instHelper      (context, wsiType);
	const NativeObjects            native          (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
	const Unique<VkSurfaceKHR>     surface         (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
	const DeviceHelper             devHelper       (context, instHelper.vki, instHelper.instance, *surface);
	const VkSwapchainCreateInfoKHR swapchainInfo = getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
	const Unique<VkSwapchainKHR>   swapchain       (createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));

	deUint32 numImages;
	VK_CHECK(devHelper.vkd.getSwapchainImagesKHR(*devHelper.device, *swapchain, &numImages, DE_NULL));
	const deUint32 minImageCount = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, devHelper.physicalDevice, *surface).minImageCount;
	if (numImages < minImageCount) return tcu::TestStatus::fail("Get swapchain images returned less than minImageCount images");
	const deUint32 numAcquirableImages = numImages - minImageCount + 1;

	const auto fences = createFences(devHelper.vkd, *devHelper.device, numAcquirableImages + 1);
	deUint32 dummy;
	for (deUint32 i = 0; i < numAcquirableImages; ++i) {
		VK_CHECK_WSI(devHelper.vkd.acquireNextImageKHR(*devHelper.device, *swapchain, std::numeric_limits<deUint64>::max(), (VkSemaphore)0, **fences[i], &dummy));
	}

	const deUint64 millisecond = 1000000;
	const deUint64 timeout = 50 * millisecond; // arbitrary realistic non-0 non-infinite timeout
	const auto result = devHelper.vkd.acquireNextImageKHR(*devHelper.device, *swapchain, timeout, (VkSemaphore)0, **fences[numAcquirableImages], &dummy);

	if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR && result != VK_TIMEOUT ){
		return tcu::TestStatus::fail("Implementation failed to respond well acquiring too many images with timeout");
	}

	// cleanup
	const deUint32 numFences = (result == VK_TIMEOUT) ? static_cast<deUint32>(fences.size() - 1) : static_cast<deUint32>(fences.size());
	vector<vk::VkFence> fencesRaw(numFences);
	std::transform(fences.begin(), fences.begin() + numFences, fencesRaw.begin(), [](const FenceSp& f) -> vk::VkFence{ return **f; });
	VK_CHECK(devHelper.vkd.waitForFences(*devHelper.device, numFences, fencesRaw.data(), VK_TRUE, std::numeric_limits<deUint64>::max()));

	return tcu::TestStatus::pass("Acquire too many swapchain images test succeeded");
}

void getBasicRenderPrograms (SourceCollections& dst, Type)
{
	WsiTriangleRenderer::getPrograms(dst);
}

void getBasicRenderPrograms (SourceCollections& dst, MultiSwapchainParams)
{
	WsiTriangleRenderer::getPrograms(dst);
}

void populateRenderGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
{
	addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Test", getBasicRenderPrograms, basicRenderTest<AcquireNextImageWrapper>, wsiType);
	addFunctionCaseWithPrograms(testGroup, "basic2", "Basic Rendering Test using AcquireNextImage2", getBasicRenderPrograms, basicRenderTest<AcquireNextImage2Wrapper>, wsiType);
	addFunctionCaseWithPrograms(testGroup, "device_group", "Basic Rendering Test using device_group", getBasicRenderPrograms, deviceGroupRenderTest, wsiType);
	addFunctionCaseWithPrograms(testGroup, "device_group2", "Rendering Test using device_group and VkImageSwapchainCreateInfo", getBasicRenderPrograms, deviceGroupRenderTest2, wsiType);

	const MultiSwapchainParams kTwoSwapchains	{ wsiType, 2u	};
	const MultiSwapchainParams kTenSwapchains	{ wsiType, 10u	};

	addFunctionCaseWithPrograms(testGroup, "2swapchains", "2 Swapchains Rendering Test", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImageWrapper>, kTwoSwapchains);
	addFunctionCaseWithPrograms(testGroup, "2swapchains2", "2 Swapchains Rendering Test using AcquireNextImage2", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImage2Wrapper>, kTwoSwapchains);
	addFunctionCaseWithPrograms(testGroup, "10swapchains", "10 Swapchains Rendering Test", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImageWrapper>, kTenSwapchains);
	addFunctionCaseWithPrograms(testGroup, "10swapchains2", "10 Swapchains Rendering Test using AcquireNextImage2", getBasicRenderPrograms, multiSwapchainRenderTest<AcquireNextImage2Wrapper>, kTenSwapchains);
}

void populateGetImagesGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
{
	addFunctionCase(testGroup, "incomplete", "Test VK_INCOMPLETE return code", getImagesIncompleteResultTest, wsiType);
	addFunctionCase(testGroup, "count",	"Test proper count of images", getImagesResultsCountTest, wsiType);
}

void populateModifyGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
{
	const PlatformProperties&	platformProperties	= getPlatformProperties(wsiType);

	if (platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE)
	{
		addFunctionCaseWithPrograms(testGroup, "resize", "Resize Swapchain Test", getBasicRenderPrograms, resizeSwapchainTest, wsiType);
	}

	// \todo [2016-05-30 jesse] Add tests for modifying preTransform, compositeAlpha, presentMode
}

void populateDestroyGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
{
	addFunctionCase(testGroup, "null_handle", "Destroying a VK_NULL_HANDLE swapchain", destroyNullHandleSwapchainTest, wsiType);
}

void populateAcquireGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
{
	addFunctionCase(testGroup, "too_many", "Test acquiring too many images with 0 timeout", acquireTooManyTest, wsiType);
	addFunctionCase(testGroup, "too_many_timeout", "Test acquiring too many images with timeout", acquireTooManyTimeoutTest, wsiType);
}

} // anonymous

void createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
{
	addTestGroup(testGroup, "create",			"Create VkSwapchain with various parameters",					populateSwapchainGroup,		GroupParameters(wsiType, createSwapchainTest));
	addTestGroup(testGroup, "simulate_oom",		"Simulate OOM using callbacks during swapchain construction",	populateSwapchainGroup,		GroupParameters(wsiType, createSwapchainSimulateOOMTest));
	addTestGroup(testGroup, "render",			"Rendering Tests",												populateRenderGroup,		wsiType);
	addTestGroup(testGroup, "modify",			"Modify VkSwapchain",											populateModifyGroup,		wsiType);
	addTestGroup(testGroup, "destroy",			"Destroy VkSwapchain",											populateDestroyGroup,		wsiType);
	addTestGroup(testGroup, "get_images",		"Get swapchain images",											populateGetImagesGroup,		wsiType);
	addTestGroup(testGroup, "acquire",			"Ancquire next swapchain image",								populateAcquireGroup,		wsiType);
}

} // wsi
} // vkt
