/*-------------------------------------------------------------------------
 * 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 "vkObjTypeImpl.inl"
#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 de::SharedPtr;

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 void *					pNext			= nullptr;
	const VkPhysicalDeviceFeatures	features		= getDeviceFeaturesForWsi();

	VkDevicePrivateDataCreateInfoEXT pdci =
	{
		VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT,	// VkStructureType                       sType;
		DE_NULL,												// const void*                           pNext;
		4u,														// uint32_t                              privateDataSlotRequestCount;
	};
	VkPhysicalDevicePrivateDataFeaturesEXT privateDataFeatures =
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT,	// VkStructureType    sType;
		&pdci,															// void*              pNext;
		VK_TRUE,														// VkBool32           privateData;
	};

	vector<const char*>				extensions;
	extensions.push_back("VK_KHR_swapchain");
	if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_private_data")))
	{
		extensions.push_back("VK_EXT_private_data");
		pNext = &privateDataFeatures;
	}

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

	for (int ndx = 0; ndx < (int)extensions.size(); ++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");
}

template<typename T> static deUint64 HandleToInt(T t) { return t.getInternal(); }

tcu::TestStatus createSwapchainPrivateDataTest (Context& context, TestParameters params)
{
	if (!context.getPrivateDataFeaturesEXT().privateData)
		TCU_THROW(NotSupportedError, "privateData not supported");

	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));

	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:
			{
				const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(devHelper.vkd, *devHelper.device, &curParams));

				const int numSlots = 100;
				typedef Unique<VkPrivateDataSlotEXT>				PrivateDataSlotUp;
				typedef SharedPtr<PrivateDataSlotUp>				PrivateDataSlotSp;
				vector<PrivateDataSlotSp> slots;

				const VkPrivateDataSlotCreateInfoEXT createInfo =
				{
					VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT,	// VkStructureType                    sType;
					DE_NULL,												// const void*                        pNext;
					0u,														// VkPrivateDataSlotCreateFlagsEXT    flags;
				};

				for (int i = 0; i < numSlots; ++i)
				{
					Move<VkPrivateDataSlotEXT> s = createPrivateDataSlotEXT(devHelper.vkd, *devHelper.device, &createInfo, DE_NULL);
					slots.push_back(PrivateDataSlotSp(new PrivateDataSlotUp(s)));
				}

				// Based on code in vktApiObjectManagementTests.cpp
				for (int r = 0; r < 3; ++r)
				{
					deUint64 data;

					for (int i = 0; i < numSlots; ++i)
					{
						data = 1234;
						devHelper.vkd.getPrivateDataEXT(*devHelper.device, getObjectType<VkSwapchainKHR>(), HandleToInt(swapchain.get()), **slots[i], &data);
						// Don't test default value of zero on Android, due to spec erratum
						if (params.wsiType != TYPE_ANDROID)
						{
							if (data != 0)
								return tcu::TestStatus::fail("Expected initial value of zero");
						}
					}

					for (int i = 0; i < numSlots; ++i)
						VK_CHECK(devHelper.vkd.setPrivateDataEXT(*devHelper.device, getObjectType<VkSwapchainKHR>(), HandleToInt(swapchain.get()), **slots[i], i*i*i + 1));

					for (int i = 0; i < numSlots; ++i)
					{
						data = 1234;
						devHelper.vkd.getPrivateDataEXT(*devHelper.device, getObjectType<VkSwapchainKHR>(), HandleToInt(swapchain.get()), **slots[i], &data);
						if (data != (deUint64)(i*i*i + 1))
							return tcu::TestStatus::fail("Didn't read back set value");
					}

					// Destroy and realloc slots for the next iteration
					slots.clear();
					for (int i = 0; i < numSlots; ++i)
					{
						Move<VkPrivateDataSlotEXT> s = createPrivateDataSlotEXT(devHelper.vkd, *devHelper.device, &createInfo, DE_NULL);
						slots.push_back(PrivateDataSlotSp(new PrivateDataSlotUp(s)));
					}
				}


			}
			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);
}

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

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

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,
							  bool                      isSignaled = true)
{
	vector<FenceSp> fences(numFences);

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

	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, false);
	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, false);
	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);
	addTestGroup(testGroup, "private_data",		"Create VkSwapchain and use VK_EXT_private_data",				populateSwapchainPrivateDataGroup,		GroupParameters(wsiType, createSwapchainPrivateDataTest));
}

} // wsi
} // vkt
