/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Device Initialization Tests
 *//*--------------------------------------------------------------------*/

#include "vktApiDeviceInitializationTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktCustomInstancesDevices.hpp"

#include "vkDefs.hpp"
#include "vkPlatform.hpp"
#include "vkStrUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkApiVersion.hpp"
#include "vkAllocationCallbackUtil.hpp"
#include "vkDeviceFeatures.hpp"

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

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"

#include <vector>
#include <set>

namespace vkt
{
namespace api
{

namespace
{

using namespace vk;
using namespace std;
using std::vector;
using tcu::TestLog;

tcu::TestStatus createInstanceTest (Context& context)
{
	tcu::TestLog&				log						= context.getTestContext().getLog();
	tcu::ResultCollector		resultCollector			(log);
	const char*					appNames[]				= { "appName", DE_NULL, "",  "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" };
	const char*					engineNames[]			= { "engineName", DE_NULL, "",  "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" };
	const int					patchNumbers[]			= { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 };
	const deUint32				appVersions[]			= { 0, 1, (deUint32)-1 };
	const deUint32				engineVersions[]		= { 0, 1, (deUint32)-1 };
	const deUint32				apiVersion				= context.getUsedApiVersion();
	vector<VkApplicationInfo>	appInfos;

	// test over appName
	for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++)
	{
		const VkApplicationInfo appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
			DE_NULL,								// const void*					pNext;
			appNames[appNameNdx],					// const char*					pAppName;
			0u,										// deUint32						appVersion;
			"engineName",							// const char*					pEngineName;
			0u,										// deUint32						engineVersion;
			apiVersion,								// deUint32						apiVersion;
		};

		appInfos.push_back(appInfo);
	}

	// test over engineName
	for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++)
	{
		const VkApplicationInfo appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
			DE_NULL,								// const void*					pNext;
			"appName",								// const char*					pAppName;
			0u,										// deUint32						appVersion;
			engineNames[engineNameNdx],				// const char*					pEngineName;
			0u,										// deUint32						engineVersion;
			apiVersion,								// deUint32						apiVersion;
		};

		appInfos.push_back(appInfo);
	}

	// test over appVersion
	for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++)
	{
		const VkApplicationInfo appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
			DE_NULL,								// const void*					pNext;
			"appName",								// const char*					pAppName;
			appVersions[appVersionNdx],				// deUint32						appVersion;
			"engineName",							// const char*					pEngineName;
			0u,										// deUint32						engineVersion;
			apiVersion,								// deUint32						apiVersion;
		};

		appInfos.push_back(appInfo);
	}

	// test over engineVersion
	for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++)
	{
		const VkApplicationInfo appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
			DE_NULL,								// const void*					pNext;
			"appName",								// const char*					pAppName;
			0u,										// deUint32						appVersion;
			"engineName",							// const char*					pEngineName;
			engineVersions[engineVersionNdx],		// deUint32						engineVersion;
			apiVersion,								// deUint32						apiVersion;
		};

		appInfos.push_back(appInfo);
	}
	const deUint32	manjorNum	= unpackVersion(apiVersion).majorNum;
	const deUint32	minorNum	= unpackVersion(apiVersion).minorNum;

	// patch component of api version checking (should be ignored by implementation)
	for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++)
	{
		const VkApplicationInfo appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,									// VkStructureType				sType;
			DE_NULL,															// const void*					pNext;
			"appName",															// const char*					pAppName;
			0u,																	// deUint32						appVersion;
			"engineName",														// const char*					pEngineName;
			0u,																	// deUint32						engineVersion;
			VK_MAKE_VERSION(manjorNum, minorNum, patchNumbers[patchVersion]),	// deUint32						apiVersion;
		};

		appInfos.push_back(appInfo);
	}

	// test when apiVersion is 0
	{
		const VkApplicationInfo appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
			DE_NULL,								// const void*					pNext;
			"appName",								// const char*					pAppName;
			0u,										// deUint32						appVersion;
			"engineName",							// const char*					pEngineName;
			0u,										// deUint32						engineVersion;
			0u,										// deUint32						apiVersion;
		};

		appInfos.push_back(appInfo);
	}

	// run the tests!
	for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx)
	{
		const VkApplicationInfo&		appInfo					= appInfos[appInfoNdx];
		const VkInstanceCreateInfo		instanceCreateInfo		=
		{
			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
			DE_NULL,								// const void*					pNext;
			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
			&appInfo,								// const VkApplicationInfo*		pAppInfo;
			0u,										// deUint32						layerCount;
			DE_NULL,								// const char*const*			ppEnabledLayernames;
			0u,										// deUint32						extensionCount;
			DE_NULL,								// const char*const*			ppEnabledExtensionNames;
		};

		log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage;

		try
		{
			CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
			log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
		}
		catch (const vk::Error& err)
		{
			resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
		}
	}

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

tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context)
{
	tcu::TestLog&				log						= context.getTestContext().getLog();
	tcu::ResultCollector		resultCollector			(log);
	const PlatformInterface&	platformInterface		= context.getPlatformInterface();

	deUint32					instanceApiVersion		= 0u;
	platformInterface.enumerateInstanceVersion(&instanceApiVersion);

	const ApiVersion			apiVersion				= unpackVersion(instanceApiVersion);

	const deUint32				invalidMajorVersion		= (1 << 10) - 1;
	const deUint32				invalidMinorVersion		= (1 << 10) - 1;
	vector<ApiVersion>			invalidApiVersions;

	invalidApiVersions.push_back(ApiVersion(invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
	invalidApiVersions.push_back(ApiVersion(apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum));

	for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++)
	{
		const VkApplicationInfo appInfo					=
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,			// VkStructureType				sType;
			DE_NULL,									// const void*					pNext;
			"appName",									// const char*					pAppName;
			0u,											// deUint32						appVersion;
			"engineName",								// const char*					pEngineName;
			0u,											// deUint32						engineVersion;
			pack(invalidApiVersions[apiVersionNdx]),	// deUint32						apiVersion;
		};
		const VkInstanceCreateInfo	instanceCreateInfo	=
		{
			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,		// VkStructureType				sType;
			DE_NULL,									// const void*					pNext;
			(VkInstanceCreateFlags)0u,					// VkInstanceCreateFlags		flags;
			&appInfo,									// const VkApplicationInfo*		pAppInfo;
			0u,											// deUint32						layerCount;
			DE_NULL,									// const char*const*			ppEnabledLayernames;
			0u,											// deUint32						extensionCount;
			DE_NULL,									// const char*const*			ppEnabledExtensionNames;
		};

		log << TestLog::Message
			<< "API version reported by enumerateInstanceVersion: " << apiVersion
			<< ", api version used to create instance: " << invalidApiVersions[apiVersionNdx]
			<< TestLog::EndMessage;

		{
			UncheckedInstance	instance;
			const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);

			if (apiVersion.majorNum == 1 && apiVersion.minorNum == 0)
			{
				if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
				{
					TCU_CHECK(!static_cast<bool>(instance));
					log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
				}
				else
					resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
			}
			else if (apiVersion.majorNum == 1 && apiVersion.minorNum >= 1)
			{
				if (result == VK_SUCCESS)
				{
					TCU_CHECK(static_cast<bool>(instance));
					log << TestLog::Message << "Pass, instance creation with nonstandard apiVersion succeeds for Vulkan 1.1" << TestLog::EndMessage;
				}
				else if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
				{
					resultCollector.fail("Fail, In Vulkan 1.1 instance creation must not return VK_ERROR_INCOMPATIBLE_DRIVER.");
				}
				else
				{
					std::ostringstream message;
					message << "Fail, createInstance failed with " << result;
					resultCollector.fail(message.str().c_str());
				}
			}
		}
	}

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

tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context)
{
	tcu::TestLog&				log						= context.getTestContext().getLog();
	tcu::ResultCollector		resultCollector			(log);

	const VkInstanceCreateInfo	instanceCreateInfo		=
	{
		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
		DE_NULL,								// const void*					pNext;
		(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
		DE_NULL,								// const VkApplicationInfo*		pAppInfo;
		0u,										// deUint32						layerCount;
		DE_NULL,								// const char*const*			ppEnabledLayernames;
		0u,										// deUint32						extensionCount;
		DE_NULL,								// const char*const*			ppEnabledExtensionNames;
	};

	log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage;

	try
	{
		CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
		log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
	}
	catch (const vk::Error& err)
	{
		resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
	}

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

tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context)
{
	tcu::TestLog&						log						= context.getTestContext().getLog();
	const char*							enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"};
	const deUint32						apiVersion				= context.getUsedApiVersion();
	const VkApplicationInfo				appInfo					=
	{
		VK_STRUCTURE_TYPE_APPLICATION_INFO,						// VkStructureType				sType;
		DE_NULL,												// const void*					pNext;
		"appName",												// const char*					pAppName;
		0u,														// deUint32						appVersion;
		"engineName",											// const char*					pEngineName;
		0u,														// deUint32						engineVersion;
		apiVersion,												// deUint32						apiVersion;
	};

	const VkInstanceCreateInfo			instanceCreateInfo		=
	{
		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,					// VkStructureType				sType;
		DE_NULL,												// const void*					pNext;
		(VkInstanceCreateFlags)0u,								// VkInstanceCreateFlags		flags;
		&appInfo,												// const VkApplicationInfo*		pAppInfo;
		0u,														// deUint32						layerCount;
		DE_NULL,												// const char*const*			ppEnabledLayernames;
		DE_LENGTH_OF_ARRAY(enabledExtensions),					// deUint32						extensionCount;
		enabledExtensions,										// const char*const*			ppEnabledExtensionNames;
	};

	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;

	{
		UncheckedInstance	instance;
		const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);

		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
		{
			TCU_CHECK(!static_cast<bool>(instance));
			return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected.");
		}
		else
			return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded.");
	}
}

enum
{
	UTF8ABUSE_LONGNAME = 0,
	UTF8ABUSE_BADNAMES,
	UTF8ABUSE_OVERLONGNUL,
	UTF8ABUSE_OVERLONG,
	UTF8ABUSE_ZALGO,
	UTF8ABUSE_CHINESE,
	UTF8ABUSE_EMPTY,
	UTF8ABUSE_MAX
};

string getUTF8AbuseString (int index)
{
	switch (index)
	{
	case UTF8ABUSE_LONGNAME:
		// Generate a long name.
		{
			std::string longname;
			longname.resize(65535, 'k');
			return longname;
		}

	case UTF8ABUSE_BADNAMES:
		// Various illegal code points in utf-8
		return string(
			"Illegal bytes in UTF-8: "
			"\xc0 \xc1 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff"
			"illegal surrogates: \xed\xad\xbf \xed\xbe\x80");

	case UTF8ABUSE_OVERLONGNUL:
		// Zero encoded as overlong, not exactly legal but often supported to differentiate from terminating zero
		return string("UTF-8 encoded nul \xC0\x80 (should not end name)");

	case UTF8ABUSE_OVERLONG:
		// Some overlong encodings
		return string(
			"UTF-8 overlong \xF0\x82\x82\xAC \xfc\x83\xbf\xbf\xbf\xbf \xf8\x87\xbf\xbf\xbf "
			"\xf0\x8f\xbf\xbf");

	case UTF8ABUSE_ZALGO:
		// Internet "zalgo" meme "bleeding text"
		return string(
			"\x56\xcc\xb5\xcc\x85\xcc\x94\xcc\x88\xcd\x8a\xcc\x91\xcc\x88\xcd\x91\xcc\x83\xcd\x82"
			"\xcc\x83\xcd\x90\xcc\x8a\xcc\x92\xcc\x92\xcd\x8b\xcc\x94\xcd\x9d\xcc\x98\xcc\xab\xcc"
			"\xae\xcc\xa9\xcc\xad\xcc\x97\xcc\xb0\x75\xcc\xb6\xcc\xbe\xcc\x80\xcc\x82\xcc\x84\xcd"
			"\x84\xcc\x90\xcd\x86\xcc\x9a\xcd\x84\xcc\x9b\xcd\x86\xcd\x92\xcc\x9a\xcd\x99\xcd\x99"
			"\xcc\xbb\xcc\x98\xcd\x8e\xcd\x88\xcd\x9a\xcc\xa6\xcc\x9c\xcc\xab\xcc\x99\xcd\x94\xcd"
			"\x99\xcd\x95\xcc\xa5\xcc\xab\xcd\x89\x6c\xcc\xb8\xcc\x8e\xcc\x8b\xcc\x8b\xcc\x9a\xcc"
			"\x8e\xcd\x9d\xcc\x80\xcc\xa1\xcc\xad\xcd\x9c\xcc\xba\xcc\x96\xcc\xb3\xcc\xa2\xcd\x8e"
			"\xcc\xa2\xcd\x96\x6b\xcc\xb8\xcc\x84\xcd\x81\xcc\xbf\xcc\x8d\xcc\x89\xcc\x85\xcc\x92"
			"\xcc\x84\xcc\x90\xcd\x81\xcc\x93\xcd\x90\xcd\x92\xcd\x9d\xcc\x84\xcd\x98\xcd\x9d\xcd"
			"\xa0\xcd\x91\xcc\x94\xcc\xb9\xcd\x93\xcc\xa5\xcd\x87\xcc\xad\xcc\xa7\xcd\x96\xcd\x99"
			"\xcc\x9d\xcc\xbc\xcd\x96\xcd\x93\xcc\x9d\xcc\x99\xcc\xa8\xcc\xb1\xcd\x85\xcc\xba\xcc"
			"\xa7\x61\xcc\xb8\xcc\x8e\xcc\x81\xcd\x90\xcd\x84\xcd\x8c\xcc\x8c\xcc\x85\xcd\x86\xcc"
			"\x84\xcd\x84\xcc\x90\xcc\x84\xcc\x8d\xcd\x99\xcd\x8d\xcc\xb0\xcc\xa3\xcc\xa6\xcd\x89"
			"\xcd\x8d\xcd\x87\xcc\x98\xcd\x8d\xcc\xa4\xcd\x9a\xcd\x8e\xcc\xab\xcc\xb9\xcc\xac\xcc"
			"\xa2\xcd\x87\xcc\xa0\xcc\xb3\xcd\x89\xcc\xb9\xcc\xa7\xcc\xa6\xcd\x89\xcd\x95\x6e\xcc"
			"\xb8\xcd\x8a\xcc\x8a\xcd\x82\xcc\x9b\xcd\x81\xcd\x90\xcc\x85\xcc\x9b\xcd\x80\xcd\x91"
			"\xcd\x9b\xcc\x81\xcd\x81\xcc\x9a\xcc\xb3\xcd\x9c\xcc\x9e\xcc\x9d\xcd\x99\xcc\xa2\xcd"
			"\x93\xcd\x96\xcc\x97\xff");

	case UTF8ABUSE_CHINESE:
		// Some Chinese glyphs.
		// "English equivalent: The devil is in the details", https://en.wikiquote.org/wiki/Chinese_proverbs
		return string(
			"\xe8\xaf\xbb\xe4\xb9\xa6\xe9\xa1\xbb\xe7\x94\xa8\xe6\x84\x8f\xef\xbc\x8c\xe4\xb8\x80"
			"\xe5\xad\x97\xe5\x80\xbc\xe5\x8d\x83\xe9\x87\x91\x20");

	default:
		DE_ASSERT(index == UTF8ABUSE_EMPTY);
		// Also try an empty string.
		return string("");
	}
}

tcu::TestStatus createInstanceWithExtensionNameAbuseTest (Context& context)
{
	const char*					extensionList[1]	= { 0 };
	const deUint32				apiVersion			= context.getUsedApiVersion();
	deUint32					failCount			= 0;

	for (int i = 0; i < UTF8ABUSE_MAX; i++)
	{
		string abuseString	= getUTF8AbuseString(i);
		extensionList[0]	= abuseString.c_str();

		const VkApplicationInfo		appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,				// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			"appName",										// const char*				pAppName;
			0u,												// deUint32					appVersion;
			"engineName",									// const char*				pEngineName;
			0u,												// deUint32					engineVersion;
			apiVersion,										// deUint32					apiVersion;
		};

		const VkInstanceCreateInfo	instanceCreateInfo =
		{
			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			(VkInstanceCreateFlags)0u,						// VkInstanceCreateFlags	flags;
			&appInfo,										// const VkApplicationInfo*	pAppInfo;
			0u,												// deUint32					layerCount;
			DE_NULL,										// const char*const*		ppEnabledLayernames;
			1u,												// deUint32					extensionCount;
			extensionList,									// const char*const*		ppEnabledExtensionNames;
		};

		{
			UncheckedInstance	instance;
			const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);

			if (result != VK_ERROR_EXTENSION_NOT_PRESENT)
				failCount++;

			TCU_CHECK(!static_cast<bool>(instance));
		}
	}

	if (failCount > 0)
		return tcu::TestStatus::fail("Fail, creating instances with unsupported extensions succeeded.");

	return tcu::TestStatus::pass("Pass, creating instances with unsupported extensions were rejected.");
}

