188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos/*-------------------------------------------------------------------------
288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos * Vulkan Conformance Tests
388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos * ------------------------
488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos *
588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos * Copyright (c) 2016 Google Inc.
688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos *
7978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
8978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * you may not use this file except in compliance with the License.
9978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * You may obtain a copy of the License at
1088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos *
11978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
1288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos *
13978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Unless required by applicable law or agreed to in writing, software
14978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
15978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * See the License for the specific language governing permissions and
17978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * limitations under the License.
1888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos *
1988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos *//*!
2088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos * \file
2188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos * \brief VkSwapchain Tests
2288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos *//*--------------------------------------------------------------------*/
2388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
2488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vktWsiSwapchainTests.hpp"
2588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
2688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vktTestCaseUtil.hpp"
2788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vktTestGroupUtil.hpp"
2888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
2988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkDefs.hpp"
3088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkPlatform.hpp"
3188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkStrUtil.hpp"
3288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkRef.hpp"
3388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkRefUtil.hpp"
3488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkQueryUtil.hpp"
3588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkMemUtil.hpp"
3688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkDeviceUtil.hpp"
3788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkPrograms.hpp"
3888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkTypeUtil.hpp"
3988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkWsiPlatform.hpp"
4088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "vkWsiUtil.hpp"
41f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos#include "vkAllocationCallbackUtil.hpp"
4288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
4388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "tcuTestLog.hpp"
4488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "tcuFormatUtil.hpp"
4588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "tcuPlatform.hpp"
4688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "tcuResultCollector.hpp"
4788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
4888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "deUniquePtr.hpp"
4988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "deStringUtil.hpp"
5088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos#include "deArrayUtil.hpp"
518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos#include "deSharedPtr.hpp"
528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos#include <limits>
5488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
5588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosnamespace vkt
5688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
5788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosnamespace wsi
5888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
5988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
6088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosnamespace
6188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
6288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
6388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing namespace vk;
6488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing namespace vk::wsi;
6588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
6688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing tcu::TestLog;
6788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing tcu::Maybe;
6888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing tcu::UVec2;
6988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
7088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing de::MovePtr;
7188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing de::UniquePtr;
7288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
7388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing std::string;
7488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosusing std::vector;
7588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
7688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulostypedef vector<VkExtensionProperties> Extensions;
7788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
7888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosvoid checkAllSupported (const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
7988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
8088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
8188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		 requiredExtName != requiredExtensions.end();
8288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		 ++requiredExtName)
8388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
8488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
8588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
8688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
8788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
8888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
89f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry HaulosMove<VkInstance> createInstanceWithWsi (const PlatformInterface&		vkp,
90f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos										const Extensions&				supportedExtensions,
91f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos										Type							wsiType,
92f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos										const VkAllocationCallbacks*	pAllocator	= DE_NULL)
9388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
9488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	vector<string>	extensions;
9588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
9688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	extensions.push_back("VK_KHR_surface");
9788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	extensions.push_back(getExtensionName(wsiType));
9888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
99e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	// VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
100e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	// the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
101e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	// but using them without enabling the extension is not allowed. Thus we have
102e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	// two options:
103e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	//
104e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	// 1) Filter out non-core formats to stay within valid usage.
105e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	//
106e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	// 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
107e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	//
108e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	// We opt for (2) as it provides basic coverage for the extension as a bonus.
109e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos	if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
110e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos		extensions.push_back("VK_EXT_swapchain_colorspace");
111e67afec906e5e1b2052ecb5007f2d22bc7c634fdPyry Haulos
11288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	checkAllSupported(supportedExtensions, extensions);
11388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
114f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos	return createDefaultInstance(vkp, vector<string>(), extensions, pAllocator);
11588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
11688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
11788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry HaulosVkPhysicalDeviceFeatures getDeviceFeaturesForWsi (void)
11888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
11988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	VkPhysicalDeviceFeatures features;
12088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	deMemset(&features, 0, sizeof(features));
12188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return features;
12288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
12388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
124f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry HaulosMove<VkDevice> createDeviceWithWsi (const InstanceInterface&		vki,
125f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos									VkPhysicalDevice				physicalDevice,
126f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos									const Extensions&				supportedExtensions,
127f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos									const deUint32					queueFamilyIndex,
128f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos									const VkAllocationCallbacks*	pAllocator = DE_NULL)
12988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
13088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const float						queuePriorities[]	= { 1.0f };
13188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const VkDeviceQueueCreateInfo	queueInfos[]		=
13288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
13388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
13488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
13588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			DE_NULL,
13688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			(VkDeviceQueueCreateFlags)0,
13788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			queueFamilyIndex,
13888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			DE_LENGTH_OF_ARRAY(queuePriorities),
13988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			&queuePriorities[0]
14088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
14188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	};
14288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const VkPhysicalDeviceFeatures	features		= getDeviceFeaturesForWsi();
14388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const char* const				extensions[]	= { "VK_KHR_swapchain" };
14488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const VkDeviceCreateInfo		deviceParams	=
14588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
14688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
14788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		DE_NULL,
14888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		(VkDeviceCreateFlags)0,
14988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		DE_LENGTH_OF_ARRAY(queueInfos),
15088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		&queueInfos[0],
15188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		0u,									// enabledLayerCount
15288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		DE_NULL,							// ppEnabledLayerNames
153cb5487328285ae33eb53ae36f14794a60200e8e0Pyry Haulos		DE_LENGTH_OF_ARRAY(extensions),		// enabledExtensionCount
154cb5487328285ae33eb53ae36f14794a60200e8e0Pyry Haulos		DE_ARRAY_BEGIN(extensions),			// ppEnabledExtensionNames
15588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		&features
15688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	};
15788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
15888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
15988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
16088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
16188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
16288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
16388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
164f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos	return createDevice(vki, physicalDevice, &deviceParams, pAllocator);
16588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
16688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
16788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry HaulosdeUint32 getNumQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
16888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
16988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	deUint32	numFamilies		= 0;
17088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
17188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
17288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
17388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return numFamilies;
17488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
17588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
17688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosvector<deUint32> getSupportedQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
17788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
17888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const deUint32		numTotalFamilyIndices	= getNumQueueFamilyIndices(vki, physicalDevice);
17988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	vector<deUint32>	supportedFamilyIndices;
18088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
18188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
18288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
18388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
18488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			supportedFamilyIndices.push_back(queueFamilyNdx);
18588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
18688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
18788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return supportedFamilyIndices;
18888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
18988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
19088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry HaulosdeUint32 chooseQueueFamilyIndex (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
19188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
19288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const vector<deUint32>	supportedFamilyIndices	= getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
19388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
19488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	if (supportedFamilyIndices.empty())
19588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		TCU_THROW(NotSupportedError, "Device doesn't support presentation");
19688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
19788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return supportedFamilyIndices[0];
19888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
19988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
20088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosstruct InstanceHelper
20188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
20288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const vector<VkExtensionProperties>	supportedExtensions;
20388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const Unique<VkInstance>			instance;
20488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const InstanceDriver				vki;
20588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
206f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos	InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
20788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		: supportedExtensions	(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
20888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																	  DE_NULL))
20988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, instance				(createInstanceWithWsi(context.getPlatformInterface(),
21088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos													   supportedExtensions,
211f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos													   wsiType,
212f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos													   pAllocator))
21388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, vki					(context.getPlatformInterface(), *instance)
21488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{}
21588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos};
21688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
21788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry HaulosVkQueue getDeviceQueue (const DeviceInterface& vkd, VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex)
21888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
21988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	VkQueue queue = (VkQueue)0;
22088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue);
22188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return queue;
22288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
22388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
22488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosstruct DeviceHelper
22588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
22688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const VkPhysicalDevice	physicalDevice;
22788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const deUint32			queueFamilyIndex;
22888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const Unique<VkDevice>	device;
22988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const DeviceDriver		vkd;
23088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const VkQueue			queue;
23188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
232f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos	DeviceHelper (Context&						context,
233f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos				  const InstanceInterface&		vki,
234f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos				  VkInstance					instance,
235f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos				  VkSurfaceKHR					surface,
236f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos				  const VkAllocationCallbacks*	pAllocator = DE_NULL)
23788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		: physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
23888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, surface))
23988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, device			(createDeviceWithWsi(vki,
24088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos												 physicalDevice,
24188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos												 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
242f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos												 queueFamilyIndex,
243f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos												 pAllocator))
24488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, vkd				(vki, *device)
24588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, queue				(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
24688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
24788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
24888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos};
24988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
25088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry HaulosMovePtr<Display> createDisplay (const vk::Platform&	platform,
25188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos								const Extensions&	supportedExtensions,
25288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos								Type				wsiType)
25388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
25488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	try
25588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
25688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		return MovePtr<Display>(platform.createWsiDisplay(wsiType));
25788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
25888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	catch (const tcu::NotSupportedError& e)
25988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
26088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))))
26188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
26288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			// If VK_KHR_{platform}_surface was supported, vk::Platform implementation
26388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			// must support creating native display & window for that WSI type.
26488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			throw tcu::TestError(e.getMessage());
26588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
26688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		else
26788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			throw;
26888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
26988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
27088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
27188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry HaulosMovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
27288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
27388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	try
27488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
27588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		return MovePtr<Window>(display.createWindow(initialSize));
27688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
27788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	catch (const tcu::NotSupportedError& e)
27888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
27988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		// See createDisplay - assuming that wsi::Display was supported platform port
28088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		// should also support creating a window.
28188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		throw tcu::TestError(e.getMessage());
28288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
28388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
28488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
28588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosstruct NativeObjects
28688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
28788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const UniquePtr<Display>	display;
28888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const UniquePtr<Window>		window;
28988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
29088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	NativeObjects (Context&				context,
29188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				   const Extensions&	supportedExtensions,
29288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				   Type					wsiType,
29388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				   const Maybe<UVec2>&	initialWindowSize = tcu::nothing<UVec2>())
29488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		: display	(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
29588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, window	(createWindow(*display, initialWindowSize))
29688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{}
29788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos};
29888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
29988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosenum TestDimension
30088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
30188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_MIN_IMAGE_COUNT = 0,	//!< Test all supported image counts
30288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_IMAGE_FORMAT,		//!< Test all supported formats
30388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_IMAGE_EXTENT,		//!< Test various (supported) extents
30488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_IMAGE_ARRAY_LAYERS,
30588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_IMAGE_USAGE,
30688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_IMAGE_SHARING_MODE,
30788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_PRE_TRANSFORM,
30888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_COMPOSITE_ALPHA,
30988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_PRESENT_MODE,
31088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_CLIPPED,
31188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
31288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TEST_DIMENSION_LAST
31388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos};
31488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
31588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosconst char* getTestDimensionName (TestDimension dimension)
31688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
31788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	static const char* const s_names[] =
31888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
31988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"min_image_count",
32088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"image_format",
32188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"image_extent",
32288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"image_array_layers",
32388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"image_usage",
32488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"image_sharing_mode",
32588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"pre_transform",
32688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"composite_alpha",
32788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"present_mode",
32888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		"clipped"
32988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	};
33088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return de::getSizedArrayElement<TEST_DIMENSION_LAST>(s_names, dimension);
33188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
33288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
33388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosstruct TestParameters
33488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
33588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	Type			wsiType;
33688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TestDimension	dimension;
33788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
33888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TestParameters (Type wsiType_, TestDimension dimension_)
33988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		: wsiType	(wsiType_)
34088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, dimension	(dimension_)
34188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{}
34288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
34388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	TestParameters (void)
34488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		: wsiType	(TYPE_LAST)
34588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, dimension	(TEST_DIMENSION_LAST)
34688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{}
34788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos};
34888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
34988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosvector<VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (Type								wsiType,
350653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos																  TestDimension						dimension,
35188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																  const VkSurfaceCapabilitiesKHR&	capabilities,
35288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																  const vector<VkSurfaceFormatKHR>&	formats,
35388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																  const vector<VkPresentModeKHR>&	presentModes)
35488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
35588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const PlatformProperties&			platformProperties	= getPlatformProperties(wsiType);
35688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	vector<VkSwapchainCreateInfoKHR>	cases;
3573d8e6ee58a6f3a7701a3e6cdc4ba9fb14b162410Pyry Haulos	const VkSurfaceTransformFlagBitsKHR defaultTransform	= (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
35888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const VkSwapchainCreateInfoKHR		baseParameters		=
35988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
36088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
36188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		DE_NULL,
36288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		(VkSwapchainCreateFlagsKHR)0,
36388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		(VkSurfaceKHR)0,
36488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		capabilities.minImageCount,
36588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		formats[0].format,
36688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		formats[0].colorSpace,
36788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		(platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE
36888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			? capabilities.minImageExtent : capabilities.currentExtent),
36988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		1u,									// imageArrayLayers
37088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
37188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VK_SHARING_MODE_EXCLUSIVE,
37288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		0u,
37388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		(const deUint32*)DE_NULL,
3743d8e6ee58a6f3a7701a3e6cdc4ba9fb14b162410Pyry Haulos		defaultTransform,
37588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
37688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VK_PRESENT_MODE_FIFO_KHR,
37788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VK_FALSE,							// clipped
37888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		(VkSwapchainKHR)0					// oldSwapchain
37988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	};
38088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
38188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	switch (dimension)
38288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
38388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_MIN_IMAGE_COUNT:
38488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
3853d8e6ee58a6f3a7701a3e6cdc4ba9fb14b162410Pyry Haulos			const deUint32	maxImageCountToTest	= de::clamp(16u, capabilities.minImageCount, (capabilities.maxImageCount > 0) ? capabilities.maxImageCount : capabilities.minImageCount + 16u);
38688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
38788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			for (deUint32 imageCount = capabilities.minImageCount; imageCount <= maxImageCountToTest; ++imageCount)
38888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
38988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.push_back(baseParameters);
39088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().minImageCount = imageCount;
39188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
39288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
39388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
39488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
39588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
39688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_IMAGE_FORMAT:
39788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
39888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
39988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
40088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.push_back(baseParameters);
40188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().imageFormat		= curFmt->format;
40288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().imageColorSpace	= curFmt->colorSpace;
40388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
40488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
40588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
40688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
40788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
40888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_IMAGE_EXTENT:
40988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
41088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			static const VkExtent2D	s_testSizes[]	=
41188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
41288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{ 1, 1 },
41388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{ 16, 32 },
41488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{ 32, 16 },
41588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{ 632, 231 },
41688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{ 117, 998 },
41788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			};
41888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
41988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			if (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE ||
42088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE)
42188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
42288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_testSizes); ++ndx)
42388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{
42488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.push_back(baseParameters);
42588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.back().imageExtent.width	= de::clamp(s_testSizes[ndx].width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
42688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.back().imageExtent.height	= de::clamp(s_testSizes[ndx].height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
42788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				}
42888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
42988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
43088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			if (platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE)
43188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
43288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.push_back(baseParameters);
43388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().imageExtent = capabilities.currentExtent;
43488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
43588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
43688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			if (platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE)
43788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
43888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.push_back(baseParameters);
43988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().imageExtent = capabilities.minImageExtent;
44088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
44188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.push_back(baseParameters);
44288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().imageExtent = capabilities.maxImageExtent;
44388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
44488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
44588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
44688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
44788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
44888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_IMAGE_ARRAY_LAYERS:
44988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
45088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			const deUint32	maxLayers	= de::min(capabilities.maxImageArrayLayers, 16u);
45188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
45288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			for (deUint32 numLayers = 1; numLayers <= maxLayers; ++numLayers)
45388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
45488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.push_back(baseParameters);
45588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().imageArrayLayers = numLayers;
45688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
45788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
45888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
45988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
46088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
46188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_IMAGE_USAGE:
46288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
46388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			for (deUint32 flags = 1u; flags <= capabilities.supportedUsageFlags; ++flags)
46488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
46588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				if ((flags & ~capabilities.supportedUsageFlags) == 0)
46688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{
46788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.push_back(baseParameters);
46888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.back().imageUsage = flags;
46988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				}
47088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
47188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
47288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
47388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
47488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
47588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_IMAGE_SHARING_MODE:
47688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
47788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.push_back(baseParameters);
47888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.back().imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
47988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
48088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.push_back(baseParameters);
48188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.back().imageSharingMode = VK_SHARING_MODE_CONCURRENT;
48288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
48388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
48488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
48588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
48688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_PRE_TRANSFORM:
48788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
48888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			for (deUint32 transform = 1u;
48988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				 transform <= capabilities.supportedTransforms;
49088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				 transform = transform<<1u)
49188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
49288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				if ((transform & capabilities.supportedTransforms) != 0)
49388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{
49488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.push_back(baseParameters);
49588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.back().preTransform = (VkSurfaceTransformFlagBitsKHR)transform;
49688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				}
49788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
49888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
49988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
50088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
50188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
50288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_COMPOSITE_ALPHA:
50388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
50488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			for (deUint32 alphaMode = 1u;
50588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				 alphaMode <= capabilities.supportedCompositeAlpha;
50688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				 alphaMode = alphaMode<<1u)
50788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
50888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				if ((alphaMode & capabilities.supportedCompositeAlpha) != 0)
50988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				{
51088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.push_back(baseParameters);
51188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos					cases.back().compositeAlpha = (VkCompositeAlphaFlagBitsKHR)alphaMode;
51288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				}
51388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
51488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
51588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
51688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
51788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
51888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_PRESENT_MODE:
51988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
52088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			for (vector<VkPresentModeKHR>::const_iterator curMode = presentModes.begin(); curMode != presentModes.end(); ++curMode)
52188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			{
52288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.push_back(baseParameters);
52388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos				cases.back().presentMode = *curMode;
52488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			}
52588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
52688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
52788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
52888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
52988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		case TEST_DIMENSION_CLIPPED:
53088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
53188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.push_back(baseParameters);
53288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.back().clipped = VK_FALSE;
53388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
53488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.push_back(baseParameters);
53588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			cases.back().clipped = VK_TRUE;
53688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
53788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			break;
53888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
53988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
54088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		default:
54188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			DE_FATAL("Impossible");
54288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
54388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
54488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	DE_ASSERT(!cases.empty());
54588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return cases;
54688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
54788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
54888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosvector<VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (Type								wsiType,
54988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																  TestDimension						dimension,
55088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																  const InstanceInterface&			vki,
55188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																  VkPhysicalDevice					physicalDevice,
55288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																  VkSurfaceKHR						surface)
55388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
55488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const VkSurfaceCapabilitiesKHR		capabilities	= getPhysicalDeviceSurfaceCapabilities(vki,
55588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																							   physicalDevice,
55688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																							   surface);
55788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const vector<VkSurfaceFormatKHR>	formats			= getPhysicalDeviceSurfaceFormats(vki,
55888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																						  physicalDevice,
55988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																						  surface);
56088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const vector<VkPresentModeKHR>		presentModes	= getPhysicalDeviceSurfacePresentModes(vki,
56188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																							   physicalDevice,
56288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos																							   surface);
56388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
56488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return generateSwapchainParameterCases(wsiType, dimension, capabilities, formats, presentModes);
56588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
56688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
56788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulostcu::TestStatus createSwapchainTest (Context& context, TestParameters params)
56888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
56988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const InstanceHelper					instHelper	(context, params.wsiType);
57088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const NativeObjects						native		(context, instHelper.supportedExtensions, params.wsiType);
57188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const Unique<VkSurfaceKHR>				surface		(createSurface(instHelper.vki, *instHelper.instance, params.wsiType, *native.display, *native.window));
57288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const DeviceHelper						devHelper	(context, instHelper.vki, *instHelper.instance, *surface);
57388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	const vector<VkSwapchainCreateInfoKHR>	cases		(generateSwapchainParameterCases(params.wsiType, params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));
57488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
57588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
57688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
57788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		VkSwapchainCreateInfoKHR	curParams	= cases[caseNdx];
57888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
57988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		curParams.surface				= *surface;
58088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		curParams.queueFamilyIndexCount	= 1u;
58188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		curParams.pQueueFamilyIndices	= &devHelper.queueFamilyIndex;
58288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
58388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		context.getTestContext().getLog()
58488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			<< TestLog::Message << "Sub-case " << (caseNdx+1) << " / " << cases.size() << ": " << curParams << TestLog::EndMessage;
58588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
58688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		{
58788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos			const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(devHelper.vkd, *devHelper.device, &curParams));
58888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		}
58988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
59088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
59188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	return tcu::TestStatus::pass("Creating swapchain succeeded");
59288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
59388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
5942beac9057d9113ac306632d819ded852691a6842Pyry Haulostcu::TestStatus createSwapchainSimulateOOMTest (Context& context, TestParameters params)
595f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos{
5962beac9057d9113ac306632d819ded852691a6842Pyry Haulos	const size_t				maxCases			= 300u;
5972beac9057d9113ac306632d819ded852691a6842Pyry Haulos	const deUint32				maxAllocs			= 1024u;
5987734f52e21c826b08737e08aff04e479cd7fc362Mika Isojärvi
5992beac9057d9113ac306632d819ded852691a6842Pyry Haulos	tcu::TestLog&				log					= context.getTestContext().getLog();
6002beac9057d9113ac306632d819ded852691a6842Pyry Haulos	tcu::ResultCollector		results				(log);
601f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6022beac9057d9113ac306632d819ded852691a6842Pyry Haulos	AllocationCallbackRecorder	allocationRecorder	(getSystemAllocator());
6032beac9057d9113ac306632d819ded852691a6842Pyry Haulos	DeterministicFailAllocator	failingAllocator	(allocationRecorder.getCallbacks(),
6042beac9057d9113ac306632d819ded852691a6842Pyry Haulos													 DeterministicFailAllocator::MODE_DO_NOT_COUNT,
6052beac9057d9113ac306632d819ded852691a6842Pyry Haulos													 0);
606f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos	{
6072beac9057d9113ac306632d819ded852691a6842Pyry Haulos		const InstanceHelper					instHelper	(context, params.wsiType, failingAllocator.getCallbacks());
6082beac9057d9113ac306632d819ded852691a6842Pyry Haulos		const NativeObjects						native		(context, instHelper.supportedExtensions, params.wsiType);
6092beac9057d9113ac306632d819ded852691a6842Pyry Haulos		const Unique<VkSurfaceKHR>				surface		(createSurface(instHelper.vki,
6102beac9057d9113ac306632d819ded852691a6842Pyry Haulos																			*instHelper.instance,
6112beac9057d9113ac306632d819ded852691a6842Pyry Haulos																			params.wsiType,
6122beac9057d9113ac306632d819ded852691a6842Pyry Haulos																			*native.display,
6132beac9057d9113ac306632d819ded852691a6842Pyry Haulos																			*native.window,
6142beac9057d9113ac306632d819ded852691a6842Pyry Haulos																			failingAllocator.getCallbacks()));
6152beac9057d9113ac306632d819ded852691a6842Pyry Haulos		const DeviceHelper						devHelper	(context, instHelper.vki, *instHelper.instance, *surface, failingAllocator.getCallbacks());
6162beac9057d9113ac306632d819ded852691a6842Pyry Haulos		const vector<VkSwapchainCreateInfoKHR>	allCases	(generateSwapchainParameterCases(params.wsiType, params.dimension, instHelper.vki, devHelper.physicalDevice, *surface));
6172beac9057d9113ac306632d819ded852691a6842Pyry Haulos
6182beac9057d9113ac306632d819ded852691a6842Pyry Haulos		if (maxCases < allCases.size())
6192beac9057d9113ac306632d819ded852691a6842Pyry Haulos			log << TestLog::Message << "Note: Will only test first " << maxCases << " cases out of total of " << allCases.size() << " parameter combinations" << TestLog::EndMessage;
6202beac9057d9113ac306632d819ded852691a6842Pyry Haulos
6212beac9057d9113ac306632d819ded852691a6842Pyry Haulos		for (size_t caseNdx = 0; caseNdx < de::min(maxCases, allCases.size()); ++caseNdx)
622f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos		{
6232beac9057d9113ac306632d819ded852691a6842Pyry Haulos			log << TestLog::Message << "Testing parameter case " << caseNdx << ": " << allCases[caseNdx] << TestLog::EndMessage;
6242beac9057d9113ac306632d819ded852691a6842Pyry Haulos
6252beac9057d9113ac306632d819ded852691a6842Pyry Haulos			for (deUint32 numPassingAllocs = 0; numPassingAllocs <= maxAllocs; ++numPassingAllocs)
626f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos			{
6272beac9057d9113ac306632d819ded852691a6842Pyry Haulos				bool	gotOOM	= false;
628f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6292beac9057d9113ac306632d819ded852691a6842Pyry Haulos				failingAllocator.reset(DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs);
630f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6312beac9057d9113ac306632d819ded852691a6842Pyry Haulos				log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
632f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6332beac9057d9113ac306632d819ded852691a6842Pyry Haulos				try
634f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos				{
6352beac9057d9113ac306632d819ded852691a6842Pyry Haulos					VkSwapchainCreateInfoKHR	curParams	= allCases[caseNdx];
6362beac9057d9113ac306632d819ded852691a6842Pyry Haulos
6372beac9057d9113ac306632d819ded852691a6842Pyry Haulos					curParams.surface				= *surface;
6382beac9057d9113ac306632d819ded852691a6842Pyry Haulos					curParams.queueFamilyIndexCount	= 1u;
6392beac9057d9113ac306632d819ded852691a6842Pyry Haulos					curParams.pQueueFamilyIndices	= &devHelper.queueFamilyIndex;
6402beac9057d9113ac306632d819ded852691a6842Pyry Haulos
6412beac9057d9113ac306632d819ded852691a6842Pyry Haulos					{
6422beac9057d9113ac306632d819ded852691a6842Pyry Haulos						const Unique<VkSwapchainKHR>	swapchain	(createSwapchainKHR(devHelper.vkd, *devHelper.device, &curParams, failingAllocator.getCallbacks()));
6432beac9057d9113ac306632d819ded852691a6842Pyry Haulos					}
6442beac9057d9113ac306632d819ded852691a6842Pyry Haulos				}
6452beac9057d9113ac306632d819ded852691a6842Pyry Haulos				catch (const OutOfMemoryError& e)
6462beac9057d9113ac306632d819ded852691a6842Pyry Haulos				{
6472beac9057d9113ac306632d819ded852691a6842Pyry Haulos					log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
6482beac9057d9113ac306632d819ded852691a6842Pyry Haulos					gotOOM = true;
649f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos				}
650f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6512beac9057d9113ac306632d819ded852691a6842Pyry Haulos				if (!gotOOM)
6522beac9057d9113ac306632d819ded852691a6842Pyry Haulos				{
6532beac9057d9113ac306632d819ded852691a6842Pyry Haulos					log << TestLog::Message << "Creating swapchain succeeded!" << TestLog::EndMessage;
654f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6552beac9057d9113ac306632d819ded852691a6842Pyry Haulos					if (numPassingAllocs == 0)
6562beac9057d9113ac306632d819ded852691a6842Pyry Haulos						results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
657f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6582beac9057d9113ac306632d819ded852691a6842Pyry Haulos					break;
6592beac9057d9113ac306632d819ded852691a6842Pyry Haulos				}
6602beac9057d9113ac306632d819ded852691a6842Pyry Haulos				else if (numPassingAllocs == maxAllocs)
6612beac9057d9113ac306632d819ded852691a6842Pyry Haulos					results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Creating swapchain did not succeed, callback limit exceeded");
6622beac9057d9113ac306632d819ded852691a6842Pyry Haulos			}
663f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos		}
664f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
6652beac9057d9113ac306632d819ded852691a6842Pyry Haulos		context.getTestContext().touchWatchdog();
6667734f52e21c826b08737e08aff04e479cd7fc362Mika Isojärvi	}
6672beac9057d9113ac306632d819ded852691a6842Pyry Haulos
6682beac9057d9113ac306632d819ded852691a6842Pyry Haulos	if (!validateAndLog(log, allocationRecorder, 0u))
6692beac9057d9113ac306632d819ded852691a6842Pyry Haulos		results.fail("Detected invalid system allocation callback");
6702beac9057d9113ac306632d819ded852691a6842Pyry Haulos
6712beac9057d9113ac306632d819ded852691a6842Pyry Haulos	return tcu::TestStatus(results.getResult(), results.getMessage());
672f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos}
673f1d576d0d3f98e27b55038c5b29df26d1d0f0d79Pyry Haulos
67488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosstruct GroupParameters
67588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
67688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	typedef FunctionInstance1<TestParameters>::Function	Function;
67788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
67888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	Type		wsiType;
67988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	Function	function;
68088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
68188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	GroupParameters (Type wsiType_, Function function_)
68288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		: wsiType	(wsiType_)
68388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, function	(function_)
68488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{}
68588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
68688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	GroupParameters (void)
68788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		: wsiType	(TYPE_LAST)
68888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		, function	((Function)DE_NULL)
68988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{}
69088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos};
69188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
69288ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosvoid populateSwapchainGroup (tcu::TestCaseGroup* testGroup, GroupParameters params)
69388ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
69488ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	for (int dimensionNdx = 0; dimensionNdx < TEST_DIMENSION_LAST; ++dimensionNdx)
69588ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	{
69688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		const TestDimension		testDimension	= (TestDimension)dimensionNdx;
69788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
69888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos		addFunctionCase(testGroup, getTestDimensionName(testDimension), "", params.function, TestParameters(params.wsiType, testDimension));
69988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos	}
70088ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
70188ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
7028e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosVkSwapchainCreateInfoKHR getBasicSwapchainParameters (Type						wsiType,
7038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos													  const InstanceInterface&	vki,
7048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos													  VkPhysicalDevice			physicalDevice,
7058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos													  VkSurfaceKHR				surface,
7068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos													  const tcu::UVec2&			desiredSize,
7078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos													  deUint32					desiredImageCount)
7088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
7098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkSurfaceCapabilitiesKHR		capabilities		= getPhysicalDeviceSurfaceCapabilities(vki,
7108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																								   physicalDevice,
7118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																								   surface);
7128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const vector<VkSurfaceFormatKHR>	formats				= getPhysicalDeviceSurfaceFormats(vki,
7138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																							  physicalDevice,
7148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																							  surface);
7158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const PlatformProperties&			platformProperties	= getPlatformProperties(wsiType);
7163d8e6ee58a6f3a7701a3e6cdc4ba9fb14b162410Pyry Haulos	const VkSurfaceTransformFlagBitsKHR transform			= (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
7178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkSwapchainCreateInfoKHR		parameters			=
7188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
7198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
7208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
7218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkSwapchainCreateFlagsKHR)0,
7228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		surface,
7233d8e6ee58a6f3a7701a3e6cdc4ba9fb14b162410Pyry Haulos		de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount),
7248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		formats[0].format,
7258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		formats[0].colorSpace,
7268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
7278e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),
7288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,									// imageArrayLayers
7298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
7308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_SHARING_MODE_EXCLUSIVE,
7318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,
7328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(const deUint32*)DE_NULL,
7333d8e6ee58a6f3a7701a3e6cdc4ba9fb14b162410Pyry Haulos		transform,
7348e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
7358e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_PRESENT_MODE_FIFO_KHR,
7368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,							// clipped
7378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkSwapchainKHR)0					// oldSwapchain
7388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
7398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return parameters;
7418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
7428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulostypedef de::SharedPtr<Unique<VkImageView> >		ImageViewSp;
7448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulostypedef de::SharedPtr<Unique<VkFramebuffer> >	FramebufferSp;
7458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosclass TriangleRenderer
7478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
7488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulospublic:
7498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									TriangleRenderer	(const DeviceInterface&		vkd,
7508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkDevice				device,
7518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 Allocator&					allocator,
7528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const BinaryCollection&	binaryRegistry,
7538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const vector<VkImage>		swapchainImages,
7548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkFormat				framebufferFormat,
7558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const UVec2&				renderSize);
7568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									~TriangleRenderer	(void);
7578e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7588e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	void							recordFrame			(VkCommandBuffer			cmdBuffer,
7598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 deUint32					imageNdx,
7608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 deUint32					frameNdx) const;
7618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	static void						getPrograms			(SourceCollections& dst);
7638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosprivate:
7658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	static Move<VkRenderPass>		createRenderPass	(const DeviceInterface&		vkd,
7668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkDevice				device,
7678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkFormat				colorAttachmentFormat);
7688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	static Move<VkPipelineLayout>	createPipelineLayout(const DeviceInterface&		vkd,
7698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 VkDevice					device);
7708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	static Move<VkPipeline>			createPipeline		(const DeviceInterface&		vkd,
7718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkDevice				device,
7728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkRenderPass			renderPass,
7738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkPipelineLayout		pipelineLayout,
7748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const BinaryCollection&	binaryCollection,
7758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const UVec2&				renderSize);
7768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7778e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	static Move<VkImageView>		createAttachmentView(const DeviceInterface&		vkd,
7788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkDevice				device,
7798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkImage				image,
7808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkFormat				format);
7818e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	static Move<VkFramebuffer>		createFramebuffer	(const DeviceInterface&		vkd,
7828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkDevice				device,
7838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkRenderPass			renderPass,
7848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkImageView			colorAttachment,
7858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const UVec2&				renderSize);
7868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	static Move<VkBuffer>			createBuffer		(const DeviceInterface&		vkd,
7888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 VkDevice					device,
7898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 VkDeviceSize				size,
7908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 VkBufferUsageFlags			usage);
7918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const DeviceInterface&			m_vkd;
7938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const vector<VkImage>			m_swapchainImages;
7958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const tcu::UVec2				m_renderSize;
7968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
7978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkRenderPass>		m_renderPass;
7988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkPipelineLayout>	m_pipelineLayout;
7998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkPipeline>		m_pipeline;
8008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
8018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkBuffer>			m_vertexBuffer;
8028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const UniquePtr<Allocation>		m_vertexBufferMemory;
8038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
8048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	vector<ImageViewSp>				m_attachmentViews;
8058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	vector<FramebufferSp>			m_framebuffers;
8068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos};
8078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
8088e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkRenderPass> TriangleRenderer::createRenderPass (const DeviceInterface&	vkd,
8098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos													   const VkDevice			device,
8108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos													   const VkFormat			colorAttachmentFormat)
8118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
8128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkAttachmentDescription	colorAttDesc		=
8138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
8148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkAttachmentDescriptionFlags)0,
8158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		colorAttachmentFormat,
8168e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_SAMPLE_COUNT_1_BIT,
8178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_ATTACHMENT_LOAD_OP_CLEAR,
8188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_ATTACHMENT_STORE_OP_STORE,
8198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_ATTACHMENT_LOAD_OP_DONT_CARE,
8208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_ATTACHMENT_STORE_OP_DONT_CARE,
8218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_IMAGE_LAYOUT_UNDEFINED,
8228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
8238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
8248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkAttachmentReference		colorAttRef			=
8258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
8268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,
8278e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
8288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
8298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkSubpassDescription		subpassDesc			=
8308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
8318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkSubpassDescriptionFlags)0u,
8328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_PIPELINE_BIND_POINT_GRAPHICS,
8338e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,							// inputAttachmentCount
8348e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,					// pInputAttachments
8358e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,							// colorAttachmentCount
8368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&colorAttRef,				// pColorAttachments
8378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,					// pResolveAttachments
8388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,					// depthStencilAttachment
8398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,							// preserveAttachmentCount
8408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,					// pPreserveAttachments
8418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
8428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkSubpassDependency		dependencies[]		=
8438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
8448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
8458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_SUBPASS_EXTERNAL,	// srcSubpass
8468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,						// dstSubpass
8478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
8488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
8498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_ACCESS_MEMORY_READ_BIT,
8508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
8518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
8528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_DEPENDENCY_BY_REGION_BIT
8538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		},
8548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
8558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,						// srcSubpass
8568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_SUBPASS_EXTERNAL,	// dstSubpass
8578e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
8588e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
8598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
8608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
8618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_ACCESS_MEMORY_READ_BIT,
8628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_DEPENDENCY_BY_REGION_BIT
8638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		},
8648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
8658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkRenderPassCreateInfo	renderPassParams	=
8668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
8678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
8688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
8698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkRenderPassCreateFlags)0,
8708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
8718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&colorAttDesc,
8728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
8738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&subpassDesc,
8748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_LENGTH_OF_ARRAY(dependencies),
8758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		dependencies,
8768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
8778e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
8788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createRenderPass(vkd, device, &renderPassParams);
8798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
8808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
8818e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkPipelineLayout> TriangleRenderer::createPipelineLayout (const DeviceInterface&	vkd,
8828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos															   const VkDevice			device)
8838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
8848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPushConstantRange						pushConstantRange		=
8858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
8868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_SHADER_STAGE_VERTEX_BIT,
8878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// offset
8888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(deUint32)sizeof(deUint32),					// size
8898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
8908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineLayoutCreateInfo				pipelineLayoutParams	=
8918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
8928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
8938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
8948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(vk::VkPipelineLayoutCreateFlags)0,
8958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// setLayoutCount
8968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,									// pSetLayouts
8978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
8988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&pushConstantRange,
8998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
9008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
9018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
9028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
9038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
9048e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkPipeline> TriangleRenderer::createPipeline (const DeviceInterface&	vkd,
9058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												   const VkDevice			device,
9068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												   const VkRenderPass		renderPass,
9078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												   const VkPipelineLayout	pipelineLayout,
9088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												   const BinaryCollection&	binaryCollection,
9098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												   const UVec2&				renderSize)
9108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
9118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
9128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	//		 and can be deleted immediately following that call.
9138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkShaderModule>					vertShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
9148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkShaderModule>					fragShaderModule		(createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
9158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
9168e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkSpecializationInfo						emptyShaderSpecParams	=
9178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
9188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// mapEntryCount
9198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,									// pMap
9208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0,											// dataSize
9218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,									// pData
9228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
9238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineShaderStageCreateInfo			shaderStageParams[]		=
9248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
9258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
9268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
9278e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			DE_NULL,
9288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			(VkPipelineShaderStageCreateFlags)0,
9298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_SHADER_STAGE_VERTEX_BIT,
9308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			*vertShaderModule,
9318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			"main",
9328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			&emptyShaderSpecParams,
9338e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		},
9348e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
9358e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
9368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			DE_NULL,
9378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			(VkPipelineShaderStageCreateFlags)0,
9388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_SHADER_STAGE_FRAGMENT_BIT,
9398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			*fragShaderModule,
9408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			"main",
9418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			&emptyShaderSpecParams,
9428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		}
9438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
9448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineDepthStencilStateCreateInfo		depthStencilParams		=
9458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
9468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
9478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
9488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineDepthStencilStateCreateFlags)0,
9498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_FALSE,									// depthTestEnable
9508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_FALSE,									// depthWriteEnable
9518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_COMPARE_OP_ALWAYS,						// depthCompareOp
9528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_FALSE,									// depthBoundsTestEnable
9538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_FALSE,									// stencilTestEnable
9548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
9558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STENCIL_OP_KEEP,							// failOp
9568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STENCIL_OP_KEEP,							// passOp
9578e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STENCIL_OP_KEEP,							// depthFailOp
9588e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_COMPARE_OP_ALWAYS,						// compareOp
9598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,											// compareMask
9608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,											// writeMask
9618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,											// reference
9628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		},											// front
9638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
9648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STENCIL_OP_KEEP,							// failOp
9658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STENCIL_OP_KEEP,							// passOp
9668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STENCIL_OP_KEEP,							// depthFailOp
9678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_COMPARE_OP_ALWAYS,						// compareOp
9688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,											// compareMask
9698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,											// writeMask
9708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,											// reference
9718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		},											// back
9728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		-1.0f,										// minDepthBounds
9738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		+1.0f,										// maxDepthBounds
9748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
9758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkViewport								viewport0				=
9768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
9778e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0.0f,										// x
9788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0.0f,										// y
9798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(float)renderSize.x(),						// width
9808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(float)renderSize.y(),						// height
9818e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0.0f,										// minDepth
9828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1.0f,										// maxDepth
9838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
9848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkRect2D									scissor0				=
9858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
9868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{ 0u, 0u, },								// offset
9878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{ renderSize.x(), renderSize.y() },			// extent
9888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
9898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineViewportStateCreateInfo			viewportParams			=
9908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
9918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
9928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
9938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineViewportStateCreateFlags)0,
9948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
9958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&viewport0,
9968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
9978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&scissor0
9988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
9998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineMultisampleStateCreateInfo		multisampleParams		=
10008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
10028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
10038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineMultisampleStateCreateFlags)0,
10048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_SAMPLE_COUNT_1_BIT,						// rasterizationSamples
10058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,									// sampleShadingEnable
10068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0.0f,										// minSampleShading
10078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(const VkSampleMask*)DE_NULL,				// sampleMask
10088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,									// alphaToCoverageEnable
10098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,									// alphaToOneEnable
10108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineRasterizationStateCreateInfo	rasterParams			=
10128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
10148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
10158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineRasterizationStateCreateFlags)0,
10163d8e6ee58a6f3a7701a3e6cdc4ba9fb14b162410Pyry Haulos		VK_FALSE,									// depthClampEnable
10178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,									// rasterizerDiscardEnable
10188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_POLYGON_MODE_FILL,						// polygonMode
10198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_CULL_MODE_NONE,							// cullMode
10208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FRONT_FACE_COUNTER_CLOCKWISE,			// frontFace
10218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,									// depthBiasEnable
10228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0.0f,										// depthBiasConstantFactor
10238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0.0f,										// depthBiasClamp
10248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0.0f,										// depthBiasSlopeFactor
10258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1.0f,										// lineWidth
10268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10278e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyParams		=
10288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
10308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
10318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineInputAssemblyStateCreateFlags)0,
10328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
10338e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_FALSE,									// primitiveRestartEnable
10348e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10358e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkVertexInputBindingDescription			vertexBinding0			=
10368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// binding
10388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(deUint32)sizeof(tcu::Vec4),				// stride
10398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_VERTEX_INPUT_RATE_VERTEX,				// inputRate
10408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkVertexInputAttributeDescription			vertexAttrib0			=
10428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// location
10448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// binding
10458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FORMAT_R32G32B32A32_SFLOAT,				// format
10468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// offset
10478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams	=
10498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
10518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
10528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineVertexInputStateCreateFlags)0,
10538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
10548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&vertexBinding0,
10558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
10568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&vertexAttrib0,
10578e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10588e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineColorBlendAttachmentState		attBlendParams0			=
10598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,									// blendEnable
10618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_BLEND_FACTOR_ONE,						// srcColorBlendFactor
10628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_BLEND_FACTOR_ZERO,						// dstColorBlendFactor
10638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_BLEND_OP_ADD,							// colorBlendOp
10648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_BLEND_FACTOR_ONE,						// srcAlphaBlendFactor
10658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_BLEND_FACTOR_ZERO,						// dstAlphaBlendFactor
10668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_BLEND_OP_ADD,							// alphaBlendOp
10678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VK_COLOR_COMPONENT_R_BIT|
10688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		 VK_COLOR_COMPONENT_G_BIT|
10698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		 VK_COLOR_COMPONENT_B_BIT|
10708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		 VK_COLOR_COMPONENT_A_BIT),					// colorWriteMask
10718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkPipelineColorBlendStateCreateInfo		blendParams				=
10738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
10758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
10768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineColorBlendStateCreateFlags)0,
10778e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_FALSE,									// logicOpEnable
10788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_LOGIC_OP_COPY,
10798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
10808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&attBlendParams0,
10818e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{ 0.0f, 0.0f, 0.0f, 0.0f },					// blendConstants[4]
10828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
10838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkGraphicsPipelineCreateInfo				pipelineParams			=
10848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
10858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
10868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
10878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkPipelineCreateFlags)0,
10888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(deUint32)DE_LENGTH_OF_ARRAY(shaderStageParams),
10898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		shaderStageParams,
10908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&vertexInputStateParams,
10918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&inputAssemblyParams,
10928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(const VkPipelineTessellationStateCreateInfo*)DE_NULL,
10938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&viewportParams,
10948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&rasterParams,
10958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&multisampleParams,
10968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&depthStencilParams,
10978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&blendParams,
10988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,
10998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		pipelineLayout,
11008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		renderPass,
11018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// subpass
11028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,									// basePipelineHandle
11038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0u,											// basePipelineIndex
11048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
11058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createGraphicsPipeline(vkd, device, (VkPipelineCache)0, &pipelineParams);
11078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
11088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11098e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkImageView> TriangleRenderer::createAttachmentView (const DeviceInterface&	vkd,
11108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														  const VkDevice			device,
11118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														  const VkImage				image,
11128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														  const VkFormat			format)
11138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
11148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkImageViewCreateInfo		viewParams	=
11158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
11168e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
11178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
11188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkImageViewCreateFlags)0,
11198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		image,
11208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_IMAGE_VIEW_TYPE_2D,
11218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		format,
11228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		vk::makeComponentMappingRGBA(),
11238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
11248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_IMAGE_ASPECT_COLOR_BIT,
11258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,						// baseMipLevel
11268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			1u,						// levelCount
11278e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			0u,						// baseArrayLayer
11288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			1u,						// layerCount
11298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		},
11308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
11318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createImageView(vkd, device, &viewParams);
11338e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
11348e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11358e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkFramebuffer> TriangleRenderer::createFramebuffer	(const DeviceInterface&		vkd,
11368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkDevice				device,
11378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkRenderPass			renderPass,
11388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const VkImageView			colorAttachment,
11398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos														 const UVec2&				renderSize)
11408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
11418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkFramebufferCreateInfo	framebufferParams	=
11428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
11438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
11448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
11458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkFramebufferCreateFlags)0,
11468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		renderPass,
11478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
11488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		&colorAttachment,
11498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		renderSize.x(),
11508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		renderSize.y(),
11518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,							// layers
11528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
11538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createFramebuffer(vkd, device, &framebufferParams);
11558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
11568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11578e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkBuffer> TriangleRenderer::createBuffer (const DeviceInterface&	vkd,
11588e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos											   VkDevice					device,
11598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos											   VkDeviceSize				size,
11608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos											   VkBufferUsageFlags		usage)
11618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
11628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkBufferCreateInfo	bufferParams	=
11638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
11648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
11658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
11668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkBufferCreateFlags)0,
11678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		size,
11688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		usage,
11698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_SHARING_MODE_EXCLUSIVE,
11708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		0,
11718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL
11728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
11738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createBuffer(vkd, device, &bufferParams);
11758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
11768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11778e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosTriangleRenderer::TriangleRenderer (const DeviceInterface&	vkd,
11788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									const VkDevice			device,
11798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									Allocator&				allocator,
11808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									const BinaryCollection&	binaryRegistry,
11818e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									const vector<VkImage>	swapchainImages,
11828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									const VkFormat			framebufferFormat,
11838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									const UVec2&			renderSize)
11848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	: m_vkd					(vkd)
11858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	, m_swapchainImages		(swapchainImages)
11868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	, m_renderSize			(renderSize)
11878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	, m_renderPass			(createRenderPass(vkd, device, framebufferFormat))
11888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	, m_pipelineLayout		(createPipelineLayout(vkd, device))
11898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	, m_pipeline			(createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
11908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	, m_vertexBuffer		(createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
11918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	, m_vertexBufferMemory	(allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
11928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos							 MemoryRequirement::HostVisible))
11938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
11948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	m_attachmentViews.resize(swapchainImages.size());
11958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	m_framebuffers.resize(swapchainImages.size());
11968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
11978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
11988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
11998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		m_attachmentViews[imageNdx]	= ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
12008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		m_framebuffers[imageNdx]	= FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
12018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	}
12028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	VK_CHECK(vkd.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
12048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
12068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		const VkMappedMemoryRange	memRange	=
12078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
12088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
12098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			DE_NULL,
12108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			m_vertexBufferMemory->getMemory(),
12118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			m_vertexBufferMemory->getOffset(),
12128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_WHOLE_SIZE
12138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		};
12148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		const tcu::Vec4				vertices[]	=
12158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
12168e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
12178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
12188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
12198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		};
12208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);
12218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		deMemcpy(m_vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
12238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_CHECK(vkd.flushMappedMemoryRanges(device, 1u, &memRange));
12248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	}
12258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
12268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12278e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosTriangleRenderer::~TriangleRenderer (void)
12288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
12298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
12308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosvoid TriangleRenderer::recordFrame (VkCommandBuffer	cmdBuffer,
12328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									deUint32		imageNdx,
12338e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									deUint32		frameNdx) const
12348e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
12358e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkFramebuffer	curFramebuffer	= **m_framebuffers[imageNdx];
12368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
12388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		const VkCommandBufferBeginInfo	cmdBufBeginParams	=
12398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
12408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
12418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			DE_NULL,
12428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			(VkCommandBufferUsageFlags)0,
12438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			(const VkCommandBufferInheritanceInfo*)DE_NULL,
12448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		};
12458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_CHECK(m_vkd.beginCommandBuffer(cmdBuffer, &cmdBufBeginParams));
12468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	}
12478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
12498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		const VkClearValue			clearValue		= makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f);
12508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		const VkRenderPassBeginInfo	passBeginParams	=
12518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
12528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
12538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			DE_NULL,
12548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			*m_renderPass,
12558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			curFramebuffer,
12568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			{
12578e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				{ 0, 0 },
12588e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
12598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			},													// renderArea
12608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			1u,													// clearValueCount
12618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			&clearValue,										// pClearValues
12628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		};
12638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		m_vkd.cmdBeginRenderPass(cmdBuffer, &passBeginParams, VK_SUBPASS_CONTENTS_INLINE);
12648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	}
12658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
12678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
12698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		const VkDeviceSize bindingOffset = 0;
12708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
12718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	}
12728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
12748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
12758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	m_vkd.cmdEndRenderPass(cmdBuffer);
12768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12778e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	VK_CHECK(m_vkd.endCommandBuffer(cmdBuffer));
12788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
12798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
12808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosvoid TriangleRenderer::getPrograms (SourceCollections& dst)
12818e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
12828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	dst.glslSources.add("tri-vert") << glu::VertexSource(
12838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"#version 310 es\n"
12848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"layout(location = 0) in highp vec4 a_position;\n"
12858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"layout(push_constant) uniform FrameData\n"
12868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"{\n"
12878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"    highp uint frameNdx;\n"
12888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"} frameData;\n"
12898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"void main (void)\n"
12908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"{\n"
12918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"    highp float angle = float(frameData.frameNdx) / 100.0;\n"
12928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"    highp float c     = cos(angle);\n"
12938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"    highp float s     = sin(angle);\n"
12948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"    highp mat4  t     = mat4( c, -s,  0,  0,\n"
12958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"                              s,  c,  0,  0,\n"
12968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"                              0,  0,  1,  0,\n"
12978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"                              0,  0,  0,  1);\n"
12988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"    gl_Position = t * a_position;\n"
12998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"}\n");
13008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	dst.glslSources.add("tri-frag") << glu::FragmentSource(
13018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"#version 310 es\n"
13028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"layout(location = 0) out lowp vec4 o_color;\n"
13038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		"void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
13048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
13058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulostypedef de::SharedPtr<Unique<VkCommandBuffer> >	CommandBufferSp;
13078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulostypedef de::SharedPtr<Unique<VkFence> >			FenceSp;
13088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulostypedef de::SharedPtr<Unique<VkSemaphore> >		SemaphoreSp;
13098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13108e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkFence> createFence (const DeviceInterface&	vkd,
13118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos						   const VkDevice			device)
13128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
13138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkFenceCreateInfo	fenceParams	=
13148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
13158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
13168e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
13178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkFenceCreateFlags)0,
13188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
13198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createFence(vkd, device, &fenceParams);
13208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
13218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosvector<FenceSp> createFences (const DeviceInterface&	vkd,
13238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos							  const VkDevice			device,
13248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos							  size_t					numFences)
13258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
13268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	vector<FenceSp> fences(numFences);
13278e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	for (size_t ndx = 0; ndx < numFences; ++ndx)
13298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		fences[ndx] = FenceSp(new Unique<VkFence>(createFence(vkd, device)));
13308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return fences;
13328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
13338e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13348e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkSemaphore> createSemaphore (const DeviceInterface&	vkd,
13358e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos								   const VkDevice			device)
13368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
13378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkSemaphoreCreateInfo	semaphoreParams	=
13388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
13398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
13408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
13418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		(VkSemaphoreCreateFlags)0,
13428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
13438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return vk::createSemaphore(vkd, device, &semaphoreParams);
13448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
13458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosvector<SemaphoreSp> createSemaphores (const DeviceInterface&	vkd,
13478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									  const VkDevice			device,
13488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									  size_t					numSemaphores)
13498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
13508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	vector<SemaphoreSp> semaphores(numSemaphores);
13518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	for (size_t ndx = 0; ndx < numSemaphores; ++ndx)
13538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		semaphores[ndx] = SemaphoreSp(new Unique<VkSemaphore>(createSemaphore(vkd, device)));
13548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return semaphores;
13568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
13578e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13588e1cce4ba720300676a239cb264795c9ea301cbcPyry HaulosMove<VkCommandPool> createCommandPool (const DeviceInterface&	vkd,
13598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									   const VkDevice			device,
13608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									   VkCommandPoolCreateFlags	flags,
13618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos									   deUint32					queueFamilyIndex)
13628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
13638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkCommandPoolCreateInfo	commandPoolParams	=
13648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
13658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
13668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
13678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		flags,
13688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		queueFamilyIndex
13698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
13708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return createCommandPool(vkd, device, &commandPoolParams);
13728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
13738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosvector<CommandBufferSp> allocateCommandBuffers (const DeviceInterface&		vkd,
13758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												const VkDevice				device,
13768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												const VkCommandPool			commandPool,
13778e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												const VkCommandBufferLevel	level,
13788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos												const size_t				numCommandBuffers)
13798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
13808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkCommandBufferAllocateInfo	allocInfo	=
13818e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
13828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
13838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		DE_NULL,
13848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		commandPool,
13858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		level,
13868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		1u,
13878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	};
13888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	vector<CommandBufferSp>				buffers		(numCommandBuffers);
13908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	for (size_t ndx = 0; ndx < numCommandBuffers; ++ndx)
13928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		buffers[ndx] = CommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(vkd, device, &allocInfo)));
13938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	return buffers;
13958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
13968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
13978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulostcu::TestStatus basicRenderTest (Context& context, Type wsiType)
13988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
13998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const tcu::UVec2				desiredSize					(256, 256);
14008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const InstanceHelper			instHelper					(context, wsiType);
14018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const NativeObjects				native						(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
14028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkSurfaceKHR>		surface						(createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
14038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const DeviceHelper				devHelper					(context, instHelper.vki, *instHelper.instance, *surface);
14048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const DeviceInterface&			vkd							= devHelper.vkd;
14058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkDevice					device						= *devHelper.device;
1406f31905d3c4bcdd5978d7dc21ddf2723a89454a3bPyry Haulos	SimpleAllocator					allocator					(vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
14078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const VkSwapchainCreateInfoKHR	swapchainInfo				= getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
14088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkSwapchainKHR>	swapchain					(createSwapchainKHR(vkd, device, &swapchainInfo));
14098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const vector<VkImage>			swapchainImages				= getSwapchainImages(vkd, device, *swapchain);
14108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14118e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const TriangleRenderer			renderer					(vkd,
1412f31905d3c4bcdd5978d7dc21ddf2723a89454a3bPyry Haulos																 device,
1413f31905d3c4bcdd5978d7dc21ddf2723a89454a3bPyry Haulos																 allocator,
1414f31905d3c4bcdd5978d7dc21ddf2723a89454a3bPyry Haulos																 context.getBinaryCollection(),
1415f31905d3c4bcdd5978d7dc21ddf2723a89454a3bPyry Haulos																 swapchainImages,
1416f31905d3c4bcdd5978d7dc21ddf2723a89454a3bPyry Haulos																 swapchainInfo.imageFormat,
1417f31905d3c4bcdd5978d7dc21ddf2723a89454a3bPyry Haulos																 tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
14188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const Unique<VkCommandPool>		commandPool					(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
14208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const size_t					maxQueuedFrames				= swapchainImages.size()*2;
14228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// We need to keep hold of fences from vkAcquireNextImageKHR to actually
14248e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// limit number of frames we allow to be queued.
14258e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const vector<FenceSp>			imageReadyFences			(createFences(vkd, device, maxQueuedFrames));
14268e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14278e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to pass
14288e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// the semaphore in same time as the fence we use to meter rendering.
14298e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const vector<SemaphoreSp>		imageReadySemaphores		(createSemaphores(vkd, device, maxQueuedFrames+1));
14308e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14318e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// For rest we simply need maxQueuedFrames as we will wait for image
14328e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// from frameNdx-maxQueuedFrames to become available to us, guaranteeing that
14338e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	// previous uses must have completed.
14348e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const vector<SemaphoreSp>		renderingCompleteSemaphores	(createSemaphores(vkd, device, maxQueuedFrames));
14358e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	const vector<CommandBufferSp>	commandBuffers				(allocateCommandBuffers(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));
14368e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14378e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	try
14388e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
14398e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		const deUint32	numFramesToRender	= 60*10;
14408e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14418e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
14428e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		{
14438e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			const VkFence		imageReadyFence		= **imageReadyFences[frameNdx%imageReadyFences.size()];
14448e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
14458e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			deUint32			imageNdx			= ~0u;
14468e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14478e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			if (frameNdx >= maxQueuedFrames)
14488e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
14498e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14508e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));
14518e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14528e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			{
14538e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				const VkResult	acquireResult	= vkd.acquireNextImageKHR(device,
14548e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																		  *swapchain,
14558e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																		  std::numeric_limits<deUint64>::max(),
14568e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																		  imageReadySemaphore,
14578e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																		  imageReadyFence,
14588e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos																		  &imageNdx);
14598e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14608e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				if (acquireResult == VK_SUBOPTIMAL_KHR)
14618e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
14628e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				else
14638e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					VK_CHECK(acquireResult);
14648e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			}
14658e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14668e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			TCU_CHECK((size_t)imageNdx < swapchainImages.size());
14678e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14688e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			{
14698e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				const VkSemaphore			renderingCompleteSemaphore	= **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
14708e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				const VkCommandBuffer		commandBuffer				= **commandBuffers[frameNdx%commandBuffers.size()];
14718e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				const VkPipelineStageFlags	waitDstStage				= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
14728e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				const VkSubmitInfo			submitInfo					=
14738e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				{
14748e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					VK_STRUCTURE_TYPE_SUBMIT_INFO,
14758e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					DE_NULL,
14768e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					1u,
14778e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					&imageReadySemaphore,
14788e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					&waitDstStage,
14798e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					1u,
14808e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					&commandBuffer,
14818e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					1u,
14828e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					&renderingCompleteSemaphore
14838e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				};
14848e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				const VkPresentInfoKHR		presentInfo					=
14858e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				{
14868e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
14878e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					DE_NULL,
14888e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					1u,
14898e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					&renderingCompleteSemaphore,
14908e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					1u,
14918e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					&*swapchain,
14928e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					&imageNdx,
14938e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos					(VkResult*)DE_NULL
14948e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				};
14958e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
14968e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
14978e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, (VkFence)0));
14988e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos				VK_CHECK(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
14998e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos			}
15008e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		}
15018e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
15028e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		VK_CHECK(vkd.deviceWaitIdle(device));
15038e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	}
15048e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	catch (...)
15058e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	{
15068e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		// Make sure device is idle before destroying resources
15078e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		vkd.deviceWaitIdle(device);
15088e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos		throw;
15098e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	}
15108e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
15114d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	return tcu::TestStatus::pass("Rendering tests succeeded");
15128e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
15138e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
151474a8338764495b470180da1f4c587c3401373314Jesse Hallvector<tcu::UVec2> getSwapchainSizeSequence (const VkSurfaceCapabilitiesKHR& capabilities, const tcu::UVec2& defaultSize)
151574a8338764495b470180da1f4c587c3401373314Jesse Hall{
151674a8338764495b470180da1f4c587c3401373314Jesse Hall	vector<tcu::UVec2> sizes(3);
151774a8338764495b470180da1f4c587c3401373314Jesse Hall	sizes[0] = defaultSize / 2u;
151874a8338764495b470180da1f4c587c3401373314Jesse Hall	sizes[1] = defaultSize;
151974a8338764495b470180da1f4c587c3401373314Jesse Hall	sizes[2] = defaultSize * 2u;
152074a8338764495b470180da1f4c587c3401373314Jesse Hall
152174a8338764495b470180da1f4c587c3401373314Jesse Hall	for (deUint32 i = 0; i < sizes.size(); ++i)
152274a8338764495b470180da1f4c587c3401373314Jesse Hall	{
152374a8338764495b470180da1f4c587c3401373314Jesse Hall		sizes[i].x() = de::clamp(sizes[i].x(), capabilities.minImageExtent.width,  capabilities.maxImageExtent.width);
152474a8338764495b470180da1f4c587c3401373314Jesse Hall		sizes[i].y() = de::clamp(sizes[i].y(), capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
152574a8338764495b470180da1f4c587c3401373314Jesse Hall	}
152674a8338764495b470180da1f4c587c3401373314Jesse Hall
152774a8338764495b470180da1f4c587c3401373314Jesse Hall	return sizes;
152874a8338764495b470180da1f4c587c3401373314Jesse Hall}
152974a8338764495b470180da1f4c587c3401373314Jesse Hall
153074a8338764495b470180da1f4c587c3401373314Jesse Halltcu::TestStatus resizeSwapchainTest (Context& context, Type wsiType)
153174a8338764495b470180da1f4c587c3401373314Jesse Hall{
153274a8338764495b470180da1f4c587c3401373314Jesse Hall	const tcu::UVec2				desiredSize			(256, 256);
153374a8338764495b470180da1f4c587c3401373314Jesse Hall	const InstanceHelper			instHelper			(context, wsiType);
153474a8338764495b470180da1f4c587c3401373314Jesse Hall	const NativeObjects				native				(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
153574a8338764495b470180da1f4c587c3401373314Jesse Hall	const Unique<VkSurfaceKHR>		surface				(createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
153674a8338764495b470180da1f4c587c3401373314Jesse Hall	const DeviceHelper				devHelper			(context, instHelper.vki, *instHelper.instance, *surface);
153774a8338764495b470180da1f4c587c3401373314Jesse Hall	const PlatformProperties&		platformProperties	= getPlatformProperties(wsiType);
153874a8338764495b470180da1f4c587c3401373314Jesse Hall	const VkSurfaceCapabilitiesKHR	capabilities		= getPhysicalDeviceSurfaceCapabilities(instHelper.vki, devHelper.physicalDevice, *surface);
153974a8338764495b470180da1f4c587c3401373314Jesse Hall	const DeviceInterface&			vkd					= devHelper.vkd;
154074a8338764495b470180da1f4c587c3401373314Jesse Hall	const VkDevice					device				= *devHelper.device;
154174a8338764495b470180da1f4c587c3401373314Jesse Hall	SimpleAllocator					allocator			(vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
154274a8338764495b470180da1f4c587c3401373314Jesse Hall	vector<tcu::UVec2>				sizes				= getSwapchainSizeSequence(capabilities, desiredSize);
154374a8338764495b470180da1f4c587c3401373314Jesse Hall	Move<VkSwapchainKHR>			prevSwapchain;
154474a8338764495b470180da1f4c587c3401373314Jesse Hall
154574a8338764495b470180da1f4c587c3401373314Jesse Hall	DE_ASSERT(platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE);
15469533257d111cdcdae77cc67caf39bc0c9bcfb7b6Pyry Haulos	DE_UNREF(platformProperties);
154774a8338764495b470180da1f4c587c3401373314Jesse Hall
154874a8338764495b470180da1f4c587c3401373314Jesse Hall	for (deUint32 sizeNdx = 0; sizeNdx < sizes.size(); ++sizeNdx)
154974a8338764495b470180da1f4c587c3401373314Jesse Hall	{
155074a8338764495b470180da1f4c587c3401373314Jesse Hall		// \todo [2016-05-30 jesse] This test currently waits for idle and
155174a8338764495b470180da1f4c587c3401373314Jesse Hall		// recreates way more than necessary when recreating the swapchain. Make
155274a8338764495b470180da1f4c587c3401373314Jesse Hall		// it match expected real app behavior better by smoothly switching from
155374a8338764495b470180da1f4c587c3401373314Jesse Hall		// old to new swapchain. Once that is done, it will also be possible to
155474a8338764495b470180da1f4c587c3401373314Jesse Hall		// test creating a new swapchain while images from the previous one are
155574a8338764495b470180da1f4c587c3401373314Jesse Hall		// still acquired.
155674a8338764495b470180da1f4c587c3401373314Jesse Hall
155774a8338764495b470180da1f4c587c3401373314Jesse Hall		VkSwapchainCreateInfoKHR		swapchainInfo				= getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, sizes[sizeNdx], 2);
155874a8338764495b470180da1f4c587c3401373314Jesse Hall		swapchainInfo.oldSwapchain = *prevSwapchain;
155974a8338764495b470180da1f4c587c3401373314Jesse Hall
156074a8338764495b470180da1f4c587c3401373314Jesse Hall		Move<VkSwapchainKHR>			swapchain					(createSwapchainKHR(vkd, device, &swapchainInfo));
156174a8338764495b470180da1f4c587c3401373314Jesse Hall		const vector<VkImage>			swapchainImages				= getSwapchainImages(vkd, device, *swapchain);
156274a8338764495b470180da1f4c587c3401373314Jesse Hall		const TriangleRenderer			renderer					(vkd,
156374a8338764495b470180da1f4c587c3401373314Jesse Hall																	device,
156474a8338764495b470180da1f4c587c3401373314Jesse Hall																	allocator,
156574a8338764495b470180da1f4c587c3401373314Jesse Hall																	context.getBinaryCollection(),
156674a8338764495b470180da1f4c587c3401373314Jesse Hall																	swapchainImages,
156774a8338764495b470180da1f4c587c3401373314Jesse Hall																	swapchainInfo.imageFormat,
156874a8338764495b470180da1f4c587c3401373314Jesse Hall																	tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
156974a8338764495b470180da1f4c587c3401373314Jesse Hall		const Unique<VkCommandPool>		commandPool					(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
157074a8338764495b470180da1f4c587c3401373314Jesse Hall		const size_t					maxQueuedFrames				= swapchainImages.size()*2;
157174a8338764495b470180da1f4c587c3401373314Jesse Hall
157274a8338764495b470180da1f4c587c3401373314Jesse Hall		// We need to keep hold of fences from vkAcquireNextImageKHR to actually
157374a8338764495b470180da1f4c587c3401373314Jesse Hall		// limit number of frames we allow to be queued.
157474a8338764495b470180da1f4c587c3401373314Jesse Hall		const vector<FenceSp>			imageReadyFences			(createFences(vkd, device, maxQueuedFrames));
157574a8338764495b470180da1f4c587c3401373314Jesse Hall
157674a8338764495b470180da1f4c587c3401373314Jesse Hall		// We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to pass
157774a8338764495b470180da1f4c587c3401373314Jesse Hall		// the semaphore in same time as the fence we use to meter rendering.
157874a8338764495b470180da1f4c587c3401373314Jesse Hall		const vector<SemaphoreSp>		imageReadySemaphores		(createSemaphores(vkd, device, maxQueuedFrames+1));
157974a8338764495b470180da1f4c587c3401373314Jesse Hall
158074a8338764495b470180da1f4c587c3401373314Jesse Hall		// For rest we simply need maxQueuedFrames as we will wait for image
158174a8338764495b470180da1f4c587c3401373314Jesse Hall		// from frameNdx-maxQueuedFrames to become available to us, guaranteeing that
158274a8338764495b470180da1f4c587c3401373314Jesse Hall		// previous uses must have completed.
158374a8338764495b470180da1f4c587c3401373314Jesse Hall		const vector<SemaphoreSp>		renderingCompleteSemaphores	(createSemaphores(vkd, device, maxQueuedFrames));
158474a8338764495b470180da1f4c587c3401373314Jesse Hall		const vector<CommandBufferSp>	commandBuffers				(allocateCommandBuffers(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));
158574a8338764495b470180da1f4c587c3401373314Jesse Hall
158674a8338764495b470180da1f4c587c3401373314Jesse Hall		try
158774a8338764495b470180da1f4c587c3401373314Jesse Hall		{
158874a8338764495b470180da1f4c587c3401373314Jesse Hall			const deUint32	numFramesToRender	= 60;
158974a8338764495b470180da1f4c587c3401373314Jesse Hall
159074a8338764495b470180da1f4c587c3401373314Jesse Hall			for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
159174a8338764495b470180da1f4c587c3401373314Jesse Hall			{
159274a8338764495b470180da1f4c587c3401373314Jesse Hall				const VkFence		imageReadyFence		= **imageReadyFences[frameNdx%imageReadyFences.size()];
159374a8338764495b470180da1f4c587c3401373314Jesse Hall				const VkSemaphore	imageReadySemaphore	= **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
159474a8338764495b470180da1f4c587c3401373314Jesse Hall				deUint32			imageNdx			= ~0u;
159574a8338764495b470180da1f4c587c3401373314Jesse Hall
159674a8338764495b470180da1f4c587c3401373314Jesse Hall				if (frameNdx >= maxQueuedFrames)
159774a8338764495b470180da1f4c587c3401373314Jesse Hall					VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
159874a8338764495b470180da1f4c587c3401373314Jesse Hall
159974a8338764495b470180da1f4c587c3401373314Jesse Hall				VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));
160074a8338764495b470180da1f4c587c3401373314Jesse Hall
160174a8338764495b470180da1f4c587c3401373314Jesse Hall				{
160274a8338764495b470180da1f4c587c3401373314Jesse Hall					const VkResult	acquireResult	= vkd.acquireNextImageKHR(device,
160374a8338764495b470180da1f4c587c3401373314Jesse Hall																			  *swapchain,
160474a8338764495b470180da1f4c587c3401373314Jesse Hall																			  std::numeric_limits<deUint64>::max(),
160574a8338764495b470180da1f4c587c3401373314Jesse Hall																			  imageReadySemaphore,
160674a8338764495b470180da1f4c587c3401373314Jesse Hall																			  imageReadyFence,
160774a8338764495b470180da1f4c587c3401373314Jesse Hall																			  &imageNdx);
160874a8338764495b470180da1f4c587c3401373314Jesse Hall
160974a8338764495b470180da1f4c587c3401373314Jesse Hall					if (acquireResult == VK_SUBOPTIMAL_KHR)
161074a8338764495b470180da1f4c587c3401373314Jesse Hall						context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
161174a8338764495b470180da1f4c587c3401373314Jesse Hall					else
161274a8338764495b470180da1f4c587c3401373314Jesse Hall						VK_CHECK(acquireResult);
161374a8338764495b470180da1f4c587c3401373314Jesse Hall				}
161474a8338764495b470180da1f4c587c3401373314Jesse Hall
161574a8338764495b470180da1f4c587c3401373314Jesse Hall				TCU_CHECK((size_t)imageNdx < swapchainImages.size());
161674a8338764495b470180da1f4c587c3401373314Jesse Hall
161774a8338764495b470180da1f4c587c3401373314Jesse Hall				{
161874a8338764495b470180da1f4c587c3401373314Jesse Hall					const VkSemaphore			renderingCompleteSemaphore	= **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
161974a8338764495b470180da1f4c587c3401373314Jesse Hall					const VkCommandBuffer		commandBuffer				= **commandBuffers[frameNdx%commandBuffers.size()];
162074a8338764495b470180da1f4c587c3401373314Jesse Hall					const VkPipelineStageFlags	waitDstStage				= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
162174a8338764495b470180da1f4c587c3401373314Jesse Hall					const VkSubmitInfo			submitInfo					=
162274a8338764495b470180da1f4c587c3401373314Jesse Hall					{
162374a8338764495b470180da1f4c587c3401373314Jesse Hall						VK_STRUCTURE_TYPE_SUBMIT_INFO,
162474a8338764495b470180da1f4c587c3401373314Jesse Hall						DE_NULL,
162574a8338764495b470180da1f4c587c3401373314Jesse Hall						1u,
162674a8338764495b470180da1f4c587c3401373314Jesse Hall						&imageReadySemaphore,
162774a8338764495b470180da1f4c587c3401373314Jesse Hall						&waitDstStage,
162874a8338764495b470180da1f4c587c3401373314Jesse Hall						1u,
162974a8338764495b470180da1f4c587c3401373314Jesse Hall						&commandBuffer,
163074a8338764495b470180da1f4c587c3401373314Jesse Hall						1u,
163174a8338764495b470180da1f4c587c3401373314Jesse Hall						&renderingCompleteSemaphore
163274a8338764495b470180da1f4c587c3401373314Jesse Hall					};
163374a8338764495b470180da1f4c587c3401373314Jesse Hall					const VkPresentInfoKHR		presentInfo					=
163474a8338764495b470180da1f4c587c3401373314Jesse Hall					{
163574a8338764495b470180da1f4c587c3401373314Jesse Hall						VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
163674a8338764495b470180da1f4c587c3401373314Jesse Hall						DE_NULL,
163774a8338764495b470180da1f4c587c3401373314Jesse Hall						1u,
163874a8338764495b470180da1f4c587c3401373314Jesse Hall						&renderingCompleteSemaphore,
163974a8338764495b470180da1f4c587c3401373314Jesse Hall						1u,
164074a8338764495b470180da1f4c587c3401373314Jesse Hall						&*swapchain,
164174a8338764495b470180da1f4c587c3401373314Jesse Hall						&imageNdx,
164274a8338764495b470180da1f4c587c3401373314Jesse Hall						(VkResult*)DE_NULL
164374a8338764495b470180da1f4c587c3401373314Jesse Hall					};
164474a8338764495b470180da1f4c587c3401373314Jesse Hall
164574a8338764495b470180da1f4c587c3401373314Jesse Hall					renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
164674a8338764495b470180da1f4c587c3401373314Jesse Hall					VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, (VkFence)0));
164774a8338764495b470180da1f4c587c3401373314Jesse Hall					VK_CHECK(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
164874a8338764495b470180da1f4c587c3401373314Jesse Hall				}
164974a8338764495b470180da1f4c587c3401373314Jesse Hall			}
165074a8338764495b470180da1f4c587c3401373314Jesse Hall
165174a8338764495b470180da1f4c587c3401373314Jesse Hall			VK_CHECK(vkd.deviceWaitIdle(device));
165274a8338764495b470180da1f4c587c3401373314Jesse Hall
165374a8338764495b470180da1f4c587c3401373314Jesse Hall			prevSwapchain = swapchain;
165474a8338764495b470180da1f4c587c3401373314Jesse Hall		}
165574a8338764495b470180da1f4c587c3401373314Jesse Hall		catch (...)
165674a8338764495b470180da1f4c587c3401373314Jesse Hall		{
165774a8338764495b470180da1f4c587c3401373314Jesse Hall			// Make sure device is idle before destroying resources
165874a8338764495b470180da1f4c587c3401373314Jesse Hall			vkd.deviceWaitIdle(device);
165974a8338764495b470180da1f4c587c3401373314Jesse Hall			throw;
166074a8338764495b470180da1f4c587c3401373314Jesse Hall		}
166174a8338764495b470180da1f4c587c3401373314Jesse Hall	}
166274a8338764495b470180da1f4c587c3401373314Jesse Hall
16634d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	return tcu::TestStatus::pass("Resizing tests succeeded");
16644d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski}
16654d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski
16664d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowskitcu::TestStatus getImagesIncompleteResultTest (Context& context, Type wsiType)
16674d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski{
16684d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const tcu::UVec2				desiredSize		(256, 256);
16694d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const InstanceHelper			instHelper		(context, wsiType);
16704d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const NativeObjects				native			(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
16714d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const Unique<VkSurfaceKHR>		surface			(createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
16724d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const DeviceHelper				devHelper		(context, instHelper.vki, *instHelper.instance, *surface);
16734d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const VkSwapchainCreateInfoKHR	swapchainInfo	= getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, *surface, desiredSize, 2);
16744d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const Unique<VkSwapchainKHR>	swapchain		(createSwapchainKHR(devHelper.vkd, *devHelper.device, &swapchainInfo));
16754d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski
16764d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	vector<VkImage>		swapchainImages	= getSwapchainImages(devHelper.vkd, *devHelper.device, *swapchain);
16774d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski
16784d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	ValidateQueryBits::fillBits(swapchainImages.begin(), swapchainImages.end());
16794d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski
16804d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const deUint32		usedCount		= static_cast<deUint32>(swapchainImages.size() / 2);
16814d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	deUint32			count			= usedCount;
16824d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	const VkResult		result			= devHelper.vkd.getSwapchainImagesKHR(*devHelper.device, *swapchain, &count, &swapchainImages[0]);
16834d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski
16844d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	if (count != usedCount || result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(swapchainImages.begin() + count, swapchainImages.end()))
16854d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski		return tcu::TestStatus::fail("Get swapchain images didn't return VK_INCOMPLETE");
16864d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	else
16874d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski		return tcu::TestStatus::pass("Get swapchain images tests succeeded");
168874a8338764495b470180da1f4c587c3401373314Jesse Hall}
168974a8338764495b470180da1f4c587c3401373314Jesse Hall
1690310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowskitcu::TestStatus destroyNullHandleSwapchainTest (Context& context, Type wsiType)
1691310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski{
1692310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	const InstanceHelper		instHelper	(context, wsiType);
1693310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	const NativeObjects			native		(context, instHelper.supportedExtensions, wsiType);
1694310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	const Unique<VkSurfaceKHR>	surface		(createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
1695310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	const DeviceHelper			devHelper	(context, instHelper.vki, *instHelper.instance, *surface);
1696310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	const VkSwapchainKHR		nullHandle	= DE_NULL;
1697310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski
1698310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	// Default allocator
1699310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	devHelper.vkd.destroySwapchainKHR(*devHelper.device, nullHandle, DE_NULL);
1700310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski
1701310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	// Custom allocator
1702310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	{
1703310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski		AllocationCallbackRecorder	recordingAllocator	(getSystemAllocator(), 1u);
1704310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski
1705310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski		devHelper.vkd.destroySwapchainKHR(*devHelper.device, nullHandle, recordingAllocator.getCallbacks());
1706310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski
1707310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski		if (recordingAllocator.getNumRecords() != 0u)
1708310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski			return tcu::TestStatus::fail("Implementation allocated/freed the memory");
1709310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	}
1710310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski
1711310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	return tcu::TestStatus::pass("Destroying a VK_NULL_HANDLE surface has no effect");
1712310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski}
1713310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski
17148e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosvoid getBasicRenderPrograms (SourceCollections& dst, Type)
17158e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
17168e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	TriangleRenderer::getPrograms(dst);
17178e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
17188e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
17198e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulosvoid populateRenderGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
17208e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos{
17218e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos	addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Test", getBasicRenderPrograms, basicRenderTest, wsiType);
17228e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos}
17238e1cce4ba720300676a239cb264795c9ea301cbcPyry Haulos
17244d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowskivoid populateGetImagesGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
17254d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski{
17264d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	addFunctionCase(testGroup, "incomplete", "Test VK_INCOMPLETE return code", getImagesIncompleteResultTest, wsiType);
17274d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski}
17284d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski
172974a8338764495b470180da1f4c587c3401373314Jesse Hallvoid populateModifyGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
173074a8338764495b470180da1f4c587c3401373314Jesse Hall{
173174a8338764495b470180da1f4c587c3401373314Jesse Hall	const PlatformProperties&	platformProperties	= getPlatformProperties(wsiType);
173274a8338764495b470180da1f4c587c3401373314Jesse Hall
173374a8338764495b470180da1f4c587c3401373314Jesse Hall	if (platformProperties.swapchainExtent != PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE)
173474a8338764495b470180da1f4c587c3401373314Jesse Hall	{
173574a8338764495b470180da1f4c587c3401373314Jesse Hall		addFunctionCaseWithPrograms(testGroup, "resize", "Resize Swapchain Test", getBasicRenderPrograms, resizeSwapchainTest, wsiType);
173674a8338764495b470180da1f4c587c3401373314Jesse Hall	}
173774a8338764495b470180da1f4c587c3401373314Jesse Hall
173874a8338764495b470180da1f4c587c3401373314Jesse Hall	// \todo [2016-05-30 jesse] Add tests for modifying preTransform, compositeAlpha, presentMode
173974a8338764495b470180da1f4c587c3401373314Jesse Hall}
174074a8338764495b470180da1f4c587c3401373314Jesse Hall
1741310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowskivoid populateDestroyGroup (tcu::TestCaseGroup* testGroup, Type wsiType)
1742310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski{
1743310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	addFunctionCase(testGroup, "null_handle", "Destroying a VK_NULL_HANDLE swapchain", destroyNullHandleSwapchainTest, wsiType);
1744310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski}
1745310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski
174688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos} // anonymous
174788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
174888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulosvoid createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
174988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos{
17507734f52e21c826b08737e08aff04e479cd7fc362Mika Isojärvi	addTestGroup(testGroup, "create",			"Create VkSwapchain with various parameters",					populateSwapchainGroup,		GroupParameters(wsiType, createSwapchainTest));
17512beac9057d9113ac306632d819ded852691a6842Pyry Haulos	addTestGroup(testGroup, "simulate_oom",		"Simulate OOM using callbacks during swapchain construction",	populateSwapchainGroup,		GroupParameters(wsiType, createSwapchainSimulateOOMTest));
17527734f52e21c826b08737e08aff04e479cd7fc362Mika Isojärvi	addTestGroup(testGroup, "render",			"Rendering Tests",												populateRenderGroup,		wsiType);
175374a8338764495b470180da1f4c587c3401373314Jesse Hall	addTestGroup(testGroup, "modify",			"Modify VkSwapchain",											populateModifyGroup,		wsiType);
1754310579ce7bb07adb316e5ba949a69d38c9001389Maciej Jesionowski	addTestGroup(testGroup, "destroy",			"Destroy VkSwapchain",											populateDestroyGroup,		wsiType);
17554d2a7c4bb5ae834b4eb17bc5e5218ccf0d607736Maciej Jesionowski	addTestGroup(testGroup, "get_images",		"Get swapchain images",											populateGetImagesGroup,		wsiType);
175688ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos}
175788ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos
175888ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos} // wsi
175988ae848c85a938be0cb7c82a879bb66a495d0c7bPyry Haulos} // vkt
1760