• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "vktCustomInstancesDevices.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkStrUtil.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkDeviceUtil.hpp"
36 #include "vkApiVersion.hpp"
37 #include "vkAllocationCallbackUtil.hpp"
38 #include "vkDeviceFeatures.hpp"
39 
40 #include "tcuTestLog.hpp"
41 #include "tcuResultCollector.hpp"
42 #include "tcuCommandLine.hpp"
43 
44 #include "deUniquePtr.hpp"
45 #include "deStringUtil.hpp"
46 
47 #include <vector>
48 #include <set>
49 
50 namespace vkt
51 {
52 namespace api
53 {
54 
55 namespace
56 {
57 
58 using namespace vk;
59 using namespace std;
60 using std::vector;
61 using tcu::TestLog;
62 
createInstanceTest(Context & context)63 tcu::TestStatus createInstanceTest (Context& context)
64 {
65 	tcu::TestLog&				log						= context.getTestContext().getLog();
66 	tcu::ResultCollector		resultCollector			(log);
67 	const char*					appNames[]				= { "appName", DE_NULL, "",  "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" };
68 	const char*					engineNames[]			= { "engineName", DE_NULL, "",  "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" };
69 	const int					patchNumbers[]			= { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 };
70 	const deUint32				appVersions[]			= { 0, 1, (deUint32)-1 };
71 	const deUint32				engineVersions[]		= { 0, 1, (deUint32)-1 };
72 	const deUint32				apiVersion				= context.getUsedApiVersion();
73 	vector<VkApplicationInfo>	appInfos;
74 
75 	// test over appName
76 	for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++)
77 	{
78 		const VkApplicationInfo appInfo =
79 		{
80 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
81 			DE_NULL,								// const void*					pNext;
82 			appNames[appNameNdx],					// const char*					pAppName;
83 			0u,										// deUint32						appVersion;
84 			"engineName",							// const char*					pEngineName;
85 			0u,										// deUint32						engineVersion;
86 			apiVersion,								// deUint32						apiVersion;
87 		};
88 
89 		appInfos.push_back(appInfo);
90 	}
91 
92 	// test over engineName
93 	for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++)
94 	{
95 		const VkApplicationInfo appInfo =
96 		{
97 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
98 			DE_NULL,								// const void*					pNext;
99 			"appName",								// const char*					pAppName;
100 			0u,										// deUint32						appVersion;
101 			engineNames[engineNameNdx],				// const char*					pEngineName;
102 			0u,										// deUint32						engineVersion;
103 			apiVersion,								// deUint32						apiVersion;
104 		};
105 
106 		appInfos.push_back(appInfo);
107 	}
108 
109 	// test over appVersion
110 	for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++)
111 	{
112 		const VkApplicationInfo appInfo =
113 		{
114 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
115 			DE_NULL,								// const void*					pNext;
116 			"appName",								// const char*					pAppName;
117 			appVersions[appVersionNdx],				// deUint32						appVersion;
118 			"engineName",							// const char*					pEngineName;
119 			0u,										// deUint32						engineVersion;
120 			apiVersion,								// deUint32						apiVersion;
121 		};
122 
123 		appInfos.push_back(appInfo);
124 	}
125 
126 	// test over engineVersion
127 	for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++)
128 	{
129 		const VkApplicationInfo appInfo =
130 		{
131 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
132 			DE_NULL,								// const void*					pNext;
133 			"appName",								// const char*					pAppName;
134 			0u,										// deUint32						appVersion;
135 			"engineName",							// const char*					pEngineName;
136 			engineVersions[engineVersionNdx],		// deUint32						engineVersion;
137 			apiVersion,								// deUint32						apiVersion;
138 		};
139 
140 		appInfos.push_back(appInfo);
141 	}
142 	const deUint32	manjorNum	= unpackVersion(apiVersion).majorNum;
143 	const deUint32	minorNum	= unpackVersion(apiVersion).minorNum;
144 
145 	// patch component of api version checking (should be ignored by implementation)
146 	for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++)
147 	{
148 		const VkApplicationInfo appInfo =
149 		{
150 			VK_STRUCTURE_TYPE_APPLICATION_INFO,									// VkStructureType				sType;
151 			DE_NULL,															// const void*					pNext;
152 			"appName",															// const char*					pAppName;
153 			0u,																	// deUint32						appVersion;
154 			"engineName",														// const char*					pEngineName;
155 			0u,																	// deUint32						engineVersion;
156 			VK_MAKE_VERSION(manjorNum, minorNum, patchNumbers[patchVersion]),	// deUint32						apiVersion;
157 		};
158 
159 		appInfos.push_back(appInfo);
160 	}
161 
162 	// test when apiVersion is 0
163 	{
164 		const VkApplicationInfo appInfo =
165 		{
166 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
167 			DE_NULL,								// const void*					pNext;
168 			"appName",								// const char*					pAppName;
169 			0u,										// deUint32						appVersion;
170 			"engineName",							// const char*					pEngineName;
171 			0u,										// deUint32						engineVersion;
172 			0u,										// deUint32						apiVersion;
173 		};
174 
175 		appInfos.push_back(appInfo);
176 	}
177 
178 	// run the tests!
179 	for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx)
180 	{
181 		const VkApplicationInfo&		appInfo					= appInfos[appInfoNdx];
182 		const VkInstanceCreateInfo		instanceCreateInfo		=
183 		{
184 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
185 			DE_NULL,								// const void*					pNext;
186 			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
187 			&appInfo,								// const VkApplicationInfo*		pAppInfo;
188 			0u,										// deUint32						layerCount;
189 			DE_NULL,								// const char*const*			ppEnabledLayernames;
190 			0u,										// deUint32						extensionCount;
191 			DE_NULL,								// const char*const*			ppEnabledExtensionNames;
192 		};
193 
194 		log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage;
195 
196 		try
197 		{
198 			CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
199 			log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
200 		}
201 		catch (const vk::Error& err)
202 		{
203 			resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
204 		}
205 	}
206 
207 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
208 }
209 
createInstanceWithInvalidApiVersionTest(Context & context)210 tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context)
211 {
212 	tcu::TestLog&				log						= context.getTestContext().getLog();
213 	tcu::ResultCollector		resultCollector			(log);
214 	const PlatformInterface&	platformInterface		= context.getPlatformInterface();
215 
216 	deUint32					instanceApiVersion		= 0u;
217 	platformInterface.enumerateInstanceVersion(&instanceApiVersion);
218 
219 	const ApiVersion			apiVersion				= unpackVersion(instanceApiVersion);
220 
221 	const deUint32				invalidMajorVersion		= (1 << 10) - 1;
222 	const deUint32				invalidMinorVersion		= (1 << 10) - 1;
223 	vector<ApiVersion>			invalidApiVersions;
224 
225 	invalidApiVersions.push_back(ApiVersion(invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
226 	invalidApiVersions.push_back(ApiVersion(apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum));
227 
228 	for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++)
229 	{
230 		const VkApplicationInfo appInfo					=
231 		{
232 			VK_STRUCTURE_TYPE_APPLICATION_INFO,			// VkStructureType				sType;
233 			DE_NULL,									// const void*					pNext;
234 			"appName",									// const char*					pAppName;
235 			0u,											// deUint32						appVersion;
236 			"engineName",								// const char*					pEngineName;
237 			0u,											// deUint32						engineVersion;
238 			pack(invalidApiVersions[apiVersionNdx]),	// deUint32						apiVersion;
239 		};
240 		const VkInstanceCreateInfo	instanceCreateInfo	=
241 		{
242 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,		// VkStructureType				sType;
243 			DE_NULL,									// const void*					pNext;
244 			(VkInstanceCreateFlags)0u,					// VkInstanceCreateFlags		flags;
245 			&appInfo,									// const VkApplicationInfo*		pAppInfo;
246 			0u,											// deUint32						layerCount;
247 			DE_NULL,									// const char*const*			ppEnabledLayernames;
248 			0u,											// deUint32						extensionCount;
249 			DE_NULL,									// const char*const*			ppEnabledExtensionNames;
250 		};
251 
252 		log << TestLog::Message
253 			<< "API version reported by enumerateInstanceVersion: " << apiVersion
254 			<< ", api version used to create instance: " << invalidApiVersions[apiVersionNdx]
255 			<< TestLog::EndMessage;
256 
257 		{
258 			UncheckedInstance	instance;
259 			const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
260 
261 			if (apiVersion.majorNum == 1 && apiVersion.minorNum == 0)
262 			{
263 				if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
264 				{
265 					TCU_CHECK(!static_cast<bool>(instance));
266 					log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
267 				}
268 				else
269 					resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
270 			}
271 			else if (apiVersion.majorNum == 1 && apiVersion.minorNum >= 1)
272 			{
273 				if (result == VK_SUCCESS)
274 				{
275 					TCU_CHECK(static_cast<bool>(instance));
276 					log << TestLog::Message << "Pass, instance creation with nonstandard apiVersion succeeds for Vulkan 1.1" << TestLog::EndMessage;
277 				}
278 				else if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
279 				{
280 					resultCollector.fail("Fail, In Vulkan 1.1 instance creation must not return VK_ERROR_INCOMPATIBLE_DRIVER.");
281 				}
282 				else
283 				{
284 					std::ostringstream message;
285 					message << "Fail, createInstance failed with " << result;
286 					resultCollector.fail(message.str().c_str());
287 				}
288 			}
289 		}
290 	}
291 
292 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
293 }
294 
createInstanceWithNullApplicationInfoTest(Context & context)295 tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context)
296 {
297 	tcu::TestLog&				log						= context.getTestContext().getLog();
298 	tcu::ResultCollector		resultCollector			(log);
299 
300 	const VkInstanceCreateInfo	instanceCreateInfo		=
301 	{
302 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
303 		DE_NULL,								// const void*					pNext;
304 		(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
305 		DE_NULL,								// const VkApplicationInfo*		pAppInfo;
306 		0u,										// deUint32						layerCount;
307 		DE_NULL,								// const char*const*			ppEnabledLayernames;
308 		0u,										// deUint32						extensionCount;
309 		DE_NULL,								// const char*const*			ppEnabledExtensionNames;
310 	};
311 
312 	log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage;
313 
314 	try
315 	{
316 		CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
317 		log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
318 	}
319 	catch (const vk::Error& err)
320 	{
321 		resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
322 	}
323 
324 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
325 }
326 
createInstanceWithUnsupportedExtensionsTest(Context & context)327 tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context)
328 {
329 	tcu::TestLog&						log						= context.getTestContext().getLog();
330 	const char*							enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"};
331 	const deUint32						apiVersion				= context.getUsedApiVersion();
332 	const VkApplicationInfo				appInfo					=
333 	{
334 		VK_STRUCTURE_TYPE_APPLICATION_INFO,						// VkStructureType				sType;
335 		DE_NULL,												// const void*					pNext;
336 		"appName",												// const char*					pAppName;
337 		0u,														// deUint32						appVersion;
338 		"engineName",											// const char*					pEngineName;
339 		0u,														// deUint32						engineVersion;
340 		apiVersion,												// deUint32						apiVersion;
341 	};
342 
343 	const VkInstanceCreateInfo			instanceCreateInfo		=
344 	{
345 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,					// VkStructureType				sType;
346 		DE_NULL,												// const void*					pNext;
347 		(VkInstanceCreateFlags)0u,								// VkInstanceCreateFlags		flags;
348 		&appInfo,												// const VkApplicationInfo*		pAppInfo;
349 		0u,														// deUint32						layerCount;
350 		DE_NULL,												// const char*const*			ppEnabledLayernames;
351 		DE_LENGTH_OF_ARRAY(enabledExtensions),					// deUint32						extensionCount;
352 		enabledExtensions,										// const char*const*			ppEnabledExtensionNames;
353 	};
354 
355 	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
356 
357 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
358 		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
359 
360 	{
361 		UncheckedInstance	instance;
362 		const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
363 
364 		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
365 		{
366 			TCU_CHECK(!static_cast<bool>(instance));
367 			return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected.");
368 		}
369 		else
370 			return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded.");
371 	}
372 }
373 
374 enum
375 {
376 	UTF8ABUSE_LONGNAME = 0,
377 	UTF8ABUSE_BADNAMES,
378 	UTF8ABUSE_OVERLONGNUL,
379 	UTF8ABUSE_OVERLONG,
380 	UTF8ABUSE_ZALGO,
381 	UTF8ABUSE_CHINESE,
382 	UTF8ABUSE_EMPTY,
383 	UTF8ABUSE_MAX
384 };
385 
getUTF8AbuseString(int index)386 string getUTF8AbuseString (int index)
387 {
388 	switch (index)
389 	{
390 	case UTF8ABUSE_LONGNAME:
391 		// Generate a long name.
392 		{
393 			std::string longname;
394 			longname.resize(65535, 'k');
395 			return longname;
396 		}
397 
398 	case UTF8ABUSE_BADNAMES:
399 		// Various illegal code points in utf-8
400 		return string(
401 			"Illegal bytes in UTF-8: "
402 			"\xc0 \xc1 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff"
403 			"illegal surrogates: \xed\xad\xbf \xed\xbe\x80");
404 
405 	case UTF8ABUSE_OVERLONGNUL:
406 		// Zero encoded as overlong, not exactly legal but often supported to differentiate from terminating zero
407 		return string("UTF-8 encoded nul \xC0\x80 (should not end name)");
408 
409 	case UTF8ABUSE_OVERLONG:
410 		// Some overlong encodings
411 		return string(
412 			"UTF-8 overlong \xF0\x82\x82\xAC \xfc\x83\xbf\xbf\xbf\xbf \xf8\x87\xbf\xbf\xbf "
413 			"\xf0\x8f\xbf\xbf");
414 
415 	case UTF8ABUSE_ZALGO:
416 		// Internet "zalgo" meme "bleeding text"
417 		return string(
418 			"\x56\xcc\xb5\xcc\x85\xcc\x94\xcc\x88\xcd\x8a\xcc\x91\xcc\x88\xcd\x91\xcc\x83\xcd\x82"
419 			"\xcc\x83\xcd\x90\xcc\x8a\xcc\x92\xcc\x92\xcd\x8b\xcc\x94\xcd\x9d\xcc\x98\xcc\xab\xcc"
420 			"\xae\xcc\xa9\xcc\xad\xcc\x97\xcc\xb0\x75\xcc\xb6\xcc\xbe\xcc\x80\xcc\x82\xcc\x84\xcd"
421 			"\x84\xcc\x90\xcd\x86\xcc\x9a\xcd\x84\xcc\x9b\xcd\x86\xcd\x92\xcc\x9a\xcd\x99\xcd\x99"
422 			"\xcc\xbb\xcc\x98\xcd\x8e\xcd\x88\xcd\x9a\xcc\xa6\xcc\x9c\xcc\xab\xcc\x99\xcd\x94\xcd"
423 			"\x99\xcd\x95\xcc\xa5\xcc\xab\xcd\x89\x6c\xcc\xb8\xcc\x8e\xcc\x8b\xcc\x8b\xcc\x9a\xcc"
424 			"\x8e\xcd\x9d\xcc\x80\xcc\xa1\xcc\xad\xcd\x9c\xcc\xba\xcc\x96\xcc\xb3\xcc\xa2\xcd\x8e"
425 			"\xcc\xa2\xcd\x96\x6b\xcc\xb8\xcc\x84\xcd\x81\xcc\xbf\xcc\x8d\xcc\x89\xcc\x85\xcc\x92"
426 			"\xcc\x84\xcc\x90\xcd\x81\xcc\x93\xcd\x90\xcd\x92\xcd\x9d\xcc\x84\xcd\x98\xcd\x9d\xcd"
427 			"\xa0\xcd\x91\xcc\x94\xcc\xb9\xcd\x93\xcc\xa5\xcd\x87\xcc\xad\xcc\xa7\xcd\x96\xcd\x99"
428 			"\xcc\x9d\xcc\xbc\xcd\x96\xcd\x93\xcc\x9d\xcc\x99\xcc\xa8\xcc\xb1\xcd\x85\xcc\xba\xcc"
429 			"\xa7\x61\xcc\xb8\xcc\x8e\xcc\x81\xcd\x90\xcd\x84\xcd\x8c\xcc\x8c\xcc\x85\xcd\x86\xcc"
430 			"\x84\xcd\x84\xcc\x90\xcc\x84\xcc\x8d\xcd\x99\xcd\x8d\xcc\xb0\xcc\xa3\xcc\xa6\xcd\x89"
431 			"\xcd\x8d\xcd\x87\xcc\x98\xcd\x8d\xcc\xa4\xcd\x9a\xcd\x8e\xcc\xab\xcc\xb9\xcc\xac\xcc"
432 			"\xa2\xcd\x87\xcc\xa0\xcc\xb3\xcd\x89\xcc\xb9\xcc\xa7\xcc\xa6\xcd\x89\xcd\x95\x6e\xcc"
433 			"\xb8\xcd\x8a\xcc\x8a\xcd\x82\xcc\x9b\xcd\x81\xcd\x90\xcc\x85\xcc\x9b\xcd\x80\xcd\x91"
434 			"\xcd\x9b\xcc\x81\xcd\x81\xcc\x9a\xcc\xb3\xcd\x9c\xcc\x9e\xcc\x9d\xcd\x99\xcc\xa2\xcd"
435 			"\x93\xcd\x96\xcc\x97\xff");
436 
437 	case UTF8ABUSE_CHINESE:
438 		// Some Chinese glyphs.
439 		// "English equivalent: The devil is in the details", https://en.wikiquote.org/wiki/Chinese_proverbs
440 		return string(
441 			"\xe8\xaf\xbb\xe4\xb9\xa6\xe9\xa1\xbb\xe7\x94\xa8\xe6\x84\x8f\xef\xbc\x8c\xe4\xb8\x80"
442 			"\xe5\xad\x97\xe5\x80\xbc\xe5\x8d\x83\xe9\x87\x91\x20");
443 
444 	default:
445 		DE_ASSERT(index == UTF8ABUSE_EMPTY);
446 		// Also try an empty string.
447 		return string("");
448 	}
449 }
450 
createInstanceWithExtensionNameAbuseTest(Context & context)451 tcu::TestStatus createInstanceWithExtensionNameAbuseTest (Context& context)
452 {
453 	const char*					extensionList[1]	= { 0 };
454 	const deUint32				apiVersion			= context.getUsedApiVersion();
455 	deUint32					failCount			= 0;
456 
457 	for (int i = 0; i < UTF8ABUSE_MAX; i++)
458 	{
459 		string abuseString	= getUTF8AbuseString(i);
460 		extensionList[0]	= abuseString.c_str();
461 
462 		const VkApplicationInfo		appInfo =
463 		{
464 			VK_STRUCTURE_TYPE_APPLICATION_INFO,				// VkStructureType			sType;
465 			DE_NULL,										// const void*				pNext;
466 			"appName",										// const char*				pAppName;
467 			0u,												// deUint32					appVersion;
468 			"engineName",									// const char*				pEngineName;
469 			0u,												// deUint32					engineVersion;
470 			apiVersion,										// deUint32					apiVersion;
471 		};
472 
473 		const VkInstanceCreateInfo	instanceCreateInfo =
474 		{
475 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,			// VkStructureType			sType;
476 			DE_NULL,										// const void*				pNext;
477 			(VkInstanceCreateFlags)0u,						// VkInstanceCreateFlags	flags;
478 			&appInfo,										// const VkApplicationInfo*	pAppInfo;
479 			0u,												// deUint32					layerCount;
480 			DE_NULL,										// const char*const*		ppEnabledLayernames;
481 			1u,												// deUint32					extensionCount;
482 			extensionList,									// const char*const*		ppEnabledExtensionNames;
483 		};
484 
485 		{
486 			UncheckedInstance	instance;
487 			const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
488 
489 			if (result != VK_ERROR_EXTENSION_NOT_PRESENT)
490 				failCount++;
491 
492 			TCU_CHECK(!static_cast<bool>(instance));
493 		}
494 	}
495 
496 	if (failCount > 0)
497 		return tcu::TestStatus::fail("Fail, creating instances with unsupported extensions succeeded.");
498 
499 	return tcu::TestStatus::pass("Pass, creating instances with unsupported extensions were rejected.");
500 }
501 
createInstanceWithLayerNameAbuseTest(Context & context)502 tcu::TestStatus createInstanceWithLayerNameAbuseTest (Context& context)
503 {
504 	const PlatformInterface&	platformInterface	= context.getPlatformInterface();
505 	const char*					layerList[1]		= { 0 };
506 	const deUint32				apiVersion			= context.getUsedApiVersion();
507 	deUint32					failCount			= 0;
508 
509 	for (int i = 0; i < UTF8ABUSE_MAX; i++)
510 	{
511 		string abuseString	= getUTF8AbuseString(i);
512 		layerList[0]		= abuseString.c_str();
513 
514 		const VkApplicationInfo		appInfo =
515 		{
516 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType			sType;
517 			DE_NULL,								// const void*				pNext;
518 			"appName",								// const char*				pAppName;
519 			0u,										// deUint32					appVersion;
520 			"engineName",							// const char*				pEngineName;
521 			0u,										// deUint32					engineVersion;
522 			apiVersion,								// deUint32					apiVersion;
523 		};
524 
525 		const VkInstanceCreateInfo	instanceCreateInfo =
526 		{
527 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType			sType;
528 			DE_NULL,								// const void*				pNext;
529 			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags	flags;
530 			&appInfo,								// const VkApplicationInfo*	pAppInfo;
531 			1u,										// deUint32					layerCount;
532 			layerList,								// const char*const*		ppEnabledLayernames;
533 			0u,										// deUint32					extensionCount;
534 			DE_NULL,								// const char*const*		ppEnabledExtensionNames;
535 		};
536 
537 		{
538 			VkInstance		instance	= (VkInstance)0;
539 			const VkResult	result		= platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
540 			const bool		gotInstance	= !!instance;
541 
542 			if (instance)
543 			{
544 				const InstanceDriver instanceIface(platformInterface, instance);
545 				instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
546 			}
547 
548 			if (result != VK_ERROR_LAYER_NOT_PRESENT)
549 				failCount++;
550 
551 			TCU_CHECK(!gotInstance);
552 		}
553 	}
554 
555 	if (failCount > 0)
556 		return tcu::TestStatus::fail("Fail, creating instances with unsupported layers succeeded.");
557 
558 	return tcu::TestStatus::pass("Pass, creating instances with unsupported layers were rejected.");
559 }
560 
enumerateDevicesAllocLeakTest(Context & context)561 tcu::TestStatus enumerateDevicesAllocLeakTest(Context& context)
562 {
563 	// enumeratePhysicalDevices uses instance-provided allocator
564 	// and this test checks if all alocated memory is freed
565 
566 	typedef AllocationCallbackRecorder::RecordIterator RecordIterator;
567 
568 	DeterministicFailAllocator	objAllocator	(getSystemAllocator(), DeterministicFailAllocator::MODE_DO_NOT_COUNT, 0);
569 	AllocationCallbackRecorder	recorder		(objAllocator.getCallbacks(), 128);
570 	const auto					instance		= createCustomInstanceFromContext(context, recorder.getCallbacks(), true);
571 	const auto&					vki				= instance.getDriver();
572 	vector<VkPhysicalDevice>	devices			(enumeratePhysicalDevices(vki, instance));
573 	RecordIterator				recordToCheck	(recorder.getRecordsEnd());
574 
575 	try
576 	{
577 		devices = enumeratePhysicalDevices(vki, instance);
578 	}
579 	catch (const vk::OutOfMemoryError& e)
580 	{
581 		if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY)
582 			return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Got out of memory error - leaks in enumeratePhysicalDevices not tested.");
583 	}
584 
585 	// make sure that same number of allocations and frees was done
586 	deInt32			allocationRecords	(0);
587 	RecordIterator	lastRecordToCheck	(recorder.getRecordsEnd());
588 	while (recordToCheck != lastRecordToCheck)
589 	{
590 		const AllocationCallbackRecord& record = *recordToCheck;
591 		switch (record.type)
592 		{
593 		case AllocationCallbackRecord::TYPE_ALLOCATION:
594 			++allocationRecords;
595 			break;
596 		case AllocationCallbackRecord::TYPE_FREE:
597 			if (record.data.free.mem != DE_NULL)
598 				--allocationRecords;
599 			break;
600 		default:
601 			break;
602 		}
603 		++recordToCheck;
604 	}
605 
606 	if (allocationRecords)
607 		return tcu::TestStatus::fail("enumeratePhysicalDevices leaked memory");
608 	return tcu::TestStatus::pass("Ok");
609 }
610 
createDeviceTest(Context & context)611 tcu::TestStatus createDeviceTest (Context& context)
612 {
613 	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
614 	const CustomInstance			instance				(createCustomInstanceFromContext(context));
615 	const InstanceDriver&			instanceDriver			(instance.getDriver());
616 	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
617 	const deUint32					queueFamilyIndex		= 0;
618 	const deUint32					queueCount				= 1;
619 	const deUint32					queueIndex				= 0;
620 	const float						queuePriority			= 1.0f;
621 
622 	const vector<VkQueueFamilyProperties> queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
623 
624 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
625 	{
626 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
627 		DE_NULL,
628 		(VkDeviceQueueCreateFlags)0u,
629 		queueFamilyIndex,						//queueFamilyIndex;
630 		queueCount,								//queueCount;
631 		&queuePriority,							//pQueuePriorities;
632 	};
633 
634 	const VkDeviceCreateInfo		deviceCreateInfo	=
635 	{
636 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
637 		DE_NULL,								//pNext;
638 		(VkDeviceCreateFlags)0u,
639 		1,										//queueRecordCount;
640 		&deviceQueueCreateInfo,					//pRequestedQueues;
641 		0,										//layerCount;
642 		DE_NULL,								//ppEnabledLayerNames;
643 		0,										//extensionCount;
644 		DE_NULL,								//ppEnabledExtensionNames;
645 		DE_NULL,								//pEnabledFeatures;
646 	};
647 
648 	const Unique<VkDevice>			device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
649 	const DeviceDriver				deviceDriver			(platformInterface, instance, device.get());
650 	const VkQueue					queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
651 
652 	VK_CHECK(deviceDriver.queueWaitIdle(queue));
653 
654 	return tcu::TestStatus::pass("Pass");
655 }
656 
createMultipleDevicesTest(Context & context)657 tcu::TestStatus createMultipleDevicesTest (Context& context)
658 {
659 	tcu::TestLog&										log						= context.getTestContext().getLog();
660 	tcu::ResultCollector								resultCollector			(log);
661 	const int											numDevices				= 5;
662 	const PlatformInterface&							platformInterface		= context.getPlatformInterface();
663 	const CustomInstance								instance				(createCustomInstanceFromContext(context));
664 	const InstanceDriver&								instanceDriver			(instance.getDriver());
665 	const VkPhysicalDevice								physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
666 	const vector<VkQueueFamilyProperties>				queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
667 	const deUint32										queueFamilyIndex		= 0;
668 	const deUint32										queueCount				= 1;
669 	const deUint32										queueIndex				= 0;
670 	const float											queuePriority			= 1.0f;
671 	const VkDeviceQueueCreateInfo						deviceQueueCreateInfo	=
672 	{
673 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
674 		DE_NULL,
675 		(VkDeviceQueueCreateFlags)0u,					//flags;
676 		queueFamilyIndex,								//queueFamilyIndex;
677 		queueCount,										//queueCount;
678 		&queuePriority,									//pQueuePriorities;
679 	};
680 
681 	const VkDeviceCreateInfo							deviceCreateInfo		=
682 	{
683 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,			//sType;
684 		DE_NULL,										//pNext;
685 		(VkDeviceCreateFlags)0u,
686 		1,												//queueRecordCount;
687 		&deviceQueueCreateInfo,							//pRequestedQueues;
688 		0,												//layerCount;
689 		DE_NULL,										//ppEnabledLayerNames;
690 		0,												//extensionCount;
691 		DE_NULL,										//ppEnabledExtensionNames;
692 		DE_NULL,										//pEnabledFeatures;
693 	};
694 
695 	vector<VkDevice>									devices(numDevices, (VkDevice)DE_NULL);
696 
697 	try
698 	{
699 		for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++)
700 		{
701 			const VkResult result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]);
702 
703 			if (result != VK_SUCCESS)
704 			{
705 				resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result));
706 				break;
707 			}
708 
709 			{
710 				const DeviceDriver	deviceDriver	(platformInterface, instance, devices[deviceNdx]);
711 				const VkQueue		queue			= getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex);
712 
713 				VK_CHECK(deviceDriver.queueWaitIdle(queue));
714 			}
715 		}
716 	}
717 	catch (const vk::Error& error)
718 	{
719 		resultCollector.fail(de::toString(error.getError()));
720 	}
721 	catch (...)
722 	{
723 		for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
724 		{
725 			if (devices[deviceNdx] != (VkDevice)DE_NULL)
726 			{
727 				DeviceDriver deviceDriver(platformInterface, instance, devices[deviceNdx]);
728 				deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
729 			}
730 		}
731 
732 		throw;
733 	}
734 
735 	for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
736 	{
737 		if (devices[deviceNdx] != (VkDevice)DE_NULL)
738 		{
739 			DeviceDriver deviceDriver(platformInterface, instance, devices[deviceNdx]);
740 			deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
741 		}
742 	}
743 
744 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
745 }
746 
createDeviceWithUnsupportedExtensionsTest(Context & context)747 tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context)
748 {
749 	tcu::TestLog&					log						= context.getTestContext().getLog();
750 	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
751 	const CustomInstance			instance				(createCustomInstanceFromContext(context, DE_NULL, false));
752 	const InstanceDriver&			instanceDriver			(instance.getDriver());
753 	const char*						enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"};
754 	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
755 	const float						queuePriority			= 1.0f;
756 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
757 	{
758 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
759 		DE_NULL,
760 		(VkDeviceQueueCreateFlags)0u,
761 		0,										//queueFamilyIndex;
762 		1,										//queueCount;
763 		&queuePriority,							//pQueuePriorities;
764 	};
765 
766 	const VkDeviceCreateInfo		deviceCreateInfo		=
767 	{
768 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
769 		DE_NULL,								//pNext;
770 		(VkDeviceCreateFlags)0u,
771 		1,										//queueRecordCount;
772 		&deviceQueueCreateInfo,					//pRequestedQueues;
773 		0,										//layerCount;
774 		DE_NULL,								//ppEnabledLayerNames;
775 		DE_LENGTH_OF_ARRAY(enabledExtensions),	//extensionCount;
776 		enabledExtensions,						//ppEnabledExtensionNames;
777 		DE_NULL,								//pEnabledFeatures;
778 	};
779 
780 	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
781 
782 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
783 		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
784 
785 	{
786 		VkDevice		device		= (VkDevice)0;
787 		const VkResult	result		= createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device);
788 		const bool		gotDevice	= !!device;
789 
790 		if (device)
791 		{
792 			const DeviceDriver	deviceIface	(platformInterface, instance, device);
793 			deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
794 		}
795 
796 		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
797 		{
798 			TCU_CHECK(!gotDevice);
799 			return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected.");
800 		}
801 		else
802 			return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed.");
803 	}
804 }
805 
getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties> & queueFamilyProperties)806 deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)
807 {
808 	deUint32 maxQueueCount = 0;
809 
810 	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
811 	{
812 		maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount);
813 	}
814 
815 	return maxQueueCount;
816 }
817 
createDeviceWithVariousQueueCountsTest(Context & context)818 tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context)
819 {
820 	tcu::TestLog&							log						= context.getTestContext().getLog();
821 	const int								queueCountDiff			= 1;
822 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
823 	const CustomInstance					instance				(createCustomInstanceFromContext(context));
824 	const InstanceDriver&					instanceDriver			(instance.getDriver());
825 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
826 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
827 	const vector<float>						queuePriorities			(getGlobalMaxQueueCount(queueFamilyProperties), 1.0f);
828 	vector<VkDeviceQueueCreateInfo>			deviceQueueCreateInfos;
829 
830 	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
831 	{
832 		const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount;
833 
834 		for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff)
835 		{
836 			const VkDeviceQueueCreateInfo queueCreateInfo =
837 			{
838 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
839 				DE_NULL,
840 				(VkDeviceQueueCreateFlags)0u,
841 				queueFamilyNdx,
842 				queueCount,
843 				queuePriorities.data()
844 			};
845 
846 			deviceQueueCreateInfos.push_back(queueCreateInfo);
847 		}
848 	}
849 
850 	for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++)
851 	{
852 		const VkDeviceQueueCreateInfo&	queueCreateInfo		= deviceQueueCreateInfos[testNdx];
853 		const VkDeviceCreateInfo		deviceCreateInfo	=
854 		{
855 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
856 			DE_NULL,								//pNext;
857 			(VkDeviceCreateFlags)0u,
858 			1,										//queueRecordCount;
859 			&queueCreateInfo,						//pRequestedQueues;
860 			0,										//layerCount;
861 			DE_NULL,								//ppEnabledLayerNames;
862 			0,										//extensionCount;
863 			DE_NULL,								//ppEnabledExtensionNames;
864 			DE_NULL,								//pEnabledFeatures;
865 		};
866 
867 		const Unique<VkDevice>			device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
868 		const DeviceDriver				deviceDriver		(platformInterface, instance, device.get());
869 		const deUint32					queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
870 		const deUint32					queueCount			= deviceCreateInfo.pQueueCreateInfos->queueCount;
871 
872 		for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++)
873 		{
874 			const VkQueue		queue	= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex);
875 			VkResult			result;
876 
877 			TCU_CHECK(!!queue);
878 
879 			result = deviceDriver.queueWaitIdle(queue);
880 			if (result != VK_SUCCESS)
881 			{
882 				log << TestLog::Message
883 					<< "vkQueueWaitIdle failed"
884 					<< ",  queueIndex = " << queueIndex
885 					<< ", queueCreateInfo " << queueCreateInfo
886 					<< ", Error Code: " << result
887 					<< TestLog::EndMessage;
888 				return tcu::TestStatus::fail("Fail");
889 			}
890 		}
891 	}
892 	return tcu::TestStatus::pass("Pass");
893 }
894 
checkGlobalPrioritySupport(Context & context)895 void checkGlobalPrioritySupport (Context& context)
896 {
897 	context.requireDeviceFunctionality("VK_EXT_global_priority");
898 }
899 
createDeviceWithGlobalPriorityTest(Context & context)900 tcu::TestStatus createDeviceWithGlobalPriorityTest (Context& context)
901 {
902 	tcu::TestLog&							log						= context.getTestContext().getLog();
903 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
904 	const CustomInstance					instance				(createCustomInstanceFromContext(context));
905 	const InstanceDriver&					instanceDriver			(instance.getDriver());
906 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
907 	const vector<float>						queuePriorities			(1, 1.0f);
908 	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 };
909 
910 	for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
911 	{
912 		const VkDeviceQueueGlobalPriorityCreateInfoEXT	queueGlobalPriority		=
913 		{
914 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,	//sType;
915 			DE_NULL,														//pNext;
916 			globalPriority													//globalPriority;
917 		};
918 
919 		const VkDeviceQueueCreateInfo	queueCreateInfo		=
920 		{
921 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//sType;
922 			&queueGlobalPriority,						//pNext;
923 			(VkDeviceQueueCreateFlags)0u,				//flags;
924 			0,											//queueFamilyIndex;
925 			1,											//queueCount;
926 			queuePriorities.data()						//pQueuePriorities;
927 		};
928 
929 		const VkDeviceCreateInfo		deviceCreateInfo	=
930 		{
931 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
932 			DE_NULL,								//pNext;
933 			(VkDeviceCreateFlags)0u,				//flags;
934 			1,										//queueRecordCount;
935 			&queueCreateInfo,						//pRequestedQueues;
936 			0,										//layerCount;
937 			DE_NULL,								//ppEnabledLayerNames;
938 			0,										//extensionCount;
939 			DE_NULL,								//ppEnabledExtensionNames;
940 			DE_NULL,								//pEnabledFeatures;
941 		};
942 
943 		const bool		mayBeDenied				= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
944 
945 		try
946 		{
947 			const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
948 			const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
949 			const deUint32				queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
950 			const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, 0);
951 			VkResult					result;
952 
953 			TCU_CHECK(!!queue);
954 
955 			result = deviceDriver.queueWaitIdle(queue);
956 			if (result == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
957 			{
958 				continue;
959 			}
960 
961 			if (result != VK_SUCCESS)
962 			{
963 				log << TestLog::Message
964 					<< "vkQueueWaitIdle failed"
965 					<< ", globalPriority = " << globalPriority
966 					<< ", queueCreateInfo " << queueCreateInfo
967 					<< ", Error Code: " << result
968 					<< TestLog::EndMessage;
969 				return tcu::TestStatus::fail("Fail");
970 			}
971 		}
972 		catch (const Error& error)
973 		{
974 			if (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
975 			{
976 				continue;
977 			}
978 			else
979 			{
980 				log << TestLog::Message
981 					<< "exception thrown " << error.getMessage()
982 					<< ", globalPriority = " << globalPriority
983 					<< ", queueCreateInfo " << queueCreateInfo
984 					<< ", Error Code: " << error.getError()
985 					<< TestLog::EndMessage;
986 				return tcu::TestStatus::fail("Fail");
987 			}
988 		}
989 	}
990 
991 	return tcu::TestStatus::pass("Pass");
992 }
993 
checkGlobalPriorityQuerySupport(Context & context)994 void checkGlobalPriorityQuerySupport (Context& context)
995 {
996 	context.requireDeviceFunctionality("VK_EXT_global_priority_query");
997 }
998 
isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)999 deBool isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)
1000 {
1001 	switch (priority) {
1002 		case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:
1003 		case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:
1004 		case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:
1005 		case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:
1006 			return DE_TRUE;
1007 		default:
1008 			return DE_FALSE;
1009 	}
1010 }
1011 
checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT & properties)1012 void checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT& properties)
1013 {
1014 	TCU_CHECK(properties.priorityCount > 0);
1015 	TCU_CHECK(properties.priorityCount <= VK_MAX_GLOBAL_PRIORITY_SIZE_EXT);
1016 	TCU_CHECK(isValidGlobalPriority(properties.priorities[0]));
1017 
1018 	for (deUint32 ndx = 1; ndx < properties.priorityCount; ndx++)
1019 	{
1020 		TCU_CHECK(isValidGlobalPriority(properties.priorities[ndx]));
1021 		TCU_CHECK(properties.priorities[ndx] == (properties.priorities[ndx - 1] << 1));
1022 	}
1023 }
1024 
createDeviceWithQueriedGlobalPriorityTest(Context & context)1025 tcu::TestStatus createDeviceWithQueriedGlobalPriorityTest (Context& context)
1026 {
1027 	tcu::TestLog&					log							= context.getTestContext().getLog();
1028 	const PlatformInterface&		platformInterface			= context.getPlatformInterface();
1029 	const CustomInstance			instance					(createCustomInstanceFromContext(context));
1030 	const InstanceDriver&			instanceDriver				(instance.getDriver());
1031 	const VkPhysicalDevice			physicalDevice				= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1032 	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 };
1033 	const vector<float>				queuePriorities				(1, 1.0f);
1034 	std::vector<const char*>		enabledExtensions			= {"VK_EXT_global_priority", "VK_EXT_global_priority_query"};
1035 	deUint32						queueFamilyPropertyCount	= ~0u;
1036 
1037 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, DE_NULL);
1038 	TCU_CHECK(queueFamilyPropertyCount > 0);
1039 
1040 	std::vector<VkQueueFamilyProperties2>					queueFamilyProperties2		(queueFamilyPropertyCount);
1041 	std::vector<VkQueueFamilyGlobalPriorityPropertiesEXT>	globalPriorityProperties	(queueFamilyPropertyCount);
1042 
1043 	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1044 	{
1045 		globalPriorityProperties[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT;
1046 		globalPriorityProperties[ndx].pNext	= DE_NULL;
1047 		queueFamilyProperties2[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1048 		queueFamilyProperties2[ndx].pNext	= &globalPriorityProperties[ndx];
1049 	}
1050 
1051 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
1052 	TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());
1053 
1054 	if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
1055 	{
1056 		enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
1057 	}
1058 
1059 	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1060 	{
1061 		checkGlobalPriorityProperties(globalPriorityProperties[ndx]);
1062 
1063 		for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
1064 		{
1065 			const VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT	globalPriorityQueryFeatures		=
1066 			{
1067 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,	//sType;
1068 				DE_NULL,																//pNext;
1069 				VK_TRUE																	//globalPriorityQuery;
1070 			};
1071 			const VkDeviceQueueGlobalPriorityCreateInfoEXT			queueGlobalPriorityCreateInfo	=
1072 			{
1073 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,			//sType;
1074 				DE_NULL,																//pNext;
1075 				globalPriority,															//globalPriority;
1076 			};
1077 			const VkDeviceQueueCreateInfo							queueCreateInfo					=
1078 			{
1079 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,								//sType;
1080 				&queueGlobalPriorityCreateInfo,											//pNext;
1081 				(VkDeviceQueueCreateFlags)0u,											//flags;
1082 				ndx,																	//queueFamilyIndex;
1083 				1,																		//queueCount;
1084 				queuePriorities.data()													//pQueuePriorities;
1085 			};
1086 			const VkDeviceCreateInfo								deviceCreateInfo				=
1087 			{
1088 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,									//sType;
1089 				&globalPriorityQueryFeatures,											//pNext;
1090 				(VkDeviceCreateFlags)0u,												//flags;
1091 				1,																		//queueRecordCount;
1092 				&queueCreateInfo,														//pRequestedQueues;
1093 				0,																		//layerCount;
1094 				DE_NULL,																//ppEnabledLayerNames;
1095 				(deUint32)enabledExtensions.size(),										//extensionCount;
1096 				enabledExtensions.data(),												//ppEnabledExtensionNames;
1097 				DE_NULL,																//pEnabledFeatures;
1098 			};
1099 			const bool												mayBeDenied						= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
1100 			const bool												mustFail						= globalPriority < globalPriorityProperties[ndx].priorities[0] || globalPriority > globalPriorityProperties[ndx].priorities[globalPriorityProperties[ndx].priorityCount - 1];
1101 
1102 			try
1103 			{
1104 				const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1105 				const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
1106 				const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, ndx, 0);
1107 
1108 				TCU_CHECK(!!queue);
1109 
1110 				if (mustFail)
1111 				{
1112 					log << TestLog::Message
1113 						<< "device creation must fail but not"
1114 						<< ", globalPriority = " << globalPriority
1115 						<< ", queueCreateInfo " << queueCreateInfo
1116 						<< TestLog::EndMessage;
1117 					return tcu::TestStatus::fail("Fail");
1118 				}
1119 			}
1120 			catch (const Error& error)
1121 			{
1122 				if (mustFail || (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied))
1123 				{
1124 					continue;
1125 				}
1126 				else
1127 				{
1128 					log << TestLog::Message
1129 						<< "exception thrown " << error.getMessage()
1130 						<< ", globalPriority = " << globalPriority
1131 						<< ", queueCreateInfo " << queueCreateInfo
1132 						<< ", Error Code: " << error.getError()
1133 						<< TestLog::EndMessage;
1134 					return tcu::TestStatus::fail("Fail");
1135 				}
1136 			}
1137 		}
1138 	}
1139 
1140 	return tcu::TestStatus::pass("Pass");
1141 }
1142 
createDeviceFeatures2Test(Context & context)1143 tcu::TestStatus createDeviceFeatures2Test (Context& context)
1144 {
1145 	const PlatformInterface&				vkp						= context.getPlatformInterface();
1146 	const CustomInstance					instance				(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
1147 	const InstanceDriver&					vki						(instance.getDriver());
1148 	const VkPhysicalDevice					physicalDevice			= chooseDevice(vki, instance, context.getTestContext().getCommandLine());
1149 	const deUint32							queueFamilyIndex		= 0;
1150 	const deUint32							queueCount				= 1;
1151 	const deUint32							queueIndex				= 0;
1152 	const float								queuePriority			= 1.0f;
1153 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
1154 
1155 	VkPhysicalDeviceFeatures2		enabledFeatures;
1156 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1157 	{
1158 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1159 		DE_NULL,
1160 		(VkDeviceQueueCreateFlags)0u,
1161 		queueFamilyIndex,
1162 		queueCount,
1163 		&queuePriority,
1164 	};
1165 
1166 	const VkDeviceCreateInfo		deviceCreateInfo	=
1167 	{
1168 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1169 		&enabledFeatures,
1170 		(VkDeviceCreateFlags)0u,
1171 		1,
1172 		&deviceQueueCreateInfo,
1173 		0u,
1174 		DE_NULL,
1175 		0,
1176 		DE_NULL,
1177 		DE_NULL,
1178 	};
1179 
1180 	// Populate enabledFeatures
1181 	enabledFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1182 	enabledFeatures.pNext		= DE_NULL;
1183 
1184 	vki.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
1185 
1186 	{
1187 		const Unique<VkDevice>	device		(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceCreateInfo));
1188 		const DeviceDriver		vkd			(vkp, instance, device.get());
1189 		const VkQueue			queue		= getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);
1190 
1191 		VK_CHECK(vkd.queueWaitIdle(queue));
1192 	}
1193 
1194 	return tcu::TestStatus::pass("Pass");
1195 }
1196 
1197 struct Feature
1198 {
1199 	const char*	name;
1200 	size_t		offset;
1201 };
1202 
1203 #define FEATURE_ITEM(STRUCT, MEMBER) {#MEMBER, DE_OFFSET_OF(STRUCT, MEMBER)}
1204 // This macro is used to avoid the "out of array bounds" compiler warnings/errors in the checkFeatures function.
1205 #define SAFE_OFFSET(LIMITING_STRUCT, STRUCT, MEMBER) std::min(static_cast<deUint32>(sizeof(LIMITING_STRUCT) - sizeof(VkBool32)), DE_OFFSET_OF(STRUCT, MEMBER))
1206 
1207 template<typename StructType>
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)1208 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)
1209 {
1210 	struct StructureBase
1211 	{
1212 		VkStructureType		sType;
1213 		void*				pNext;
1214 	};
1215 
1216 	for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
1217 	{
1218 		// Test only features that are not supported.
1219 		if (*(((VkBool32*)((deUint8*)(supportedFeatures) + features[featureNdx].offset))))
1220 			continue;
1221 
1222 		StructType structCopy;
1223 		deMemset(&structCopy, 0, sizeof(StructType));
1224 
1225 		auto* structBase = reinterpret_cast<StructureBase*>(&structCopy);
1226 		VkStructureType structureType = reinterpret_cast<const StructureBase*>(supportedFeatures)->sType;
1227 		structBase->sType = structureType;
1228 		structBase->pNext = DE_NULL;
1229 
1230 		VkPhysicalDeviceFeatures physicalDeviceFeaturesCopy = defaultPhysicalDeviceFeatures;
1231 
1232 		// Some features require that other feature(s) are also enabled.
1233 
1234 		// If rayTracingPipelineShaderGroupHandleCaptureReplayMixed is VK_TRUE, rayTracingPipelineShaderGroupHandleCaptureReplay must also be VK_TRUE.
1235 		if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR &&
1236 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplayMixed))
1237 		{
1238 			DE_ASSERT((std::is_same<VkPhysicalDeviceRayTracingPipelineFeaturesKHR, StructType>::value));
1239 			auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplay));
1240 			*memberPtr = VK_TRUE;
1241 		}
1242 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES)
1243 		{
1244 			DE_ASSERT((std::is_same<VkPhysicalDeviceVulkan11Features, StructType>::value));
1245 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1246 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1247 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader) ||
1248 				features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader))
1249 			{
1250 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, multiview));
1251 				*memberPtr = VK_TRUE;
1252 			}
1253 
1254 			// If variablePointers is enabled then variablePointersStorageBuffer must also be enabled.
1255 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, variablePointers))
1256 			{
1257 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer));
1258 				*memberPtr = VK_TRUE;
1259 			}
1260 		}
1261 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES)
1262 		{
1263 			DE_ASSERT((std::is_same<VkPhysicalDeviceMultiviewFeatures, StructType>::value));
1264 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1265 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1266 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewGeometryShader) ||
1267 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewTessellationShader))
1268 			{
1269 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceMultiviewFeatures, multiview));
1270 				*memberPtr = VK_TRUE;
1271 			}
1272 		}
1273 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
1274 		{
1275 			DE_ASSERT((std::is_same<VkPhysicalDeviceRobustness2FeaturesEXT, StructType>::value));
1276 			// If robustBufferAccess2 is enabled then robustBufferAccess must also be enabled.
1277 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRobustness2FeaturesEXT, robustBufferAccess2))
1278 			{
1279 				physicalDeviceFeaturesCopy.robustBufferAccess = true;
1280 			}
1281 		}
1282 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT)
1283 		{
1284 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, StructType>::value));
1285 			// If sparseImageInt64Atomics is enabled, shaderImageInt64Atomics must be enabled.
1286 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, sparseImageInt64Atomics))
1287 			{
1288 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, shaderImageInt64Atomics));
1289 				*memberPtr = VK_TRUE;
1290 			}
1291 		}
1292 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT)
1293 		{
1294 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, StructType>::value));
1295 			// If sparseImageFloat32Atomics is enabled, shaderImageFloat32Atomics must be enabled.
1296 			if (features[featureNdx].offset ==
1297 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32Atomics)) {
1298 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32Atomics));
1299 				*memberPtr = VK_TRUE;
1300 			}
1301 
1302 			// If sparseImageFloat32AtomicAdd is enabled, shaderImageFloat32AtomicAdd must be enabled.
1303 			if (features[featureNdx].offset ==
1304 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32AtomicAdd)) {
1305 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32AtomicAdd));
1306 				*memberPtr = VK_TRUE;
1307 			}
1308 		}
1309 		else if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT)
1310 		{
1311 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, StructType>::value));
1312 			// If sparseImageFloat32AtomicMinMax is enabled, shaderImageFloat32AtomicMinMax must be enabled.
1313 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, sparseImageFloat32AtomicMinMax))
1314 			{
1315 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderImageFloat32AtomicMinMax));
1316 				*memberPtr = VK_TRUE;
1317 			}
1318 		}
1319 
1320 		// Enable the feature we're testing.
1321 		*reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + features[featureNdx].offset) = VK_TRUE;
1322 
1323 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1324 		{
1325 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
1326 			DE_NULL,									// pNext
1327 			(VkDeviceQueueCreateFlags)0u,				// flags
1328 			queueFamilyIndex,							// queueFamilyIndex
1329 			queueCount,									// queueCount
1330 			&queuePriority								// pQueuePriorities
1331 		};
1332 		const VkPhysicalDeviceFeatures2 deviceFeatures2 =
1333 		{
1334 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,	// sType
1335 			&structCopy,									// pNext
1336 			physicalDeviceFeaturesCopy						// features
1337 		};
1338 		const VkDeviceCreateInfo		deviceCreateInfo		=
1339 		{
1340 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,											// sType
1341 			&deviceFeatures2,																// pNext
1342 			(VkDeviceCreateFlags)0u,														// flags
1343 			1,																				// queueCreateInfoCount
1344 			&deviceQueueCreateInfo,															// pQueueCreateInfos
1345 			0u,																				// enabledLayerCount
1346 			DE_NULL,																		// ppEnabledLayerNames
1347 			static_cast<deUint32>(extensionNames == DE_NULL ? 0 : extensionNames->size()),	// enabledExtensionCount
1348 			extensionNames == DE_NULL ? DE_NULL : extensionNames->data(),					// ppEnabledExtensionNames
1349 			DE_NULL																			// pEnabledFeatures
1350 		};
1351 
1352 		VkDevice		device = (VkDevice)DE_NULL;
1353 		const VkResult	res	= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1354 
1355 		if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1356 		{
1357 			numErrors++;
1358 			resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1359 				+ de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
1360 		}
1361 		if (device != (VkDevice)DE_NULL)
1362 		{
1363 			DeviceDriver deviceDriver(vkp, instance, device);
1364 			deviceDriver.destroyDevice(device, DE_NULL);
1365 		}
1366 	}
1367 }
1368 
removeExtensions(const vector<string> & a,const vector<const char * > & b)1369 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
1370 {
1371 	vector<string>	res;
1372 	set<string>		removeExts	(b.begin(), b.end());
1373 
1374 	for (const auto & aIter : a)
1375 	{
1376 		if (!de::contains(removeExts, aIter))
1377 			res.push_back(aIter);
1378 	}
1379 
1380 	return res;
1381 }
1382 
createDeviceWithUnsupportedFeaturesTest(Context & context)1383 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
1384 {
1385 	const PlatformInterface&				vkp						= context.getPlatformInterface();
1386 	tcu::TestLog&							log						= context.getTestContext().getLog();
1387 	tcu::ResultCollector					resultCollector			(log);
1388 	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
1389 	const InstanceDriver&					instanceDriver			(instance.getDriver());
1390 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1391 	const deUint32							queueFamilyIndex		= 0;
1392 	const deUint32							queueCount				= 1;
1393 	const float								queuePriority			= 1.0f;
1394 	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
1395 	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
1396 	const VkPhysicalDeviceFeatures			deviceFeatures			= deviceFeatures2.features;
1397 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
1398 	int										numErrors				= 0;
1399 
1400 	// Test features listed in VkPhysicalDeviceFeatures structure
1401 	{
1402 		static const Feature features[] =
1403 		{
1404 			// robustBufferAccess is removed, because it's always supported.
1405 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
1406 			FEATURE_ITEM(VkPhysicalDeviceFeatures, imageCubeArray),
1407 			FEATURE_ITEM(VkPhysicalDeviceFeatures, independentBlend),
1408 			FEATURE_ITEM(VkPhysicalDeviceFeatures, geometryShader),
1409 			FEATURE_ITEM(VkPhysicalDeviceFeatures, tessellationShader),
1410 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sampleRateShading),
1411 			FEATURE_ITEM(VkPhysicalDeviceFeatures, dualSrcBlend),
1412 			FEATURE_ITEM(VkPhysicalDeviceFeatures, logicOp),
1413 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiDrawIndirect),
1414 			FEATURE_ITEM(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
1415 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthClamp),
1416 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBiasClamp),
1417 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fillModeNonSolid),
1418 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBounds),
1419 			FEATURE_ITEM(VkPhysicalDeviceFeatures, wideLines),
1420 			FEATURE_ITEM(VkPhysicalDeviceFeatures, largePoints),
1421 			FEATURE_ITEM(VkPhysicalDeviceFeatures, alphaToOne),
1422 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiViewport),
1423 			FEATURE_ITEM(VkPhysicalDeviceFeatures, samplerAnisotropy),
1424 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionETC2),
1425 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
1426 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionBC),
1427 			FEATURE_ITEM(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
1428 			FEATURE_ITEM(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
1429 			FEATURE_ITEM(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
1430 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
1431 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
1432 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
1433 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
1434 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
1435 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
1436 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
1437 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
1438 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
1439 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
1440 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
1441 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderClipDistance),
1442 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderCullDistance),
1443 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderFloat64),
1444 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt64),
1445 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt16),
1446 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceResidency),
1447 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceMinLod),
1448 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseBinding),
1449 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
1450 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
1451 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
1452 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency2Samples),
1453 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency4Samples),
1454 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency8Samples),
1455 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency16Samples),
1456 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyAliased),
1457 			FEATURE_ITEM(VkPhysicalDeviceFeatures, variableMultisampleRate),
1458 			FEATURE_ITEM(VkPhysicalDeviceFeatures, inheritedQueries)
1459 		};
1460 
1461 		for (const auto& feature : features)
1462 		{
1463 			// Test only features that are not supported.
1464 			if (*(((VkBool32*)((deUint8*)(&deviceFeatures) + feature.offset))))
1465 				continue;
1466 
1467 			VkPhysicalDeviceFeatures		enabledFeatures			= deviceFeatures;
1468 			*((VkBool32*)((deUint8*)(&enabledFeatures) + feature.offset)) = VK_TRUE;
1469 
1470 			const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1471 			{
1472 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1473 				DE_NULL,
1474 				(VkDeviceQueueCreateFlags)0u,
1475 				queueFamilyIndex,
1476 				queueCount,
1477 				&queuePriority
1478 			};
1479 			const VkDeviceCreateInfo		deviceCreateInfo		=
1480 			{
1481 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1482 				DE_NULL,
1483 				(VkDeviceCreateFlags)0u,
1484 				1,
1485 				&deviceQueueCreateInfo,
1486 				0u,
1487 				DE_NULL,
1488 				0,
1489 				DE_NULL,
1490 				&enabledFeatures
1491 			};
1492 
1493 			VkDevice		device	= DE_NULL;
1494 			const VkResult	res		= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1495 
1496 			if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1497 			{
1498 				numErrors++;
1499 				resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1500 				+ de::toString(feature.name) + ", which was reported as unsupported.");
1501 			}
1502 
1503 			if (device != DE_NULL)
1504 			{
1505 				DeviceDriver deviceDriver(vkp, instance, device);
1506 				deviceDriver.destroyDevice(device, DE_NULL);
1507 			}
1508 		}
1509 	}
1510 
1511 	VkPhysicalDeviceFeatures emptyDeviceFeatures;
1512 	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));
1513 
1514 	// Only non-core extensions will be used when creating the device.
1515 	vector<const char*>	coreExtensions;
1516 	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
1517 	vector<string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
1518 
1519 	vector<const char*> extensionNames;
1520 	extensionNames.reserve(nonCoreExtensions.size());
1521 	for (const string& extension : nonCoreExtensions)
1522 		extensionNames.push_back(extension.c_str());
1523 
1524 	// Test features provided by extensions and Vulkan 1.1 and 1.2.
1525 
1526 	#include "vkDeviceFeatureTest.inl"
1527 
1528 	if (numErrors > 1)
1529 		return tcu::TestStatus(resultCollector.getResult(), "Enabling " + de::toString(numErrors) + " unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
1530 	else
1531 		return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
1532 }
1533 
createDeviceQueue2Test(Context & context)1534 tcu::TestStatus createDeviceQueue2Test (Context& context)
1535 {
1536 	if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
1537 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1538 
1539 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1540 	const VkInstance						instance				= context.getInstance();
1541 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
1542 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1543 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1544 	const deUint32							queueCount				= 1;
1545 	const deUint32							queueIndex				= 0;
1546 	const float								queuePriority			= 1.0f;
1547 
1548 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1549 	{
1550 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1551 		DE_NULL,														// void*							pNext;
1552 		VK_FALSE														// VkBool32							protectedMemory;
1553 	};
1554 
1555 	VkPhysicalDeviceFeatures2				features2;
1556 	deMemset(&features2, 0, sizeof(features2));
1557 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1558 	features2.pNext													= &protectedMemoryFeature;
1559 
1560 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1561 	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1562 		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1563 
1564 	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
1565 	{
1566 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
1567 		DE_NULL,														// const void*						pNext;
1568 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1569 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1570 		queueCount,														// deUint32							queueCount;
1571 		&queuePriority,													// const float*						pQueuePriorities;
1572 	};
1573 	const VkDeviceCreateInfo				deviceCreateInfo		=
1574 	{
1575 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
1576 		&features2,														// const void*						pNext;
1577 		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
1578 		1,																// deUint32							queueCreateInfoCount;
1579 		&deviceQueueCreateInfo,											// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1580 		0,																// deUint32							enabledLayerCount;
1581 		DE_NULL,														// const char* const*				ppEnabledLayerNames;
1582 		0,																// deUint32							enabledExtensionCount;
1583 		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
1584 		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1585 	};
1586 
1587 	const VkDeviceQueueInfo2				deviceQueueInfo2		=
1588 	{
1589 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
1590 		DE_NULL,														// const void*						pNext;
1591 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1592 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1593 		queueIndex,														// deUint32							queueIndex;
1594 	};
1595 
1596 	{
1597 		const Unique<VkDevice>				device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1598 		const DeviceDriver					deviceDriver			(platformInterface, instance, device.get());
1599 		const VkQueue						queue2					= getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);
1600 
1601 		VK_CHECK(deviceDriver.queueWaitIdle(queue2));
1602 	}
1603 
1604 	return tcu::TestStatus::pass("Pass");
1605 }
1606 
createDeviceQueue2UnmatchedFlagsTest(Context & context)1607 tcu::TestStatus createDeviceQueue2UnmatchedFlagsTest (Context& context)
1608 {
1609 	if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
1610 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1611 
1612 	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
1613 	const VkInstance				instance				= context.getInstance();
1614 	const InstanceInterface&		instanceDriver			= context.getInstanceInterface();
1615 	const VkPhysicalDevice			physicalDevice			= context.getPhysicalDevice();
1616 
1617 	// Check if VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT flag can be used.
1618 	{
1619 		VkPhysicalDeviceProtectedMemoryFeatures		protectedFeatures;
1620 		protectedFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
1621 		protectedFeatures.pNext		= DE_NULL;
1622 
1623 		VkPhysicalDeviceFeatures2					deviceFeatures;
1624 		deviceFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1625 		deviceFeatures.pNext		= &protectedFeatures;
1626 
1627 		instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures);
1628 		if (!protectedFeatures.protectedMemory)
1629 		{
1630 			TCU_THROW(NotSupportedError, "protectedMemory feature is not supported, no queue creation flags available");
1631 		}
1632 	}
1633 
1634 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1635 	const deUint32							queueCount				= 1;
1636 	const deUint32							queueIndex				= 0;
1637 	const float								queuePriority			= 1.0f;
1638 	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
1639 	{
1640 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// VkStructureType					sType;
1641 		DE_NULL,									// const void*						pNext;
1642 		(VkDeviceQueueCreateFlags)0u,				// VkDeviceQueueCreateFlags			flags;
1643 		queueFamilyIndex,							// deUint32							queueFamilyIndex;
1644 		queueCount,									// deUint32							queueCount;
1645 		&queuePriority,								// const float*						pQueuePriorities;
1646 	};
1647 	VkPhysicalDeviceProtectedMemoryFeatures	protectedFeatures		=
1648 	{
1649 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType				sType;
1650 		DE_NULL,														// void*						pNext;
1651 		VK_TRUE															// VkBool32						protectedMemory;
1652 	};
1653 
1654 	VkPhysicalDeviceFeatures				emptyDeviceFeatures;
1655 	deMemset(&emptyDeviceFeatures, 0, sizeof(emptyDeviceFeatures));
1656 
1657 	const VkPhysicalDeviceFeatures2			deviceFeatures			=
1658 	{
1659 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,					// VkStructureType				sType;
1660 		&protectedFeatures,												// void*						pNext;
1661 		emptyDeviceFeatures												// VkPhysicalDeviceFeatures		features;
1662 	};
1663 
1664 	const VkDeviceCreateInfo				deviceCreateInfo		=
1665 	{
1666 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// VkStructureType					sType;
1667 		&deviceFeatures,							// const void*						pNext;
1668 		(VkDeviceCreateFlags)0u,					// VkDeviceCreateFlags				flags;
1669 		1,											// deUint32							queueCreateInfoCount;
1670 		&deviceQueueCreateInfo,						// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1671 		0,											// deUint32							enabledLayerCount;
1672 		DE_NULL,									// const char* const*				ppEnabledLayerNames;
1673 		0,											// deUint32							enabledExtensionCount;
1674 		DE_NULL,									// const char* const*				ppEnabledExtensionNames;
1675 		DE_NULL,									// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1676 	};
1677 
1678 	const VkDeviceQueueInfo2				deviceQueueInfo2		=
1679 	{
1680 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,		// VkStructureType					sType;
1681 		DE_NULL,									// const void*						pNext;
1682 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,		// VkDeviceQueueCreateFlags			flags;
1683 		queueFamilyIndex,							// deUint32							queueFamilyIndex;
1684 		queueIndex,									// deUint32							queueIndex;
1685 	};
1686 
1687 	{
1688 		const Unique<VkDevice>		device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1689 		const DeviceDriver			deviceDriver			(platformInterface, instance, device.get());
1690 		const VkQueue				queue2					= getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);
1691 
1692 		if (queue2 != DE_NULL)
1693 			return tcu::TestStatus::fail("Fail, getDeviceQueue2 should return VK_NULL_HANDLE when flags in VkDeviceQueueCreateInfo and VkDeviceQueueInfo2 are different.");
1694 
1695 		const VkQueue				queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
1696 
1697 		VK_CHECK(deviceDriver.queueWaitIdle(queue));
1698 	}
1699 
1700 	return tcu::TestStatus::pass("Pass");
1701 }
1702 
1703 // Allocation tracking utilities
1704 struct	AllocTrack
1705 {
1706 	bool						active;
1707 	bool						wasAllocated;
1708 	void*						alignedStartAddress;
1709 	char*						actualStartAddress;
1710 	size_t						requestedSizeBytes;
1711 	size_t						actualSizeBytes;
1712 	VkSystemAllocationScope		allocScope;
1713 	deUint64					userData;
1714 
AllocTrackvkt::api::__anond2c26e020111::AllocTrack1715 	AllocTrack()
1716 		: active				(false)
1717 		, wasAllocated			(false)
1718 		, alignedStartAddress	(DE_NULL)
1719 		, actualStartAddress	(DE_NULL)
1720 		, requestedSizeBytes	(0)
1721 		, actualSizeBytes		(0)
1722 		, allocScope			(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)
1723 		, userData(0)			{}
1724 };
1725 
1726 // Global vector to track allocations. This will be resized before each test and emptied after
1727 // However, we have to globally define it so the allocation callback functions work properly
1728 std::vector<AllocTrack>	g_allocatedVector;
1729 bool					g_intentionalFailEnabled	= false;
1730 deUint32				g_intenionalFailIndex		= 0;
1731 deUint32				g_intenionalFailCount		= 0;
1732 size_t					g_allocationsCount			= 0;
1733 
freeAllocTracker(void)1734 void freeAllocTracker (void)
1735 {
1736 	g_allocatedVector.clear();
1737 	g_allocationsCount = 0;
1738 }
1739 
initAllocTracker(size_t size,deUint32 intentionalFailIndex=(deUint32)~0)1740 void initAllocTracker (size_t size, deUint32 intentionalFailIndex = (deUint32)~0)
1741 {
1742 	if (g_allocatedVector.size() > 0)
1743 		freeAllocTracker();
1744 
1745 	g_allocatedVector.resize(size);
1746 
1747 	if (intentionalFailIndex != (deUint32)~0)
1748 	{
1749 		g_intentionalFailEnabled	= true;
1750 		g_intenionalFailIndex		= intentionalFailIndex;
1751 		g_intenionalFailCount		= 0;
1752 	}
1753 	else
1754 	{
1755 		g_intentionalFailEnabled	= false;
1756 		g_intenionalFailIndex		= 0;
1757 		g_intenionalFailCount		= 0;
1758 	}
1759 
1760 	g_allocationsCount = 0;
1761 }
1762 
isAllocTrackerEmpty()1763 bool isAllocTrackerEmpty ()
1764 {
1765 	bool success		= true;
1766 	bool wasAllocated	= false;
1767 
1768 	for (deUint32 vectorIdx	= 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1769 	{
1770 		if (g_allocatedVector[vectorIdx].active)
1771 			success = false;
1772 		else if (!wasAllocated && g_allocatedVector[vectorIdx].wasAllocated)
1773 			wasAllocated = true;
1774 	}
1775 
1776 	if (!g_intentionalFailEnabled && !wasAllocated)
1777 		success = false;
1778 
1779 	return success;
1780 }
1781 
allocCallbackFunc(void * pUserData,size_t size,size_t alignment,VkSystemAllocationScope allocationScope)1782 VKAPI_ATTR void *VKAPI_CALL allocCallbackFunc (void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
1783 {
1784 	if (g_intentionalFailEnabled)
1785 		if (++g_intenionalFailCount >= g_intenionalFailIndex)
1786 			return DE_NULL;
1787 
1788 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1789 	{
1790 		if (!g_allocatedVector[vectorIdx].active)
1791 		{
1792 			g_allocatedVector[vectorIdx].requestedSizeBytes		= size;
1793 			g_allocatedVector[vectorIdx].actualSizeBytes		= size + (alignment - 1);
1794 			g_allocatedVector[vectorIdx].alignedStartAddress	= DE_NULL;
1795 			g_allocatedVector[vectorIdx].actualStartAddress		= new char[g_allocatedVector[vectorIdx].actualSizeBytes];
1796 
1797 			if (g_allocatedVector[vectorIdx].actualStartAddress != DE_NULL)
1798 			{
1799 				deUint64 addr	=	(deUint64)g_allocatedVector[vectorIdx].actualStartAddress;
1800 				addr			+=	(alignment - 1);
1801 				addr			&=	~(alignment - 1);
1802 				g_allocatedVector[vectorIdx].alignedStartAddress	= (void *)addr;
1803 				g_allocatedVector[vectorIdx].allocScope				= allocationScope;
1804 				g_allocatedVector[vectorIdx].userData				= (deUint64)pUserData;
1805 				g_allocatedVector[vectorIdx].active					= true;
1806 				g_allocatedVector[vectorIdx].wasAllocated			= true;
1807 			}
1808 
1809 			g_allocationsCount++;
1810 			return g_allocatedVector[vectorIdx].alignedStartAddress;
1811 		}
1812 	}
1813 	return DE_NULL;
1814 }
1815 
freeCallbackFunc(void * pUserData,void * pMemory)1816 VKAPI_ATTR void VKAPI_CALL freeCallbackFunc (void *pUserData, void *pMemory)
1817 {
1818 	DE_UNREF(pUserData);
1819 
1820 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1821 	{
1822 		if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pMemory)
1823 		{
1824 			delete[] g_allocatedVector[vectorIdx].actualStartAddress;
1825 			g_allocatedVector[vectorIdx].active = false;
1826 			break;
1827 		}
1828 	}
1829 }
1830 
reallocCallbackFunc(void * pUserData,void * pOriginal,size_t size,size_t alignment,VkSystemAllocationScope allocationScope)1831 VKAPI_ATTR void *VKAPI_CALL reallocCallbackFunc (void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
1832 {
1833 	if (pOriginal != DE_NULL)
1834 	{
1835 		for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1836 		{
1837 			if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pOriginal)
1838 			{
1839 				if (size == 0)
1840 				{
1841 					freeCallbackFunc(pUserData, pOriginal);
1842 					return DE_NULL;
1843 				}
1844 				else if (size < g_allocatedVector[vectorIdx].requestedSizeBytes)
1845 					return pOriginal;
1846 				else
1847 				{
1848 					void *pNew = allocCallbackFunc(pUserData, size, alignment, allocationScope);
1849 
1850 					if (pNew != DE_NULL)
1851 					{
1852 						size_t copySize = size;
1853 
1854 						if (g_allocatedVector[vectorIdx].requestedSizeBytes < size)
1855 							copySize = g_allocatedVector[vectorIdx].requestedSizeBytes;
1856 
1857 						memcpy(pNew, pOriginal, copySize);
1858 						freeCallbackFunc(pUserData, pOriginal);
1859 					}
1860 					return pNew;
1861 				}
1862 			}
1863 		}
1864 		return DE_NULL;
1865 	}
1866 	else
1867 		return allocCallbackFunc(pUserData, size, alignment, allocationScope);
1868 }
1869 
createInstanceDeviceIntentionalAllocFail(Context & context)1870 tcu::TestStatus createInstanceDeviceIntentionalAllocFail (Context& context)
1871 {
1872 	const PlatformInterface&	vkp					= context.getPlatformInterface();
1873 	const deUint32				chosenDevice		= context.getTestContext().getCommandLine().getVKDeviceId() - 1;
1874 	VkInstance					instance			= DE_NULL;
1875 	VkDevice					device				= DE_NULL;
1876 	deUint32					physicalDeviceCount	= 0;
1877 	deUint32					queueFamilyCount	= 0;
1878 	deUint32					queueFamilyIndex	= 0;
1879 	const float					queuePriority		= 0.0f;
1880 	const VkAllocationCallbacks	allocationCallbacks	=
1881 	{
1882 		DE_NULL,								// userData
1883 		allocCallbackFunc,						// pfnAllocation
1884 		reallocCallbackFunc,					// pfnReallocation
1885 		freeCallbackFunc,						// pfnFree
1886 		DE_NULL,								// pfnInternalAllocation
1887 		DE_NULL									// pfnInternalFree
1888 	};
1889 	const VkApplicationInfo		appInfo				=
1890 	{
1891 		VK_STRUCTURE_TYPE_APPLICATION_INFO,		// sType
1892 		DE_NULL,								// pNext
1893 		"appName",								// pApplicationName
1894 		0u,										// applicationVersion
1895 		"engineName",							// pEngineName
1896 		0u,										// engineVersion
1897 		VK_API_VERSION_1_0						// apiVersion
1898 	};
1899 
1900 	const VkInstanceCreateInfo	instanceCreateInfo	=
1901 	{
1902 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// sType
1903 		DE_NULL,								// pNext
1904 		(VkInstanceCreateFlags)0u,				// flags
1905 		&appInfo,								// pApplicationInfo
1906 		0u,										// enabledLayerCount
1907 		DE_NULL,								// ppEnabledLayerNames
1908 		0u,										// enabledExtensionCount
1909 		DE_NULL									// ppEnabledExtensionNames
1910 	};
1911 
1912 	deUint32					failIndex			= 0;
1913 	VkResult					result				= VK_SUCCESS;
1914 	size_t						max_allowed_alloc	= 0;
1915 
1916 	do
1917 	{
1918 		if (max_allowed_alloc == 0)
1919 		{
1920 			if (result != VK_SUCCESS)
1921 				return tcu::TestStatus::fail("Could not create instance and device");
1922 
1923 			initAllocTracker(99999);
1924 		}
1925 		else
1926 		{
1927 			initAllocTracker(max_allowed_alloc, failIndex++);
1928 
1929 			if (failIndex >= static_cast<deUint32>(max_allowed_alloc))
1930 				return tcu::TestStatus::fail("Out of retries, could not create instance and device");
1931 		}
1932 
1933 		// if the number of allocations the driver makes is large, we may end up
1934 		// taking more than the watchdog timeout. touch here to avoid spurious
1935 		// failures.
1936 		if (failIndex % 128 == 0)
1937 			context.getTestContext().touchWatchdog();
1938 
1939 		result = vkp.createInstance(&instanceCreateInfo, &allocationCallbacks, &instance);
1940 
1941 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1942 		{
1943 			if (!isAllocTrackerEmpty())
1944 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1945 
1946 			freeAllocTracker();
1947 			continue;
1948 		}
1949 		else if (result != VK_SUCCESS)
1950 			return tcu::TestStatus::fail("createInstance returned " + de::toString(result));
1951 
1952 		const InstanceDriver		instanceDriver	(vkp, instance);
1953 		const InstanceInterface&	vki				(instanceDriver);
1954 
1955 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, DE_NULL);
1956 
1957 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1958 		{
1959 			vki.destroyInstance(instance, &allocationCallbacks);
1960 
1961 			if (!isAllocTrackerEmpty())
1962 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1963 
1964 			freeAllocTracker();
1965 			continue;
1966 		}
1967 		else if (result != VK_SUCCESS)
1968 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
1969 
1970 		vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
1971 
1972 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
1973 
1974 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1975 		{
1976 			vki.destroyInstance(instance, &allocationCallbacks);
1977 
1978 			if (!isAllocTrackerEmpty())
1979 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1980 
1981 			freeAllocTracker();
1982 			continue;
1983 		}
1984 		else if (result != VK_SUCCESS)
1985 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
1986 
1987 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, DE_NULL);
1988 
1989 		if (queueFamilyCount == 0u)
1990 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
1991 
1992 		vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
1993 
1994 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, queueFamilies.data());
1995 
1996 		if (queueFamilyCount == 0u)
1997 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
1998 
1999 		for (deUint32 i = 0; i < queueFamilyCount; i++)
2000 		{
2001 			if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
2002 			{
2003 				queueFamilyIndex = i;
2004 				break;
2005 			}
2006 		}
2007 
2008 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
2009 		{
2010 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
2011 			DE_NULL,									// pNext
2012 			(VkDeviceQueueCreateFlags)0u,				// flags
2013 			queueFamilyIndex,							// queueFamilyIndex
2014 			1u,											// queueCount
2015 			&queuePriority								// pQueuePriorities
2016 		};
2017 
2018 		const VkDeviceCreateInfo		deviceCreateInfo		=
2019 		{
2020 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// sType
2021 			DE_NULL,									// pNext
2022 			(VkDeviceCreateFlags)0u,					// flags
2023 			1u,											// queueCreateInfoCount
2024 			&deviceQueueCreateInfo,						// pQueueCreateInfos
2025 			0u,											// enabledLayerCount
2026 			DE_NULL,									// ppEnabledLayerNames
2027 			0u,											// enabledExtensionCount
2028 			DE_NULL,									// ppEnabledExtensionNames
2029 			DE_NULL										// pEnabledFeatures
2030 		};
2031 
2032 		result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vki, physicalDevices[chosenDevice], &deviceCreateInfo, &allocationCallbacks, &device);
2033 
2034 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2035 		{
2036 			vki.destroyInstance(instance, &allocationCallbacks);
2037 
2038 			if (!isAllocTrackerEmpty())
2039 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2040 
2041 			freeAllocTracker();
2042 			continue;
2043 		}
2044 		else if (result != VK_SUCCESS)
2045 			return tcu::TestStatus::fail("VkCreateDevice returned " + de::toString(result));
2046 
2047 		DeviceDriver(vkp, instance, device).destroyDevice(device, &allocationCallbacks);
2048 		vki.destroyInstance(instance, &allocationCallbacks);
2049 		if (max_allowed_alloc == 0)
2050 		{
2051 			max_allowed_alloc	= g_allocationsCount + 100;
2052 			result				= VK_ERROR_OUT_OF_HOST_MEMORY;
2053 		}
2054 		freeAllocTracker();
2055 	}
2056 	while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
2057 
2058 	return tcu::TestStatus::pass("Pass");
2059 }
2060 
2061 } // anonymous
2062 
createDeviceInitializationTests(tcu::TestContext & testCtx)2063 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
2064 {
2065 	de::MovePtr<tcu::TestCaseGroup>	deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));
2066 
2067 	addFunctionCase(deviceInitializationTests.get(), "create_instance_name_version",					"", createInstanceTest);
2068 	addFunctionCase(deviceInitializationTests.get(), "create_instance_invalid_api_version",				"", createInstanceWithInvalidApiVersionTest);
2069 	addFunctionCase(deviceInitializationTests.get(), "create_instance_null_appinfo",					"", createInstanceWithNullApplicationInfoTest);
2070 	addFunctionCase(deviceInitializationTests.get(), "create_instance_unsupported_extensions",			"", createInstanceWithUnsupportedExtensionsTest);
2071 	addFunctionCase(deviceInitializationTests.get(), "create_instance_extension_name_abuse",			"", createInstanceWithExtensionNameAbuseTest);
2072 	addFunctionCase(deviceInitializationTests.get(), "create_instance_layer_name_abuse",				"", createInstanceWithLayerNameAbuseTest);
2073 	addFunctionCase(deviceInitializationTests.get(), "enumerate_devices_alloc_leak",					"", enumerateDevicesAllocLeakTest);
2074 	addFunctionCase(deviceInitializationTests.get(), "create_device",									"", createDeviceTest);
2075 	addFunctionCase(deviceInitializationTests.get(), "create_multiple_devices",							"", createMultipleDevicesTest);
2076 	addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_extensions",			"", createDeviceWithUnsupportedExtensionsTest);
2077 	addFunctionCase(deviceInitializationTests.get(), "create_device_various_queue_counts",				"", createDeviceWithVariousQueueCountsTest);
2078 	addFunctionCase(deviceInitializationTests.get(), "create_device_global_priority",					"", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest);
2079 	addFunctionCase(deviceInitializationTests.get(), "create_device_global_priority_query",				"", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest);
2080 	addFunctionCase(deviceInitializationTests.get(), "create_device_features2",							"", createDeviceFeatures2Test);
2081 	addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_features",				"", createDeviceWithUnsupportedFeaturesTest);
2082 	addFunctionCase(deviceInitializationTests.get(), "create_device_queue2",							"", createDeviceQueue2Test);
2083 	addFunctionCase(deviceInitializationTests.get(), "create_device_queue2_unmatched_flags",			"", createDeviceQueue2UnmatchedFlagsTest);
2084 	addFunctionCase(deviceInitializationTests.get(), "create_instance_device_intentional_alloc_fail",	"", createInstanceDeviceIntentionalAllocFail);
2085 
2086 	return deviceInitializationTests.release();
2087 }
2088 
2089 } // api
2090 } // vkt
2091