/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
 *
 * 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 Protected memory interaction with VkSwapchain Tests
 *//*--------------------------------------------------------------------*/

#include "vktProtectedMemWsiSwapchainTests.hpp"

#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.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 "vkObjUtil.hpp"
#include "vkWsiPlatform.hpp"
#include "vkWsiUtil.hpp"
#include "vkAllocationCallbackUtil.hpp"
#include "vkCmdUtil.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 "vktProtectedMemContext.hpp"
#include "vktProtectedMemUtils.hpp"

namespace vkt
{
namespace ProtectedMem
{

namespace
{

typedef std::vector<vk::VkExtensionProperties> Extensions;

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

std::vector<std::string> getRequiredWsiExtensions (const Extensions&	supportedExtensions,
												   vk::wsi::Type		wsiType)
{
	std::vector<std::string>	extensions;

	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, vk::RequiredExtension("VK_EXT_swapchain_colorspace")))
		extensions.push_back("VK_EXT_swapchain_colorspace");

	checkAllSupported(supportedExtensions, extensions);

	return extensions;
}

de::MovePtr<vk::wsi::Display> createDisplay (const vk::Platform&	platform,
											 const Extensions&		supportedExtensions,
											 vk::wsi::Type			wsiType)
{
	try
	{
		return de::MovePtr<vk::wsi::Display>(platform.createWsiDisplay(wsiType));
	}
	catch (const tcu::NotSupportedError& e)
	{
		if (isExtensionSupported(supportedExtensions, vk::RequiredExtension(getExtensionName(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;
	}
}

de::MovePtr<vk::wsi::Window> createWindow (const vk::wsi::Display& display, const tcu::Maybe<tcu::UVec2>& initialSize)
{
	try
	{
		return de::MovePtr<vk::wsi::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());
	}
}

struct NativeObjects
{
	const de::UniquePtr<vk::wsi::Display>	display;
	const de::UniquePtr<vk::wsi::Window>	window;

	NativeObjects (Context&							context,
				   const Extensions&				supportedExtensions,
				   vk::wsi::Type					wsiType,
				   const tcu::Maybe<tcu::UVec2>&	initialWindowSize = tcu::nothing<tcu::UVec2>())
		: display				(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
		, window				(createWindow(*display, initialWindowSize))
	{}
};

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
{
	vk::wsi::Type	wsiType;
	TestDimension	dimension;

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

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

static vk::VkCompositeAlphaFlagBitsKHR firstSupportedCompositeAlpha(const vk::VkSurfaceCapabilitiesKHR& capabilities)
{
	deUint32 alphaMode = 1u;

	for (;alphaMode < capabilities.supportedCompositeAlpha;	alphaMode = alphaMode<<1u)
	{
		if ((alphaMode & capabilities.supportedCompositeAlpha) != 0)
		{
			break;
		}
	}

	return (vk::VkCompositeAlphaFlagBitsKHR)alphaMode;
}

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

	switch (dimension)
	{
		case TEST_DIMENSION_MIN_IMAGE_COUNT:
		{
			// Estimate how much memory each swapchain image consumes. This isn't perfect, since
			// swapchain images may have additional constraints that equivalent non-swapchain
			// images don't have. But it's the best we can do.
			const vk::DeviceInterface&				vkd					= context.getDeviceInterface();
			vk::VkDevice							device				= context.getDevice();
			vk::VkMemoryRequirements				memoryRequirements;
			{
				const vk::VkImageCreateInfo			imageInfo			=
				{
					vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
					DE_NULL,
					vk::VK_IMAGE_CREATE_PROTECTED_BIT,
					vk::VK_IMAGE_TYPE_2D,
					baseParameters.imageFormat,
					{
						baseParameters.imageExtent.width,
						baseParameters.imageExtent.height,
						1,
					},
					1,	// mipLevels
					baseParameters.imageArrayLayers,
					vk::VK_SAMPLE_COUNT_1_BIT,
					vk::VK_IMAGE_TILING_OPTIMAL,
					baseParameters.imageUsage,
					baseParameters.imageSharingMode,
					baseParameters.queueFamilyIndexCount,
					baseParameters.pQueueFamilyIndices,
					vk::VK_IMAGE_LAYOUT_UNDEFINED
				};
				vk::Move<vk::VkImage>				image				= vk::createImage(vkd, device, &imageInfo);

				memoryRequirements	= vk::getImageMemoryRequirements(vkd, device, *image);
			}

			// Determine the maximum memory heap space available for protected images
			vk::VkPhysicalDeviceMemoryProperties	memoryProperties	= vk::getPhysicalDeviceMemoryProperties(context.getInstanceDriver(), context.getPhysicalDevice());
			vk::VkDeviceSize						protectedHeapSize	= 0;
			vk::VkDeviceSize						maxMemoryUsage		= 0;
			deUint32								protectedHeapMask	= 0;

			for (deUint32 memType = 0; memType < memoryProperties.memoryTypeCount; memType++)
			{
				deUint32 heapIndex	= memoryProperties.memoryTypes[memType].heapIndex;
				if ((memoryRequirements.memoryTypeBits & (1u << memType)) != 0 &&
					(memoryProperties.memoryTypes[memType].propertyFlags & vk::VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0 &&
					(protectedHeapMask & (1u << heapIndex)) == 0)
				{
					protectedHeapSize = de::max(protectedHeapSize, memoryProperties.memoryHeaps[heapIndex].size);
					maxMemoryUsage    = protectedHeapSize / 4 ; /* Use at maximum 25% of heap */
					protectedHeapMask |= 1u << heapIndex;
				}
			}

			// If the implementation doesn't have a max image count, min+16 means we won't clamp.
			// Limit it to how many protected images we estimate can be allocated - 25% of heap size
			const deUint32	maxImageCount		= de::min((capabilities.maxImageCount > 0) ? capabilities.maxImageCount : capabilities.minImageCount + 16u,
														  deUint32(maxMemoryUsage / memoryRequirements.size));
			if (maxImageCount < capabilities.minImageCount)
				TCU_THROW(NotSupportedError, "Memory heap doesn't have enough memory!.");

			const deUint32	maxImageCountToTest	= de::clamp(16u, capabilities.minImageCount, maxImageCount);
			for (deUint32 imageCount = capabilities.minImageCount; imageCount <= maxImageCountToTest; ++imageCount)
			{
				cases.push_back(baseParameters);
				cases.back().minImageCount = imageCount;
			}

			break;
		}

		case TEST_DIMENSION_IMAGE_FORMAT:
		{
			for (std::vector<vk::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 vk::VkExtent2D	s_testSizes[]	=
			{
				{ 1, 1 },
				{ 16, 32 },
				{ 32, 16 },
				{ 632, 231 },
				{ 117, 998 },
			};

			const vk::DeviceInterface&				vkd					= context.getDeviceInterface();
			vk::VkDevice							device				= context.getDevice();
			vk::VkPhysicalDeviceMemoryProperties	memoryProperties	= vk::getPhysicalDeviceMemoryProperties(context.getInstanceDriver(), context.getPhysicalDevice());
			vk::VkDeviceSize						protectedHeapSize	= 0;
			vk::VkDeviceSize						maxMemoryUsage		= 0;

			for (deUint32 memType = 0; memType < memoryProperties.memoryTypeCount; memType++)
			{
				deUint32 heapIndex	= memoryProperties.memoryTypes[memType].heapIndex;
				if (memoryProperties.memoryTypes[memType].propertyFlags & vk::VK_MEMORY_PROPERTY_PROTECTED_BIT)
				{
					protectedHeapSize = de::max(protectedHeapSize, memoryProperties.memoryHeaps[heapIndex].size);
					maxMemoryUsage    = protectedHeapSize / 4 ; /* Use at maximum 25% of heap */
				}
			}

			if (platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE ||
				platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE)
			{
				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_testSizes); ++ndx)
				{
					vk::VkMemoryRequirements memoryRequirements;
					{
						const vk::VkImageCreateInfo imageInfo =
						{
							vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
							DE_NULL,
							vk::VK_IMAGE_CREATE_PROTECTED_BIT,
							vk::VK_IMAGE_TYPE_2D,
							baseParameters.imageFormat,
							{
								s_testSizes[ndx].width,
								s_testSizes[ndx].height,
								1,
							},
							1,	// mipLevels
							baseParameters.imageArrayLayers,
							vk::VK_SAMPLE_COUNT_1_BIT,
							vk::VK_IMAGE_TILING_OPTIMAL,
							baseParameters.imageUsage,
							baseParameters.imageSharingMode,
							baseParameters.queueFamilyIndexCount,
							baseParameters.pQueueFamilyIndices,
							vk::VK_IMAGE_LAYOUT_UNDEFINED
						};

						vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &imageInfo);

						memoryRequirements = vk::getImageMemoryRequirements(vkd, device, *image);
					}

					// Check for the image size requirement based on double/triple buffering
					if (memoryRequirements.size  * capabilities.minImageCount < maxMemoryUsage)
					{
						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 != vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE)
			{
				vk::VkMemoryRequirements memoryRequirements;
				{
					const vk::VkImageCreateInfo imageInfo =
					{
						vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
						DE_NULL,
						vk::VK_IMAGE_CREATE_PROTECTED_BIT,
						vk::VK_IMAGE_TYPE_2D,
						baseParameters.imageFormat,
						{
							capabilities.currentExtent.width,
							capabilities.currentExtent.height,
							1,
						},
						1,	// mipLevels
						baseParameters.imageArrayLayers,
						vk::VK_SAMPLE_COUNT_1_BIT,
						vk::VK_IMAGE_TILING_OPTIMAL,
						baseParameters.imageUsage,
						baseParameters.imageSharingMode,
						baseParameters.queueFamilyIndexCount,
						baseParameters.pQueueFamilyIndices,
						vk::VK_IMAGE_LAYOUT_UNDEFINED
					};

					vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &imageInfo);

					memoryRequirements = vk::getImageMemoryRequirements(vkd, device, *image);
				}

				// Check for the image size requirement based on double/triple buffering
				if (memoryRequirements.size  * capabilities.minImageCount < maxMemoryUsage)
				{
					cases.push_back(baseParameters);
					cases.back().imageExtent = capabilities.currentExtent;
				}
			}

			if (platformProperties.swapchainExtent != vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE)
			{
				static const vk::VkExtent2D	s_testExtentSizes[]	=
				{
					{ capabilities.minImageExtent.width, capabilities.minImageExtent.height },
					{ capabilities.maxImageExtent.width, capabilities.maxImageExtent.height },
				};

				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_testExtentSizes); ++ndx)
				{
					vk::VkMemoryRequirements memoryRequirements;
					{
						const vk::VkImageCreateInfo	imageInfo =
						{
							vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
							DE_NULL,
							vk::VK_IMAGE_CREATE_PROTECTED_BIT,
							vk::VK_IMAGE_TYPE_2D,
							baseParameters.imageFormat,
							{
								s_testExtentSizes[ndx].width,
								s_testExtentSizes[ndx].height,
								1,
							},
							1,	// mipLevels
							baseParameters.imageArrayLayers,
							vk::VK_SAMPLE_COUNT_1_BIT,
							vk::VK_IMAGE_TILING_OPTIMAL,
							baseParameters.imageUsage,
							baseParameters.imageSharingMode,
							baseParameters.queueFamilyIndexCount,
							baseParameters.pQueueFamilyIndices,
							vk::VK_IMAGE_LAYOUT_UNDEFINED
						};

						vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &imageInfo);

						memoryRequirements = vk::getImageMemoryRequirements(vkd, device, *image);
					}

					// Check for the image size requirement based on double/triple buffering
					if (memoryRequirements.size  * capabilities.minImageCount < maxMemoryUsage)
					{
						cases.push_back(baseParameters);
						cases.back().imageExtent =s_testExtentSizes[ndx];
					}
				}
			}

			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:
		{
			cases.push_back(baseParameters);
			cases.back().imageSharingMode = vk::VK_SHARING_MODE_EXCLUSIVE;

			cases.push_back(baseParameters);
			cases.back().imageSharingMode = vk::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 = (vk::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 = (vk::VkCompositeAlphaFlagBitsKHR)alphaMode;
				}
			}

			break;
		}

		case TEST_DIMENSION_PRESENT_MODE:
		{
			for (std::vector<vk::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;
}

std::vector<vk::VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (vk::wsi::Type					wsiType,
																		   TestDimension					dimension,
																		   const ProtectedContext&			context,
																		   vk::VkSurfaceKHR					surface)
{
	const vk::InstanceInterface&				vki				= context.getInstanceDriver();
	vk::VkPhysicalDevice						physicalDevice	= context.getPhysicalDevice();
	const vk::VkSurfaceCapabilitiesKHR			capabilities	= vk::wsi::getPhysicalDeviceSurfaceCapabilities(vki,
																											   physicalDevice,
																											   surface);
	const std::vector<vk::VkSurfaceFormatKHR>	formats			= vk::wsi::getPhysicalDeviceSurfaceFormats(vki,
																										   physicalDevice,
																										   surface);
	const std::vector<vk::VkPresentModeKHR>		presentModes	= vk::wsi::getPhysicalDeviceSurfacePresentModes(vki,
																											    physicalDevice,
																											    surface);

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

tcu::TestStatus createSwapchainTest (Context& baseCtx, TestParameters params)
{
	std::vector<vk::VkExtensionProperties>			supportedExtensions (enumerateInstanceExtensionProperties(baseCtx.getPlatformInterface(), DE_NULL));
	std::vector<std::string>						instExts	= getRequiredWsiExtensions(supportedExtensions, params.wsiType);
	std::vector<std::string>						devExts;
	devExts.push_back("VK_KHR_swapchain");

	const NativeObjects								native		(baseCtx, supportedExtensions, params.wsiType);
	ProtectedContext								context		(baseCtx, params.wsiType, *native.display, *native.window, instExts, devExts);
	vk::VkSurfaceKHR								surface		= context.getSurface();
	const std::vector<vk::VkSwapchainCreateInfoKHR>	cases		(generateSwapchainParameterCases(params.wsiType,
																								 params.dimension,
																								 context,
																								 surface));
	deUint32										queueIdx	= context.getQueueFamilyIndex();
	for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
	{
		vk::VkSwapchainCreateInfoKHR	curParams	= cases[caseNdx];

		curParams.surface				= surface;
		curParams.queueFamilyIndexCount	= 1u;
		curParams.pQueueFamilyIndices	= &queueIdx;

		context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Sub-case " << (caseNdx+1) << " / " << cases.size() << ": " << curParams << tcu::TestLog::EndMessage;

		{
			const vk::Unique<vk::VkSwapchainKHR>	swapchain	(createSwapchainKHR(context.getDeviceDriver(), context.getDevice(), &curParams));
		}
	}

	return tcu::TestStatus::pass("Creating swapchain succeeded");
}

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

	vk::wsi::Type	wsiType;
	Function		function;

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

	GroupParameters (void)
		: wsiType	(vk::wsi::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));
	}
}

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

	return parameters;
}

typedef de::SharedPtr<vk::Unique<vk::VkImageView> >		ImageViewSp;
typedef de::SharedPtr<vk::Unique<vk::VkFramebuffer> >	FramebufferSp;

class TriangleRenderer
{
public:
												TriangleRenderer	(ProtectedContext&				context,
																	 const vk::BinaryCollection&	binaryRegistry,
																	 const std::vector<vk::VkImage>	swapchainImages,
																	 const vk::VkFormat				framebufferFormat,
																	 const tcu::UVec2&				renderSize);
												~TriangleRenderer	(void);

	void										recordFrame			(vk::VkCommandBuffer			cmdBuffer,
																	 deUint32						imageNdx,
																	 deUint32						frameNdx) const;

	static void									getPrograms			(vk::SourceCollections&			dst);

private:
	static vk::Move<vk::VkRenderPass>			createRenderPass	(const vk::DeviceInterface&		vkd,
																	 const vk::VkDevice				device,
																	 const vk::VkFormat				colorAttachmentFormat);
	static vk::Move<vk::VkPipelineLayout>		createPipelineLayout(const vk::DeviceInterface&		vkd,
																	 vk::VkDevice					device);
	static vk::Move<vk::VkPipeline>				createPipeline		(const vk::DeviceInterface&		vkd,
																	 const vk::VkDevice				device,
																	 const vk::VkRenderPass			renderPass,
																	 const vk::VkPipelineLayout		pipelineLayout,
																	 const vk::BinaryCollection&	binaryCollection,
																	 const tcu::UVec2&				renderSize);

	const vk::DeviceInterface&					m_vkd;

	const std::vector<vk::VkImage>				m_swapchainImages;
	const tcu::UVec2							m_renderSize;

	const vk::Unique<vk::VkRenderPass>			m_renderPass;
	const vk::Unique<vk::VkPipelineLayout>		m_pipelineLayout;
	const vk::Unique<vk::VkPipeline>			m_pipeline;

	const de::UniquePtr<vk::BufferWithMemory>	m_vertexBuffer;

	std::vector<ImageViewSp>					m_attachmentViews;
	std::vector<FramebufferSp>					m_framebuffers;
};

vk::Move<vk::VkRenderPass> TriangleRenderer::createRenderPass (const vk::DeviceInterface&	vkd,
															   const vk::VkDevice			device,
															   const vk::VkFormat			colorAttachmentFormat)
{
	const vk::VkAttachmentDescription	colorAttDesc		=
	{
		(vk::VkAttachmentDescriptionFlags)0,
		colorAttachmentFormat,
		vk::VK_SAMPLE_COUNT_1_BIT,
		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
		vk::VK_ATTACHMENT_STORE_OP_STORE,
		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
		vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
		vk::VK_IMAGE_LAYOUT_UNDEFINED,
		vk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
	};
	const vk::VkAttachmentReference		colorAttRef			=
	{
		0u,
		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
	};
	const vk::VkSubpassDescription		subpassDesc			=
	{
		(vk::VkSubpassDescriptionFlags)0u,
		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
		0u,							// inputAttachmentCount
		DE_NULL,					// pInputAttachments
		1u,							// colorAttachmentCount
		&colorAttRef,				// pColorAttachments
		DE_NULL,					// pResolveAttachments
		DE_NULL,					// depthStencilAttachment
		0u,							// preserveAttachmentCount
		DE_NULL,					// pPreserveAttachments
	};
	const vk::VkSubpassDependency		dependencies[]		=
	{
		{
			VK_SUBPASS_EXTERNAL,	// srcSubpass
			0u,						// dstSubpass
			vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
			vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
			vk::VK_ACCESS_MEMORY_READ_BIT,
			(vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
			 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
			vk::VK_DEPENDENCY_BY_REGION_BIT
		},
		{
			0u,						// srcSubpass
			VK_SUBPASS_EXTERNAL,	// dstSubpass
			vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
			vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
			(vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
			 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
			vk::VK_ACCESS_MEMORY_READ_BIT,
			vk::VK_DEPENDENCY_BY_REGION_BIT
		},
	};
	const vk::VkRenderPassCreateInfo	renderPassParams	=
	{
		vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
		DE_NULL,
		(vk::VkRenderPassCreateFlags)0,
		1u,
		&colorAttDesc,
		1u,
		&subpassDesc,
		DE_LENGTH_OF_ARRAY(dependencies),
		dependencies,
	};

	return vk::createRenderPass(vkd, device, &renderPassParams);
}

vk::Move<vk::VkPipelineLayout> TriangleRenderer::createPipelineLayout (const vk::DeviceInterface&	vkd,
																	   const vk::VkDevice			device)
{
	const vk::VkPushConstantRange					pushConstantRange		=
	{
		vk::VK_SHADER_STAGE_VERTEX_BIT,
		0u,											// offset
		(deUint32)sizeof(deUint32),					// size
	};
	const vk::VkPipelineLayoutCreateInfo			pipelineLayoutParams	=
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
		DE_NULL,
		(vk::VkPipelineLayoutCreateFlags)0,
		0u,											// setLayoutCount
		DE_NULL,									// pSetLayouts
		1u,
		&pushConstantRange,
	};

	return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
}

vk::Move<vk::VkPipeline> TriangleRenderer::createPipeline (const vk::DeviceInterface&	vkd,
														   const vk::VkDevice			device,
														   const vk::VkRenderPass		renderPass,
														   const vk::VkPipelineLayout	pipelineLayout,
														   const vk::BinaryCollection&	binaryCollection,
														   const tcu::UVec2&			renderSize)
{
	// \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
	//		 and can be deleted immediately following that call.
	const vk::Unique<vk::VkShaderModule>				vertShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
	const vk::Unique<vk::VkShaderModule>				fragShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
	const std::vector<vk::VkViewport>					viewports				(1, vk::makeViewport(renderSize));
	const std::vector<vk::VkRect2D>						scissors				(1, vk::makeRect2D(renderSize));

	return vk::makeGraphicsPipeline(vkd,				// const DeviceInterface&            vk
									device,				// const VkDevice                    device
									pipelineLayout,		// const VkPipelineLayout            pipelineLayout
									*vertShaderModule,	// const VkShaderModule              vertexShaderModule
									DE_NULL,			// const VkShaderModule              tessellationControlShaderModule
									DE_NULL,			// const VkShaderModule              tessellationEvalShaderModule
									DE_NULL,			// const VkShaderModule              geometryShaderModule
									*fragShaderModule,	// const VkShaderModule              fragmentShaderModule
									renderPass,			// const VkRenderPass                renderPass
									viewports,			// const std::vector<VkViewport>&    viewports
									scissors);			// const std::vector<VkRect2D>&      scissors
}

TriangleRenderer::TriangleRenderer (ProtectedContext&				context,
									const vk::BinaryCollection&		binaryRegistry,
									const std::vector<vk::VkImage>	swapchainImages,
									const vk::VkFormat				framebufferFormat,
									const tcu::UVec2&				renderSize)
	: m_vkd					(context.getDeviceInterface())
	, m_swapchainImages		(swapchainImages)
	, m_renderSize			(renderSize)
	, m_renderPass			(createRenderPass(m_vkd, context.getDevice(), framebufferFormat))
	, m_pipelineLayout		(createPipelineLayout(m_vkd, context.getDevice()))
	, m_pipeline			(createPipeline(m_vkd, context.getDevice(), *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
	, m_vertexBuffer		(makeBuffer(context,
									PROTECTION_DISABLED,
									context.getQueueFamilyIndex(),
									(deUint32)(sizeof(float)*4*3),
									vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
									vk::MemoryRequirement::HostVisible))
{
	m_attachmentViews.resize(swapchainImages.size());
	m_framebuffers.resize(swapchainImages.size());

	for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
	{
		m_attachmentViews[imageNdx]	= ImageViewSp(new vk::Unique<vk::VkImageView>(createImageView(context, swapchainImages[imageNdx], framebufferFormat)));
		m_framebuffers[imageNdx]	= FramebufferSp(new vk::Unique<vk::VkFramebuffer>(createFramebuffer(context,
																										renderSize.x(),
																										renderSize.y(),
																										*m_renderPass,
																										**m_attachmentViews[imageNdx])));
	}

	// Upload vertex data
	{
		const tcu::Vec4				vertices[]	=
		{
			tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
			tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
			tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
		};
		DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);

		deMemcpy(m_vertexBuffer->getAllocation().getHostPtr(), &vertices[0], sizeof(vertices));
		vk::flushMappedMemoryRange(m_vkd, context.getDevice(), m_vertexBuffer->getAllocation().getMemory(), m_vertexBuffer->getAllocation().getOffset(), sizeof(vertices));
	}
}

TriangleRenderer::~TriangleRenderer (void)
{
}

void TriangleRenderer::recordFrame (vk::VkCommandBuffer	cmdBuffer,
									deUint32			imageNdx,
									deUint32			frameNdx) const
{
	const vk::VkFramebuffer	curFramebuffer	= **m_framebuffers[imageNdx];

	beginCommandBuffer(m_vkd, cmdBuffer, 0u);

	beginRenderPass(m_vkd, cmdBuffer, *m_renderPass, curFramebuffer, vk::makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.125f, 0.25f, 0.75f, 1.0f));
	m_vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);

	{
		const vk::VkDeviceSize bindingOffset = 0;
		m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &bindingOffset);
	}

	m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, vk::VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
	m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
	endRenderPass(m_vkd, cmdBuffer);

	endCommandBuffer(m_vkd, cmdBuffer);
}

void TriangleRenderer::getPrograms (vk::SourceCollections& dst)
{
	dst.glslSources.add("tri-vert") << glu::VertexSource(
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 a_position;\n"
		"layout(push_constant) uniform FrameData\n"
		"{\n"
		"    highp uint frameNdx;\n"
		"} frameData;\n"
		"void main (void)\n"
		"{\n"
		"    highp float angle = float(frameData.frameNdx) / 100.0;\n"
		"    highp float c     = cos(angle);\n"
		"    highp float s     = sin(angle);\n"
		"    highp mat4  t     = mat4( c, -s,  0,  0,\n"
		"                              s,  c,  0,  0,\n"
		"                              0,  0,  1,  0,\n"
		"                              0,  0,  0,  1);\n"
		"    gl_Position = t * a_position;\n"
		"}\n");
	dst.glslSources.add("tri-frag") << glu::FragmentSource(
		"#version 310 es\n"
		"layout(location = 0) out lowp vec4 o_color;\n"
		"void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
}

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

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

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

	return fences;
}

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

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