tcu::TestStatus createInstanceWithLayerNameAbuseTest (Context& context)
{
	const PlatformInterface&	platformInterface	= context.getPlatformInterface();
	const char*					layerList[1]		= { 0 };
	const deUint32				apiVersion			= context.getUsedApiVersion();
	deUint32					failCount			= 0;

	for (int i = 0; i < UTF8ABUSE_MAX; i++)
	{
		string abuseString	= getUTF8AbuseString(i);
		layerList[0]		= abuseString.c_str();

		const VkApplicationInfo		appInfo =
		{
			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType			sType;
			DE_NULL,								// const void*				pNext;
			"appName",								// const char*				pAppName;
			0u,										// deUint32					appVersion;
			"engineName",							// const char*				pEngineName;
			0u,										// deUint32					engineVersion;
			apiVersion,								// deUint32					apiVersion;
		};

		const VkInstanceCreateInfo	instanceCreateInfo =
		{
			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType			sType;
			DE_NULL,								// const void*				pNext;
			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags	flags;
			&appInfo,								// const VkApplicationInfo*	pAppInfo;
			1u,										// deUint32					layerCount;
			layerList,								// const char*const*		ppEnabledLayernames;
			0u,										// deUint32					extensionCount;
			DE_NULL,								// const char*const*		ppEnabledExtensionNames;
		};

		{
			VkInstance		instance	= (VkInstance)0;
			const VkResult	result		= platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
			const bool		gotInstance	= !!instance;

			if (instance)
			{
				const InstanceDriver instanceIface(platformInterface, instance);
				instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
			}

			if (result != VK_ERROR_LAYER_NOT_PRESENT)
				failCount++;

			TCU_CHECK(!gotInstance);
		}
	}

	if (failCount > 0)
		return tcu::TestStatus::fail("Fail, creating instances with unsupported layers succeeded.");

	return tcu::TestStatus::pass("Pass, creating instances with unsupported layers were rejected.");
}

tcu::TestStatus enumerateDevicesAllocLeakTest(Context& context)
{
	// enumeratePhysicalDevices uses instance-provided allocator
	// and this test checks if all alocated memory is freed

	typedef AllocationCallbackRecorder::RecordIterator RecordIterator;

	DeterministicFailAllocator	objAllocator	(getSystemAllocator(), DeterministicFailAllocator::MODE_DO_NOT_COUNT, 0);
	AllocationCallbackRecorder	recorder		(objAllocator.getCallbacks(), 128);
	const auto					instance		= createCustomInstanceFromContext(context, recorder.getCallbacks(), true);
	const auto&					vki				= instance.getDriver();
	vector<VkPhysicalDevice>	devices			(enumeratePhysicalDevices(vki, instance));
	RecordIterator				recordToCheck	(recorder.getRecordsEnd());

	try
	{
		devices = enumeratePhysicalDevices(vki, instance);
	}
	catch (const vk::OutOfMemoryError& e)
	{
		if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY)
			return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Got out of memory error - leaks in enumeratePhysicalDevices not tested.");
	}

	// make sure that same number of allocations and frees was done
	deInt32			allocationRecords	(0);
	RecordIterator	lastRecordToCheck	(recorder.getRecordsEnd());
	while (recordToCheck != lastRecordToCheck)
	{
		const AllocationCallbackRecord& record = *recordToCheck;
		switch (record.type)
		{
		case AllocationCallbackRecord::TYPE_ALLOCATION:
			++allocationRecords;
			break;
		case AllocationCallbackRecord::TYPE_FREE:
			if (record.data.free.mem != DE_NULL)
				--allocationRecords;
			break;
		default:
			break;
		}
		++recordToCheck;
	}

	if (allocationRecords)
		return tcu::TestStatus::fail("enumeratePhysicalDevices leaked memory");
	return tcu::TestStatus::pass("Ok");
}

tcu::TestStatus createDeviceTest (Context& context)
{
	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
	const CustomInstance			instance				(createCustomInstanceFromContext(context));
	const InstanceDriver&			instanceDriver			(instance.getDriver());
	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32					queueFamilyIndex		= 0;
	const deUint32					queueCount				= 1;
	const deUint32					queueIndex				= 0;
	const float						queuePriority			= 1.0f;

	const vector<VkQueueFamilyProperties> queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);

	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
		DE_NULL,
		(VkDeviceQueueCreateFlags)0u,
		queueFamilyIndex,						//queueFamilyIndex;
		queueCount,								//queueCount;
		&queuePriority,							//pQueuePriorities;
	};

	const VkDeviceCreateInfo		deviceCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
		DE_NULL,								//pNext;
		(VkDeviceCreateFlags)0u,
		1,										//queueRecordCount;
		&deviceQueueCreateInfo,					//pRequestedQueues;
		0,										//layerCount;
		DE_NULL,								//ppEnabledLayerNames;
		0,										//extensionCount;
		DE_NULL,								//ppEnabledExtensionNames;
		DE_NULL,								//pEnabledFeatures;
	};

	const Unique<VkDevice>			device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
	const DeviceDriver				deviceDriver			(platformInterface, instance, device.get());
	const VkQueue					queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);

	VK_CHECK(deviceDriver.queueWaitIdle(queue));

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

tcu::TestStatus createMultipleDevicesTest (Context& context)
{
	tcu::TestLog&										log						= context.getTestContext().getLog();
	tcu::ResultCollector								resultCollector			(log);
	const int											numDevices				= 5;
	const PlatformInterface&							platformInterface		= context.getPlatformInterface();
	const CustomInstance								instance				(createCustomInstanceFromContext(context));
	const InstanceDriver&								instanceDriver			(instance.getDriver());
	const VkPhysicalDevice								physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const vector<VkQueueFamilyProperties>				queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
	const deUint32										queueFamilyIndex		= 0;
	const deUint32										queueCount				= 1;
	const deUint32										queueIndex				= 0;
	const float											queuePriority			= 1.0f;
	const VkDeviceQueueCreateInfo						deviceQueueCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
		DE_NULL,
		(VkDeviceQueueCreateFlags)0u,					//flags;
		queueFamilyIndex,								//queueFamilyIndex;
		queueCount,										//queueCount;
		&queuePriority,									//pQueuePriorities;
	};

	const VkDeviceCreateInfo							deviceCreateInfo		=
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,			//sType;
		DE_NULL,										//pNext;
		(VkDeviceCreateFlags)0u,
		1,												//queueRecordCount;
		&deviceQueueCreateInfo,							//pRequestedQueues;
		0,												//layerCount;
		DE_NULL,										//ppEnabledLayerNames;
		0,												//extensionCount;
		DE_NULL,										//ppEnabledExtensionNames;
		DE_NULL,										//pEnabledFeatures;
	};

	vector<VkDevice>									devices(numDevices, (VkDevice)DE_NULL);

	try
	{
		for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++)
		{
			const VkResult result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]);

			if (result != VK_SUCCESS)
			{
				resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result));
				break;
			}

			{
				const DeviceDriver	deviceDriver	(platformInterface, instance, devices[deviceNdx]);
				const VkQueue		queue			= getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex);

				VK_CHECK(deviceDriver.queueWaitIdle(queue));
			}
		}
	}
	catch (const vk::Error& error)
	{
		resultCollector.fail(de::toString(error.getError()));
	}
	catch (...)
	{
		for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
		{
			if (devices[deviceNdx] != (VkDevice)DE_NULL)
			{
				DeviceDriver deviceDriver(platformInterface, instance, devices[deviceNdx]);
				deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
			}
		}

		throw;
	}

	for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
	{
		if (devices[deviceNdx] != (VkDevice)DE_NULL)
		{
			DeviceDriver deviceDriver(platformInterface, instance, devices[deviceNdx]);
			deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
		}
	}

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

tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context)
{
	tcu::TestLog&					log						= context.getTestContext().getLog();
	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
	const CustomInstance			instance				(createCustomInstanceFromContext(context, DE_NULL, false));
	const InstanceDriver&			instanceDriver			(instance.getDriver());
	const char*						enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"};
	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const float						queuePriority			= 1.0f;
	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
		DE_NULL,
		(VkDeviceQueueCreateFlags)0u,
		0,										//queueFamilyIndex;
		1,										//queueCount;
		&queuePriority,							//pQueuePriorities;
	};

	const VkDeviceCreateInfo		deviceCreateInfo		=
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
		DE_NULL,								//pNext;
		(VkDeviceCreateFlags)0u,
		1,										//queueRecordCount;
		&deviceQueueCreateInfo,					//pRequestedQueues;
		0,										//layerCount;
		DE_NULL,								//ppEnabledLayerNames;
		DE_LENGTH_OF_ARRAY(enabledExtensions),	//extensionCount;
		enabledExtensions,						//ppEnabledExtensionNames;
		DE_NULL,								//pEnabledFeatures;
	};

	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;

	{
		VkDevice		device		= (VkDevice)0;
		const VkResult	result		= createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device);
		const bool		gotDevice	= !!device;

		if (device)
		{
			const DeviceDriver	deviceIface	(platformInterface, instance, device);
			deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
		}

		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
		{
			TCU_CHECK(!gotDevice);
			return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected.");
		}
		else
			return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed.");
	}
}

deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)
{
	deUint32 maxQueueCount = 0;

	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
	{
		maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount);
	}

	return maxQueueCount;
}

tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context)
{
	tcu::TestLog&							log						= context.getTestContext().getLog();
	const int								queueCountDiff			= 1;
	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
	const CustomInstance					instance				(createCustomInstanceFromContext(context));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
	const vector<float>						queuePriorities			(getGlobalMaxQueueCount(queueFamilyProperties), 1.0f);
	vector<VkDeviceQueueCreateInfo>			deviceQueueCreateInfos;

	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
	{
		const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount;

		for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff)
		{
			const VkDeviceQueueCreateInfo queueCreateInfo =
			{
				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
				DE_NULL,
				(VkDeviceQueueCreateFlags)0u,
				queueFamilyNdx,
				queueCount,
				queuePriorities.data()
			};

			deviceQueueCreateInfos.push_back(queueCreateInfo);
		}
	}

	for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++)
	{
		const VkDeviceQueueCreateInfo&	queueCreateInfo		= deviceQueueCreateInfos[testNdx];
		const VkDeviceCreateInfo		deviceCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
			DE_NULL,								//pNext;
			(VkDeviceCreateFlags)0u,
			1,										//queueRecordCount;
			&queueCreateInfo,						//pRequestedQueues;
			0,										//layerCount;
			DE_NULL,								//ppEnabledLayerNames;
			0,										//extensionCount;
			DE_NULL,								//ppEnabledExtensionNames;
			DE_NULL,								//pEnabledFeatures;
		};

		const Unique<VkDevice>			device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
		const DeviceDriver				deviceDriver		(platformInterface, instance, device.get());
		const deUint32					queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
		const deUint32					queueCount			= deviceCreateInfo.pQueueCreateInfos->queueCount;

		for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++)
		{
			const VkQueue		queue	= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex);
			VkResult			result;

			TCU_CHECK(!!queue);

			result = deviceDriver.queueWaitIdle(queue);
			if (result != VK_SUCCESS)
			{
				log << TestLog::Message
					<< "vkQueueWaitIdle failed"
					<< ",  queueIndex = " << queueIndex
					<< ", queueCreateInfo " << queueCreateInfo
					<< ", Error Code: " << result
					<< TestLog::EndMessage;
				return tcu::TestStatus::fail("Fail");
			}
		}
	}
	return tcu::TestStatus::pass("Pass");
}

void checkGlobalPrioritySupport (Context& context)
{
	context.requireDeviceFunctionality("VK_EXT_global_priority");
}

tcu::TestStatus createDeviceWithGlobalPriorityTest (Context& context)
{
	tcu::TestLog&							log						= context.getTestContext().getLog();
	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
	const CustomInstance					instance				(createCustomInstanceFromContext(context));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const vector<float>						queuePriorities			(1, 1.0f);
	const VkQueueGlobalPriorityEXT			globalPriorities[]		= { VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT, VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT, VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT, VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT };

	for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
	{
		const VkDeviceQueueGlobalPriorityCreateInfoEXT	queueGlobalPriority		=
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,	//sType;
			DE_NULL,														//pNext;
			globalPriority													//globalPriority;
		};

		const VkDeviceQueueCreateInfo	queueCreateInfo		=
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//sType;
			&queueGlobalPriority,						//pNext;
			(VkDeviceQueueCreateFlags)0u,				//flags;
			0,											//queueFamilyIndex;
			1,											//queueCount;
			queuePriorities.data()						//pQueuePriorities;
		};

		const VkDeviceCreateInfo		deviceCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
			DE_NULL,								//pNext;
			(VkDeviceCreateFlags)0u,				//flags;
			1,										//queueRecordCount;
			&queueCreateInfo,						//pRequestedQueues;
			0,										//layerCount;
			DE_NULL,								//ppEnabledLayerNames;
			0,										//extensionCount;
			DE_NULL,								//ppEnabledExtensionNames;
			DE_NULL,								//pEnabledFeatures;
		};

		const bool		mayBeDenied				= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;

		try
		{
			const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
			const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
			const deUint32				queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
			const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, 0);
			VkResult					result;

			TCU_CHECK(!!queue);

			result = deviceDriver.queueWaitIdle(queue);
			if (result == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
			{
				continue;
			}

			if (result != VK_SUCCESS)
			{
				log << TestLog::Message
					<< "vkQueueWaitIdle failed"
					<< ", globalPriority = " << globalPriority
					<< ", queueCreateInfo " << queueCreateInfo
					<< ", Error Code: " << result
					<< TestLog::EndMessage;
				return tcu::TestStatus::fail("Fail");
			}
		}
		catch (const Error& error)
		{
			if (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
			{
				continue;
			}
			else
			{
				log << TestLog::Message
					<< "exception thrown " << error.getMessage()
					<< ", globalPriority = " << globalPriority
					<< ", queueCreateInfo " << queueCreateInfo
					<< ", Error Code: " << error.getError()
					<< TestLog::EndMessage;
				return tcu::TestStatus::fail("Fail");
			}
		}
	}

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

void checkGlobalPriorityQuerySupport (Context& context)
{
	context.requireDeviceFunctionality("VK_EXT_global_priority_query");
}

deBool isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)
{
	switch (priority) {
		case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:
		case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:
		case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:
		case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:
			return DE_TRUE;
		default:
			return DE_FALSE;
	}
}

void checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT& properties)
{
	TCU_CHECK(properties.priorityCount > 0);
	TCU_CHECK(properties.priorityCount <= VK_MAX_GLOBAL_PRIORITY_SIZE_EXT);
	TCU_CHECK(isValidGlobalPriority(properties.priorities[0]));

	for (deUint32 ndx = 1; ndx < properties.priorityCount; ndx++)
	{
		TCU_CHECK(isValidGlobalPriority(properties.priorities[ndx]));
		TCU_CHECK(properties.priorities[ndx] == (properties.priorities[ndx - 1] << 1));
	}
}

