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 #include "vkSafetyCriticalUtil.hpp"
40 
41 #include "tcuTestLog.hpp"
42 #include "tcuResultCollector.hpp"
43 #include "tcuCommandLine.hpp"
44 
45 #include "deUniquePtr.hpp"
46 #include "deStringUtil.hpp"
47 
48 #include <limits>
49 #include <numeric>
50 #include <vector>
51 #include <set>
52 
53 namespace vkt
54 {
55 namespace api
56 {
57 
58 namespace
59 {
60 
61 using namespace vk;
62 using namespace std;
63 using std::vector;
64 using tcu::TestLog;
65 
createInstanceTest(Context& context)66 tcu::TestStatus createInstanceTest (Context& context)
67 {
68 	tcu::TestLog&				log						= context.getTestContext().getLog();
69 	tcu::ResultCollector		resultCollector			(log);
70 	const char*					appNames[]				= { "appName", DE_NULL, "",  "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" };
71 	const char*					engineNames[]			= { "engineName", DE_NULL, "",  "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" };
72 	const int					patchNumbers[]			= { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 };
73 	const deUint32				appVersions[]			= { 0, 1, (deUint32)-1 };
74 	const deUint32				engineVersions[]		= { 0, 1, (deUint32)-1 };
75 	const deUint32				apiVersion				= context.getUsedApiVersion();
76 	vector<VkApplicationInfo>	appInfos;
77 
78 	// test over appName
79 	for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++)
80 	{
81 		const VkApplicationInfo appInfo =
82 		{
83 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
84 			DE_NULL,								// const void*					pNext;
85 			appNames[appNameNdx],					// const char*					pAppName;
86 			0u,										// deUint32						appVersion;
87 			"engineName",							// const char*					pEngineName;
88 			0u,										// deUint32						engineVersion;
89 			apiVersion,								// deUint32						apiVersion;
90 		};
91 
92 		appInfos.push_back(appInfo);
93 	}
94 
95 	// test over engineName
96 	for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++)
97 	{
98 		const VkApplicationInfo appInfo =
99 		{
100 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
101 			DE_NULL,								// const void*					pNext;
102 			"appName",								// const char*					pAppName;
103 			0u,										// deUint32						appVersion;
104 			engineNames[engineNameNdx],				// const char*					pEngineName;
105 			0u,										// deUint32						engineVersion;
106 			apiVersion,								// deUint32						apiVersion;
107 		};
108 
109 		appInfos.push_back(appInfo);
110 	}
111 
112 	// test over appVersion
113 	for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++)
114 	{
115 		const VkApplicationInfo appInfo =
116 		{
117 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
118 			DE_NULL,								// const void*					pNext;
119 			"appName",								// const char*					pAppName;
120 			appVersions[appVersionNdx],				// deUint32						appVersion;
121 			"engineName",							// const char*					pEngineName;
122 			0u,										// deUint32						engineVersion;
123 			apiVersion,								// deUint32						apiVersion;
124 		};
125 
126 		appInfos.push_back(appInfo);
127 	}
128 
129 	// test over engineVersion
130 	for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++)
131 	{
132 		const VkApplicationInfo appInfo =
133 		{
134 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
135 			DE_NULL,								// const void*					pNext;
136 			"appName",								// const char*					pAppName;
137 			0u,										// deUint32						appVersion;
138 			"engineName",							// const char*					pEngineName;
139 			engineVersions[engineVersionNdx],		// deUint32						engineVersion;
140 			apiVersion,								// deUint32						apiVersion;
141 		};
142 
143 		appInfos.push_back(appInfo);
144 	}
145 
146 	const deUint32	variantNum	= unpackVersion(apiVersion).variantNum;
147 	const deUint32	majorNum	= unpackVersion(apiVersion).majorNum;
148 	const deUint32	minorNum	= unpackVersion(apiVersion).minorNum;
149 
150 	// patch component of api version checking (should be ignored by implementation)
151 	for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++)
152 	{
153 		const VkApplicationInfo appInfo =
154 		{
155 			VK_STRUCTURE_TYPE_APPLICATION_INFO,													// VkStructureType				sType;
156 			DE_NULL,																			// const void*					pNext;
157 			"appName",																			// const char*					pAppName;
158 			0u,																					// deUint32						appVersion;
159 			"engineName",																		// const char*					pEngineName;
160 			0u,																					// deUint32						engineVersion;
161 			VK_MAKE_API_VERSION(variantNum, majorNum, minorNum, patchNumbers[patchVersion]),	// deUint32						apiVersion;
162 		};
163 
164 		appInfos.push_back(appInfo);
165 	}
166 
167 	// test when apiVersion is 0
168 	{
169 		const VkApplicationInfo appInfo =
170 		{
171 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType				sType;
172 			DE_NULL,								// const void*					pNext;
173 			"appName",								// const char*					pAppName;
174 			0u,										// deUint32						appVersion;
175 			"engineName",							// const char*					pEngineName;
176 			0u,										// deUint32						engineVersion;
177 			0u,										// deUint32						apiVersion;
178 		};
179 
180 		appInfos.push_back(appInfo);
181 	}
182 
183 	// run the tests!
184 	for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx)
185 	{
186 		const VkApplicationInfo&		appInfo					= appInfos[appInfoNdx];
187 		const VkInstanceCreateInfo		instanceCreateInfo		=
188 		{
189 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
190 			DE_NULL,								// const void*					pNext;
191 			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
192 			&appInfo,								// const VkApplicationInfo*		pAppInfo;
193 			0u,										// deUint32						layerCount;
194 			DE_NULL,								// const char*const*			ppEnabledLayernames;
195 			0u,										// deUint32						extensionCount;
196 			DE_NULL,								// const char*const*			ppEnabledExtensionNames;
197 		};
198 
199 		log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage;
200 
201 		try
202 		{
203 			CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
204 			log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
205 		}
206 		catch (const vk::Error& err)
207 		{
208 			resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
209 		}
210 	}
211 
212 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
213 }
214 
createInstanceWithInvalidApiVersionTest(Context& context)215 tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context)
216 {
217 	tcu::TestLog&				log						= context.getTestContext().getLog();
218 	tcu::ResultCollector		resultCollector			(log);
219 	const PlatformInterface&	platformInterface		= context.getPlatformInterface();
220 
221 	deUint32					instanceApiVersion		= 0u;
222 	platformInterface.enumerateInstanceVersion(&instanceApiVersion);
223 
224 	const ApiVersion			apiVersion				= unpackVersion(instanceApiVersion);
225 
226 	const deUint32				invalidApiVariant		= (1 << 3) - 1;
227 	const deUint32				invalidMajorVersion		= (1 << 7) - 1;
228 	const deUint32				invalidMinorVersion		= (1 << 10) - 1;
229 	vector<ApiVersion>			invalidApiVersions;
230 
231 	invalidApiVersions.push_back(ApiVersion(invalidApiVariant, invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
232 	invalidApiVersions.push_back(ApiVersion(apiVersion.variantNum, invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
233 	invalidApiVersions.push_back(ApiVersion(apiVersion.variantNum, apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum));
234 #ifdef CTS_USES_VULKANSC
235 	invalidApiVersions.push_back(ApiVersion(invalidApiVariant, apiVersion.majorNum, apiVersion.minorNum, apiVersion.patchNum));
236 	invalidApiVersions.push_back(ApiVersion(0, apiVersion.majorNum, apiVersion.minorNum, apiVersion.patchNum));
237 #endif // CTS_USES_VULKANSC
238 
239 	for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++)
240 	{
241 		const VkApplicationInfo appInfo					=
242 		{
243 			VK_STRUCTURE_TYPE_APPLICATION_INFO,			// VkStructureType				sType;
244 			DE_NULL,									// const void*					pNext;
245 			"appName",									// const char*					pAppName;
246 			0u,											// deUint32						appVersion;
247 			"engineName",								// const char*					pEngineName;
248 			0u,											// deUint32						engineVersion;
249 			pack(invalidApiVersions[apiVersionNdx]),	// deUint32						apiVersion;
250 		};
251 		const VkInstanceCreateInfo	instanceCreateInfo	=
252 		{
253 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,		// VkStructureType				sType;
254 			DE_NULL,									// const void*					pNext;
255 			(VkInstanceCreateFlags)0u,					// VkInstanceCreateFlags		flags;
256 			&appInfo,									// const VkApplicationInfo*		pAppInfo;
257 			0u,											// deUint32						layerCount;
258 			DE_NULL,									// const char*const*			ppEnabledLayernames;
259 			0u,											// deUint32						extensionCount;
260 			DE_NULL,									// const char*const*			ppEnabledExtensionNames;
261 		};
262 
263 		log << TestLog::Message
264 			<< "API version reported by enumerateInstanceVersion: " << apiVersion
265 			<< ", api version used to create instance: " << invalidApiVersions[apiVersionNdx]
266 			<< TestLog::EndMessage;
267 
268 		{
269 			UncheckedInstance	instance;
270 			const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
271 
272 #ifdef CTS_USES_VULKANSC
273 			if (invalidApiVersions[apiVersionNdx].variantNum == apiVersion.variantNum)
274 #else
275 			if (apiVersion.majorNum == 1 && apiVersion.minorNum == 0)
276 			{
277 				if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
278 				{
279 					TCU_CHECK(!static_cast<bool>(instance));
280 					log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
281 				}
282 				else
283 					resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
284 			}
285 			else if (apiVersion.majorNum == 1 && apiVersion.minorNum >= 1)
286 #endif // CTS_USES_VULKANSC
287 			{
288 				if (result == VK_SUCCESS)
289 				{
290 					TCU_CHECK(static_cast<bool>(instance));
291 					log << TestLog::Message << "Pass, instance creation with nonstandard apiVersion succeeds for "
292 						<< ((apiVersion.variantNum == 0) ? "Vulkan 1.1" : "Vulkan SC when api variant is correct") << TestLog::EndMessage;
293 				}
294 				else if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
295 				{
296 					std::ostringstream message;
297 					message << "Fail, instance creation must not return VK_ERROR_INCOMPATIBLE_DRIVER for "
298 						<< ((apiVersion.variantNum == 0) ? "Vulkan 1.1" : "Vulkan SC when api variant is correct");
299 					resultCollector.fail(message.str().c_str());
300 				}
301 				else
302 				{
303 					std::ostringstream message;
304 					message << "Fail, createInstance failed with " << result;
305 					resultCollector.fail(message.str().c_str());
306 				}
307 			}
308 #ifdef CTS_USES_VULKANSC
309 			else if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
310 			{
311 				TCU_CHECK(!static_cast<bool>(instance));
312 				log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
313 			}
314 			else
315 				resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
316 #endif // CTS_USES_VULKANSC
317 		}
318 	}
319 
320 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
321 }
322 
createInstanceWithNullApplicationInfoTest(Context& context)323 tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context)
324 {
325 	tcu::TestLog&				log						= context.getTestContext().getLog();
326 	tcu::ResultCollector		resultCollector			(log);
327 
328 	const VkInstanceCreateInfo	instanceCreateInfo		=
329 	{
330 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType				sType;
331 		DE_NULL,								// const void*					pNext;
332 		(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags		flags;
333 		DE_NULL,								// const VkApplicationInfo*		pAppInfo;
334 		0u,										// deUint32						layerCount;
335 		DE_NULL,								// const char*const*			ppEnabledLayernames;
336 		0u,										// deUint32						extensionCount;
337 		DE_NULL,								// const char*const*			ppEnabledExtensionNames;
338 	};
339 
340 	log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage;
341 
342 	try
343 	{
344 		CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
345 		log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
346 	}
347 	catch (const vk::Error& err)
348 	{
349 		resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
350 	}
351 
352 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
353 }
354 
createInstanceWithUnsupportedExtensionsTest(Context& context)355 tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context)
356 {
357 	tcu::TestLog&						log						= context.getTestContext().getLog();
358 	const char*							enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"};
359 	const deUint32						apiVersion				= context.getUsedApiVersion();
360 	const VkApplicationInfo				appInfo					=
361 	{
362 		VK_STRUCTURE_TYPE_APPLICATION_INFO,						// VkStructureType				sType;
363 		DE_NULL,												// const void*					pNext;
364 		"appName",												// const char*					pAppName;
365 		0u,														// deUint32						appVersion;
366 		"engineName",											// const char*					pEngineName;
367 		0u,														// deUint32						engineVersion;
368 		apiVersion,												// deUint32						apiVersion;
369 	};
370 
371 	const VkInstanceCreateInfo			instanceCreateInfo		=
372 	{
373 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,					// VkStructureType				sType;
374 		DE_NULL,												// const void*					pNext;
375 		(VkInstanceCreateFlags)0u,								// VkInstanceCreateFlags		flags;
376 		&appInfo,												// const VkApplicationInfo*		pAppInfo;
377 		0u,														// deUint32						layerCount;
378 		DE_NULL,												// const char*const*			ppEnabledLayernames;
379 		DE_LENGTH_OF_ARRAY(enabledExtensions),					// deUint32						extensionCount;
380 		enabledExtensions,										// const char*const*			ppEnabledExtensionNames;
381 	};
382 
383 	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
384 
385 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
386 		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
387 
388 	{
389 		UncheckedInstance	instance;
390 		const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
391 
392 		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
393 		{
394 			TCU_CHECK(!static_cast<bool>(instance));
395 			return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected.");
396 		}
397 		else
398 			return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded.");
399 	}
400 }
401 
402 enum
403 {
404 	UTF8ABUSE_LONGNAME = 0,
405 	UTF8ABUSE_BADNAMES,
406 	UTF8ABUSE_OVERLONGNUL,
407 	UTF8ABUSE_OVERLONG,
408 	UTF8ABUSE_ZALGO,
409 	UTF8ABUSE_CHINESE,
410 	UTF8ABUSE_EMPTY,
411 	UTF8ABUSE_MAX
412 };
413 
getUTF8AbuseString(int index)414 string getUTF8AbuseString (int index)
415 {
416 	switch (index)
417 	{
418 	case UTF8ABUSE_LONGNAME:
419 		// Generate a long name.
420 		{
421 			std::string longname;
422 			longname.resize(65535, 'k');
423 			return longname;
424 		}
425 
426 	case UTF8ABUSE_BADNAMES:
427 		// Various illegal code points in utf-8
428 		return string(
429 			"Illegal bytes in UTF-8: "
430 			"\xc0 \xc1 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff"
431 			"illegal surrogates: \xed\xad\xbf \xed\xbe\x80");
432 
433 	case UTF8ABUSE_OVERLONGNUL:
434 		// Zero encoded as overlong, not exactly legal but often supported to differentiate from terminating zero
435 		return string("UTF-8 encoded nul \xC0\x80 (should not end name)");
436 
437 	case UTF8ABUSE_OVERLONG:
438 		// Some overlong encodings
439 		return string(
440 			"UTF-8 overlong \xF0\x82\x82\xAC \xfc\x83\xbf\xbf\xbf\xbf \xf8\x87\xbf\xbf\xbf "
441 			"\xf0\x8f\xbf\xbf");
442 
443 	case UTF8ABUSE_ZALGO:
444 		// Internet "zalgo" meme "bleeding text"
445 		return string(
446 			"\x56\xcc\xb5\xcc\x85\xcc\x94\xcc\x88\xcd\x8a\xcc\x91\xcc\x88\xcd\x91\xcc\x83\xcd\x82"
447 			"\xcc\x83\xcd\x90\xcc\x8a\xcc\x92\xcc\x92\xcd\x8b\xcc\x94\xcd\x9d\xcc\x98\xcc\xab\xcc"
448 			"\xae\xcc\xa9\xcc\xad\xcc\x97\xcc\xb0\x75\xcc\xb6\xcc\xbe\xcc\x80\xcc\x82\xcc\x84\xcd"
449 			"\x84\xcc\x90\xcd\x86\xcc\x9a\xcd\x84\xcc\x9b\xcd\x86\xcd\x92\xcc\x9a\xcd\x99\xcd\x99"
450 			"\xcc\xbb\xcc\x98\xcd\x8e\xcd\x88\xcd\x9a\xcc\xa6\xcc\x9c\xcc\xab\xcc\x99\xcd\x94\xcd"
451 			"\x99\xcd\x95\xcc\xa5\xcc\xab\xcd\x89\x6c\xcc\xb8\xcc\x8e\xcc\x8b\xcc\x8b\xcc\x9a\xcc"
452 			"\x8e\xcd\x9d\xcc\x80\xcc\xa1\xcc\xad\xcd\x9c\xcc\xba\xcc\x96\xcc\xb3\xcc\xa2\xcd\x8e"
453 			"\xcc\xa2\xcd\x96\x6b\xcc\xb8\xcc\x84\xcd\x81\xcc\xbf\xcc\x8d\xcc\x89\xcc\x85\xcc\x92"
454 			"\xcc\x84\xcc\x90\xcd\x81\xcc\x93\xcd\x90\xcd\x92\xcd\x9d\xcc\x84\xcd\x98\xcd\x9d\xcd"
455 			"\xa0\xcd\x91\xcc\x94\xcc\xb9\xcd\x93\xcc\xa5\xcd\x87\xcc\xad\xcc\xa7\xcd\x96\xcd\x99"
456 			"\xcc\x9d\xcc\xbc\xcd\x96\xcd\x93\xcc\x9d\xcc\x99\xcc\xa8\xcc\xb1\xcd\x85\xcc\xba\xcc"
457 			"\xa7\x61\xcc\xb8\xcc\x8e\xcc\x81\xcd\x90\xcd\x84\xcd\x8c\xcc\x8c\xcc\x85\xcd\x86\xcc"
458 			"\x84\xcd\x84\xcc\x90\xcc\x84\xcc\x8d\xcd\x99\xcd\x8d\xcc\xb0\xcc\xa3\xcc\xa6\xcd\x89"
459 			"\xcd\x8d\xcd\x87\xcc\x98\xcd\x8d\xcc\xa4\xcd\x9a\xcd\x8e\xcc\xab\xcc\xb9\xcc\xac\xcc"
460 			"\xa2\xcd\x87\xcc\xa0\xcc\xb3\xcd\x89\xcc\xb9\xcc\xa7\xcc\xa6\xcd\x89\xcd\x95\x6e\xcc"
461 			"\xb8\xcd\x8a\xcc\x8a\xcd\x82\xcc\x9b\xcd\x81\xcd\x90\xcc\x85\xcc\x9b\xcd\x80\xcd\x91"
462 			"\xcd\x9b\xcc\x81\xcd\x81\xcc\x9a\xcc\xb3\xcd\x9c\xcc\x9e\xcc\x9d\xcd\x99\xcc\xa2\xcd"
463 			"\x93\xcd\x96\xcc\x97\xff");
464 
465 	case UTF8ABUSE_CHINESE:
466 		// Some Chinese glyphs.
467 		// "English equivalent: The devil is in the details", https://en.wikiquote.org/wiki/Chinese_proverbs
468 		return string(
469 			"\xe8\xaf\xbb\xe4\xb9\xa6\xe9\xa1\xbb\xe7\x94\xa8\xe6\x84\x8f\xef\xbc\x8c\xe4\xb8\x80"
470 			"\xe5\xad\x97\xe5\x80\xbc\xe5\x8d\x83\xe9\x87\x91\x20");
471 
472 	default:
473 		DE_ASSERT(index == UTF8ABUSE_EMPTY);
474 		// Also try an empty string.
475 		return string("");
476 	}
477 }
478 
createInstanceWithExtensionNameAbuseTest(Context& context)479 tcu::TestStatus createInstanceWithExtensionNameAbuseTest (Context& context)
480 {
481 	const char*					extensionList[1]	= { 0 };
482 	const deUint32				apiVersion			= context.getUsedApiVersion();
483 	deUint32					failCount			= 0;
484 
485 	for (int i = 0; i < UTF8ABUSE_MAX; i++)
486 	{
487 		string abuseString	= getUTF8AbuseString(i);
488 		extensionList[0]	= abuseString.c_str();
489 
490 		const VkApplicationInfo		appInfo =
491 		{
492 			VK_STRUCTURE_TYPE_APPLICATION_INFO,				// VkStructureType			sType;
493 			DE_NULL,										// const void*				pNext;
494 			"appName",										// const char*				pAppName;
495 			0u,												// deUint32					appVersion;
496 			"engineName",									// const char*				pEngineName;
497 			0u,												// deUint32					engineVersion;
498 			apiVersion,										// deUint32					apiVersion;
499 		};
500 
501 		const VkInstanceCreateInfo	instanceCreateInfo =
502 		{
503 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,			// VkStructureType			sType;
504 			DE_NULL,										// const void*				pNext;
505 			(VkInstanceCreateFlags)0u,						// VkInstanceCreateFlags	flags;
506 			&appInfo,										// const VkApplicationInfo*	pAppInfo;
507 			0u,												// deUint32					layerCount;
508 			DE_NULL,										// const char*const*		ppEnabledLayernames;
509 			1u,												// deUint32					extensionCount;
510 			extensionList,									// const char*const*		ppEnabledExtensionNames;
511 		};
512 
513 		{
514 			UncheckedInstance	instance;
515 			const VkResult		result		= createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
516 
517 			if (result != VK_ERROR_EXTENSION_NOT_PRESENT)
518 				failCount++;
519 
520 			TCU_CHECK(!static_cast<bool>(instance));
521 		}
522 	}
523 
524 	if (failCount > 0)
525 		return tcu::TestStatus::fail("Fail, creating instances with unsupported extensions succeeded.");
526 
527 	return tcu::TestStatus::pass("Pass, creating instances with unsupported extensions were rejected.");
528 }
529 
createInstanceWithLayerNameAbuseTest(Context& context)530 tcu::TestStatus createInstanceWithLayerNameAbuseTest (Context& context)
531 {
532 	const PlatformInterface&	platformInterface	= context.getPlatformInterface();
533 	const char*					layerList[1]		= { 0 };
534 	const deUint32				apiVersion			= context.getUsedApiVersion();
535 	deUint32					failCount			= 0;
536 
537 	for (int i = 0; i < UTF8ABUSE_MAX; i++)
538 	{
539 		string abuseString	= getUTF8AbuseString(i);
540 		layerList[0]		= abuseString.c_str();
541 
542 		const VkApplicationInfo		appInfo =
543 		{
544 			VK_STRUCTURE_TYPE_APPLICATION_INFO,		// VkStructureType			sType;
545 			DE_NULL,								// const void*				pNext;
546 			"appName",								// const char*				pAppName;
547 			0u,										// deUint32					appVersion;
548 			"engineName",							// const char*				pEngineName;
549 			0u,										// deUint32					engineVersion;
550 			apiVersion,								// deUint32					apiVersion;
551 		};
552 
553 		const VkInstanceCreateInfo	instanceCreateInfo =
554 		{
555 			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// VkStructureType			sType;
556 			DE_NULL,								// const void*				pNext;
557 			(VkInstanceCreateFlags)0u,				// VkInstanceCreateFlags	flags;
558 			&appInfo,								// const VkApplicationInfo*	pAppInfo;
559 			1u,										// deUint32					layerCount;
560 			layerList,								// const char*const*		ppEnabledLayernames;
561 			0u,										// deUint32					extensionCount;
562 			DE_NULL,								// const char*const*		ppEnabledExtensionNames;
563 		};
564 
565 		{
566 			VkInstance		instance	= (VkInstance)0;
567 			const VkResult	result		= platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
568 			const bool		gotInstance	= !!instance;
569 
570 			if (instance)
571 			{
572 				const InstanceDriver instanceIface(platformInterface, instance);
573 				instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
574 			}
575 
576 			if (result != VK_ERROR_LAYER_NOT_PRESENT)
577 				failCount++;
578 
579 			TCU_CHECK(!gotInstance);
580 		}
581 	}
582 
583 	if (failCount > 0)
584 		return tcu::TestStatus::fail("Fail, creating instances with unsupported layers succeeded.");
585 
586 	return tcu::TestStatus::pass("Pass, creating instances with unsupported layers were rejected.");
587 }
588 
589 #ifndef CTS_USES_VULKANSC
enumerateDevicesAllocLeakTest(Context& context)590 tcu::TestStatus enumerateDevicesAllocLeakTest(Context& context)
591 {
592 	// enumeratePhysicalDevices uses instance-provided allocator
593 	// and this test checks if all alocated memory is freed
594 
595 	typedef AllocationCallbackRecorder::RecordIterator RecordIterator;
596 
597 	DeterministicFailAllocator	objAllocator	(getSystemAllocator(), DeterministicFailAllocator::MODE_DO_NOT_COUNT, 0);
598 	AllocationCallbackRecorder	recorder		(objAllocator.getCallbacks(), 128);
599 	const auto					instance		= createCustomInstanceFromContext(context, recorder.getCallbacks(), true);
600 	const auto&					vki				= instance.getDriver();
601 	vector<VkPhysicalDevice>	devices			(enumeratePhysicalDevices(vki, instance));
602 	RecordIterator				recordToCheck	(recorder.getRecordsEnd());
603 
604 	try
605 	{
606 		devices = enumeratePhysicalDevices(vki, instance);
607 	}
608 	catch (const vk::OutOfMemoryError& e)
609 	{
610 		if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY)
611 			return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Got out of memory error - leaks in enumeratePhysicalDevices not tested.");
612 	}
613 
614 	// make sure that same number of allocations and frees was done
615 	deInt32			allocationRecords	(0);
616 	RecordIterator	lastRecordToCheck	(recorder.getRecordsEnd());
617 	while (recordToCheck != lastRecordToCheck)
618 	{
619 		const AllocationCallbackRecord& record = *recordToCheck;
620 		switch (record.type)
621 		{
622 		case AllocationCallbackRecord::TYPE_ALLOCATION:
623 			++allocationRecords;
624 			break;
625 		case AllocationCallbackRecord::TYPE_FREE:
626 			if (record.data.free.mem != DE_NULL)
627 				--allocationRecords;
628 			break;
629 		default:
630 			break;
631 		}
632 		++recordToCheck;
633 	}
634 
635 	if (allocationRecords)
636 		return tcu::TestStatus::fail("enumeratePhysicalDevices leaked memory");
637 	return tcu::TestStatus::pass("Ok");
638 }
639 #endif // CTS_USES_VULKANSC
640 
createDeviceTest(Context& context)641 tcu::TestStatus createDeviceTest (Context& context)
642 {
643 	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
644 	const CustomInstance			instance				(createCustomInstanceFromContext(context));
645 	const InstanceDriver&			instanceDriver			(instance.getDriver());
646 	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
647 	const deUint32					queueFamilyIndex		= 0;
648 	const deUint32					queueCount				= 1;
649 	const deUint32					queueIndex				= 0;
650 	const float						queuePriority			= 1.0f;
651 
652 	const vector<VkQueueFamilyProperties> queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
653 
654 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
655 	{
656 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
657 		DE_NULL,
658 		(VkDeviceQueueCreateFlags)0u,
659 		queueFamilyIndex,						//queueFamilyIndex;
660 		queueCount,								//queueCount;
661 		&queuePriority,							//pQueuePriorities;
662 	};
663 
664 	void* pNext												= DE_NULL;
665 #ifdef CTS_USES_VULKANSC
666 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
667 	memReservationInfo.pNext								= pNext;
668 	pNext													= &memReservationInfo;
669 
670 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
671 	sc10Features.pNext										= pNext;
672 	pNext													= &sc10Features;
673 #endif // CTS_USES_VULKANSC
674 
675 	const VkDeviceCreateInfo		deviceCreateInfo	=
676 	{
677 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
678 		pNext,									//pNext;
679 		(VkDeviceCreateFlags)0u,
680 		1,										//queueRecordCount;
681 		&deviceQueueCreateInfo,					//pRequestedQueues;
682 		0,										//layerCount;
683 		DE_NULL,								//ppEnabledLayerNames;
684 		0,										//extensionCount;
685 		DE_NULL,								//ppEnabledExtensionNames;
686 		DE_NULL,								//pEnabledFeatures;
687 	};
688 
689 	const Unique<VkDevice>			device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
690 	const DeviceDriver				deviceDriver			(platformInterface, instance, device.get());
691 	const VkQueue					queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
692 
693 	VK_CHECK(deviceDriver.queueWaitIdle(queue));
694 
695 	return tcu::TestStatus::pass("Pass");
696 }
697 
createMultipleDevicesTest(Context& context)698 tcu::TestStatus createMultipleDevicesTest (Context& context)
699 {
700 	tcu::TestLog&										log						= context.getTestContext().getLog();
701 	tcu::ResultCollector								resultCollector			(log);
702 #ifndef CTS_USES_VULKANSC
703 	const int											numDevices				= 5;
704 #else
705 	const int											numDevices				= 2;
706 #endif // CTS_USES_VULKANSC
707 
708 	const PlatformInterface&							platformInterface		= context.getPlatformInterface();
709 
710 	vector<CustomInstance>								instances;
711 	vector<VkDevice>									devices(numDevices, (VkDevice)DE_NULL);
712 
713 	try
714 	{
715 		for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++)
716 		{
717 			instances.emplace_back(createCustomInstanceFromContext(context));
718 
719 			const InstanceDriver&								instanceDriver			(instances.back().getDriver());
720 			const VkPhysicalDevice								physicalDevice			= chooseDevice(instanceDriver, instances.back(), context.getTestContext().getCommandLine());
721 			const vector<VkQueueFamilyProperties>				queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
722 			const deUint32										queueFamilyIndex		= 0;
723 			const deUint32										queueCount				= 1;
724 			const deUint32										queueIndex				= 0;
725 			const float											queuePriority			= 1.0f;
726 			const VkDeviceQueueCreateInfo						deviceQueueCreateInfo	=
727 			{
728 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
729 				DE_NULL,
730 				(VkDeviceQueueCreateFlags)0u,					//flags;
731 				queueFamilyIndex,								//queueFamilyIndex;
732 				queueCount,										//queueCount;
733 				&queuePriority,									//pQueuePriorities;
734 			};
735 
736 			void* pNext												= DE_NULL;
737 #ifdef CTS_USES_VULKANSC
738 			VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
739 			memReservationInfo.pNext								= pNext;
740 			pNext													= &memReservationInfo;
741 
742 			VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
743 			sc10Features.pNext										= pNext;
744 			pNext													= &sc10Features;
745 #endif // CTS_USES_VULKANSC
746 
747 			const VkDeviceCreateInfo							deviceCreateInfo		=
748 			{
749 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,			//sType;
750 				pNext,											//pNext;
751 				(VkDeviceCreateFlags)0u,
752 				1,												//queueRecordCount;
753 				&deviceQueueCreateInfo,							//pRequestedQueues;
754 				0,												//layerCount;
755 				DE_NULL,										//ppEnabledLayerNames;
756 				0,												//extensionCount;
757 				DE_NULL,										//ppEnabledExtensionNames;
758 				DE_NULL,										//pEnabledFeatures;
759 			};
760 
761 			const VkResult result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]);
762 
763 			if (result != VK_SUCCESS)
764 			{
765 				resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result));
766 				break;
767 			}
768 
769 			{
770 				const DeviceDriver	deviceDriver	(platformInterface, instances.back(), devices[deviceNdx]);
771 				const VkQueue		queue			= getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex);
772 
773 				VK_CHECK(deviceDriver.queueWaitIdle(queue));
774 			}
775 		}
776 	}
777 	catch (const vk::Error& error)
778 	{
779 		resultCollector.fail(de::toString(error.getError()));
780 	}
781 	catch (...)
782 	{
783 		for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
784 		{
785 			if (devices[deviceNdx] != (VkDevice)DE_NULL)
786 			{
787 				DeviceDriver deviceDriver(platformInterface, instances[deviceNdx], devices[deviceNdx]);
788 				deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
789 			}
790 		}
791 
792 		throw;
793 	}
794 
795 	for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
796 	{
797 		if (devices[deviceNdx] != (VkDevice)DE_NULL)
798 		{
799 			DeviceDriver deviceDriver(platformInterface, instances[deviceNdx], devices[deviceNdx]);
800 			deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
801 		}
802 	}
803 
804 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
805 }
806 
createDeviceWithUnsupportedExtensionsTest(Context& context)807 tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context)
808 {
809 	tcu::TestLog&					log						= context.getTestContext().getLog();
810 	const PlatformInterface&		platformInterface		= context.getPlatformInterface();
811 	const CustomInstance			instance				(createCustomInstanceFromContext(context, DE_NULL, false));
812 	const InstanceDriver&			instanceDriver			(instance.getDriver());
813 	const char*						enabledExtensions[]		= {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"};
814 	const VkPhysicalDevice			physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
815 	const float						queuePriority			= 1.0f;
816 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
817 	{
818 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
819 		DE_NULL,
820 		(VkDeviceQueueCreateFlags)0u,
821 		0,										//queueFamilyIndex;
822 		1,										//queueCount;
823 		&queuePriority,							//pQueuePriorities;
824 	};
825 
826 	void* pNext												= DE_NULL;
827 #ifdef CTS_USES_VULKANSC
828 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
829 	memReservationInfo.pNext								= pNext;
830 	pNext													= &memReservationInfo;
831 
832 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
833 	sc10Features.pNext										= pNext;
834 	pNext													= &sc10Features;
835 #endif // CTS_USES_VULKANSC
836 
837 	const VkDeviceCreateInfo		deviceCreateInfo		=
838 	{
839 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
840 		pNext,									//pNext;
841 		(VkDeviceCreateFlags)0u,
842 		1,										//queueRecordCount;
843 		&deviceQueueCreateInfo,					//pRequestedQueues;
844 		0,										//layerCount;
845 		DE_NULL,								//ppEnabledLayerNames;
846 		DE_LENGTH_OF_ARRAY(enabledExtensions),	//extensionCount;
847 		enabledExtensions,						//ppEnabledExtensionNames;
848 		DE_NULL,								//pEnabledFeatures;
849 	};
850 
851 	log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
852 
853 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
854 		log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
855 
856 	{
857 		VkDevice		device		= (VkDevice)0;
858 		const VkResult	result		= createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device);
859 		const bool		gotDevice	= !!device;
860 
861 		if (device)
862 		{
863 			const DeviceDriver	deviceIface	(platformInterface, instance, device);
864 			deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
865 		}
866 
867 		if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
868 		{
869 			TCU_CHECK(!gotDevice);
870 			return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected.");
871 		}
872 		else
873 			return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed.");
874 	}
875 }
876 
getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)877 deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)
878 {
879 	deUint32 maxQueueCount = 0;
880 
881 	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
882 	{
883 		maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount);
884 	}
885 
886 	return maxQueueCount;
887 }
888 
createDeviceWithVariousQueueCountsTest(Context& context)889 tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context)
890 {
891 	tcu::TestLog&							log						= context.getTestContext().getLog();
892 	const int								queueCountDiff			= 1;
893 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
894 	const CustomInstance					instance				(createCustomInstanceFromContext(context));
895 	const InstanceDriver&					instanceDriver			(instance.getDriver());
896 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
897 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
898 	const vector<float>						queuePriorities			(getGlobalMaxQueueCount(queueFamilyProperties), 1.0f);
899 	vector<VkDeviceQueueCreateInfo>			deviceQueueCreateInfos;
900 
901 	for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
902 	{
903 		const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount;
904 
905 		for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff)
906 		{
907 			const VkDeviceQueueCreateInfo queueCreateInfo =
908 			{
909 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
910 				DE_NULL,
911 				(VkDeviceQueueCreateFlags)0u,
912 				queueFamilyNdx,
913 				queueCount,
914 				queuePriorities.data()
915 			};
916 
917 			deviceQueueCreateInfos.push_back(queueCreateInfo);
918 		}
919 	}
920 
921 	for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++)
922 	{
923 		const VkDeviceQueueCreateInfo&	queueCreateInfo			= deviceQueueCreateInfos[testNdx];
924 		void* pNext												= DE_NULL;
925 #ifdef CTS_USES_VULKANSC
926 		VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
927 		memReservationInfo.pNext								= pNext;
928 		pNext													= &memReservationInfo;
929 
930 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
931 		sc10Features.pNext										= pNext;
932 		pNext													= &sc10Features;
933 #endif // CTS_USES_VULKANSC
934 
935 		const VkDeviceCreateInfo		deviceCreateInfo		=
936 		{
937 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
938 			pNext,									//pNext;
939 			(VkDeviceCreateFlags)0u,
940 			1,										//queueRecordCount;
941 			&queueCreateInfo,						//pRequestedQueues;
942 			0,										//layerCount;
943 			DE_NULL,								//ppEnabledLayerNames;
944 			0,										//extensionCount;
945 			DE_NULL,								//ppEnabledExtensionNames;
946 			DE_NULL,								//pEnabledFeatures;
947 		};
948 
949 		const Unique<VkDevice>			device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
950 		const DeviceDriver				deviceDriver		(platformInterface, instance, device.get());
951 		const deUint32					queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
952 		const deUint32					queueCount			= deviceCreateInfo.pQueueCreateInfos->queueCount;
953 
954 		for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++)
955 		{
956 			const VkQueue		queue	= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex);
957 			VkResult			result;
958 
959 			TCU_CHECK(!!queue);
960 
961 			result = deviceDriver.queueWaitIdle(queue);
962 			if (result != VK_SUCCESS)
963 			{
964 				log << TestLog::Message
965 					<< "vkQueueWaitIdle failed"
966 					<< ",  queueIndex = " << queueIndex
967 					<< ", queueCreateInfo " << queueCreateInfo
968 					<< ", Error Code: " << result
969 					<< TestLog::EndMessage;
970 				return tcu::TestStatus::fail("Fail");
971 			}
972 		}
973 	}
974 	return tcu::TestStatus::pass("Pass");
975 }
976 
checkGlobalPrioritySupport(Context& context, bool useKhrGlobalPriority)977 void checkGlobalPrioritySupport (Context& context, bool useKhrGlobalPriority)
978 {
979 	const std::string extName = (useKhrGlobalPriority ? "VK_KHR_global_priority" : "VK_EXT_global_priority");
980 	context.requireDeviceFunctionality(extName);
981 }
982 
createDeviceWithGlobalPriorityTest(Context& context, bool useKhrGlobalPriority)983 tcu::TestStatus createDeviceWithGlobalPriorityTest (Context& context, bool useKhrGlobalPriority)
984 {
985 	tcu::TestLog&							log						= context.getTestContext().getLog();
986 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
987 	const CustomInstance					instance				(createCustomInstanceFromContext(context));
988 	const InstanceDriver&					instanceDriver			(instance.getDriver());
989 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
990 	const vector<float>						queuePriorities			(1, 1.0f);
991 	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 };
992 
993 #ifndef CTS_USES_VULKANSC
994 	deUint32						queueFamilyPropertyCount	= ~0u;
995 
996 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, DE_NULL);
997 	TCU_CHECK(queueFamilyPropertyCount > 0);
998 
999 	std::vector<VkQueueFamilyProperties2>					queueFamilyProperties2		(queueFamilyPropertyCount);
1000 	std::vector<VkQueueFamilyGlobalPriorityPropertiesKHR>	globalPriorityProperties	(queueFamilyPropertyCount);
1001 
1002 	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1003 	{
1004 		globalPriorityProperties[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR;
1005 		globalPriorityProperties[ndx].pNext	= DE_NULL;
1006 		queueFamilyProperties2[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1007 		queueFamilyProperties2[ndx].pNext	= &globalPriorityProperties[ndx];
1008 	}
1009 
1010 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
1011 	TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());
1012 
1013 	std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority", "VK_EXT_global_priority_query" };
1014 
1015 	if (useKhrGlobalPriority)
1016 		enabledExtensions = { "VK_KHR_global_priority" };
1017 
1018 	VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT	globalPriorityQueryFeatures
1019 	{
1020 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,	//sType;
1021 		DE_NULL,																//pNext;
1022 		VK_TRUE																	//globalPriorityQuery;
1023 	};
1024 #else
1025 	(void)useKhrGlobalPriority;
1026 	std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority" };
1027 #endif // CTS_USES_VULKANSC
1028 
1029 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1030 	{
1031 		enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
1032 	}
1033 
1034 	for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
1035 	{
1036 		const VkDeviceQueueGlobalPriorityCreateInfoEXT	queueGlobalPriority		=
1037 		{
1038 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,	//sType;
1039 			DE_NULL,														//pNext;
1040 			globalPriority													//globalPriority;
1041 		};
1042 
1043 		const VkDeviceQueueCreateInfo	queueCreateInfo		=
1044 		{
1045 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//sType;
1046 			&queueGlobalPriority,						//pNext;
1047 			(VkDeviceQueueCreateFlags)0u,				//flags;
1048 			0,											//queueFamilyIndex;
1049 			1,											//queueCount;
1050 			queuePriorities.data()						//pQueuePriorities;
1051 		};
1052 
1053 		void* pNext												= DE_NULL;
1054 #ifdef CTS_USES_VULKANSC
1055 		VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1056 		memReservationInfo.pNext								= pNext;
1057 		pNext													= &memReservationInfo;
1058 
1059 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1060 		sc10Features.pNext										= pNext;
1061 		pNext													= &sc10Features;
1062 #else
1063 		pNext = &globalPriorityQueryFeatures;
1064 #endif // CTS_USES_VULKANSC
1065 
1066 		const VkDeviceCreateInfo		deviceCreateInfo		=
1067 		{
1068 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	//sType;
1069 			pNext,									//pNext;
1070 			(VkDeviceCreateFlags)0u,				//flags;
1071 			1,										//queueRecordCount;
1072 			&queueCreateInfo,						//pRequestedQueues;
1073 			0,										//layerCount;
1074 			DE_NULL,								//ppEnabledLayerNames;
1075 			(deUint32)enabledExtensions.size(),		//extensionCount;
1076 			enabledExtensions.data(),				//ppEnabledExtensionNames;
1077 			DE_NULL,								//pEnabledFeatures;
1078 		};
1079 
1080 		const bool		mayBeDenied				= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
1081 #ifndef CTS_USES_VULKANSC
1082 		const bool		mustFail				= globalPriority < globalPriorityProperties[0].priorities[0] || globalPriority > globalPriorityProperties[0].priorities[globalPriorityProperties[0].priorityCount - 1];
1083 #endif // CTS_USES_VULKANSC
1084 
1085 		try
1086 		{
1087 			const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1088 			const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
1089 			const deUint32				queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
1090 			const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, 0);
1091 			VkResult					result;
1092 
1093 			TCU_CHECK(!!queue);
1094 
1095 			result = deviceDriver.queueWaitIdle(queue);
1096 			if (result == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
1097 			{
1098 				continue;
1099 			}
1100 
1101 #ifndef CTS_USES_VULKANSC
1102 			if (result == VK_ERROR_INITIALIZATION_FAILED && mustFail)
1103 			{
1104 				continue;
1105 			}
1106 
1107 			if (mustFail)
1108 			{
1109 				log << TestLog::Message
1110 					<< "device creation must fail but not"
1111 					<< ", globalPriority = " << globalPriority
1112 					<< ", queueCreateInfo " << queueCreateInfo
1113 					<< TestLog::EndMessage;
1114 				return tcu::TestStatus::fail("Fail");
1115 			}
1116 #endif // CTS_USES_VULKANSC
1117 
1118 			if (result != VK_SUCCESS)
1119 			{
1120 				log << TestLog::Message
1121 					<< "vkQueueWaitIdle failed"
1122 					<< ", globalPriority = " << globalPriority
1123 					<< ", queueCreateInfo " << queueCreateInfo
1124 					<< ", Error Code: " << result
1125 					<< TestLog::EndMessage;
1126 				return tcu::TestStatus::fail("Fail");
1127 			}
1128 		}
1129 		catch (const Error& error)
1130 		{
1131 			if ((error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
1132 #ifndef CTS_USES_VULKANSC
1133 			   || (error.getError() == VK_ERROR_INITIALIZATION_FAILED && mustFail)
1134 #endif // CTS_USES_VULKANSC
1135 			   )
1136 			{
1137 				continue;
1138 			}
1139 			else
1140 			{
1141 				log << TestLog::Message
1142 					<< "exception thrown " << error.getMessage()
1143 					<< ", globalPriority = " << globalPriority
1144 					<< ", queueCreateInfo " << queueCreateInfo
1145 					<< ", Error Code: " << error.getError()
1146 					<< TestLog::EndMessage;
1147 				return tcu::TestStatus::fail("Fail");
1148 			}
1149 		}
1150 	}
1151 
1152 	return tcu::TestStatus::pass("Pass");
1153 }
1154 
1155 #ifndef CTS_USES_VULKANSC
checkGlobalPriorityQuerySupport(Context& context, bool useKhrGlobalPriority)1156 void checkGlobalPriorityQuerySupport (Context& context, bool useKhrGlobalPriority)
1157 {
1158 	const std::string extName = (useKhrGlobalPriority ? "VK_KHR_global_priority" : "VK_EXT_global_priority_query");
1159 	context.requireDeviceFunctionality(extName);
1160 }
1161 
isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)1162 deBool isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)
1163 {
1164 	switch (priority) {
1165 		case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:
1166 		case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:
1167 		case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:
1168 		case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:
1169 			return DE_TRUE;
1170 		default:
1171 			return DE_FALSE;
1172 	}
1173 }
1174 
checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT& properties)1175 void checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT& properties)
1176 {
1177 	TCU_CHECK(properties.priorityCount > 0);
1178 	TCU_CHECK(properties.priorityCount <= VK_MAX_GLOBAL_PRIORITY_SIZE_KHR);
1179 	TCU_CHECK(isValidGlobalPriority(properties.priorities[0]));
1180 
1181 	for (deUint32 ndx = 1; ndx < properties.priorityCount; ndx++)
1182 	{
1183 		TCU_CHECK(isValidGlobalPriority(properties.priorities[ndx]));
1184 		TCU_CHECK(properties.priorities[ndx] == (properties.priorities[ndx - 1] << 1));
1185 	}
1186 }
1187 #endif // CTS_USES_VULKANSC
1188 
1189 #ifndef CTS_USES_VULKANSC
createDeviceWithQueriedGlobalPriorityTest(Context& context, bool useKhrGlobalPriority)1190 tcu::TestStatus createDeviceWithQueriedGlobalPriorityTest (Context& context, bool useKhrGlobalPriority)
1191 {
1192 	tcu::TestLog&					log							= context.getTestContext().getLog();
1193 	const PlatformInterface&		platformInterface			= context.getPlatformInterface();
1194 	const CustomInstance			instance					(createCustomInstanceFromContext(context));
1195 	const InstanceDriver&			instanceDriver				(instance.getDriver());
1196 	const VkPhysicalDevice			physicalDevice				= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1197 	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 };
1198 	const vector<float>				queuePriorities				(1, 1.0f);
1199 	deUint32						queueFamilyPropertyCount	= ~0u;
1200 
1201 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, DE_NULL);
1202 	TCU_CHECK(queueFamilyPropertyCount > 0);
1203 
1204 	std::vector<VkQueueFamilyProperties2>					queueFamilyProperties2		(queueFamilyPropertyCount);
1205 	std::vector<VkQueueFamilyGlobalPriorityPropertiesEXT>	globalPriorityProperties	(queueFamilyPropertyCount);
1206 
1207 	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1208 	{
1209 		globalPriorityProperties[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT;
1210 		globalPriorityProperties[ndx].pNext	= DE_NULL;
1211 		queueFamilyProperties2[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1212 		queueFamilyProperties2[ndx].pNext	= &globalPriorityProperties[ndx];
1213 	}
1214 
1215 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
1216 	TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());
1217 
1218 	std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority", "VK_EXT_global_priority_query" };
1219 	if (useKhrGlobalPriority)
1220 		enabledExtensions = { "VK_KHR_global_priority" };
1221 
1222 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1223 	{
1224 		enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
1225 	}
1226 
1227 	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1228 	{
1229 		checkGlobalPriorityProperties(globalPriorityProperties[ndx]);
1230 
1231 		for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
1232 		{
1233 			const VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT	globalPriorityQueryFeatures		=
1234 			{
1235 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,	//sType;
1236 				DE_NULL,																//pNext;
1237 				VK_TRUE																	//globalPriorityQuery;
1238 			};
1239 			const VkDeviceQueueGlobalPriorityCreateInfoEXT			queueGlobalPriorityCreateInfo	=
1240 			{
1241 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,			//sType;
1242 				DE_NULL,																//pNext;
1243 				globalPriority,															//globalPriority;
1244 			};
1245 			const VkDeviceQueueCreateInfo							queueCreateInfo					=
1246 			{
1247 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,								//sType;
1248 				&queueGlobalPriorityCreateInfo,											//pNext;
1249 				(VkDeviceQueueCreateFlags)0u,											//flags;
1250 				ndx,																	//queueFamilyIndex;
1251 				1,																		//queueCount;
1252 				queuePriorities.data()													//pQueuePriorities;
1253 			};
1254 			const VkDeviceCreateInfo								deviceCreateInfo				=
1255 			{
1256 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,									//sType;
1257 				&globalPriorityQueryFeatures,											//pNext;
1258 				(VkDeviceCreateFlags)0u,												//flags;
1259 				1,																		//queueRecordCount;
1260 				&queueCreateInfo,														//pRequestedQueues;
1261 				0,																		//layerCount;
1262 				DE_NULL,																//ppEnabledLayerNames;
1263 				(deUint32)enabledExtensions.size(),										//extensionCount;
1264 				enabledExtensions.data(),												//ppEnabledExtensionNames;
1265 				DE_NULL,																//pEnabledFeatures;
1266 			};
1267 			const bool												mayBeDenied						= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
1268 			const bool												mustFail						= globalPriority < globalPriorityProperties[ndx].priorities[0] || globalPriority > globalPriorityProperties[ndx].priorities[globalPriorityProperties[ndx].priorityCount - 1];
1269 
1270 			try
1271 			{
1272 				const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1273 				const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
1274 				const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, ndx, 0);
1275 
1276 				TCU_CHECK(!!queue);
1277 
1278 				if (mustFail)
1279 				{
1280 					log << TestLog::Message
1281 						<< "device creation must fail but not"
1282 						<< ", globalPriority = " << globalPriority
1283 						<< ", queueCreateInfo " << queueCreateInfo
1284 						<< TestLog::EndMessage;
1285 					return tcu::TestStatus::fail("Fail");
1286 				}
1287 			}
1288 			catch (const Error& error)
1289 			{
1290 				if (mustFail || (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied))
1291 				{
1292 					continue;
1293 				}
1294 				else
1295 				{
1296 					log << TestLog::Message
1297 						<< "exception thrown " << error.getMessage()
1298 						<< ", globalPriority = " << globalPriority
1299 						<< ", queueCreateInfo " << queueCreateInfo
1300 						<< ", Error Code: " << error.getError()
1301 						<< TestLog::EndMessage;
1302 					return tcu::TestStatus::fail("Fail");
1303 				}
1304 			}
1305 		}
1306 	}
1307 
1308 	return tcu::TestStatus::pass("Pass");
1309 }
1310 #endif // CTS_USES_VULKANSC
1311 
createDeviceFeatures2Test(Context& context)1312 tcu::TestStatus createDeviceFeatures2Test (Context& context)
1313 {
1314 	const PlatformInterface&				vkp						= context.getPlatformInterface();
1315 	const CustomInstance					instance				(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
1316 	const InstanceDriver&					vki						(instance.getDriver());
1317 	const VkPhysicalDevice					physicalDevice			= chooseDevice(vki, instance, context.getTestContext().getCommandLine());
1318 	const deUint32							queueFamilyIndex		= 0;
1319 	const deUint32							queueCount				= 1;
1320 	const deUint32							queueIndex				= 0;
1321 	const float								queuePriority			= 1.0f;
1322 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
1323 
1324 	VkPhysicalDeviceFeatures2		enabledFeatures;
1325 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1326 	{
1327 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1328 		DE_NULL,
1329 		(VkDeviceQueueCreateFlags)0u,
1330 		queueFamilyIndex,
1331 		queueCount,
1332 		&queuePriority,
1333 	};
1334 
1335 	void* pNext												= &enabledFeatures;
1336 #ifdef CTS_USES_VULKANSC
1337 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1338 	memReservationInfo.pNext								= pNext;
1339 	pNext													= &memReservationInfo;
1340 
1341 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1342 	sc10Features.pNext										= pNext;
1343 	pNext													= &sc10Features;
1344 #endif // CTS_USES_VULKANSC
1345 
1346 	const VkDeviceCreateInfo		deviceCreateInfo		=
1347 	{
1348 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1349 		pNext,
1350 		(VkDeviceCreateFlags)0u,
1351 		1,
1352 		&deviceQueueCreateInfo,
1353 		0u,
1354 		DE_NULL,
1355 		0,
1356 		DE_NULL,
1357 		DE_NULL,
1358 	};
1359 
1360 	// Populate enabledFeatures
1361 	enabledFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1362 	enabledFeatures.pNext		= DE_NULL;
1363 
1364 	vki.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
1365 
1366 	{
1367 		const Unique<VkDevice>	device		(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceCreateInfo));
1368 		const DeviceDriver		vkd			(vkp, instance, device.get());
1369 		const VkQueue			queue		= getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);
1370 
1371 		VK_CHECK(vkd.queueWaitIdle(queue));
1372 	}
1373 
1374 	return tcu::TestStatus::pass("Pass");
1375 }
1376 
1377 struct Feature
1378 {
1379 	const char*	name;
1380 	size_t		offset;
1381 };
1382 
1383 #define FEATURE_ITEM(STRUCT, MEMBER) {#MEMBER, DE_OFFSET_OF(STRUCT, MEMBER)}
1384 // This macro is used to avoid the "out of array bounds" compiler warnings/errors in the checkFeatures function.
1385 #define SAFE_OFFSET(LIMITING_STRUCT, STRUCT, MEMBER) std::min(static_cast<deUint32>(sizeof(LIMITING_STRUCT) - sizeof(VkBool32)), DE_OFFSET_OF(STRUCT, MEMBER))
1386 
1387 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, VkDeviceObjectReservationCreateInfo memReservationStatMax, bool isSubProcess )1388 void checkFeatures (const PlatformInterface&				vkp,
1389 					const VkInstance&						instance,
1390 					const InstanceDriver&					instanceDriver,
1391 					const VkPhysicalDevice					physicalDevice,
1392 					int										numFeatures,
1393 					const Feature							features[],
1394 					const StructType*						supportedFeatures,
1395 					const deUint32							queueFamilyIndex,
1396 					const deUint32							queueCount,
1397 					const float								queuePriority,
1398 					int&									numErrors,
1399 					tcu::ResultCollector&					resultCollector,
1400 					const vector<const char*>*				extensionNames,
1401 					const VkPhysicalDeviceFeatures&			defaultPhysicalDeviceFeatures,
1402 #ifdef CTS_USES_VULKANSC
1403 					VkDeviceObjectReservationCreateInfo		memReservationStatMax,
1404 #endif // CTS_USES_VULKANSC
1405 					bool									isSubProcess
1406 	)
1407 {
1408 	struct StructureBase
1409 	{
1410 		VkStructureType		sType;
1411 		void*				pNext;
1412 	};
1413 
1414 	for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
1415 	{
1416 		// Test only features that are not supported.
1417 		if (*(((VkBool32*)((deUint8*)(supportedFeatures) + features[featureNdx].offset))))
1418 			continue;
1419 
1420 		StructType structCopy;
1421 		deMemset(&structCopy, 0, sizeof(StructType));
1422 
1423 		auto* structBase = reinterpret_cast<StructureBase*>(&structCopy);
1424 		VkStructureType structureType = reinterpret_cast<const StructureBase*>(supportedFeatures)->sType;
1425 		structBase->sType = structureType;
1426 		structBase->pNext = DE_NULL;
1427 
1428 		VkPhysicalDeviceFeatures physicalDeviceFeaturesCopy = defaultPhysicalDeviceFeatures;
1429 
1430 		// Some features require that other feature(s) are also enabled.
1431 
1432 		if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES)
1433 		{
1434 			DE_ASSERT((std::is_same<VkPhysicalDeviceVulkan11Features, StructType>::value));
1435 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1436 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1437 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader) ||
1438 				features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader))
1439 			{
1440 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, multiview));
1441 				*memberPtr = VK_TRUE;
1442 			}
1443 
1444 			// If variablePointers is enabled then variablePointersStorageBuffer must also be enabled.
1445 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, variablePointers))
1446 			{
1447 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer));
1448 				*memberPtr = VK_TRUE;
1449 			}
1450 		}
1451 #ifndef CTS_USES_VULKANSC
1452 		// If rayTracingPipelineShaderGroupHandleCaptureReplayMixed is VK_TRUE, rayTracingPipelineShaderGroupHandleCaptureReplay must also be VK_TRUE.
1453 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR &&
1454 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplayMixed))
1455 		{
1456 			DE_ASSERT((std::is_same<VkPhysicalDeviceRayTracingPipelineFeaturesKHR, StructType>::value));
1457 			auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplay));
1458 			*memberPtr = VK_TRUE;
1459 		}
1460 #endif // CTS_USES_VULKANSC
1461 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES)
1462 		{
1463 			DE_ASSERT((std::is_same<VkPhysicalDeviceMultiviewFeatures, StructType>::value));
1464 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1465 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1466 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewGeometryShader) ||
1467 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewTessellationShader))
1468 			{
1469 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceMultiviewFeatures, multiview));
1470 				*memberPtr = VK_TRUE;
1471 			}
1472 		}
1473 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
1474 		{
1475 			DE_ASSERT((std::is_same<VkPhysicalDeviceRobustness2FeaturesEXT, StructType>::value));
1476 			// If robustBufferAccess2 is enabled then robustBufferAccess must also be enabled.
1477 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRobustness2FeaturesEXT, robustBufferAccess2))
1478 			{
1479 				physicalDeviceFeaturesCopy.robustBufferAccess = true;
1480 			}
1481 		}
1482 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT)
1483 		{
1484 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, StructType>::value));
1485 			// If sparseImageInt64Atomics is enabled, shaderImageInt64Atomics must be enabled.
1486 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, sparseImageInt64Atomics))
1487 			{
1488 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, shaderImageInt64Atomics));
1489 				*memberPtr = VK_TRUE;
1490 			}
1491 		}
1492 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT)
1493 		{
1494 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, StructType>::value));
1495 			// If sparseImageFloat32Atomics is enabled, shaderImageFloat32Atomics must be enabled.
1496 			if (features[featureNdx].offset ==
1497 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32Atomics)) {
1498 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32Atomics));
1499 				*memberPtr = VK_TRUE;
1500 			}
1501 
1502 			// If sparseImageFloat32AtomicAdd is enabled, shaderImageFloat32AtomicAdd must be enabled.
1503 			if (features[featureNdx].offset ==
1504 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32AtomicAdd)) {
1505 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32AtomicAdd));
1506 				*memberPtr = VK_TRUE;
1507 			}
1508 		}
1509 #ifndef CTS_USES_VULKANSC
1510 		else if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT)
1511 		{
1512 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, StructType>::value));
1513 			// If sparseImageFloat32AtomicMinMax is enabled, shaderImageFloat32AtomicMinMax must be enabled.
1514 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, sparseImageFloat32AtomicMinMax))
1515 			{
1516 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderImageFloat32AtomicMinMax));
1517 				*memberPtr = VK_TRUE;
1518 			}
1519 		}
1520 #endif // CTS_USES_VULKANSC
1521 
1522 		// Enable the feature we're testing.
1523 		*reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + features[featureNdx].offset) = VK_TRUE;
1524 
1525 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1526 		{
1527 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
1528 			DE_NULL,									// pNext
1529 			(VkDeviceQueueCreateFlags)0u,				// flags
1530 			queueFamilyIndex,							// queueFamilyIndex
1531 			queueCount,									// queueCount
1532 			&queuePriority								// pQueuePriorities
1533 		};
1534 		VkPhysicalDeviceFeatures2 deviceFeatures2 =
1535 		{
1536 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,	// sType
1537 			&structCopy,									// pNext
1538 			physicalDeviceFeaturesCopy						// features
1539 		};
1540 
1541 		void* pNext												= &deviceFeatures2;
1542 #ifdef CTS_USES_VULKANSC
1543 		VkDeviceObjectReservationCreateInfo memReservationInfo	= isSubProcess? memReservationStatMax : resetDeviceObjectReservationCreateInfo();
1544 		memReservationInfo.pNext								= pNext;
1545 		pNext													= &memReservationInfo;
1546 
1547 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1548 		sc10Features.pNext										= pNext;
1549 		pNext													= &sc10Features;
1550 #else
1551 		DE_UNREF(isSubProcess);
1552 #endif // CTS_USES_VULKANSC
1553 
1554 		const VkDeviceCreateInfo		deviceCreateInfo		=
1555 		{
1556 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,											// sType
1557 			pNext,																			// pNext
1558 			(VkDeviceCreateFlags)0u,														// flags
1559 			1,																				// queueCreateInfoCount
1560 			&deviceQueueCreateInfo,															// pQueueCreateInfos
1561 			0u,																				// enabledLayerCount
1562 			DE_NULL,																		// ppEnabledLayerNames
1563 			static_cast<deUint32>(extensionNames == DE_NULL ? 0 : extensionNames->size()),	// enabledExtensionCount
1564 			extensionNames == DE_NULL ? DE_NULL : extensionNames->data(),					// ppEnabledExtensionNames
1565 			DE_NULL																			// pEnabledFeatures
1566 		};
1567 
1568 		VkDevice		device = (VkDevice)DE_NULL;
1569 		const VkResult	res	= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1570 
1571 		if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1572 		{
1573 			numErrors++;
1574 			resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1575 				+ de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
1576 		}
1577 		if (device != (VkDevice)DE_NULL)
1578 		{
1579 			DeviceDriver deviceDriver(vkp, instance, device);
1580 			deviceDriver.destroyDevice(device, DE_NULL);
1581 		}
1582 	}
1583 }
1584 
removeExtensions(const vector<string>& a, const vector<const char*>& b)1585 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
1586 {
1587 	vector<string>	res;
1588 	set<string>		removeExts	(b.begin(), b.end());
1589 
1590 	for (const auto & aIter : a)
1591 	{
1592 		if (!de::contains(removeExts, aIter))
1593 			res.push_back(aIter);
1594 	}
1595 
1596 	return res;
1597 }
1598 
createDeviceWithUnsupportedFeaturesTest(Context& context)1599 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
1600 {
1601 	const PlatformInterface&				vkp						= context.getPlatformInterface();
1602 	tcu::TestLog&							log						= context.getTestContext().getLog();
1603 	tcu::ResultCollector					resultCollector			(log);
1604 	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
1605 	const InstanceDriver&					instanceDriver			(instance.getDriver());
1606 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1607 	const deUint32							queueFamilyIndex		= 0;
1608 	const deUint32							queueCount				= 1;
1609 	const float								queuePriority			= 1.0f;
1610 	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
1611 	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
1612 	const VkPhysicalDeviceFeatures			deviceFeatures			= deviceFeatures2.features;
1613 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
1614 
1615 	// Test features listed in VkPhysicalDeviceFeatures structure
1616 	{
1617 		static const Feature features[] =
1618 		{
1619 			// robustBufferAccess is removed, because it's always supported.
1620 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
1621 			FEATURE_ITEM(VkPhysicalDeviceFeatures, imageCubeArray),
1622 			FEATURE_ITEM(VkPhysicalDeviceFeatures, independentBlend),
1623 			FEATURE_ITEM(VkPhysicalDeviceFeatures, geometryShader),
1624 			FEATURE_ITEM(VkPhysicalDeviceFeatures, tessellationShader),
1625 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sampleRateShading),
1626 			FEATURE_ITEM(VkPhysicalDeviceFeatures, dualSrcBlend),
1627 			FEATURE_ITEM(VkPhysicalDeviceFeatures, logicOp),
1628 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiDrawIndirect),
1629 			FEATURE_ITEM(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
1630 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthClamp),
1631 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBiasClamp),
1632 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fillModeNonSolid),
1633 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBounds),
1634 			FEATURE_ITEM(VkPhysicalDeviceFeatures, wideLines),
1635 			FEATURE_ITEM(VkPhysicalDeviceFeatures, largePoints),
1636 			FEATURE_ITEM(VkPhysicalDeviceFeatures, alphaToOne),
1637 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiViewport),
1638 			FEATURE_ITEM(VkPhysicalDeviceFeatures, samplerAnisotropy),
1639 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionETC2),
1640 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
1641 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionBC),
1642 			FEATURE_ITEM(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
1643 			FEATURE_ITEM(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
1644 			FEATURE_ITEM(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
1645 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
1646 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
1647 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
1648 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
1649 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
1650 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
1651 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
1652 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
1653 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
1654 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
1655 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
1656 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderClipDistance),
1657 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderCullDistance),
1658 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderFloat64),
1659 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt64),
1660 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt16),
1661 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceResidency),
1662 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceMinLod),
1663 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseBinding),
1664 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
1665 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
1666 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
1667 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency2Samples),
1668 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency4Samples),
1669 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency8Samples),
1670 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency16Samples),
1671 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyAliased),
1672 			FEATURE_ITEM(VkPhysicalDeviceFeatures, variableMultisampleRate),
1673 			FEATURE_ITEM(VkPhysicalDeviceFeatures, inheritedQueries)
1674 		};
1675 
1676 		for (const auto& feature : features)
1677 		{
1678 			// Test only features that are not supported.
1679 			if (*(((VkBool32*)((deUint8*)(&deviceFeatures) + feature.offset))))
1680 				continue;
1681 
1682 			VkPhysicalDeviceFeatures		enabledFeatures			= deviceFeatures;
1683 			*((VkBool32*)((deUint8*)(&enabledFeatures) + feature.offset)) = VK_TRUE;
1684 
1685 			const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1686 			{
1687 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1688 				DE_NULL,
1689 				(VkDeviceQueueCreateFlags)0u,
1690 				queueFamilyIndex,
1691 				queueCount,
1692 				&queuePriority
1693 			};
1694 
1695 			void* pNext												= DE_NULL;
1696 #ifdef CTS_USES_VULKANSC
1697 			VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1698 			memReservationInfo.pNext								= pNext;
1699 			pNext													= &memReservationInfo;
1700 
1701 			VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1702 			sc10Features.pNext										= pNext;
1703 			pNext													= &sc10Features;
1704 #endif // CTS_USES_VULKANSC
1705 
1706 			const VkDeviceCreateInfo		deviceCreateInfo		=
1707 			{
1708 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1709 				pNext,
1710 				(VkDeviceCreateFlags)0u,
1711 				1,
1712 				&deviceQueueCreateInfo,
1713 				0u,
1714 				DE_NULL,
1715 				0,
1716 				DE_NULL,
1717 				&enabledFeatures
1718 			};
1719 
1720 			VkDevice		device	= DE_NULL;
1721 			const VkResult	res		= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1722 
1723 			if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1724 			{
1725 				resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1726 				+ de::toString(feature.name) + ", which was reported as unsupported.");
1727 			}
1728 
1729 			if (device != DE_NULL)
1730 			{
1731 				DeviceDriver deviceDriver(vkp, instance, device);
1732 				deviceDriver.destroyDevice(device, DE_NULL);
1733 			}
1734 		}
1735 	}
1736 
1737 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
1738 }
1739 
1740 #include "vkDeviceFeatureTest.inl"
1741 
createDeviceQueue2Test(Context& context)1742 tcu::TestStatus createDeviceQueue2Test (Context& context)
1743 {
1744 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1745 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1746 
1747 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1748 	const CustomInstance					instance				(createCustomInstanceFromContext(context));
1749 	const InstanceDriver&					instanceDriver			(instance.getDriver());
1750 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1751 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1752 	const deUint32							queueCount				= 1;
1753 	const deUint32							queueIndex				= 0;
1754 	const float								queuePriority			= 1.0f;
1755 
1756 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1757 	{
1758 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1759 		DE_NULL,														// void*							pNext;
1760 		VK_FALSE														// VkBool32							protectedMemory;
1761 	};
1762 
1763 	VkPhysicalDeviceFeatures2				features2;
1764 	deMemset(&features2, 0, sizeof(features2));
1765 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1766 	features2.pNext													= &protectedMemoryFeature;
1767 
1768 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1769 	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1770 		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1771 
1772 	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
1773 	{
1774 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
1775 		DE_NULL,														// const void*						pNext;
1776 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1777 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1778 		queueCount,														// deUint32							queueCount;
1779 		&queuePriority,													// const float*						pQueuePriorities;
1780 	};
1781 
1782 	void* pNext												= &features2;
1783 #ifdef CTS_USES_VULKANSC
1784 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1785 	memReservationInfo.pNext								= pNext;
1786 	pNext													= &memReservationInfo;
1787 
1788 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1789 	sc10Features.pNext										= pNext;
1790 	pNext													= &sc10Features;
1791 #endif // CTS_USES_VULKANSC
1792 
1793 	const VkDeviceCreateInfo				deviceCreateInfo		=
1794 	{
1795 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
1796 		pNext,															// const void*						pNext;
1797 		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
1798 		1,																// deUint32							queueCreateInfoCount;
1799 		&deviceQueueCreateInfo,											// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1800 		0,																// deUint32							enabledLayerCount;
1801 		DE_NULL,														// const char* const*				ppEnabledLayerNames;
1802 		0,																// deUint32							enabledExtensionCount;
1803 		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
1804 		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1805 	};
1806 
1807 	const VkDeviceQueueInfo2				deviceQueueInfo2		=
1808 	{
1809 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
1810 		DE_NULL,														// const void*						pNext;
1811 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1812 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1813 		queueIndex,														// deUint32							queueIndex;
1814 	};
1815 
1816 	{
1817 		const Unique<VkDevice>				device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1818 		const DeviceDriver					deviceDriver			(platformInterface, instance, device.get());
1819 		const VkQueue						queue2					= getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);
1820 
1821 		VK_CHECK(deviceDriver.queueWaitIdle(queue2));
1822 	}
1823 
1824 	return tcu::TestStatus::pass("Pass");
1825 }
1826 
findQueueFamiliesWithCaps(const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)1827 map<deUint32, VkQueueFamilyProperties> findQueueFamiliesWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
1828 {
1829 	const vector<VkQueueFamilyProperties>	queueProps				= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
1830 	map<deUint32, VkQueueFamilyProperties>	queueFamilies;
1831 
1832 	for (deUint32 queueNdx = 0; queueNdx < static_cast<deUint32>(queueProps.size()); queueNdx++)
1833 	{
1834 		const VkQueueFamilyProperties&		queueFamilyProperties	= queueProps[queueNdx];
1835 
1836 		if ((queueFamilyProperties.queueFlags & requiredCaps) == requiredCaps)
1837 			queueFamilies[queueNdx] = queueFamilyProperties;
1838 	}
1839 
1840 	if (queueFamilies.empty())
1841 		TCU_THROW(NotSupportedError, "No matching queue found");
1842 
1843 	return queueFamilies;
1844 }
1845 
checkProtectedMemorySupport(Context& context)1846 void checkProtectedMemorySupport (Context& context)
1847 {
1848 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1849 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1850 
1851 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
1852 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1853 
1854 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1855 	{
1856 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1857 		DE_NULL,														// void*							pNext;
1858 		VK_FALSE														// VkBool32							protectedMemory;
1859 	};
1860 
1861 	VkPhysicalDeviceFeatures2				features2;
1862 	deMemset(&features2, 0, sizeof(features2));
1863 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1864 	features2.pNext													= &protectedMemoryFeature;
1865 
1866 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1867 	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1868 		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1869 }
1870 
createProtectedDeviceWithQueueConfig(Context& context, const std::vector<VkDeviceQueueCreateInfo>& queueCreateInfos, bool dumpExtraInfo=false)1871 Move<VkDevice> createProtectedDeviceWithQueueConfig (Context& context, const std::vector<VkDeviceQueueCreateInfo>& queueCreateInfos, bool dumpExtraInfo=false)
1872 {
1873 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1874 	const VkInstance						instance				= context.getInstance();
1875 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
1876 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1877 
1878 	if (dumpExtraInfo)
1879 	{
1880 		tcu::TestLog&						log						= context.getTestContext().getLog();
1881 
1882 		log << tcu::TestLog::Message << "Creating VkDevice with the following Queue configuration:" << tcu::TestLog::EndMessage;
1883 
1884 		for (size_t idx = 0; idx < queueCreateInfos.size(); idx++)
1885 		{
1886 			const VkDeviceQueueCreateInfo&	queueCreateInfo			= queueCreateInfos[idx];
1887 
1888 			log << tcu::TestLog::Message << "QueueCreateInfo " << idx << ": "
1889 				<< "flags: " << queueCreateInfo.flags << " "
1890 				<< "family: " << queueCreateInfo.queueFamilyIndex << " "
1891 				<< "count: " << queueCreateInfo.queueCount
1892 				<< tcu::TestLog::EndMessage;
1893 		}
1894 	}
1895 
1896 	// Protected memory features availability should be already checked at this point.
1897 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1898 	{
1899 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1900 		DE_NULL,														// void*							pNext;
1901 		VK_TRUE															// VkBool32							protectedMemory;
1902 	};
1903 
1904 	VkPhysicalDeviceFeatures2				features2;
1905 	deMemset(&features2, 0, sizeof(features2));
1906 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1907 	features2.pNext													= &protectedMemoryFeature;
1908 
1909 #ifdef CTS_USES_VULKANSC
1910 	void* pNext														= DE_NULL;
1911 
1912 	VkDeviceObjectReservationCreateInfo memReservationInfo			= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1913 	memReservationInfo.pNext										= pNext;
1914 	pNext															= &memReservationInfo;
1915 
1916 	VkPhysicalDeviceVulkanSC10Features sc10Features					= createDefaultSC10Features();
1917 	sc10Features.pNext												= pNext;
1918 	pNext															= &sc10Features;
1919 #endif // CTS_USES_VULKANSC
1920 
1921 	const VkDeviceCreateInfo				deviceCreateInfo		=
1922 	{
1923 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
1924 #ifdef CTS_USES_VULKANSC
1925 		&sc10Features,													// const void*						pNext;
1926 #else
1927 		&features2,														// const void*						pNext;
1928 #endif // CTS_USES_VULKANSC
1929 		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
1930 		(deUint32)queueCreateInfos.size(),								// deUint32							queueCreateInfoCount;
1931 		queueCreateInfos.data(),										// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1932 		0,																// deUint32							enabledLayerCount;
1933 		DE_NULL,														// const char* const*				ppEnabledLayerNames;
1934 		0,																// deUint32							enabledExtensionCount;
1935 		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
1936 		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1937 	};
1938 
1939 	return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo);
1940 }
1941 
getDeviceQueue2WithOptions(const DeviceDriver& deviceDriver, const VkDevice device, VkDeviceQueueCreateFlags flags, deUint32 queueFamilyIndex, deUint32 queueIndex)1942 VkQueue getDeviceQueue2WithOptions (const DeviceDriver& deviceDriver, const VkDevice device, VkDeviceQueueCreateFlags flags, deUint32 queueFamilyIndex, deUint32 queueIndex)
1943 {
1944 	VkDeviceQueueInfo2						queueInfo2				=
1945 	{
1946 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
1947 		DE_NULL,														// const void*						pNext;
1948 		flags,															// VkDeviceQueueCreateFlags			flags;
1949 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1950 		queueIndex,														// deUint32							queueIndex;
1951 	};
1952 
1953 	return getDeviceQueue2(deviceDriver, device, &queueInfo2);
1954 }
1955 
1956 struct QueueCreationInfo
1957 {
1958 	deUint32						familyIndex;
1959 	VkDeviceQueueCreateFlags		flags;
1960 	deUint32						count;
1961 };
1962 
runQueueCreationTestCombination(Context& context, tcu::ResultCollector& results, const std::vector<QueueCreationInfo>& testCombination, bool dumpExtraInfo=false)1963 bool runQueueCreationTestCombination (Context& context, tcu::ResultCollector& results, const std::vector<QueueCreationInfo>& testCombination, bool dumpExtraInfo=false)
1964 {
1965 	deUint32								sumQueueCount			= 0u;
1966 	for (const QueueCreationInfo& info : testCombination)
1967 	{
1968 		sumQueueCount += info.count;
1969 	}
1970 
1971 	// Have an array of queue priorities which can be used when creating the queues (it is always greater or equal to the number of queues for a given VkDeviceQueueCreateInfo).
1972 	const vector<float>						queuePriorities			(sumQueueCount, 1.0f);
1973 	vector<VkDeviceQueueCreateInfo>			queueCreateInfo;
1974 
1975 	for (const QueueCreationInfo& info : testCombination)
1976 	{
1977 		const VkDeviceQueueCreateInfo		queueInfo				=
1978 		{
1979 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
1980 			DE_NULL,														// const void*						pNext;
1981 			info.flags,														// VkDeviceQueueCreateFlags			flags;
1982 			info.familyIndex,												// deUint32							queueFamilyIndex;
1983 			info.count,														// deUint32							queueCount;
1984 			queuePriorities.data(),											// const float*						pQueuePriorities;
1985 		};
1986 		queueCreateInfo.push_back(queueInfo);
1987 	}
1988 
1989 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1990 	const VkInstance						instance				= context.getInstance();
1991 
1992 	const Unique<VkDevice>					device					(createProtectedDeviceWithQueueConfig(context, queueCreateInfo, dumpExtraInfo));
1993 	const DeviceDriver						deviceDriver			(platformInterface, instance, *device);
1994 
1995 	for (const QueueCreationInfo& info : testCombination)
1996 	{
1997 		// Query Queues (based on the test configuration)
1998 		for (deUint32 queueIdx = 0; queueIdx < info.count; queueIdx++)
1999 		{
2000 			const string					message					= "(queueFamilyIndex: " + de::toString(info.familyIndex) + ", flags: " + de::toString(info.flags) + ", queue Index: " + de::toString(queueIdx) + ")";
2001 			const VkQueue					queue					= getDeviceQueue2WithOptions(deviceDriver, *device, info.flags, info.familyIndex, queueIdx);
2002 
2003 			if (queue != DE_NULL)
2004 			{
2005 				VK_CHECK(deviceDriver.queueWaitIdle(queue));
2006 				results.addResult(QP_TEST_RESULT_PASS, "Found Queue. " + message);
2007 			} else
2008 				results.fail("Unable to access the Queue. " + message);
2009 		}
2010 	}
2011 
2012 	return results.getResult() == QP_TEST_RESULT_PASS;
2013 }
2014 
createDeviceQueue2WithTwoQueuesSmokeTest(Context& context)2015 tcu::TestStatus createDeviceQueue2WithTwoQueuesSmokeTest (Context& context)
2016 {
2017 	const bool								dumpExtraInfo			= true;
2018 
2019 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2020 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2021 	tcu::TestLog&							log						= context.getTestContext().getLog();
2022 
2023 	vector<VkQueueFamilyProperties>			queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
2024 
2025 	// Find the first protected-capabale queue with a queueCount >= 2 and use it for testing (smoke test)
2026 	constexpr deUint32						MAX_DEUINT32			= std::numeric_limits<deUint32>::max();
2027 	deUint32								queueFamilyIndex		= MAX_DEUINT32;
2028 	const VkQueueFlags						requiredCaps			= VK_QUEUE_PROTECTED_BIT;
2029 	const deUint32							requiredQueueCount		= 2;
2030 
2031 	for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); queueNdx++)
2032 	{
2033 		if ((queueFamilyProperties[queueNdx].queueFlags & requiredCaps) == requiredCaps && queueFamilyProperties[queueNdx].queueCount >= requiredQueueCount)
2034 		{
2035 			queueFamilyIndex = queueNdx;
2036 			break;
2037 		}
2038 	}
2039 
2040 	if (queueFamilyIndex == MAX_DEUINT32)
2041 		TCU_THROW(NotSupportedError, "Unable to find a queue family that is protected-capable and supports more than one queue.");
2042 
2043 	if (dumpExtraInfo)
2044 		log << tcu::TestLog::Message << "Selected VkQueueFamilyProperties index: " << queueFamilyIndex << tcu::TestLog::EndMessage;
2045 
2046 	// Use the previously selected queue family index to create 1 protected-capable and 1 unprotected queue.
2047 	const QueueCreationInfo					protectedQueueConfig	= { queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, 1 };
2048 	const QueueCreationInfo					unprotectedQueueConfig	= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, 1 };
2049 
2050 	tcu::ResultCollector					results					(log);
2051 	const std::vector<QueueCreationInfo>	testCombination			= { protectedQueueConfig, unprotectedQueueConfig };
2052 	bool									success					= runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2053 
2054 	if (success)
2055 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2056 
2057 	return tcu::TestStatus(results.getResult(), results.getMessage());
2058 }
2059 
createDeviceQueue2WithAllProtectedQueues(Context& context)2060 tcu::TestStatus createDeviceQueue2WithAllProtectedQueues (Context& context)
2061 {
2062 	const bool								dumpExtraInfo			= true;
2063 
2064 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2065 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2066 
2067 	// Select only protected-capable queue families
2068 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2069 
2070 	bool									success					= true;
2071 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2072 
2073 	// For each protected-capable queue family, create a device with the max number of queues available and all queues created as protected-capable.
2074 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2075 	{
2076 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2077 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2078 
2079 		const QueueCreationInfo				protectedQueueConfig	= { queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, queueCount };
2080 		const vector<QueueCreationInfo>		testCombination			= { protectedQueueConfig };
2081 
2082 		// Run current confugurations.
2083 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2084 	}
2085 
2086 	if (success)
2087 		return tcu::TestStatus::pass("All queues were queried correctly.");
2088 
2089 	return tcu::TestStatus(results.getResult(), results.getMessage());
2090 }
2091 
createDeviceQueue2WithAllUnprotectedQueues(Context& context)2092 tcu::TestStatus createDeviceQueue2WithAllUnprotectedQueues (Context& context)
2093 {
2094 	const bool								dumpExtraInfo			= true;
2095 
2096 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2097 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2098 
2099 	// Select all queue families with or without protected bit
2100 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, 0);
2101 
2102 	bool									success					= true;
2103 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2104 
2105 	// For each Queue Family create the max number of unprotected Queues.
2106 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2107 	{
2108 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2109 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2110 
2111 		const QueueCreationInfo				unprotectedQueueConfig	= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, queueCount };
2112 		const vector<QueueCreationInfo>		testCombination			= { unprotectedQueueConfig };
2113 
2114 		// Run current confugurations.
2115 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2116 	}
2117 
2118 	if (success)
2119 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2120 
2121 	return tcu::TestStatus(results.getResult(), results.getMessage());
2122 }
2123 
2124 typedef vector<QueueCreationInfo>					DeviceQueueConfig;
2125 typedef map<deUint32, vector<DeviceQueueConfig> >	QueueFamilyConfigurations;
2126 
buildQueueConfigurations(const map<deUint32, VkQueueFamilyProperties>& queueFamilyProperties)2127 QueueFamilyConfigurations buildQueueConfigurations (const map<deUint32, VkQueueFamilyProperties>& queueFamilyProperties)
2128 {
2129 	QueueFamilyConfigurations				queuesPerFamily;
2130 
2131 	// Build up the queue creation combinations (N protected and M unprotected queues where N+M == queueFamily.queueCount)
2132 	// on each protected-capable queue family
2133 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamily : queueFamilyProperties)
2134 	{
2135 		const deUint32						queueFamilyIndex		= queueFamily.first;
2136 		const VkQueueFamilyProperties		queueFamilyProperty		= queueFamily.second;
2137 		const deUint32						allowedQueueCount		= queueFamilyProperty.queueCount;
2138 
2139 		for (deUint32 splitCount = 0; splitCount <= allowedQueueCount; splitCount++)
2140 		{
2141 			const deUint32					protectedQueuesCount	= allowedQueueCount - splitCount;
2142 			const deUint32					unprotectedQueuesCount	= splitCount;
2143 
2144 			vector<QueueCreationInfo>		testCombination			= { };
2145 
2146 			if (protectedQueuesCount)
2147 				testCombination.push_back({ queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, protectedQueuesCount });
2148 
2149 			if (unprotectedQueuesCount)
2150 				testCombination.push_back({ queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, unprotectedQueuesCount });
2151 
2152 			queuesPerFamily[queueFamilyIndex].push_back(testCombination);
2153 		}
2154 	}
2155 
2156 	return queuesPerFamily;
2157 }
2158 
createDeviceQueue2WithNProtectedAndMUnprotectedQueues(Context& context)2159 tcu::TestStatus createDeviceQueue2WithNProtectedAndMUnprotectedQueues (Context& context)
2160 {
2161 	const bool								dumpExtraInfo			= true;
2162 
2163 	tcu::TestLog&							log						= context.getTestContext().getLog();
2164 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2165 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2166 
2167 	// Select only protected-capable queue families
2168 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2169 
2170 	// Build all protected-unprotected splits per queue family.
2171 	QueueFamilyConfigurations				queuesPerFamily			= buildQueueConfigurations(queueFamilyProperties);
2172 	vector<DeviceQueueConfig>				queueCreateCombinations;
2173 
2174 	// Transform configurations to a simple vector
2175 	for (const auto& item : queuesPerFamily)
2176 	{
2177 		const vector<DeviceQueueConfig>&	queueConfigs			= item.second;
2178 
2179 		std::copy(queueConfigs.begin(), queueConfigs.end(), std::back_inserter(queueCreateCombinations));
2180 	}
2181 
2182 	if (dumpExtraInfo)
2183 	{
2184 		for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2185 		{
2186 			ostringstream				queuesInfo;
2187 			for (const QueueCreationInfo& queueInfo : testCombination)
2188 			{
2189 				queuesInfo << "(Queue family: " << queueInfo.familyIndex << ", flags: " << queueInfo.flags << ", count: " << queueInfo.count << ")";
2190 			}
2191 
2192 			log << tcu::TestLog::Message << "Test Combination: " << queuesInfo.str() << tcu::TestLog::EndMessage;
2193 		}
2194 	}
2195 
2196 	bool									success					= true;
2197 	tcu::ResultCollector					results					(log);
2198 
2199 	// Based on the protected-unprotected queue combinations, run each test case.
2200 	for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2201 	{
2202 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2203 	}
2204 
2205 	// Run the test cases also in reverse order (so the unprotected queue creation info is at the start of the VkDeviceQueueCreateInfo vector).
2206 	for (vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2207 	{
2208 		std::reverse(testCombination.begin(), testCombination.end());
2209 
2210 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2211 	}
2212 
2213 	if (success)
2214 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2215 
2216 	return tcu::TestStatus(results.getResult(), results.getMessage());
2217 }
2218 
createDeviceQueue2WithMultipleQueueCombinations(Context& context)2219 tcu::TestStatus createDeviceQueue2WithMultipleQueueCombinations (Context& context)
2220 {
2221 	const bool								dumpExtraInfo			= true;
2222 
2223 	tcu::TestLog&							log						= context.getTestContext().getLog();
2224 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2225 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2226 
2227 	// Select only protected-capable queue families.
2228 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2229 
2230 	// Build all protected-unprotected splits per queue family.
2231 	QueueFamilyConfigurations				queuesPerFamily			= buildQueueConfigurations(queueFamilyProperties);
2232 
2233 	// Build up all combinations of queue families from the previous mapping.
2234 	vector<DeviceQueueConfig>				queueCreateCombinations;
2235 	{
2236 		vector<deUint32>					itemIndices				(queuesPerFamily.size(), 0u);
2237 
2238 		// Calculate the max number of combinations.
2239 		auto								multiplyConfigCounts	= [](deUint32& count, const typename QueueFamilyConfigurations::value_type& item) { return count * item.second.size(); };
2240 		const deUint32						itemCount				= accumulate(queuesPerFamily.begin(), queuesPerFamily.end(), 1u, multiplyConfigCounts);
2241 
2242 		for (deUint32 count = 0u; count < itemCount; count++)
2243 		{
2244 			DeviceQueueConfig				testCombination;
2245 
2246 			// Select queue configurations from each family
2247 			for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(itemIndices.size()); ndx++)
2248 			{
2249 				const auto&					familyConfigurations	= queuesPerFamily[ndx];
2250 				const DeviceQueueConfig&	targetQueueConfig		= familyConfigurations[ itemIndices[ndx] ];
2251 
2252 				std::copy(targetQueueConfig.begin(), targetQueueConfig.end(), std::back_inserter(testCombination));
2253 			}
2254 
2255 			queueCreateCombinations.push_back(testCombination);
2256 
2257 			// Increment the indices.
2258 			for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(itemIndices.size()); ndx++)
2259 			{
2260 				itemIndices[ndx]++;
2261 				if (itemIndices[ndx] < queuesPerFamily[ndx].size())
2262 				{
2263 					break;
2264 				}
2265 
2266 				// "overflow" happened in the given index, restart from zero and increment the next item index (restart loop).
2267 				itemIndices[ndx] = 0;
2268 			}
2269 		}
2270 	}
2271 
2272 	if (dumpExtraInfo)
2273 	{
2274 		for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2275 		{
2276 			ostringstream					queuesInfo;
2277 			for (const QueueCreationInfo& queueInfo : testCombination)
2278 			{
2279 				queuesInfo << "(Queue family: " << queueInfo.familyIndex << ", flags: " << queueInfo.flags << ", count: " << queueInfo.count << ")";
2280 			}
2281 
2282 			log << tcu::TestLog::Message << "Test Combination: " << queuesInfo.str() << tcu::TestLog::EndMessage;
2283 		}
2284 	}
2285 
2286 	bool									success					= true;
2287 	tcu::ResultCollector					results					(log);
2288 
2289 	// Based on the protected-unprotected queue combinations above run each test case.
2290 	for (const DeviceQueueConfig& testCombination : queueCreateCombinations)
2291 	{
2292 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2293 	}
2294 
2295 	// Run the test cases also in reverse queue order (so the unprotected queue creation info is at the start of the VkDeviceQueueCreateInfo vector).
2296 	for (DeviceQueueConfig& testCombination : queueCreateCombinations)
2297 	{
2298 		std::reverse(testCombination.begin(), testCombination.end());
2299 
2300 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2301 	}
2302 
2303 	if (success)
2304 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2305 
2306 	return tcu::TestStatus(results.getResult(), results.getMessage());
2307 }
2308 
createDeviceQueue2WithAllFamilies(Context& context)2309 tcu::TestStatus createDeviceQueue2WithAllFamilies (Context& context)
2310 {
2311 	const bool								dumpExtraInfo			= true;
2312 
2313 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2314 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2315 
2316 	// Get all queue families
2317 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, (VkDeviceQueueCreateFlags)0u);
2318 
2319 	// Create test configuration where for each queue family the maximum number of queues are created.
2320 	vector<QueueCreationInfo>				queueConfigurations;
2321 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2322 	{
2323 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2324 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2325 
2326 		const QueueCreationInfo				queueConfig				= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, queueCount };
2327 
2328 		queueConfigurations.push_back(queueConfig);
2329 	}
2330 
2331 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2332 
2333 	// Execute test to see if it possible to have all queue families created at the same time.
2334 	bool									success					= runQueueCreationTestCombination(context, results, queueConfigurations, dumpExtraInfo);
2335 
2336 	if (success)
2337 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2338 
2339 	return tcu::TestStatus(results.getResult(), results.getMessage());
2340 }
2341 
createDeviceQueue2WithAllFamiliesProtected(Context& context)2342 tcu::TestStatus createDeviceQueue2WithAllFamiliesProtected (Context& context)
2343 {
2344 	const bool								dumpExtraInfo			= true;
2345 
2346 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2347 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2348 
2349 	// Get all queue families
2350 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, (VkDeviceQueueCreateFlags)0u);
2351 
2352 	// Create test configuration where for each queue family the maximum number of queues are created.
2353 	// If a queue supports protected memory then create a protected-capable queue.
2354 	vector<QueueCreationInfo>				queueConfigurations;
2355 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2356 	{
2357 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2358 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2359 
2360 		VkDeviceQueueCreateFlags			useFlags				= (VkDeviceQueueCreateFlags)0u;
2361 		if ((queueFamilyProperty.second.queueFlags & VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT) == VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT)
2362 			useFlags |= VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
2363 
2364 		const QueueCreationInfo				queueConfig				= { queueFamilyIndex, useFlags, queueCount };
2365 
2366 		queueConfigurations.push_back(queueConfig);
2367 	}
2368 
2369 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2370 
2371 	// Execute test to see if it possible to have all queue families created at the same time.
2372 	bool									success					= runQueueCreationTestCombination(context, results, queueConfigurations, dumpExtraInfo);
2373 
2374 	if (success)
2375 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2376 
2377 	return tcu::TestStatus(results.getResult(), results.getMessage());
2378 }
2379 
2380 #ifndef CTS_USES_VULKANSC
2381 // Allocation tracking utilities
2382 struct	AllocTrack
2383 {
2384 	bool						active;
2385 	bool						wasAllocated;
2386 	void*						alignedStartAddress;
2387 	char*						actualStartAddress;
2388 	size_t						requestedSizeBytes;
2389 	size_t						actualSizeBytes;
2390 	VkSystemAllocationScope		allocScope;
2391 	deUint64					userData;
2392 
AllocTrackvkt::api::__anon29030::AllocTrack2393 	AllocTrack()
2394 		: active				(false)
2395 		, wasAllocated			(false)
2396 		, alignedStartAddress	(DE_NULL)
2397 		, actualStartAddress	(DE_NULL)
2398 		, requestedSizeBytes	(0)
2399 		, actualSizeBytes		(0)
2400 		, allocScope			(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)
2401 		, userData(0)			{}
2402 };
2403 
2404 // Global vector to track allocations. This will be resized before each test and emptied after
2405 // However, we have to globally define it so the allocation callback functions work properly
2406 std::vector<AllocTrack>	g_allocatedVector;
2407 bool					g_intentionalFailEnabled	= false;
2408 deUint32				g_intenionalFailIndex		= 0;
2409 deUint32				g_intenionalFailCount		= 0;
2410 size_t					g_allocationsCount			= 0;
2411 
freeAllocTracker(void)2412 void freeAllocTracker(void)
2413 {
2414 	g_allocatedVector.clear();
2415 	g_allocationsCount = 0;
2416 }
2417 
initAllocTracker(size_t size, deUint32 intentionalFailIndex = (deUint32)~0)2418 void initAllocTracker (size_t size, deUint32 intentionalFailIndex = (deUint32)~0)
2419 {
2420 	if (g_allocatedVector.size() > 0)
2421 		freeAllocTracker();
2422 
2423 	g_allocatedVector.resize(size);
2424 
2425 	if (intentionalFailIndex != (deUint32)~0)
2426 	{
2427 		g_intentionalFailEnabled	= true;
2428 		g_intenionalFailIndex		= intentionalFailIndex;
2429 		g_intenionalFailCount		= 0;
2430 	}
2431 	else
2432 	{
2433 		g_intentionalFailEnabled	= false;
2434 		g_intenionalFailIndex		= 0;
2435 		g_intenionalFailCount		= 0;
2436 	}
2437 
2438 	g_allocationsCount = 0;
2439 }
2440 
isAllocTrackerEmpty()2441 bool isAllocTrackerEmpty ()
2442 {
2443 	bool success		= true;
2444 	bool wasAllocated	= false;
2445 
2446 	for (deUint32 vectorIdx	= 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2447 	{
2448 		if (g_allocatedVector[vectorIdx].active)
2449 			success = false;
2450 		else if (!wasAllocated && g_allocatedVector[vectorIdx].wasAllocated)
2451 			wasAllocated = true;
2452 	}
2453 
2454 	if (!g_intentionalFailEnabled && !wasAllocated)
2455 		success = false;
2456 
2457 	return success;
2458 }
2459 
allocCallbackFunc(void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)2460 VKAPI_ATTR void *VKAPI_CALL allocCallbackFunc (void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
2461 {
2462 	if (g_intentionalFailEnabled)
2463 		if (++g_intenionalFailCount >= g_intenionalFailIndex)
2464 			return DE_NULL;
2465 
2466 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2467 	{
2468 		if (!g_allocatedVector[vectorIdx].active)
2469 		{
2470 			g_allocatedVector[vectorIdx].requestedSizeBytes		= size;
2471 			g_allocatedVector[vectorIdx].actualSizeBytes		= size + (alignment - 1);
2472 			g_allocatedVector[vectorIdx].alignedStartAddress	= DE_NULL;
2473 			g_allocatedVector[vectorIdx].actualStartAddress		= new char[g_allocatedVector[vectorIdx].actualSizeBytes];
2474 
2475 			if (g_allocatedVector[vectorIdx].actualStartAddress != DE_NULL)
2476 			{
2477 				deUint64 addr	=	(deUint64)g_allocatedVector[vectorIdx].actualStartAddress;
2478 				addr			+=	(alignment - 1);
2479 				addr			&=	~(alignment - 1);
2480 				g_allocatedVector[vectorIdx].alignedStartAddress	= (void *)addr;
2481 				g_allocatedVector[vectorIdx].allocScope				= allocationScope;
2482 				g_allocatedVector[vectorIdx].userData				= (deUint64)pUserData;
2483 				g_allocatedVector[vectorIdx].active					= true;
2484 				g_allocatedVector[vectorIdx].wasAllocated			= true;
2485 			}
2486 
2487 			g_allocationsCount++;
2488 			return g_allocatedVector[vectorIdx].alignedStartAddress;
2489 		}
2490 	}
2491 	return DE_NULL;
2492 }
2493 
freeCallbackFunc(void *pUserData, void *pMemory)2494 VKAPI_ATTR void VKAPI_CALL freeCallbackFunc (void *pUserData, void *pMemory)
2495 {
2496 	DE_UNREF(pUserData);
2497 
2498 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2499 	{
2500 		if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pMemory)
2501 		{
2502 			delete[] g_allocatedVector[vectorIdx].actualStartAddress;
2503 			g_allocatedVector[vectorIdx].active = false;
2504 			break;
2505 		}
2506 	}
2507 }
2508 
reallocCallbackFunc(void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)2509 VKAPI_ATTR void *VKAPI_CALL reallocCallbackFunc (void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
2510 {
2511 	if (pOriginal != DE_NULL)
2512 	{
2513 		for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2514 		{
2515 			if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pOriginal)
2516 			{
2517 				if (size == 0)
2518 				{
2519 					freeCallbackFunc(pUserData, pOriginal);
2520 					return DE_NULL;
2521 				}
2522 				else if (size < g_allocatedVector[vectorIdx].requestedSizeBytes)
2523 					return pOriginal;
2524 				else
2525 				{
2526 					void *pNew = allocCallbackFunc(pUserData, size, alignment, allocationScope);
2527 
2528 					if (pNew != DE_NULL)
2529 					{
2530 						size_t copySize = size;
2531 
2532 						if (g_allocatedVector[vectorIdx].requestedSizeBytes < size)
2533 							copySize = g_allocatedVector[vectorIdx].requestedSizeBytes;
2534 
2535 						memcpy(pNew, pOriginal, copySize);
2536 						freeCallbackFunc(pUserData, pOriginal);
2537 					}
2538 					return pNew;
2539 				}
2540 			}
2541 		}
2542 		return DE_NULL;
2543 	}
2544 	else
2545 		return allocCallbackFunc(pUserData, size, alignment, allocationScope);
2546 }
2547 
createInstanceDeviceIntentionalAllocFail(Context& context)2548 tcu::TestStatus createInstanceDeviceIntentionalAllocFail (Context& context)
2549 {
2550 	const PlatformInterface&	vkp					= context.getPlatformInterface();
2551 	const deUint32				chosenDevice		= context.getTestContext().getCommandLine().getVKDeviceId() - 1;
2552 	VkInstance					instance			= DE_NULL;
2553 	VkDevice					device				= DE_NULL;
2554 	deUint32					physicalDeviceCount	= 0;
2555 	deUint32					queueFamilyCount	= 0;
2556 	deUint32					queueFamilyIndex	= 0;
2557 	const float					queuePriority		= 0.0f;
2558 	const VkAllocationCallbacks	allocationCallbacks	=
2559 	{
2560 		DE_NULL,								// userData
2561 		allocCallbackFunc,						// pfnAllocation
2562 		reallocCallbackFunc,					// pfnReallocation
2563 		freeCallbackFunc,						// pfnFree
2564 		DE_NULL,								// pfnInternalAllocation
2565 		DE_NULL									// pfnInternalFree
2566 	};
2567 	const VkApplicationInfo		appInfo				=
2568 	{
2569 		VK_STRUCTURE_TYPE_APPLICATION_INFO,		// sType
2570 		DE_NULL,								// pNext
2571 		"appName",								// pApplicationName
2572 		0u,										// applicationVersion
2573 		"engineName",							// pEngineName
2574 		0u,										// engineVersion
2575 		VK_API_VERSION_1_0						// apiVersion
2576 	};
2577 
2578 	const VkInstanceCreateInfo	instanceCreateInfo	=
2579 	{
2580 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// sType
2581 		DE_NULL,								// pNext
2582 		(VkInstanceCreateFlags)0u,				// flags
2583 		&appInfo,								// pApplicationInfo
2584 		0u,										// enabledLayerCount
2585 		DE_NULL,								// ppEnabledLayerNames
2586 		0u,										// enabledExtensionCount
2587 		DE_NULL									// ppEnabledExtensionNames
2588 	};
2589 
2590 	deUint32					failIndex			= 0;
2591 	VkResult					result				= VK_SUCCESS;
2592 	size_t						max_allowed_alloc	= 0;
2593 
2594 	do
2595 	{
2596 		if (max_allowed_alloc == 0)
2597 		{
2598 			if (result != VK_SUCCESS)
2599 				return tcu::TestStatus::fail("Could not create instance and device");
2600 
2601 			initAllocTracker(99999);
2602 		}
2603 		else
2604 		{
2605 			initAllocTracker(max_allowed_alloc, failIndex++);
2606 
2607 			if (failIndex >= static_cast<deUint32>(max_allowed_alloc))
2608 				return tcu::TestStatus::fail("Out of retries, could not create instance and device");
2609 		}
2610 
2611 		// if the number of allocations the driver makes is large, we may end up
2612 		// taking more than the watchdog timeout. touch here to avoid spurious
2613 		// failures.
2614 		if (failIndex % 128 == 0)
2615 			context.getTestContext().touchWatchdog();
2616 
2617 		result = vkp.createInstance(&instanceCreateInfo, &allocationCallbacks, &instance);
2618 
2619 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2620 		{
2621 			if (!isAllocTrackerEmpty())
2622 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2623 
2624 			freeAllocTracker();
2625 			continue;
2626 		}
2627 		else if (result != VK_SUCCESS)
2628 			return tcu::TestStatus::fail("createInstance returned " + de::toString(result));
2629 
2630 		const InstanceDriver		instanceDriver	(vkp, instance);
2631 		const InstanceInterface&	vki				(instanceDriver);
2632 
2633 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, DE_NULL);
2634 
2635 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2636 		{
2637 			vki.destroyInstance(instance, &allocationCallbacks);
2638 
2639 			if (!isAllocTrackerEmpty())
2640 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2641 
2642 			freeAllocTracker();
2643 			continue;
2644 		}
2645 		else if (result != VK_SUCCESS)
2646 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
2647 
2648 		vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
2649 
2650 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
2651 
2652 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2653 		{
2654 			vki.destroyInstance(instance, &allocationCallbacks);
2655 
2656 			if (!isAllocTrackerEmpty())
2657 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2658 
2659 			freeAllocTracker();
2660 			continue;
2661 		}
2662 		else if (result != VK_SUCCESS)
2663 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
2664 
2665 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, DE_NULL);
2666 
2667 		if (queueFamilyCount == 0u)
2668 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
2669 
2670 		vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
2671 
2672 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, queueFamilies.data());
2673 
2674 		if (queueFamilyCount == 0u)
2675 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
2676 
2677 		for (deUint32 i = 0; i < queueFamilyCount; i++)
2678 		{
2679 			if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
2680 			{
2681 				queueFamilyIndex = i;
2682 				break;
2683 			}
2684 		}
2685 
2686 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
2687 		{
2688 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
2689 			DE_NULL,									// pNext
2690 			(VkDeviceQueueCreateFlags)0u,				// flags
2691 			queueFamilyIndex,							// queueFamilyIndex
2692 			1u,											// queueCount
2693 			&queuePriority								// pQueuePriorities
2694 		};
2695 
2696 		void* pNext												= DE_NULL;
2697 #ifdef CTS_USES_VULKANSC
2698 		VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
2699 		memReservationInfo.pNext								= pNext;
2700 		pNext													= &memReservationInfo;
2701 
2702 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
2703 		sc10Features.pNext										= pNext;
2704 		pNext													= &sc10Features;
2705 #endif // CTS_USES_VULKANSC
2706 
2707 		const VkDeviceCreateInfo		deviceCreateInfo		=
2708 		{
2709 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// sType
2710 			pNext,										// pNext
2711 			(VkDeviceCreateFlags)0u,					// flags
2712 			1u,											// queueCreateInfoCount
2713 			&deviceQueueCreateInfo,						// pQueueCreateInfos
2714 			0u,											// enabledLayerCount
2715 			DE_NULL,									// ppEnabledLayerNames
2716 			0u,											// enabledExtensionCount
2717 			DE_NULL,									// ppEnabledExtensionNames
2718 			DE_NULL										// pEnabledFeatures
2719 		};
2720 
2721 		result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vki, physicalDevices[chosenDevice], &deviceCreateInfo, &allocationCallbacks, &device);
2722 
2723 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2724 		{
2725 			vki.destroyInstance(instance, &allocationCallbacks);
2726 
2727 			if (!isAllocTrackerEmpty())
2728 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2729 
2730 			freeAllocTracker();
2731 			continue;
2732 		}
2733 		else if (result != VK_SUCCESS)
2734 			return tcu::TestStatus::fail("VkCreateDevice returned " + de::toString(result));
2735 
2736 		DeviceDriver(vkp, instance, device).destroyDevice(device, &allocationCallbacks);
2737 		vki.destroyInstance(instance, &allocationCallbacks);
2738 		if (max_allowed_alloc == 0)
2739 		{
2740 			max_allowed_alloc	= g_allocationsCount + 100;
2741 			result				= VK_ERROR_OUT_OF_HOST_MEMORY;
2742 		}
2743 		freeAllocTracker();
2744 	}
2745 	while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
2746 
2747 	return tcu::TestStatus::pass("Pass");
2748 }
2749 
2750 #endif // CTS_USES_VULKANSC
2751 
2752 } // anonymous
2753 
addFunctionCaseInNewSubgroup( tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string& subgroupName, const std::string& subgroupDescription, FunctionInstance0::Function testFunc)2754 static inline void addFunctionCaseInNewSubgroup (
2755 	tcu::TestContext&			testCtx,
2756 	tcu::TestCaseGroup*			group,
2757 	const std::string&			subgroupName,
2758 	const std::string&			subgroupDescription,
2759 	FunctionInstance0::Function		testFunc)
2760 {
2761 	de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2762 	addFunctionCase(subgroup.get(), "basic", "", testFunc);
2763 	group->addChild(subgroup.release());
2764 }
2765 
addFunctionCaseInNewSubgroup( tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string& subgroupName, const std::string& subgroupDescription, FunctionSupport0::Function checkSupport, FunctionInstance0::Function testFunc)2766 static inline void addFunctionCaseInNewSubgroup (
2767 	tcu::TestContext&			testCtx,
2768 	tcu::TestCaseGroup*			group,
2769 	const std::string&			subgroupName,
2770 	const std::string&			subgroupDescription,
2771 	FunctionSupport0::Function		checkSupport,
2772 	FunctionInstance0::Function		testFunc)
2773 {
2774 	de::MovePtr<tcu::TestCaseGroup> subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2775 	addFunctionCase(subgroup.get(), "basic", "", checkSupport, testFunc);
2776 	group->addChild(subgroup.release());
2777 }
2778 
2779 template<typename Arg0>
addFunctionCaseInNewSubgroup( tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string& subgroupName, const std::string& subgroupDescription, typename FunctionSupport1<Arg0>::Function checkSupport, typename FunctionInstance1<Arg0>::Function testFunc, Arg0 arg0)2780 static void addFunctionCaseInNewSubgroup (
2781 	tcu::TestContext&							testCtx,
2782 	tcu::TestCaseGroup*							group,
2783 	const std::string&							subgroupName,
2784 	const std::string&							subgroupDescription,
2785 	typename FunctionSupport1<Arg0>::Function	checkSupport,
2786 	typename FunctionInstance1<Arg0>::Function	testFunc,
2787 	Arg0										arg0)
2788 {
2789 	de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2790 	subgroup->addChild(createFunctionCase<Arg0>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "basic", "", checkSupport, testFunc, arg0));
2791 	group->addChild(subgroup.release());
2792 }
2793 
createDeviceInitializationTests(tcu::TestContext& testCtx)2794 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
2795 {
2796 	de::MovePtr<tcu::TestCaseGroup>	deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));
2797 
2798 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_name_version",					"", createInstanceTest);
2799 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_invalid_api_version",			"", createInstanceWithInvalidApiVersionTest);
2800 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_null_appinfo",					"", createInstanceWithNullApplicationInfoTest);
2801 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_unsupported_extensions",		"", createInstanceWithUnsupportedExtensionsTest);
2802 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_extension_name_abuse",			"", createInstanceWithExtensionNameAbuseTest);
2803 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_layer_name_abuse",				"", createInstanceWithLayerNameAbuseTest);
2804 #ifndef CTS_USES_VULKANSC
2805 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "enumerate_devices_alloc_leak",					"", enumerateDevicesAllocLeakTest);
2806 #endif // CTS_USES_VULKANSC
2807 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device",									"", createDeviceTest);
2808 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_multiple_devices",						"", createMultipleDevicesTest);
2809 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_unsupported_extensions",			"", createDeviceWithUnsupportedExtensionsTest);
2810 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_various_queue_counts",			"", createDeviceWithVariousQueueCountsTest);
2811 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority",					"", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, false);
2812 #ifndef CTS_USES_VULKANSC
2813 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_khr",				"", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, true);
2814 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query",			"", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, false);
2815 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query_khr",		"", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, true);
2816 #endif // CTS_USES_VULKANSC
2817 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_features2",						"", createDeviceFeatures2Test);
2818 	{
2819 		de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, "create_device_unsupported_features", ""));
2820 		addFunctionCase(subgroup.get(), "core", "", createDeviceWithUnsupportedFeaturesTest);
2821 		addSeparateUnsupportedFeatureTests(subgroup.get());
2822 		deviceInitializationTests->addChild(subgroup.release());
2823 	}
2824 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2",							"", createDeviceQueue2Test);
2825 #ifndef CTS_USES_VULKANSC
2826 	// Removed because in main process this test does not really create any instance nor device and functions creating it always return VK_SUCCESS
2827 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_device_intentional_alloc_fail",	"", createInstanceDeviceIntentionalAllocFail);
2828 #endif // CTS_USES_VULKANSC
2829 
2830 	// Tests using a single Queue Family when creating a device.
2831 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_two_queues",					"", checkProtectedMemorySupport, createDeviceQueue2WithTwoQueuesSmokeTest);
2832 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_protected",				"", checkProtectedMemorySupport, createDeviceQueue2WithAllProtectedQueues);
2833 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_unprotected",			"", checkProtectedMemorySupport, createDeviceQueue2WithAllUnprotectedQueues);
2834 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_split",						"", checkProtectedMemorySupport, createDeviceQueue2WithNProtectedAndMUnprotectedQueues);
2835 
2836 	// Tests using multiple Queue Families when creating a device.
2837 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_families",				"", checkProtectedMemorySupport, createDeviceQueue2WithAllFamilies);
2838 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_families_protected",		"", checkProtectedMemorySupport, createDeviceQueue2WithAllFamiliesProtected);
2839 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_combinations",			"", checkProtectedMemorySupport, createDeviceQueue2WithMultipleQueueCombinations);
2840 
2841 	return deviceInitializationTests.release();
2842 }
2843 
2844 } // api
2845 } // vkt
2846