	return semaphores;
}

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

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

	return buffers;
}

tcu::TestStatus basicRenderTest (Context& baseCtx, vk::wsi::Type wsiType)
{
	std::vector<vk::VkExtensionProperties>	supportedExtensions			(enumerateInstanceExtensionProperties(baseCtx.getPlatformInterface(), DE_NULL));
	std::vector<std::string>				instExts					= getRequiredWsiExtensions(supportedExtensions, wsiType);
	std::vector<std::string>				devExts;
	devExts.push_back("VK_KHR_swapchain");

	const tcu::UVec2						desiredSize					(256, 256);
	const NativeObjects						native						(baseCtx,  supportedExtensions, wsiType, tcu::just(desiredSize));
	ProtectedContext						context						(baseCtx, wsiType, *native.display, *native.window, instExts, devExts);
	vk::VkSurfaceKHR						surface						= context.getSurface();
	const vk::DeviceInterface&				vkd							= context.getDeviceInterface();
	const vk::VkDevice						device						= context.getDevice();
	const vk::VkSwapchainCreateInfoKHR		swapchainInfo				= getBasicSwapchainParameters(wsiType,
																								  context.getInstanceDriver(),
																								  context.getPhysicalDevice(),
																								  surface,
																								  desiredSize,
																								  2);
	const vk::Unique<vk::VkSwapchainKHR>	swapchain					(createSwapchainKHR(vkd, device, &swapchainInfo));
	const std::vector<vk::VkImage>			swapchainImages				= vk::wsi::getSwapchainImages(vkd, device, *swapchain);

	const TriangleRenderer					renderer					(context,
																		 context.getBinaryCollection(),
																		 swapchainImages,
																		 swapchainInfo.imageFormat,
																		 tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));

	const vk::Unique<vk::VkCommandPool>		commandPool					(makeCommandPool(vkd, device, PROTECTION_ENABLED,
																					 context.getQueueFamilyIndex()));

	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 std::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 std::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 std::vector<SemaphoreSp>			renderingCompleteSemaphores	(createSemaphores(vkd, device, maxQueuedFrames));
	const std::vector<CommandBufferSp>		commandBuffers				(allocateCommandBuffers(vkd,
																								device,
																								*commandPool,
																								vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,
																								maxQueuedFrames));

	try
	{
		const deUint32	numFramesToRender	= 60*10;

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

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

			VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));

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

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

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

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

				const vk::VkProtectedSubmitInfo		protectedInfo   =
				{
					vk::VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO,		// sType
					DE_NULL,											// pNext
					VK_TRUE,											// protectedSubmit
				};
				submitInfo.pNext = &protectedInfo;

				const vk::VkPresentInfoKHR		presentInfo					=
				{
					vk::VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
					DE_NULL,
					1u,
					&renderingCompleteSemaphore,
					1u,
					&*swapchain,
					&imageNdx,
					(vk::VkResult*)DE_NULL
				};

				renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
				VK_CHECK(vkd.queueSubmit(context.getQueue(), 1u, &submitInfo, imageReadyFence));
				VK_CHECK(vkd.queuePresentKHR(context.getQueue(), &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");
}

void getBasicRenderPrograms (vk::SourceCollections& dst, vk::wsi::Type)
{
	TriangleRenderer::getPrograms(dst);
}

void populateRenderGroup (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
{
	addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Test", getBasicRenderPrograms, basicRenderTest, wsiType);
}

void createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
{
	addTestGroup(testGroup, "create",			"Create VkSwapchain with various parameters",					populateSwapchainGroup,		GroupParameters(wsiType, createSwapchainTest));
	addTestGroup(testGroup, "render",			"Rendering Tests",												populateRenderGroup,		wsiType);
}

void createTypeSpecificTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
{
	addTestGroup(testGroup, "swapchain", "VkSwapchain Tests", createSwapchainTests, wsiType);
}

} // anonymous

tcu::TestCaseGroup* createSwapchainTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> wsiTestGroup (new tcu::TestCaseGroup(testCtx, "wsi", "WSI Tests"));

	for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
	{
		const vk::wsi::Type	wsiType		= (vk::wsi::Type)typeNdx;

		addTestGroup(&*wsiTestGroup, getName(wsiType), "", createTypeSpecificTests, wsiType);
	}

	return wsiTestGroup.release();
}

} // wsi
} // vkt