tcu::TestStatus createDeviceWithQueriedGlobalPriorityTest (Context& context)
{
	tcu::TestLog&					log							= context.getTestContext().getLog();
	const PlatformInterface&		platformInterface			= context.getPlatformInterface();
	const CustomInstance			instance					(createCustomInstanceFromContext(context));
	const InstanceDriver&			instanceDriver				(instance.getDriver());
	const VkPhysicalDevice			physicalDevice				= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const VkQueueGlobalPriorityEXT	globalPriorities[]			= { VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT, VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT, VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT, VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT };
	const vector<float>				queuePriorities				(1, 1.0f);
	std::vector<const char*>		enabledExtensions			= {"VK_EXT_global_priority", "VK_EXT_global_priority_query"};
	deUint32						queueFamilyPropertyCount	= ~0u;

	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, DE_NULL);
	TCU_CHECK(queueFamilyPropertyCount > 0);

	std::vector<VkQueueFamilyProperties2>					queueFamilyProperties2		(queueFamilyPropertyCount);
	std::vector<VkQueueFamilyGlobalPriorityPropertiesEXT>	globalPriorityProperties	(queueFamilyPropertyCount);

	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
	{
		globalPriorityProperties[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT;
		globalPriorityProperties[ndx].pNext	= DE_NULL;
		queueFamilyProperties2[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
		queueFamilyProperties2[ndx].pNext	= &globalPriorityProperties[ndx];
	}

	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
	TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());

	if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
	{
		enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
	}

	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
	{
		checkGlobalPriorityProperties(globalPriorityProperties[ndx]);

		for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
		{
			const VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT	globalPriorityQueryFeatures		=
			{
				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,	//sType;
				DE_NULL,																//pNext;
				VK_TRUE																	//globalPriorityQuery;
			};
			const VkDeviceQueueGlobalPriorityCreateInfoEXT			queueGlobalPriorityCreateInfo	=
			{
				VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,			//sType;
				DE_NULL,																//pNext;
				globalPriority,															//globalPriority;
			};
			const VkDeviceQueueCreateInfo							queueCreateInfo					=
			{
				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,								//sType;
				&queueGlobalPriorityCreateInfo,											//pNext;
				(VkDeviceQueueCreateFlags)0u,											//flags;
				ndx,																	//queueFamilyIndex;
				1,																		//queueCount;
				queuePriorities.data()													//pQueuePriorities;
			};
			const VkDeviceCreateInfo								deviceCreateInfo				=
			{
				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,									//sType;
				&globalPriorityQueryFeatures,											//pNext;
				(VkDeviceCreateFlags)0u,												//flags;
				1,																		//queueRecordCount;
				&queueCreateInfo,														//pRequestedQueues;
				0,																		//layerCount;
				DE_NULL,																//ppEnabledLayerNames;
				(deUint32)enabledExtensions.size(),										//extensionCount;
				enabledExtensions.data(),												//ppEnabledExtensionNames;
				DE_NULL,																//pEnabledFeatures;
			};
			const bool												mayBeDenied						= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
			const bool												mustFail						= globalPriority < globalPriorityProperties[ndx].priorities[0] || globalPriority > globalPriorityProperties[ndx].priorities[globalPriorityProperties[ndx].priorityCount - 1];

			try
			{
				const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
				const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
				const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, ndx, 0);

				TCU_CHECK(!!queue);

				if (mustFail)
				{
					log << TestLog::Message
						<< "device creation must fail but not"
						<< ", globalPriority = " << globalPriority
						<< ", queueCreateInfo " << queueCreateInfo
						<< TestLog::EndMessage;
					return tcu::TestStatus::fail("Fail");
				}
			}
			catch (const Error& error)
			{
				if (mustFail || (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied))
				{
					continue;
				}
				else
				{
					log << TestLog::Message
						<< "exception thrown " << error.getMessage()
						<< ", globalPriority = " << globalPriority
						<< ", queueCreateInfo " << queueCreateInfo
						<< ", Error Code: " << error.getError()
						<< TestLog::EndMessage;
					return tcu::TestStatus::fail("Fail");
				}
			}
		}
	}

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

tcu::TestStatus createDeviceFeatures2Test (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	const CustomInstance					instance				(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver&					vki						(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(vki, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const deUint32							queueIndex				= 0;
	const float								queuePriority			= 1.0f;
	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);

	VkPhysicalDeviceFeatures2		enabledFeatures;
	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
		DE_NULL,
		(VkDeviceQueueCreateFlags)0u,
		queueFamilyIndex,
		queueCount,
		&queuePriority,
	};

	const VkDeviceCreateInfo		deviceCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
		&enabledFeatures,
		(VkDeviceCreateFlags)0u,
		1,
		&deviceQueueCreateInfo,
		0u,
		DE_NULL,
		0,
		DE_NULL,
		DE_NULL,
	};

	// Populate enabledFeatures
	enabledFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	enabledFeatures.pNext		= DE_NULL;

	vki.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);

	{
		const Unique<VkDevice>	device		(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceCreateInfo));
		const DeviceDriver		vkd			(vkp, instance, device.get());
		const VkQueue			queue		= getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);

		VK_CHECK(vkd.queueWaitIdle(queue));
	}

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

struct Feature
{
	const char*	name;
	size_t		offset;
};

#define FEATURE_ITEM(STRUCT, MEMBER) {#MEMBER, DE_OFFSET_OF(STRUCT, MEMBER)}
// This macro is used to avoid the "out of array bounds" compiler warnings/errors in the checkFeatures function.
#define SAFE_OFFSET(LIMITING_STRUCT, STRUCT, MEMBER) std::min(static_cast<deUint32>(sizeof(LIMITING_STRUCT) - sizeof(VkBool32)), DE_OFFSET_OF(STRUCT, MEMBER))

