Home | History | Annotate | Download | only in api
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 Google Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Device Initialization Tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktApiDeviceInitializationTests.hpp"
     25 #include "vktTestCaseUtil.hpp"
     26 
     27 #include "vkDefs.hpp"
     28 #include "vkPlatform.hpp"
     29 #include "vkStrUtil.hpp"
     30 #include "vkRef.hpp"
     31 #include "vkRefUtil.hpp"
     32 #include "vkQueryUtil.hpp"
     33 #include "vkMemUtil.hpp"
     34 #include "vkDeviceUtil.hpp"
     35 #include "vkApiVersion.hpp"
     36 
     37 #include "tcuTestLog.hpp"
     38 #include "tcuResultCollector.hpp"
     39 
     40 #include "deUniquePtr.hpp"
     41 #include "deStringUtil.hpp"
     42 
     43 #include <vector>
     44 
     45 namespace vkt
     46 {
     47 namespace api
     48 {
     49 
     50 namespace
     51 {
     52 
     53 using namespace vk;
     54 using namespace std;
     55 using std::vector;
     56 using tcu::TestLog;
     57 
     58 tcu::TestStatus createInstanceTest (Context& context)
     59 {
     60 	tcu::TestLog&				log						= context.getTestContext().getLog();
     61 	tcu::ResultCollector		resultCollector			(log);
     62 	const char*					appNames[]				= { "appName", DE_NULL, "",  "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" };
     63 	const char*					engineNames[]			= { "engineName", DE_NULL, "",  "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" };
     64 	const int					patchNumbers[]			= { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 };
     65 	const deUint32				appVersions[]			= { 0, 1, (deUint32)-1 };
     66 	const deUint32				engineVersions[]		= { 0, 1, (deUint32)-1 };
     67 	const PlatformInterface&	platformInterface		= context.getPlatformInterface();
     68 	const deUint32				apiVersion				= context.getUsedApiVersion();
     69 	vector<VkApplicationInfo>	appInfos;
     70 
     71 	// test over appName
     72 	for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++)
     73 	{
     74 		const VkApplicationInfo appInfo =
     75 		{
     76 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
     77 			DE_NULL,								// const void*					pNext;
     78 			appNames[appNameNdx],					// const char*					pAppName;
     79 			0u,										// deUint32						appVersion;
     80 			"engineName",							// const char*					pEngineName;
     81 			0u,										// deUint32						engineVersion;
     82 			apiVersion,								// deUint32						apiVersion;
     83 		};
     84 
     85 		appInfos.push_back(appInfo);
     86 	}
     87 
     88 	// test over engineName
     89 	for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++)
     90 	{
     91 		const VkApplicationInfo appInfo =
     92 		{
     93 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
     94 			DE_NULL,								// const void*					pNext;
     95 			"appName",								// const char*					pAppName;
     96 			0u,										// deUint32						appVersion;
     97 			engineNames[engineNameNdx],				// const char*					pEngineName;
     98 			0u,										// deUint32						engineVersion;
     99 			apiVersion,								// deUint32						apiVersion;
    100 		};
    101 
    102 		appInfos.push_back(appInfo);
    103 	}
    104 
    105 	// test over appVersion
    106 	for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++)
    107 	{
    108 		const VkApplicationInfo appInfo =
    109 		{
    110 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
    111 			DE_NULL,								// const void*					pNext;
    112 			"appName",								// const char*					pAppName;
    113 			appVersions[appVersionNdx],				// deUint32						appVersion;
    114 			"engineName",							// const char*					pEngineName;
    115 			0u,										// deUint32						engineVersion;
    116 			apiVersion,								// deUint32						apiVersion;
    117 		};
    118 
    119 		appInfos.push_back(appInfo);
    120 	}
    121 
    122 	// test over engineVersion
    123 	for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++)
    124 	{
    125 		const VkApplicationInfo appInfo =
    126 		{
    127 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
    128 			DE_NULL,								// const void*					pNext;
    129 			"appName",								// const char*					pAppName;
    130 			0u,										// deUint32						appVersion;
    131 			"engineName",							// const char*					pEngineName;
    132 			engineVersions[engineVersionNdx],		// deUint32						engineVersion;
    133 			apiVersion,								// deUint32						apiVersion;
    134 		};
    135 
    136 		appInfos.push_back(appInfo);
    137 	}
    138 	const deUint32	manjorNum	= unpackVersion(apiVersion).majorNum;
    139 	const deUint32	minorNum	= unpackVersion(apiVersion).minorNum;
    140 
    141 	// patch component of api version checking (should be ignored by implementation)
    142 	for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++)
    143 	{
    144 		const VkApplicationInfo appInfo =
    145 		{
    146 			VK_STRUCTURE_TYPE_APPLICATION_INFO,									// VkStructureType				sType;
    147 			DE_NULL,															// const void*					pNext;
    148 			"appName",															// const char*					pAppName;
    149 			0u,																	// deUint32						appVersion;
    150 			"engineName",														// const char*					pEngineName;
    151 			0u,																	// deUint32						engineVersion;
    152 			VK_MAKE_VERSION(manjorNum, minorNum, patchNumbers[patchVersion]),	// deUint32						apiVersion;
    153 		};
    154 
    155 		appInfos.push_back(appInfo);
    156 	}
    157 
    158 	// test when apiVersion is 0
    159 	{
    160 		const VkApplicationInfo appInfo =
    161 		{
    162 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
    163 			DE_NULL,								// const void*					pNext;
    164 			"appName",								// const char*					pAppName;
    165 			0u,										// deUint32						appVersion;
    166 			"engineName",							// const char*					pEngineName;
    167 			0u,										// deUint32						engineVersion;
    168 			0u,										// deUint32						apiVersion;
    169 		};
    170 
    171 		appInfos.push_back(appInfo);
    172 	}
    173 
    174 	// run the tests!
    175 	for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx)
    176 	{
    177 		const VkApplicationInfo&		appInfo					= appInfos[appInfoNdx];
    178 		const VkInstanceCreateInfo		instanceCreateInfo		=
    179 		{
    180 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
    181 			DE_NULL,								// const void*					pNext;
    182 			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
    183 			&appInfo,								// const VkApplicationInfo*		pAppInfo;
    184 			0u,										// deUint32						layerCount;
    185 			DE_NULL,								// const char*const*			ppEnabledLayernames;
    186 			0u,										// deUint32						extensionCount;
    187 			DE_NULL,								// const char*const*			ppEnabledExtensionNames;
    188 		};
    189 
    190 		log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage;
    191 
    192 		try
    193 		{
    194 			const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo));
    195 			log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
    196 		}
    197 		catch (const vk::Error& err)
    198 		{
    199 			resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
    200 		}
    201 	}
    202 
    203 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
    204 }
    205 
    206 tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context)
    207 {
    208 	tcu::TestLog&				log						= context.getTestContext().getLog();
    209 	tcu::ResultCollector		resultCollector			(log);
    210 	const PlatformInterface&	platformInterface		= context.getPlatformInterface();
    211 
    212 	deUint32					instanceApiVersion		= 0u;
    213 	context.getPlatformInterface().enumerateInstanceVersion(&instanceApiVersion);
    214 
    215 	const ApiVersion			apiVersion				= unpackVersion(instanceApiVersion);
    216 
    217 	const deUint32				invalidMajorVersion		= (1 << 10) - 1;
    218 	const deUint32				invalidMinorVersion		= (1 << 10) - 1;
    219 	vector<ApiVersion>			invalidApiVersions;
    220 
    221 	invalidApiVersions.push_back(ApiVersion(invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
    222 	invalidApiVersions.push_back(ApiVersion(apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum));
    223 
    224 	for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++)
    225 	{
    226 		const VkApplicationInfo appInfo					=
    227 		{
    228 			VK_STRUCTURE_TYPE_APPLICATION_INFO,			// VkStructureType				sType;
    229 			DE_NULL,									// const void*					pNext;
    230 			"appName",									// const char*					pAppName;
    231 			0u,											// deUint32						appVersion;
    232 			"engineName",								// const char*					pEngineName;
    233 			0u,											// deUint32						engineVersion;
    234 			pack(invalidApiVersions[apiVersionNdx]),	// deUint32						apiVersion;
    235 		};
    236 		const VkInstanceCreateInfo instanceCreateInfo	=
    237 		{
    238 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,		// VkStructureType				sType;
    239 			DE_NULL,									// const void*					pNext;
    240 			(VkInstanceCreateFlags)0u,					// VkInstanceCreateFlags		flags;
    241 			&appInfo,									// const VkApplicationInfo*		pAppInfo;
    242 			0u,											// deUint32						layerCount;
    243 			DE_NULL,									// const char*const*			ppEnabledLayernames;
    244 			0u,											// deUint32						extensionCount;
    245 			DE_NULL,									// const char*const*			ppEnabledExtensionNames;
    246 		};
    247 
    248 
    249 		log << TestLog::Message
    250 			<< "API version reported by enumerateInstanceVersion: " << apiVersion
    251 			<< ", api version used to create instance: " << invalidApiVersions[apiVersionNdx]
    252 			<< TestLog::EndMessage;
    253 
    254 		{
    255 			VkInstance			instance				= (VkInstance)0;
    256 			const VkResult		result					= platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
    257 			const bool			gotInstance				= !!instance;
    258 
    259 			if (instance)
    260 			{
    261 				const InstanceDriver	instanceIface(platformInterface, instance);
    262 				instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
    263 			}
    264 
    265 			if (apiVersion.majorNum == 1 && apiVersion.minorNum == 0)
    266 			{
    267 				if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
    268 				{
    269 					TCU_CHECK(!gotInstance);
    270 					log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
    271 				}
    272 				else
    273 					resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
    274 			}
    275 			else if (apiVersion.majorNum == 1 && apiVersion.minorNum >= 1)
    276 			{
    277 				if (result == VK_SUCCESS)
    278 				{
    279 					TCU_CHECK(gotInstance);
    280 					log << TestLog::Message << "Pass, instance creation with nonstandard apiVersion succeeds for Vulkan 1.1" << TestLog::EndMessage;
    281 				}
    282 				else if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
    283 				{
    284 					resultCollector.fail("Fail, In Vulkan 1.1 instance creation must not return VK_ERROR_INCOMPATIBLE_DRIVER.");
    285 				}
    286 				else
    287 				{
    288 					std::ostringstream message;
    289 					message << "Fail, createInstance failed with " << result;
    290 					resultCollector.fail(message.str().c_str());
    291 				}
    292 			}
    293 		}
    294 	}
    295 
    296 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
    297 }
    298 
    299 tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context)
    300 {
    301 	tcu::TestLog&				log						= context.getTestContext().getLog();
    302 	tcu::ResultCollector		resultCollector			(log);
    303 	const PlatformInterface&	platformInterface		= context.getPlatformInterface();
    304 
    305 	const VkInstanceCreateInfo		instanceCreateInfo		=
    306 	{
    307 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
    308 		DE_NULL,								// const void*					pNext;
    309 		(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
    310 		DE_NULL,								// const VkApplicationInfo*		pAppInfo;
    311 		0u,										// deUint32						layerCount;
    312 		DE_NULL,								// const char*const*			ppEnabledLayernames;
    313 		0u,										// deUint32						extensionCount;
    314 		DE_NULL,								// const char*const*			ppEnabledExtensionNames;
    315 	};
    316 
    317 	log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage;
    318 
    319 	try
    320 	{
    321 		const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo));
    322 		log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
    323 	}
    324 	catch (const vk::Error& err)
    325 	{
    326 		resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
    327 	}
    328 
    329 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
    330 }
    331 
    332 tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context)
    333 {
    334 	tcu::TestLog&						log						= context.getTestContext().getLog();
    335 	const PlatformInterface&			platformInterface		= context.getPlatformInterface();
    336 	const char*							enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"};
    337 	const deUint32						apiVersion				= context.getUsedApiVersion();
    338 	const VkApplicationInfo				appInfo					=
    339 	{
    340 		VK_STRUCTURE_TYPE_APPLICATION_INFO,						// VkStructureType				sType;
    341 		DE_NULL,												// const void*					pNext;
    342 		"appName",												// const char*					pAppName;
    343 		0u,														// deUint32						appVersion;
    344 		"engineName",											// const char*					pEngineName;
    345 		0u,														// deUint32						engineVersion;
    346 		apiVersion,												// deUint32						apiVersion;
    347 	};
    348 	const VkInstanceCreateInfo			instanceCreateInfo		=
    349 	{
    350 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,					// VkStructureType				sType;
    351 		DE_NULL,												// const void*					pNext;
    352 		(VkInstanceCreateFlags)0u,								// VkInstanceCreateFlags		flags;
    353 		&appInfo,												// const VkApplicationInfo*		pAppInfo;
    354 		0u,														// deUint32						layerCount;
    355 		DE_NULL,												// const char*const*			ppEnabledLayernames;
    356 		DE_LENGTH_OF_ARRAY(enabledExtensions),					// deUint32						extensionCount;
    357 		enabledExtensions,										// const char*const*			ppEnabledExtensionNames;
    358 	};
    359 
    360 	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
    361 
    362 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
    363 		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
    364 
    365 	{
    366 		VkInstance		instance	= (VkInstance)0;
    367 		const VkResult	result		= platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
    368 		const bool		gotInstance	= !!instance;
    369 
    370 		if (instance)
    371 		{
    372 			const InstanceDriver	instanceIface	(platformInterface, instance);
    373 			instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
    374 		}
    375 
    376 		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
    377 		{
    378 			TCU_CHECK(!gotInstance);
    379 			return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected.");
    380 		}
    381 		else
    382 			return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded.");
    383 	}
    384 }
    385 
    386 tcu::TestStatus createDeviceTest (Context& context)
    387 {
    388 	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
    389 	const Unique<VkInstance>		instance				(createDefaultInstance(platformInterface, context.getUsedApiVersion()));
    390 	const InstanceDriver			instanceDriver			(platformInterface, instance.get());
    391 	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
    392 	const deUint32					queueFamilyIndex		= 0;
    393 	const deUint32					queueCount				= 1;
    394 	const deUint32					queueIndex				= 0;
    395 	const float						queuePriority			= 1.0f;
    396 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
    397 	{
    398 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    399 		DE_NULL,
    400 		(VkDeviceQueueCreateFlags)0u,
    401 		queueFamilyIndex,						//queueFamilyIndex;
    402 		queueCount,								//queueCount;
    403 		&queuePriority,							//pQueuePriorities;
    404 	};
    405 	const VkDeviceCreateInfo		deviceCreateInfo	=
    406 	{
    407 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
    408 		DE_NULL,								//pNext;
    409 		(VkDeviceCreateFlags)0u,
    410 		1,										//queueRecordCount;
    411 		&deviceQueueCreateInfo,					//pRequestedQueues;
    412 		0,										//layerCount;
    413 		DE_NULL,								//ppEnabledLayerNames;
    414 		0,										//extensionCount;
    415 		DE_NULL,								//ppEnabledExtensionNames;
    416 		DE_NULL,								//pEnabledFeatures;
    417 	};
    418 
    419 	const Unique<VkDevice>			device					(createDevice(instanceDriver, physicalDevice, &deviceCreateInfo));
    420 	const DeviceDriver				deviceDriver			(instanceDriver, device.get());
    421 	const VkQueue					queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
    422 
    423 	VK_CHECK(deviceDriver.queueWaitIdle(queue));
    424 
    425 	return tcu::TestStatus::pass("Pass");
    426 }
    427 
    428 tcu::TestStatus createMultipleDevicesTest (Context& context)
    429 {
    430 	tcu::TestLog&										log						= context.getTestContext().getLog();
    431 	tcu::ResultCollector								resultCollector			(log);
    432 	const int											numDevices				= 5;
    433 	const PlatformInterface&							platformInterface		= context.getPlatformInterface();
    434 	const Unique<VkInstance>							instance				(createDefaultInstance(platformInterface, context.getUsedApiVersion()));
    435 	const InstanceDriver								instanceDriver			(platformInterface, instance.get());
    436 	const VkPhysicalDevice								physicalDevice			= chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
    437 	const deUint32										queueFamilyIndex		= 0;
    438 	const deUint32										queueCount				= 1;
    439 	const deUint32										queueIndex				= 0;
    440 	const float											queuePriority			= 1.0f;
    441 	const VkDeviceQueueCreateInfo						deviceQueueCreateInfo	=
    442 	{
    443 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    444 		DE_NULL,
    445 		(VkDeviceQueueCreateFlags)0u,					//flags;
    446 		queueFamilyIndex,								//queueFamilyIndex;
    447 		queueCount,										//queueCount;
    448 		&queuePriority,									//pQueuePriorities;
    449 	};
    450 	const VkDeviceCreateInfo							deviceCreateInfo		=
    451 	{
    452 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,			//sType;
    453 		DE_NULL,										//pNext;
    454 		(VkDeviceCreateFlags)0u,
    455 		1,												//queueRecordCount;
    456 		&deviceQueueCreateInfo,							//pRequestedQueues;
    457 		0,												//layerCount;
    458 		DE_NULL,										//ppEnabledLayerNames;
    459 		0,												//extensionCount;
    460 		DE_NULL,										//ppEnabledExtensionNames;
    461 		DE_NULL,										//pEnabledFeatures;
    462 	};
    463 	vector<VkDevice>									devices(numDevices, (VkDevice)DE_NULL);
    464 
    465 	try
    466 	{
    467 		for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++)
    468 		{
    469 			const VkResult result = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]);
    470 
    471 			if (result != VK_SUCCESS)
    472 			{
    473 				resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result));
    474 				break;
    475 			}
    476 
    477 			{
    478 				const DeviceDriver	deviceDriver	(instanceDriver, devices[deviceNdx]);
    479 				const VkQueue		queue			= getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex);
    480 
    481 				VK_CHECK(deviceDriver.queueWaitIdle(queue));
    482 			}
    483 		}
    484 	}
    485 	catch (const vk::Error& error)
    486 	{
    487 		resultCollector.fail(de::toString(error.getError()));
    488 	}
    489 	catch (...)
    490 	{
    491 		for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
    492 		{
    493 			if (devices[deviceNdx] != (VkDevice)DE_NULL)
    494 			{
    495 				DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]);
    496 				deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
    497 			}
    498 		}
    499 
    500 		throw;
    501 	}
    502 
    503 	for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
    504 	{
    505 		if (devices[deviceNdx] != (VkDevice)DE_NULL)
    506 		{
    507 			DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]);
    508 			deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
    509 		}
    510 	}
    511 
    512 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
    513 }
    514 
    515 tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context)
    516 {
    517 	tcu::TestLog&					log						= context.getTestContext().getLog();
    518 	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
    519 	const Unique<VkInstance>		instance				(createDefaultInstance(platformInterface, context.getUsedApiVersion()));
    520 	const InstanceDriver			instanceDriver			(platformInterface, instance.get());
    521 	const char*						enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"};
    522 	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
    523 	const float						queuePriority			= 1.0f;
    524 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
    525 	{
    526 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    527 		DE_NULL,
    528 		(VkDeviceQueueCreateFlags)0u,
    529 		0,										//queueFamilyIndex;
    530 		1,										//queueCount;
    531 		&queuePriority,							//pQueuePriorities;
    532 	};
    533 	const VkDeviceCreateInfo		deviceCreateInfo		=
    534 	{
    535 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
    536 		DE_NULL,								//pNext;
    537 		(VkDeviceCreateFlags)0u,
    538 		1,										//queueRecordCount;
    539 		&deviceQueueCreateInfo,					//pRequestedQueues;
    540 		0,										//layerCount;
    541 		DE_NULL,								//ppEnabledLayerNames;
    542 		DE_LENGTH_OF_ARRAY(enabledExtensions),	//extensionCount;
    543 		enabledExtensions,						//ppEnabledExtensionNames;
    544 		DE_NULL,								//pEnabledFeatures;
    545 	};
    546 
    547 	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
    548 
    549 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
    550 		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
    551 
    552 	{
    553 		VkDevice		device		= (VkDevice)0;
    554 		const VkResult	result		= instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device);
    555 		const bool		gotDevice	= !!device;
    556 
    557 		if (device)
    558 		{
    559 			const DeviceDriver	deviceIface	(instanceDriver, device);
    560 			deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
    561 		}
    562 
    563 		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
    564 		{
    565 			TCU_CHECK(!gotDevice);
    566 			return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected.");
    567 		}
    568 		else
    569 			return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed.");
    570 	}
    571 }
    572 
    573 deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)
    574 {
    575 	deUint32 maxQueueCount = 0;
    576 
    577 	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
    578 	{
    579 		maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount);
    580 	}
    581 
    582 	return maxQueueCount;
    583 }
    584 
    585 tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context)
    586 {
    587 	tcu::TestLog&							log						= context.getTestContext().getLog();
    588 	const int								queueCountDiff			= 1;
    589 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
    590 	const Unique<VkInstance>				instance				(createDefaultInstance(platformInterface, context.getUsedApiVersion()));
    591 	const InstanceDriver					instanceDriver			(platformInterface, instance.get());
    592 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
    593 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
    594 	const vector<float>						queuePriorities			(getGlobalMaxQueueCount(queueFamilyProperties), 1.0f);
    595 	vector<VkDeviceQueueCreateInfo>			deviceQueueCreateInfos;
    596 
    597 	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
    598 	{
    599 		const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount;
    600 
    601 		for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff)
    602 		{
    603 			const VkDeviceQueueCreateInfo queueCreateInfo =
    604 			{
    605 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    606 				DE_NULL,
    607 				(VkDeviceQueueCreateFlags)0u,
    608 				queueFamilyNdx,
    609 				queueCount,
    610 				queuePriorities.data()
    611 			};
    612 
    613 			deviceQueueCreateInfos.push_back(queueCreateInfo);
    614 		}
    615 	}
    616 
    617 	for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++)
    618 	{
    619 		const VkDeviceQueueCreateInfo&	queueCreateInfo		= deviceQueueCreateInfos[testNdx];
    620 		const VkDeviceCreateInfo		deviceCreateInfo	=
    621 		{
    622 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
    623 			DE_NULL,								//pNext;
    624 			(VkDeviceCreateFlags)0u,
    625 			1,										//queueRecordCount;
    626 			&queueCreateInfo,						//pRequestedQueues;
    627 			0,										//layerCount;
    628 			DE_NULL,								//ppEnabledLayerNames;
    629 			0,										//extensionCount;
    630 			DE_NULL,								//ppEnabledExtensionNames;
    631 			DE_NULL,								//pEnabledFeatures;
    632 		};
    633 		const Unique<VkDevice>			device				(createDevice(instanceDriver, physicalDevice, &deviceCreateInfo));
    634 		const DeviceDriver				deviceDriver		(instanceDriver, device.get());
    635 		const deUint32					queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
    636 		const deUint32					queueCount			= deviceCreateInfo.pQueueCreateInfos->queueCount;
    637 
    638 		for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++)
    639 		{
    640 			const VkQueue		queue	= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex);
    641 			VkResult			result;
    642 
    643 			TCU_CHECK(!!queue);
    644 
    645 			result = deviceDriver.queueWaitIdle(queue);
    646 			if (result != VK_SUCCESS)
    647 			{
    648 				log << TestLog::Message
    649 					<< "vkQueueWaitIdle failed"
    650 					<< ",  queueIndex = " << queueIndex
    651 					<< ", queueCreateInfo " << queueCreateInfo
    652 					<< ", Error Code: " << result
    653 					<< TestLog::EndMessage;
    654 				return tcu::TestStatus::fail("Fail");
    655 			}
    656 		}
    657 	}
    658 	return tcu::TestStatus::pass("Pass");
    659 }
    660 
    661 Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, const char* extensionName, Context& context)
    662 {
    663 	const vector<VkExtensionProperties>	instanceExts		= enumerateInstanceExtensionProperties(vkp, DE_NULL);
    664 	vector<string>						enabledExts;
    665 
    666 	const deUint32						instanceVersion		= context.getUsedApiVersion();
    667 
    668 	if (!isCoreInstanceExtension(instanceVersion, extensionName))
    669 	{
    670 		if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName)))
    671 			TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str());
    672 		else
    673 			enabledExts.push_back(extensionName);
    674 	}
    675 
    676 	return createDefaultInstance(vkp, instanceVersion, vector<string>() /* layers */, enabledExts);
    677 }
    678 
    679 tcu::TestStatus createDeviceFeatures2Test (Context& context)
    680 {
    681 	const PlatformInterface&		vkp						= context.getPlatformInterface();
    682 	const Unique<VkInstance>		instance				(createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
    683 	const InstanceDriver			vki						(vkp, instance.get());
    684 	const VkPhysicalDevice			physicalDevice			= chooseDevice(vki, instance.get(), context.getTestContext().getCommandLine());
    685 	const deUint32					queueFamilyIndex		= 0;
    686 	const deUint32					queueCount				= 1;
    687 	const deUint32					queueIndex				= 0;
    688 	const float						queuePriority			= 1.0f;
    689 
    690 	VkPhysicalDeviceFeatures2		enabledFeatures;
    691 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
    692 	{
    693 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    694 		DE_NULL,
    695 		(VkDeviceQueueCreateFlags)0u,
    696 		queueFamilyIndex,
    697 		queueCount,
    698 		&queuePriority,
    699 	};
    700 	const VkDeviceCreateInfo		deviceCreateInfo	=
    701 	{
    702 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
    703 		&enabledFeatures,
    704 		(VkDeviceCreateFlags)0u,
    705 		1,
    706 		&deviceQueueCreateInfo,
    707 		0,
    708 		DE_NULL,
    709 		0,
    710 		DE_NULL,
    711 		DE_NULL,
    712 	};
    713 
    714 	// Populate enabledFeatures
    715 	enabledFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    716 	enabledFeatures.pNext		= DE_NULL;
    717 
    718 	vki.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
    719 
    720 	{
    721 		const Unique<VkDevice>	device		(createDevice(vki, physicalDevice, &deviceCreateInfo));
    722 		const DeviceDriver		vkd			(vki, device.get());
    723 		const VkQueue			queue		= getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);
    724 
    725 		VK_CHECK(vkd.queueWaitIdle(queue));
    726 	}
    727 
    728 	return tcu::TestStatus::pass("Pass");
    729 }
    730 
    731 struct Feature
    732 {
    733 	const char*	name;
    734 	size_t		offset;
    735 };
    736 
    737 #define FEATURE_ITEM(MEMBER) {#MEMBER, DE_OFFSET_OF(VkPhysicalDeviceFeatures, MEMBER)}
    738 
    739 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
    740 {
    741 	tcu::TestLog&				log						= context.getTestContext().getLog();
    742 	tcu::ResultCollector		resultCollector			(log);
    743 	const PlatformInterface&	platformInterface		= context.getPlatformInterface();
    744 	const Move<VkInstance>		instance				(createDefaultInstance(platformInterface, context.getUsedApiVersion()));
    745 	const InstanceDriver		instanceDriver			(platformInterface, instance.get());
    746 	const VkPhysicalDevice		physicalDevice			= chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
    747 	const deUint32				queueFamilyIndex		= 0;
    748 	const deUint32				queueCount				= 1;
    749 	const float					queuePriority			= 1.0f;
    750 	VkPhysicalDeviceFeatures	physicalDeviceFeatures;
    751 
    752 	instanceDriver.getPhysicalDeviceFeatures(physicalDevice, &physicalDeviceFeatures);
    753 
    754 	static const Feature features[] =
    755 	{
    756 		FEATURE_ITEM(robustBufferAccess),
    757 		FEATURE_ITEM(fullDrawIndexUint32),
    758 		FEATURE_ITEM(imageCubeArray),
    759 		FEATURE_ITEM(independentBlend),
    760 		FEATURE_ITEM(geometryShader),
    761 		FEATURE_ITEM(tessellationShader),
    762 		FEATURE_ITEM(sampleRateShading),
    763 		FEATURE_ITEM(dualSrcBlend),
    764 		FEATURE_ITEM(logicOp),
    765 		FEATURE_ITEM(multiDrawIndirect),
    766 		FEATURE_ITEM(drawIndirectFirstInstance),
    767 		FEATURE_ITEM(depthClamp),
    768 		FEATURE_ITEM(depthBiasClamp),
    769 		FEATURE_ITEM(fillModeNonSolid),
    770 		FEATURE_ITEM(depthBounds),
    771 		FEATURE_ITEM(wideLines),
    772 		FEATURE_ITEM(largePoints),
    773 		FEATURE_ITEM(alphaToOne),
    774 		FEATURE_ITEM(multiViewport),
    775 		FEATURE_ITEM(samplerAnisotropy),
    776 		FEATURE_ITEM(textureCompressionETC2),
    777 		FEATURE_ITEM(textureCompressionASTC_LDR),
    778 		FEATURE_ITEM(textureCompressionBC),
    779 		FEATURE_ITEM(occlusionQueryPrecise),
    780 		FEATURE_ITEM(pipelineStatisticsQuery),
    781 		FEATURE_ITEM(vertexPipelineStoresAndAtomics),
    782 		FEATURE_ITEM(fragmentStoresAndAtomics),
    783 		FEATURE_ITEM(shaderTessellationAndGeometryPointSize),
    784 		FEATURE_ITEM(shaderImageGatherExtended),
    785 		FEATURE_ITEM(shaderStorageImageExtendedFormats),
    786 		FEATURE_ITEM(shaderStorageImageMultisample),
    787 		FEATURE_ITEM(shaderStorageImageReadWithoutFormat),
    788 		FEATURE_ITEM(shaderStorageImageWriteWithoutFormat),
    789 		FEATURE_ITEM(shaderUniformBufferArrayDynamicIndexing),
    790 		FEATURE_ITEM(shaderSampledImageArrayDynamicIndexing),
    791 		FEATURE_ITEM(shaderStorageBufferArrayDynamicIndexing),
    792 		FEATURE_ITEM(shaderStorageImageArrayDynamicIndexing),
    793 		FEATURE_ITEM(shaderClipDistance),
    794 		FEATURE_ITEM(shaderCullDistance),
    795 		FEATURE_ITEM(shaderFloat64),
    796 		FEATURE_ITEM(shaderInt64),
    797 		FEATURE_ITEM(shaderInt16),
    798 		FEATURE_ITEM(shaderResourceResidency),
    799 		FEATURE_ITEM(shaderResourceMinLod),
    800 		FEATURE_ITEM(sparseBinding),
    801 		FEATURE_ITEM(sparseResidencyBuffer),
    802 		FEATURE_ITEM(sparseResidencyImage2D),
    803 		FEATURE_ITEM(sparseResidencyImage3D),
    804 		FEATURE_ITEM(sparseResidency2Samples),
    805 		FEATURE_ITEM(sparseResidency4Samples),
    806 		FEATURE_ITEM(sparseResidency8Samples),
    807 		FEATURE_ITEM(sparseResidency16Samples),
    808 		FEATURE_ITEM(sparseResidencyAliased),
    809 		FEATURE_ITEM(variableMultisampleRate),
    810 		FEATURE_ITEM(inheritedQueries)
    811 	};
    812 
    813 	const int	numFeatures		= DE_LENGTH_OF_ARRAY(features);
    814 	int			numErrors		= 0;
    815 
    816 	for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
    817 	{
    818 		// Test only features that are not supported.
    819 		if (*(((VkBool32*)((deUint8*)(&physicalDeviceFeatures) + features[featureNdx].offset))))
    820 			continue;
    821 
    822 		VkPhysicalDeviceFeatures enabledFeatures;
    823 
    824 		for (int i = 0; i < numFeatures; i++)
    825 			*((VkBool32*)((deUint8*)(&enabledFeatures) + features[i].offset)) = (i == featureNdx ? VK_TRUE : VK_FALSE);
    826 
    827 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
    828 		{
    829 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    830 			DE_NULL,
    831 			(VkDeviceQueueCreateFlags)0u,
    832 			queueFamilyIndex,
    833 			queueCount,
    834 			&queuePriority
    835 		};
    836 		const VkDeviceCreateInfo		deviceCreateInfo		=
    837 		{
    838 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
    839 			DE_NULL,
    840 			(VkDeviceCreateFlags)0u,
    841 			1,
    842 			&deviceQueueCreateInfo,
    843 			0,
    844 			DE_NULL,
    845 			0,
    846 			DE_NULL,
    847 			&enabledFeatures
    848 		};
    849 
    850 		VkDevice		device;
    851 		const VkResult	res	= instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL, &device);
    852 
    853 		if (res != VK_ERROR_FEATURE_NOT_PRESENT)
    854 		{
    855 			numErrors++;
    856 			resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
    857 								 + de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
    858 		}
    859 	}
    860 
    861 	if (numErrors > 1)
    862 		return tcu::TestStatus(resultCollector.getResult(), "Enabling " + de::toString(numErrors) + " unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
    863 	else
    864 		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
    865 }
    866 
    867 } // anonymous
    868 
    869 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
    870 {
    871 	de::MovePtr<tcu::TestCaseGroup>	deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));
    872 
    873 	addFunctionCase(deviceInitializationTests.get(), "create_instance_name_version",			"", createInstanceTest);
    874 	addFunctionCase(deviceInitializationTests.get(), "create_instance_invalid_api_version",		"", createInstanceWithInvalidApiVersionTest);
    875 	addFunctionCase(deviceInitializationTests.get(), "create_instance_null_appinfo",		    "", createInstanceWithNullApplicationInfoTest);
    876 	addFunctionCase(deviceInitializationTests.get(), "create_instance_unsupported_extensions",	"", createInstanceWithUnsupportedExtensionsTest);
    877 	addFunctionCase(deviceInitializationTests.get(), "create_device",							"", createDeviceTest);
    878 	addFunctionCase(deviceInitializationTests.get(), "create_multiple_devices",					"", createMultipleDevicesTest);
    879 	addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_extensions",	"", createDeviceWithUnsupportedExtensionsTest);
    880 	addFunctionCase(deviceInitializationTests.get(), "create_device_various_queue_counts",		"", createDeviceWithVariousQueueCountsTest);
    881 	addFunctionCase(deviceInitializationTests.get(), "create_device_features2",					"", createDeviceFeatures2Test);
    882 	addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_features",		"", createDeviceWithUnsupportedFeaturesTest);
    883 
    884 	return deviceInitializationTests.release();
    885 }
    886 
    887 } // api
    888 } // vkt
    889