template<typename StructType>
void checkFeatures (const PlatformInterface& vkp, const VkInstance& instance, const InstanceDriver& instanceDriver, const VkPhysicalDevice physicalDevice, int numFeatures, const Feature features[], const StructType* supportedFeatures, const deUint32 queueFamilyIndex, const deUint32 queueCount, const float queuePriority, int& numErrors, tcu::ResultCollector& resultCollector, const vector<const char*>* extensionNames, const VkPhysicalDeviceFeatures& defaultPhysicalDeviceFeatures)
{
	struct StructureBase
	{
		VkStructureType		sType;
		void*				pNext;
	};

	for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
	{
		// Test only features that are not supported.
		if (*(((VkBool32*)((deUint8*)(supportedFeatures) + features[featureNdx].offset))))
			continue;

		StructType structCopy;
		deMemset(&structCopy, 0, sizeof(StructType));

		auto* structBase = reinterpret_cast<StructureBase*>(&structCopy);
		VkStructureType structureType = reinterpret_cast<const StructureBase*>(supportedFeatures)->sType;
		structBase->sType = structureType;
		structBase->pNext = DE_NULL;

		VkPhysicalDeviceFeatures physicalDeviceFeaturesCopy = defaultPhysicalDeviceFeatures;

		// Some features require that other feature(s) are also enabled.

		// If rayTracingPipelineShaderGroupHandleCaptureReplayMixed is VK_TRUE, rayTracingPipelineShaderGroupHandleCaptureReplay must also be VK_TRUE.
		if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR &&
			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplayMixed))
		{
			DE_ASSERT((std::is_same<VkPhysicalDeviceRayTracingPipelineFeaturesKHR, StructType>::value));
			auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplay));
			*memberPtr = VK_TRUE;
		}
		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES)
		{
			DE_ASSERT((std::is_same<VkPhysicalDeviceVulkan11Features, StructType>::value));
			// If multiviewGeometryShader is enabled then multiview must also be enabled.
			// If multiviewTessellationShader is enabled then multiview must also be enabled.
			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader) ||
				features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader))
			{
				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, multiview));
				*memberPtr = VK_TRUE;
			}

			// If variablePointers is enabled then variablePointersStorageBuffer must also be enabled.
			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, variablePointers))
			{
				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer));
				*memberPtr = VK_TRUE;
			}
		}
		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES)
		{
			DE_ASSERT((std::is_same<VkPhysicalDeviceMultiviewFeatures, StructType>::value));
			// If multiviewGeometryShader is enabled then multiview must also be enabled.
			// If multiviewTessellationShader is enabled then multiview must also be enabled.
			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewGeometryShader) ||
			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewTessellationShader))
			{
				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceMultiviewFeatures, multiview));
				*memberPtr = VK_TRUE;
			}
		}
		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
		{
			DE_ASSERT((std::is_same<VkPhysicalDeviceRobustness2FeaturesEXT, StructType>::value));
			// If robustBufferAccess2 is enabled then robustBufferAccess must also be enabled.
			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRobustness2FeaturesEXT, robustBufferAccess2))
			{
				physicalDeviceFeaturesCopy.robustBufferAccess = true;
			}
		}
		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT)
		{
			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, StructType>::value));
			// If sparseImageInt64Atomics is enabled, shaderImageInt64Atomics must be enabled.
			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, sparseImageInt64Atomics))
			{
				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, shaderImageInt64Atomics));
				*memberPtr = VK_TRUE;
			}
		}
		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT)
		{
			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, StructType>::value));
			// If sparseImageFloat32Atomics is enabled, shaderImageFloat32Atomics must be enabled.
			if (features[featureNdx].offset ==
				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32Atomics)) {
				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32Atomics));
				*memberPtr = VK_TRUE;
			}

			// If sparseImageFloat32AtomicAdd is enabled, shaderImageFloat32AtomicAdd must be enabled.
			if (features[featureNdx].offset ==
				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32AtomicAdd)) {
				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32AtomicAdd));
				*memberPtr = VK_TRUE;
			}
		}
		else if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT)
		{
			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, StructType>::value));
			// If sparseImageFloat32AtomicMinMax is enabled, shaderImageFloat32AtomicMinMax must be enabled.
			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, sparseImageFloat32AtomicMinMax))
			{
				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderImageFloat32AtomicMinMax));
				*memberPtr = VK_TRUE;
			}
		}

		// Enable the feature we're testing.
		*reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + features[featureNdx].offset) = VK_TRUE;

		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
			DE_NULL,									// pNext
			(VkDeviceQueueCreateFlags)0u,				// flags
			queueFamilyIndex,							// queueFamilyIndex
			queueCount,									// queueCount
			&queuePriority								// pQueuePriorities
		};
		const VkPhysicalDeviceFeatures2 deviceFeatures2 =
		{
			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,	// sType
			&structCopy,									// pNext
			physicalDeviceFeaturesCopy						// features
		};
		const VkDeviceCreateInfo		deviceCreateInfo		=
		{
			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,											// sType
			&deviceFeatures2,																// pNext
			(VkDeviceCreateFlags)0u,														// flags
			1,																				// queueCreateInfoCount
			&deviceQueueCreateInfo,															// pQueueCreateInfos
			0u,																				// enabledLayerCount
			DE_NULL,																		// ppEnabledLayerNames
			static_cast<deUint32>(extensionNames == DE_NULL ? 0 : extensionNames->size()),	// enabledExtensionCount
			extensionNames == DE_NULL ? DE_NULL : extensionNames->data(),					// ppEnabledExtensionNames
			DE_NULL																			// pEnabledFeatures
		};

		VkDevice		device = (VkDevice)DE_NULL;
		const VkResult	res	= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);

		if (res != VK_ERROR_FEATURE_NOT_PRESENT)
		{
			numErrors++;
			resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
				+ de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
		}
		if (device != (VkDevice)DE_NULL)
		{
			DeviceDriver deviceDriver(vkp, instance, device);
			deviceDriver.destroyDevice(device, DE_NULL);
		}
	}
}

vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
{
	vector<string>	res;
	set<string>		removeExts	(b.begin(), b.end());

	for (const auto & aIter : a)
	{
		if (!de::contains(removeExts, aIter))
			res.push_back(aIter);
	}

	return res;
}

tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
{
	const PlatformInterface&				vkp						= context.getPlatformInterface();
	tcu::TestLog&							log						= context.getTestContext().getLog();
	tcu::ResultCollector					resultCollector			(log);
	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
	const InstanceDriver&					instanceDriver			(instance.getDriver());
	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
	const deUint32							queueFamilyIndex		= 0;
	const deUint32							queueCount				= 1;
	const float								queuePriority			= 1.0f;
	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
	const VkPhysicalDeviceFeatures			deviceFeatures			= deviceFeatures2.features;
	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
	int										numErrors				= 0;

	// Test features listed in VkPhysicalDeviceFeatures structure
	{
		static const Feature features[] =
		{
			// robustBufferAccess is removed, because it's always supported.
			FEATURE_ITEM(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, imageCubeArray),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, independentBlend),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, geometryShader),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, tessellationShader),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sampleRateShading),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, dualSrcBlend),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, logicOp),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiDrawIndirect),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthClamp),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBiasClamp),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, fillModeNonSolid),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBounds),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, wideLines),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, largePoints),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, alphaToOne),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiViewport),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, samplerAnisotropy),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionETC2),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionBC),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderClipDistance),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderCullDistance),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderFloat64),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt64),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt16),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceResidency),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceMinLod),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseBinding),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency2Samples),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency4Samples),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency8Samples),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency16Samples),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyAliased),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, variableMultisampleRate),
			FEATURE_ITEM(VkPhysicalDeviceFeatures, inheritedQueries)
		};

		for (const auto& feature : features)
		{
			// Test only features that are not supported.
			if (*(((VkBool32*)((deUint8*)(&deviceFeatures) + feature.offset))))
				continue;

			VkPhysicalDeviceFeatures		enabledFeatures			= deviceFeatures;
			*((VkBool32*)((deUint8*)(&enabledFeatures) + feature.offset)) = VK_TRUE;

			const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
			{
				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
				DE_NULL,
				(VkDeviceQueueCreateFlags)0u,
				queueFamilyIndex,
				queueCount,
				&queuePriority
			};
			const VkDeviceCreateInfo		deviceCreateInfo		=
			{
				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
				DE_NULL,
				(VkDeviceCreateFlags)0u,
				1,
				&deviceQueueCreateInfo,
				0u,
				DE_NULL,
				0,
				DE_NULL,
				&enabledFeatures
			};

			VkDevice		device	= DE_NULL;
			const VkResult	res		= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);

			if (res != VK_ERROR_FEATURE_NOT_PRESENT)
			{
				numErrors++;
				resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
				+ de::toString(feature.name) + ", which was reported as unsupported.");
			}

			if (device != DE_NULL)
			{
				DeviceDriver deviceDriver(vkp, instance, device);
				deviceDriver.destroyDevice(device, DE_NULL);
			}
		}
	}

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

	// Only non-core extensions will be used when creating the device.
	vector<const char*>	coreExtensions;
	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));

	vector<const char*> extensionNames;
	extensionNames.reserve(nonCoreExtensions.size());
	for (const string& extension : nonCoreExtensions)
		extensionNames.push_back(extension.c_str());

	// Test features provided by extensions and Vulkan 1.1 and 1.2.

	#include "vkDeviceFeatureTest.inl"

	if (numErrors > 1)
		return tcu::TestStatus(resultCollector.getResult(), "Enabling " + de::toString(numErrors) + " unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
	else
		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
}

tcu::TestStatus createDeviceQueue2Test (Context& context)
{
	if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");

	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
	const VkInstance						instance				= context.getInstance();
	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	const deUint32							queueCount				= 1;
	const deUint32							queueIndex				= 0;
	const float								queuePriority			= 1.0f;

	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
		DE_NULL,														// void*							pNext;
		VK_FALSE														// VkBool32							protectedMemory;
	};

	VkPhysicalDeviceFeatures2				features2;
	deMemset(&features2, 0, sizeof(features2));
	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	features2.pNext													= &protectedMemoryFeature;

	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");

	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
		DE_NULL,														// const void*						pNext;
		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
		queueFamilyIndex,												// deUint32							queueFamilyIndex;
		queueCount,														// deUint32							queueCount;
		&queuePriority,													// const float*						pQueuePriorities;
	};
	const VkDeviceCreateInfo				deviceCreateInfo		=
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
		&features2,														// const void*						pNext;
		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
		1,																// deUint32							queueCreateInfoCount;
		&deviceQueueCreateInfo,											// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
		0,																// deUint32							enabledLayerCount;
		DE_NULL,														// const char* const*				ppEnabledLayerNames;
		0,																// deUint32							enabledExtensionCount;
		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
	};

	const VkDeviceQueueInfo2				deviceQueueInfo2		=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
		DE_NULL,														// const void*						pNext;
		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
		queueFamilyIndex,												// deUint32							queueFamilyIndex;
		queueIndex,														// deUint32							queueIndex;
	};

	{
		const Unique<VkDevice>				device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
		const DeviceDriver					deviceDriver			(platformInterface, instance, device.get());
		const VkQueue						queue2					= getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);

		VK_CHECK(deviceDriver.queueWaitIdle(queue2));
	}

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

tcu::TestStatus createDeviceQueue2UnmatchedFlagsTest (Context& context)
{
	if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");

	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
	const VkInstance				instance				= context.getInstance();
	const InstanceInterface&		instanceDriver			= context.getInstanceInterface();
	const VkPhysicalDevice			physicalDevice			= context.getPhysicalDevice();

	// Check if VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT flag can be used.
	{
		VkPhysicalDeviceProtectedMemoryFeatures		protectedFeatures;
		protectedFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
		protectedFeatures.pNext		= DE_NULL;

		VkPhysicalDeviceFeatures2					deviceFeatures;
		deviceFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
		deviceFeatures.pNext		= &protectedFeatures;

		instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures);
		if (!protectedFeatures.protectedMemory)
		{
			TCU_THROW(NotSupportedError, "protectedMemory feature is not supported, no queue creation flags available");
		}
	}

	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	const deUint32							queueCount				= 1;
	const deUint32							queueIndex				= 0;
	const float								queuePriority			= 1.0f;
	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// VkStructureType					sType;
		DE_NULL,									// const void*						pNext;
		(VkDeviceQueueCreateFlags)0u,				// VkDeviceQueueCreateFlags			flags;
		queueFamilyIndex,							// deUint32							queueFamilyIndex;
		queueCount,									// deUint32							queueCount;
		&queuePriority,								// const float*						pQueuePriorities;
	};
	VkPhysicalDeviceProtectedMemoryFeatures	protectedFeatures		=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType				sType;
		DE_NULL,														// void*						pNext;
		VK_TRUE															// VkBool32						protectedMemory;
	};

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

	const VkPhysicalDeviceFeatures2			deviceFeatures			=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,					// VkStructureType				sType;
		&protectedFeatures,												// void*						pNext;
		emptyDeviceFeatures												// VkPhysicalDeviceFeatures		features;
	};

	const VkDeviceCreateInfo				deviceCreateInfo		=
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// VkStructureType					sType;
		&deviceFeatures,							// const void*						pNext;
		(VkDeviceCreateFlags)0u,					// VkDeviceCreateFlags				flags;
		1,											// deUint32							queueCreateInfoCount;
		&deviceQueueCreateInfo,						// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
		0,											// deUint32							enabledLayerCount;
		DE_NULL,									// const char* const*				ppEnabledLayerNames;
		0,											// deUint32							enabledExtensionCount;
		DE_NULL,									// const char* const*				ppEnabledExtensionNames;
		DE_NULL,									// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
	};

	const VkDeviceQueueInfo2				deviceQueueInfo2		=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,		// VkStructureType					sType;
		DE_NULL,									// const void*						pNext;
		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,		// VkDeviceQueueCreateFlags			flags;
		queueFamilyIndex,							// deUint32							queueFamilyIndex;
		queueIndex,									// deUint32							queueIndex;
	};

	{
		const Unique<VkDevice>		device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
		const DeviceDriver			deviceDriver			(platformInterface, instance, device.get());
		const VkQueue				queue2					= getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);

		if (queue2 != DE_NULL)
			return tcu::TestStatus::fail("Fail, getDeviceQueue2 should return VK_NULL_HANDLE when flags in VkDeviceQueueCreateInfo and VkDeviceQueueInfo2 are different.");

		const VkQueue				queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);

		VK_CHECK(deviceDriver.queueWaitIdle(queue));
	}

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

// Allocation tracking utilities
struct	AllocTrack
{
	bool						active;
	bool						wasAllocated;
	void*						alignedStartAddress;
	char*						actualStartAddress;
	size_t						requestedSizeBytes;
	size_t						actualSizeBytes;
	VkSystemAllocationScope		allocScope;
	deUint64					userData;

	AllocTrack()
		: active				(false)
		, wasAllocated			(false)
		, alignedStartAddress	(DE_NULL)
		, actualStartAddress	(DE_NULL)
		, requestedSizeBytes	(0)
		, actualSizeBytes		(0)
		, allocScope			(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)
		, userData(0)			{}
};

// Global vector to track allocations. This will be resized before each test and emptied after
// However, we have to globally define it so the allocation callback functions work properly
std::vector<AllocTrack>	g_allocatedVector;
bool					g_intentionalFailEnabled	= false;
deUint32				g_intenionalFailIndex		= 0;
deUint32				g_intenionalFailCount		= 0;
size_t					g_allocationsCount			= 0;

void freeAllocTracker (void)
{
	g_allocatedVector.clear();
	g_allocationsCount = 0;
}

void initAllocTracker (size_t size, deUint32 intentionalFailIndex = (deUint32)~0)
{
	if (g_allocatedVector.size() > 0)
		freeAllocTracker();

	g_allocatedVector.resize(size);

	if (intentionalFailIndex != (deUint32)~0)
	{
		g_intentionalFailEnabled	= true;
		g_intenionalFailIndex		= intentionalFailIndex;
		g_intenionalFailCount		= 0;
	}
	else
	{
		g_intentionalFailEnabled	= false;
		g_intenionalFailIndex		= 0;
		g_intenionalFailCount		= 0;
	}

	g_allocationsCount = 0;
}

bool isAllocTrackerEmpty ()
{
	bool success		= true;
	bool wasAllocated	= false;

	for (deUint32 vectorIdx	= 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
	{
		if (g_allocatedVector[vectorIdx].active)
			success = false;
		else if (!wasAllocated && g_allocatedVector[vectorIdx].wasAllocated)
			wasAllocated = true;
	}

	if (!g_intentionalFailEnabled && !wasAllocated)
		success = false;

	return success;
}

VKAPI_ATTR void *VKAPI_CALL allocCallbackFunc (void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	if (g_intentionalFailEnabled)
		if (++g_intenionalFailCount >= g_intenionalFailIndex)
			return DE_NULL;

	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
	{
		if (!g_allocatedVector[vectorIdx].active)
		{
			g_allocatedVector[vectorIdx].requestedSizeBytes		= size;
			g_allocatedVector[vectorIdx].actualSizeBytes		= size + (alignment - 1);
			g_allocatedVector[vectorIdx].alignedStartAddress	= DE_NULL;
			g_allocatedVector[vectorIdx].actualStartAddress		= new char[g_allocatedVector[vectorIdx].actualSizeBytes];

			if (g_allocatedVector[vectorIdx].actualStartAddress != DE_NULL)
			{
				deUint64 addr	=	(deUint64)g_allocatedVector[vectorIdx].actualStartAddress;
				addr			+=	(alignment - 1);
				addr			&=	~(alignment - 1);
				g_allocatedVector[vectorIdx].alignedStartAddress	= (void *)addr;
				g_allocatedVector[vectorIdx].allocScope				= allocationScope;
				g_allocatedVector[vectorIdx].userData				= (deUint64)pUserData;
				g_allocatedVector[vectorIdx].active					= true;
				g_allocatedVector[vectorIdx].wasAllocated			= true;
			}

			g_allocationsCount++;
			return g_allocatedVector[vectorIdx].alignedStartAddress;
		}
	}
	return DE_NULL;
}

VKAPI_ATTR void VKAPI_CALL freeCallbackFunc (void *pUserData, void *pMemory)
{
	DE_UNREF(pUserData);

	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
	{
		if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pMemory)
		{
			delete[] g_allocatedVector[vectorIdx].actualStartAddress;
			g_allocatedVector[vectorIdx].active = false;
			break;
		}
	}
}

VKAPI_ATTR void *VKAPI_CALL reallocCallbackFunc (void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
	if (pOriginal != DE_NULL)
	{
		for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
		{
			if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pOriginal)
			{
				if (size == 0)
				{
					freeCallbackFunc(pUserData, pOriginal);
					return DE_NULL;
				}
				else if (size < g_allocatedVector[vectorIdx].requestedSizeBytes)
					return pOriginal;
				else
				{
					void *pNew = allocCallbackFunc(pUserData, size, alignment, allocationScope);

					if (pNew != DE_NULL)
					{
						size_t copySize = size;

						if (g_allocatedVector[vectorIdx].requestedSizeBytes < size)
							copySize = g_allocatedVector[vectorIdx].requestedSizeBytes;

						memcpy(pNew, pOriginal, copySize);
						freeCallbackFunc(pUserData, pOriginal);
					}
					return pNew;
				}
			}
		}
		return DE_NULL;
	}
	else
		return allocCallbackFunc(pUserData, size, alignment, allocationScope);
}

tcu::TestStatus createInstanceDeviceIntentionalAllocFail (Context& context)
{
	const PlatformInterface&	vkp					= context.getPlatformInterface();
	const deUint32				chosenDevice		= context.getTestContext().getCommandLine().getVKDeviceId() - 1;
	VkInstance					instance			= DE_NULL;
	VkDevice					device				= DE_NULL;
	deUint32					physicalDeviceCount	= 0;
	deUint32					queueFamilyCount	= 0;
	deUint32					queueFamilyIndex	= 0;
	const float					queuePriority		= 0.0f;
	const VkAllocationCallbacks	allocationCallbacks	=
	{
		DE_NULL,								// userData
		allocCallbackFunc,						// pfnAllocation
		reallocCallbackFunc,					// pfnReallocation
		freeCallbackFunc,						// pfnFree
		DE_NULL,								// pfnInternalAllocation
		DE_NULL									// pfnInternalFree
	};
	const VkApplicationInfo		appInfo				=
	{
		VK_STRUCTURE_TYPE_APPLICATION_INFO,		// sType
		DE_NULL,								// pNext
		"appName",								// pApplicationName
		0u,										// applicationVersion
		"engineName",							// pEngineName
		0u,										// engineVersion
		VK_API_VERSION_1_0						// apiVersion
	};

	const VkInstanceCreateInfo	instanceCreateInfo	=
	{
		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// sType
		DE_NULL,								// pNext
		(VkInstanceCreateFlags)0u,				// flags
		&appInfo,								// pApplicationInfo
		0u,										// enabledLayerCount
		DE_NULL,								// ppEnabledLayerNames
		0u,										// enabledExtensionCount
		DE_NULL									// ppEnabledExtensionNames
	};

	deUint32					failIndex			= 0;
	VkResult					result				= VK_SUCCESS;
	size_t						max_allowed_alloc	= 0;

	do
	{
		if (max_allowed_alloc == 0)
		{
			if (result != VK_SUCCESS)
				return tcu::TestStatus::fail("Could not create instance and device");

			initAllocTracker(99999);
		}
		else
		{
			initAllocTracker(max_allowed_alloc, failIndex++);

			if (failIndex >= static_cast<deUint32>(max_allowed_alloc))
				return tcu::TestStatus::fail("Out of retries, could not create instance and device");
		}

		// if the number of allocations the driver makes is large, we may end up
		// taking more than the watchdog timeout. touch here to avoid spurious
		// failures.
		if (failIndex % 128 == 0)
			context.getTestContext().touchWatchdog();

		result = vkp.createInstance(&instanceCreateInfo, &allocationCallbacks, &instance);

		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
		{
			if (!isAllocTrackerEmpty())
				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));

			freeAllocTracker();
			continue;
		}
		else if (result != VK_SUCCESS)
			return tcu::TestStatus::fail("createInstance returned " + de::toString(result));

		const InstanceDriver		instanceDriver	(vkp, instance);
		const InstanceInterface&	vki				(instanceDriver);

		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, DE_NULL);

		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
		{
			vki.destroyInstance(instance, &allocationCallbacks);

			if (!isAllocTrackerEmpty())
				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));

			freeAllocTracker();
			continue;
		}
		else if (result != VK_SUCCESS)
			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));

		vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);

		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());

		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
		{
			vki.destroyInstance(instance, &allocationCallbacks);

			if (!isAllocTrackerEmpty())
				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));

			freeAllocTracker();
			continue;
		}
		else if (result != VK_SUCCESS)
			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));

		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, DE_NULL);

		if (queueFamilyCount == 0u)
			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");

		vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);

		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, queueFamilies.data());

		if (queueFamilyCount == 0u)
			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");

		for (deUint32 i = 0; i < queueFamilyCount; i++)
		{
			if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
			{
				queueFamilyIndex = i;
				break;
			}
		}

		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
			DE_NULL,									// pNext
			(VkDeviceQueueCreateFlags)0u,				// flags
			queueFamilyIndex,							// queueFamilyIndex
			1u,											// queueCount
			&queuePriority								// pQueuePriorities
		};

		const VkDeviceCreateInfo		deviceCreateInfo		=
		{
			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// sType
			DE_NULL,									// pNext
			(VkDeviceCreateFlags)0u,					// flags
			1u,											// queueCreateInfoCount
			&deviceQueueCreateInfo,						// pQueueCreateInfos
			0u,											// enabledLayerCount
			DE_NULL,									// ppEnabledLayerNames
			0u,											// enabledExtensionCount
			DE_NULL,									// ppEnabledExtensionNames
			DE_NULL										// pEnabledFeatures
		};

		result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vki, physicalDevices[chosenDevice], &deviceCreateInfo, &allocationCallbacks, &device);

		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
		{
			vki.destroyInstance(instance, &allocationCallbacks);

			if (!isAllocTrackerEmpty())
				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));

			freeAllocTracker();
			continue;
		}
		else if (result != VK_SUCCESS)
			return tcu::TestStatus::fail("VkCreateDevice returned " + de::toString(result));

		DeviceDriver(vkp, instance, device).destroyDevice(device, &allocationCallbacks);
		vki.destroyInstance(instance, &allocationCallbacks);
		if (max_allowed_alloc == 0)
		{
			max_allowed_alloc	= g_allocationsCount + 100;
			result				= VK_ERROR_OUT_OF_HOST_MEMORY;
		}
		freeAllocTracker();
	}
	while (result == VK_ERROR_OUT_OF_HOST_MEMORY);

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

} // anonymous

tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));

	addFunctionCase(deviceInitializationTests.get(), "create_instance_name_version",					"", createInstanceTest);
	addFunctionCase(deviceInitializationTests.get(), "create_instance_invalid_api_version",				"", createInstanceWithInvalidApiVersionTest);
	addFunctionCase(deviceInitializationTests.get(), "create_instance_null_appinfo",					"", createInstanceWithNullApplicationInfoTest);
	addFunctionCase(deviceInitializationTests.get(), "create_instance_unsupported_extensions",			"", createInstanceWithUnsupportedExtensionsTest);
	addFunctionCase(deviceInitializationTests.get(), "create_instance_extension_name_abuse",			"", createInstanceWithExtensionNameAbuseTest);
	addFunctionCase(deviceInitializationTests.get(), "create_instance_layer_name_abuse",				"", createInstanceWithLayerNameAbuseTest);
	addFunctionCase(deviceInitializationTests.get(), "enumerate_devices_alloc_leak",					"", enumerateDevicesAllocLeakTest);
	addFunctionCase(deviceInitializationTests.get(), "create_device",									"", createDeviceTest);
	addFunctionCase(deviceInitializationTests.get(), "create_multiple_devices",							"", createMultipleDevicesTest);
	addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_extensions",			"", createDeviceWithUnsupportedExtensionsTest);
	addFunctionCase(deviceInitializationTests.get(), "create_device_various_queue_counts",				"", createDeviceWithVariousQueueCountsTest);
	addFunctionCase(deviceInitializationTests.get(), "create_device_global_priority",					"", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest);
	addFunctionCase(deviceInitializationTests.get(), "create_device_global_priority_query",				"", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest);
	addFunctionCase(deviceInitializationTests.get(), "create_device_features2",							"", createDeviceFeatures2Test);
	addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_features",				"", createDeviceWithUnsupportedFeaturesTest);
	addFunctionCase(deviceInitializationTests.get(), "create_device_queue2",							"", createDeviceQueue2Test);
	addFunctionCase(deviceInitializationTests.get(), "create_device_queue2_unmatched_flags",			"", createDeviceQueue2UnmatchedFlagsTest);
	addFunctionCase(deviceInitializationTests.get(), "create_instance_device_intentional_alloc_fail",	"", createInstanceDeviceIntentionalAllocFail);

	return deviceInitializationTests.release();
}

} // api
} // vkt
