• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Device Initialization Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktApiDeviceInitializationTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktCustomInstancesDevices.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkStrUtil.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkDeviceUtil.hpp"
36 #include "vkApiVersion.hpp"
37 #include "vkAllocationCallbackUtil.hpp"
38 #include "vkDeviceFeatures.hpp"
39 #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 auto&								instanceDriver			= context.getInstanceInterface();
988 	const auto								instance				= context.getInstance();
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 	if (useKhrGlobalPriority)
1003 	{
1004 		for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1005 		{
1006 			globalPriorityProperties[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR;
1007 			globalPriorityProperties[ndx].pNext = DE_NULL;
1008 			queueFamilyProperties2[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1009 			queueFamilyProperties2[ndx].pNext = &globalPriorityProperties[ndx];
1010 		}
1011 
1012 		instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
1013 		TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());
1014 	}
1015 
1016 	std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority" };
1017 	if (useKhrGlobalPriority)
1018 		enabledExtensions = { "VK_KHR_global_priority" };
1019 
1020 	VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT	globalPriorityQueryFeatures
1021 	{
1022 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,	//sType;
1023 		DE_NULL,																//pNext;
1024 		VK_TRUE																	//globalPriorityQuery;
1025 	};
1026 #else
1027 	(void)useKhrGlobalPriority;
1028 	std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority" };
1029 #endif // CTS_USES_VULKANSC
1030 
1031 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1032 	{
1033 		enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
1034 	}
1035 
1036 	for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
1037 	{
1038 		const VkDeviceQueueGlobalPriorityCreateInfoEXT	queueGlobalPriority		=
1039 		{
1040 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,	//sType;
1041 			DE_NULL,														//pNext;
1042 			globalPriority													//globalPriority;
1043 		};
1044 
1045 		const VkDeviceQueueCreateInfo	queueCreateInfo		=
1046 		{
1047 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//sType;
1048 			&queueGlobalPriority,						//pNext;
1049 			(VkDeviceQueueCreateFlags)0u,				//flags;
1050 			0,											//queueFamilyIndex;
1051 			1,											//queueCount;
1052 			queuePriorities.data()						//pQueuePriorities;
1053 		};
1054 
1055 		void* pNext												= DE_NULL;
1056 #ifdef CTS_USES_VULKANSC
1057 		VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1058 		memReservationInfo.pNext								= pNext;
1059 		pNext													= &memReservationInfo;
1060 
1061 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1062 		sc10Features.pNext										= pNext;
1063 		pNext													= &sc10Features;
1064 #else
1065 		pNext = useKhrGlobalPriority ? &globalPriorityQueryFeatures : DE_NULL;
1066 #endif // CTS_USES_VULKANSC
1067 
1068 		const VkDeviceCreateInfo		deviceCreateInfo		=
1069 		{
1070 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//sType;
1071 			pNext,															//pNext;
1072 			(VkDeviceCreateFlags)0u,										//flags;
1073 			1,																//queueRecordCount;
1074 			&queueCreateInfo,												//pRequestedQueues;
1075 			0,																//layerCount;
1076 			DE_NULL,														//ppEnabledLayerNames;
1077 			(deUint32)enabledExtensions.size(),								//extensionCount;
1078 			enabledExtensions.data(),										//ppEnabledExtensionNames;
1079 			DE_NULL,														//pEnabledFeatures;
1080 		};
1081 
1082 		const bool		mayBeDenied				= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
1083 #ifndef CTS_USES_VULKANSC
1084 		const bool		mustFail				= useKhrGlobalPriority && (globalPriority < globalPriorityProperties[0].priorities[0] || globalPriority > globalPriorityProperties[0].priorities[globalPriorityProperties[0].priorityCount - 1]);
1085 #endif // CTS_USES_VULKANSC
1086 
1087 		try
1088 		{
1089 			const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1090 			const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
1091 			const deUint32				queueFamilyIndex	= deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
1092 			const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, queueFamilyIndex, 0);
1093 			VkResult					result;
1094 
1095 			TCU_CHECK(!!queue);
1096 
1097 			result = deviceDriver.queueWaitIdle(queue);
1098 			if (result == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
1099 			{
1100 				continue;
1101 			}
1102 
1103 #ifndef CTS_USES_VULKANSC
1104 			if (result == VK_ERROR_INITIALIZATION_FAILED && mustFail)
1105 			{
1106 				continue;
1107 			}
1108 
1109 			if (mustFail)
1110 			{
1111 				log << TestLog::Message
1112 					<< "device creation must fail but not"
1113 					<< ", globalPriority = " << globalPriority
1114 					<< ", queueCreateInfo " << queueCreateInfo
1115 					<< TestLog::EndMessage;
1116 				return tcu::TestStatus::fail("Fail");
1117 			}
1118 #endif // CTS_USES_VULKANSC
1119 
1120 			if (result != VK_SUCCESS)
1121 			{
1122 				log << TestLog::Message
1123 					<< "vkQueueWaitIdle failed"
1124 					<< ", globalPriority = " << globalPriority
1125 					<< ", queueCreateInfo " << queueCreateInfo
1126 					<< ", Error Code: " << result
1127 					<< TestLog::EndMessage;
1128 				return tcu::TestStatus::fail("Fail");
1129 			}
1130 		}
1131 		catch (const Error& error)
1132 		{
1133 			if ((error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
1134 #ifndef CTS_USES_VULKANSC
1135 			   || (error.getError() == VK_ERROR_INITIALIZATION_FAILED && mustFail)
1136 #endif // CTS_USES_VULKANSC
1137 			   )
1138 			{
1139 				continue;
1140 			}
1141 			else
1142 			{
1143 				log << TestLog::Message
1144 					<< "exception thrown " << error.getMessage()
1145 					<< ", globalPriority = " << globalPriority
1146 					<< ", queueCreateInfo " << queueCreateInfo
1147 					<< ", Error Code: " << error.getError()
1148 					<< TestLog::EndMessage;
1149 				return tcu::TestStatus::fail("Fail");
1150 			}
1151 		}
1152 	}
1153 
1154 	return tcu::TestStatus::pass("Pass");
1155 }
1156 
1157 #ifndef CTS_USES_VULKANSC
checkGlobalPriorityQuerySupport(Context & context,bool useKhrGlobalPriority)1158 void checkGlobalPriorityQuerySupport (Context& context, bool useKhrGlobalPriority)
1159 {
1160 	const std::string extName = (useKhrGlobalPriority ? "VK_KHR_global_priority" : "VK_EXT_global_priority_query");
1161 	context.requireDeviceFunctionality(extName);
1162 }
1163 
isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)1164 deBool isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)
1165 {
1166 	switch (priority) {
1167 		case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:
1168 		case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:
1169 		case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:
1170 		case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:
1171 			return DE_TRUE;
1172 		default:
1173 			return DE_FALSE;
1174 	}
1175 }
1176 
checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT & properties)1177 void checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT& properties)
1178 {
1179 	TCU_CHECK(properties.priorityCount > 0);
1180 	TCU_CHECK(properties.priorityCount <= VK_MAX_GLOBAL_PRIORITY_SIZE_KHR);
1181 	TCU_CHECK(isValidGlobalPriority(properties.priorities[0]));
1182 
1183 	for (deUint32 ndx = 1; ndx < properties.priorityCount; ndx++)
1184 	{
1185 		TCU_CHECK(isValidGlobalPriority(properties.priorities[ndx]));
1186 		TCU_CHECK(properties.priorities[ndx] == (properties.priorities[ndx - 1] << 1));
1187 	}
1188 }
1189 #endif // CTS_USES_VULKANSC
1190 
1191 #ifndef CTS_USES_VULKANSC
createDeviceWithQueriedGlobalPriorityTest(Context & context,bool useKhrGlobalPriority)1192 tcu::TestStatus createDeviceWithQueriedGlobalPriorityTest (Context& context, bool useKhrGlobalPriority)
1193 {
1194 	tcu::TestLog&					log							= context.getTestContext().getLog();
1195 	const PlatformInterface&		platformInterface			= context.getPlatformInterface();
1196 	const auto&						instanceDriver				= context.getInstanceInterface();
1197 	const auto						instance					= context.getInstance();
1198 	const VkPhysicalDevice			physicalDevice				= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1199 	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 };
1200 	const vector<float>				queuePriorities				(1, 1.0f);
1201 	deUint32						queueFamilyPropertyCount	= ~0u;
1202 
1203 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, DE_NULL);
1204 	TCU_CHECK(queueFamilyPropertyCount > 0);
1205 
1206 	std::vector<VkQueueFamilyProperties2>					queueFamilyProperties2		(queueFamilyPropertyCount);
1207 	std::vector<VkQueueFamilyGlobalPriorityPropertiesEXT>	globalPriorityProperties	(queueFamilyPropertyCount);
1208 
1209 	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1210 	{
1211 		globalPriorityProperties[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT;
1212 		globalPriorityProperties[ndx].pNext	= DE_NULL;
1213 		queueFamilyProperties2[ndx].sType	= VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1214 		queueFamilyProperties2[ndx].pNext	= &globalPriorityProperties[ndx];
1215 	}
1216 
1217 	instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
1218 	TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());
1219 
1220 	std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority", "VK_EXT_global_priority_query" };
1221 	if (useKhrGlobalPriority)
1222 		enabledExtensions = { "VK_KHR_global_priority" };
1223 
1224 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1225 	{
1226 		enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
1227 	}
1228 
1229 	for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1230 	{
1231 		checkGlobalPriorityProperties(globalPriorityProperties[ndx]);
1232 
1233 		for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
1234 		{
1235 			const VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT	globalPriorityQueryFeatures		=
1236 			{
1237 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,	//sType;
1238 				DE_NULL,																//pNext;
1239 				VK_TRUE																	//globalPriorityQuery;
1240 			};
1241 			const VkDeviceQueueGlobalPriorityCreateInfoEXT			queueGlobalPriorityCreateInfo	=
1242 			{
1243 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,			//sType;
1244 				DE_NULL,																//pNext;
1245 				globalPriority,															//globalPriority;
1246 			};
1247 			const VkDeviceQueueCreateInfo							queueCreateInfo					=
1248 			{
1249 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,								//sType;
1250 				&queueGlobalPriorityCreateInfo,											//pNext;
1251 				(VkDeviceQueueCreateFlags)0u,											//flags;
1252 				ndx,																	//queueFamilyIndex;
1253 				1,																		//queueCount;
1254 				queuePriorities.data()													//pQueuePriorities;
1255 			};
1256 			const VkDeviceCreateInfo								deviceCreateInfo				=
1257 			{
1258 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,									//sType;
1259 				&globalPriorityQueryFeatures,											//pNext;
1260 				(VkDeviceCreateFlags)0u,												//flags;
1261 				1,																		//queueRecordCount;
1262 				&queueCreateInfo,														//pRequestedQueues;
1263 				0,																		//layerCount;
1264 				DE_NULL,																//ppEnabledLayerNames;
1265 				(deUint32)enabledExtensions.size(),										//extensionCount;
1266 				enabledExtensions.data(),												//ppEnabledExtensionNames;
1267 				DE_NULL,																//pEnabledFeatures;
1268 			};
1269 			const bool												mayBeDenied						= globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
1270 			const bool												mustFail						= globalPriority < globalPriorityProperties[ndx].priorities[0] || globalPriority > globalPriorityProperties[ndx].priorities[globalPriorityProperties[ndx].priorityCount - 1];
1271 
1272 			try
1273 			{
1274 				const Unique<VkDevice>		device				(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1275 				const DeviceDriver			deviceDriver		(platformInterface, instance, device.get());
1276 				const VkQueue				queue				= getDeviceQueue(deviceDriver, *device, ndx, 0);
1277 
1278 				TCU_CHECK(!!queue);
1279 
1280 				if (mustFail)
1281 				{
1282 					log << TestLog::Message
1283 						<< "device creation must fail but not"
1284 						<< ", globalPriority = " << globalPriority
1285 						<< ", queueCreateInfo " << queueCreateInfo
1286 						<< TestLog::EndMessage;
1287 					return tcu::TestStatus::fail("Fail");
1288 				}
1289 			}
1290 			catch (const Error& error)
1291 			{
1292 				if (mustFail || (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied))
1293 				{
1294 					continue;
1295 				}
1296 				else
1297 				{
1298 					log << TestLog::Message
1299 						<< "exception thrown " << error.getMessage()
1300 						<< ", globalPriority = " << globalPriority
1301 						<< ", queueCreateInfo " << queueCreateInfo
1302 						<< ", Error Code: " << error.getError()
1303 						<< TestLog::EndMessage;
1304 					return tcu::TestStatus::fail("Fail");
1305 				}
1306 			}
1307 		}
1308 	}
1309 
1310 	return tcu::TestStatus::pass("Pass");
1311 }
1312 #endif // CTS_USES_VULKANSC
1313 
createDeviceFeatures2Test(Context & context)1314 tcu::TestStatus createDeviceFeatures2Test (Context& context)
1315 {
1316 	const PlatformInterface&				vkp						= context.getPlatformInterface();
1317 	const CustomInstance					instance				(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
1318 	const InstanceDriver&					vki						(instance.getDriver());
1319 	const VkPhysicalDevice					physicalDevice			= chooseDevice(vki, instance, context.getTestContext().getCommandLine());
1320 	const deUint32							queueFamilyIndex		= 0;
1321 	const deUint32							queueCount				= 1;
1322 	const deUint32							queueIndex				= 0;
1323 	const float								queuePriority			= 1.0f;
1324 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
1325 
1326 	VkPhysicalDeviceFeatures2		enabledFeatures;
1327 	const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1328 	{
1329 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1330 		DE_NULL,
1331 		(VkDeviceQueueCreateFlags)0u,
1332 		queueFamilyIndex,
1333 		queueCount,
1334 		&queuePriority,
1335 	};
1336 
1337 	void* pNext												= &enabledFeatures;
1338 #ifdef CTS_USES_VULKANSC
1339 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1340 	memReservationInfo.pNext								= pNext;
1341 	pNext													= &memReservationInfo;
1342 
1343 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1344 	sc10Features.pNext										= pNext;
1345 	pNext													= &sc10Features;
1346 #endif // CTS_USES_VULKANSC
1347 
1348 	const VkDeviceCreateInfo		deviceCreateInfo		=
1349 	{
1350 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1351 		pNext,
1352 		(VkDeviceCreateFlags)0u,
1353 		1,
1354 		&deviceQueueCreateInfo,
1355 		0u,
1356 		DE_NULL,
1357 		0,
1358 		DE_NULL,
1359 		DE_NULL,
1360 	};
1361 
1362 	// Populate enabledFeatures
1363 	enabledFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1364 	enabledFeatures.pNext		= DE_NULL;
1365 
1366 	vki.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
1367 
1368 	{
1369 		const Unique<VkDevice>	device		(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceCreateInfo));
1370 		const DeviceDriver		vkd			(vkp, instance, device.get());
1371 		const VkQueue			queue		= getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);
1372 
1373 		VK_CHECK(vkd.queueWaitIdle(queue));
1374 	}
1375 
1376 	return tcu::TestStatus::pass("Pass");
1377 }
1378 
1379 struct Feature
1380 {
1381 	const char*	name;
1382 	size_t		offset;
1383 };
1384 
1385 #define FEATURE_ITEM(STRUCT, MEMBER) {#MEMBER, DE_OFFSET_OF(STRUCT, MEMBER)}
1386 // This macro is used to avoid the "out of array bounds" compiler warnings/errors in the checkFeatures function.
1387 #define SAFE_OFFSET(LIMITING_STRUCT, STRUCT, MEMBER) std::min(static_cast<deUint32>(sizeof(LIMITING_STRUCT) - sizeof(VkBool32)), DE_OFFSET_OF(STRUCT, MEMBER))
1388 
1389 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)1390 void checkFeatures (const PlatformInterface&				vkp,
1391 					const VkInstance&						instance,
1392 					const InstanceDriver&					instanceDriver,
1393 					const VkPhysicalDevice					physicalDevice,
1394 					int										numFeatures,
1395 					const Feature							features[],
1396 					const StructType*						supportedFeatures,
1397 					const deUint32							queueFamilyIndex,
1398 					const deUint32							queueCount,
1399 					const float								queuePriority,
1400 					int&									numErrors,
1401 					tcu::ResultCollector&					resultCollector,
1402 					const vector<const char*>*				extensionNames,
1403 					const VkPhysicalDeviceFeatures&			defaultPhysicalDeviceFeatures,
1404 #ifdef CTS_USES_VULKANSC
1405 					VkDeviceObjectReservationCreateInfo		memReservationStatMax,
1406 #endif // CTS_USES_VULKANSC
1407 					bool									isSubProcess
1408 	)
1409 {
1410 	struct StructureBase
1411 	{
1412 		VkStructureType		sType;
1413 		void*				pNext;
1414 	};
1415 
1416 	for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
1417 	{
1418 		// Test only features that are not supported.
1419 		if (*(((VkBool32*)((deUint8*)(supportedFeatures) + features[featureNdx].offset))))
1420 			continue;
1421 
1422 		StructType structCopy;
1423 		deMemset(&structCopy, 0, sizeof(StructType));
1424 
1425 		auto* structBase = reinterpret_cast<StructureBase*>(&structCopy);
1426 		VkStructureType structureType = reinterpret_cast<const StructureBase*>(supportedFeatures)->sType;
1427 		structBase->sType = structureType;
1428 		structBase->pNext = DE_NULL;
1429 
1430 		VkPhysicalDeviceFeatures physicalDeviceFeaturesCopy = defaultPhysicalDeviceFeatures;
1431 
1432 		// Some features require that other feature(s) are also enabled.
1433 
1434 		if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES)
1435 		{
1436 			DE_ASSERT((std::is_same<VkPhysicalDeviceVulkan11Features, StructType>::value));
1437 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1438 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1439 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader) ||
1440 				features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader))
1441 			{
1442 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, multiview));
1443 				*memberPtr = VK_TRUE;
1444 			}
1445 
1446 			// If variablePointers is enabled then variablePointersStorageBuffer must also be enabled.
1447 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, variablePointers))
1448 			{
1449 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer));
1450 				*memberPtr = VK_TRUE;
1451 			}
1452 		}
1453 #ifndef CTS_USES_VULKANSC
1454 		// If rayTracingPipelineShaderGroupHandleCaptureReplayMixed is VK_TRUE, rayTracingPipelineShaderGroupHandleCaptureReplay must also be VK_TRUE.
1455 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR &&
1456 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplayMixed))
1457 		{
1458 			DE_ASSERT((std::is_same<VkPhysicalDeviceRayTracingPipelineFeaturesKHR, StructType>::value));
1459 			auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplay));
1460 			*memberPtr = VK_TRUE;
1461 		}
1462 #endif // CTS_USES_VULKANSC
1463 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES)
1464 		{
1465 			DE_ASSERT((std::is_same<VkPhysicalDeviceMultiviewFeatures, StructType>::value));
1466 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1467 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1468 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewGeometryShader) ||
1469 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewTessellationShader))
1470 			{
1471 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceMultiviewFeatures, multiview));
1472 				*memberPtr = VK_TRUE;
1473 			}
1474 		}
1475 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
1476 		{
1477 			DE_ASSERT((std::is_same<VkPhysicalDeviceRobustness2FeaturesEXT, StructType>::value));
1478 			// If robustBufferAccess2 is enabled then robustBufferAccess must also be enabled.
1479 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRobustness2FeaturesEXT, robustBufferAccess2))
1480 			{
1481 				physicalDeviceFeaturesCopy.robustBufferAccess = true;
1482 			}
1483 		}
1484 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT)
1485 		{
1486 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, StructType>::value));
1487 			// If sparseImageInt64Atomics is enabled, shaderImageInt64Atomics must be enabled.
1488 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, sparseImageInt64Atomics))
1489 			{
1490 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, shaderImageInt64Atomics));
1491 				*memberPtr = VK_TRUE;
1492 			}
1493 		}
1494 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT)
1495 		{
1496 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, StructType>::value));
1497 			// If sparseImageFloat32Atomics is enabled, shaderImageFloat32Atomics must be enabled.
1498 			if (features[featureNdx].offset ==
1499 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32Atomics)) {
1500 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32Atomics));
1501 				*memberPtr = VK_TRUE;
1502 			}
1503 
1504 			// If sparseImageFloat32AtomicAdd is enabled, shaderImageFloat32AtomicAdd must be enabled.
1505 			if (features[featureNdx].offset ==
1506 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32AtomicAdd)) {
1507 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32AtomicAdd));
1508 				*memberPtr = VK_TRUE;
1509 			}
1510 		}
1511 #ifndef CTS_USES_VULKANSC
1512 		else if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT)
1513 		{
1514 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, StructType>::value));
1515 			// If sparseImageFloat32AtomicMinMax is enabled, shaderImageFloat32AtomicMinMax must be enabled.
1516 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, sparseImageFloat32AtomicMinMax))
1517 			{
1518 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderImageFloat32AtomicMinMax));
1519 				*memberPtr = VK_TRUE;
1520 			}
1521 		}
1522 #endif // CTS_USES_VULKANSC
1523 
1524 		// Enable the feature we're testing.
1525 		*reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + features[featureNdx].offset) = VK_TRUE;
1526 
1527 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1528 		{
1529 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
1530 			DE_NULL,									// pNext
1531 			(VkDeviceQueueCreateFlags)0u,				// flags
1532 			queueFamilyIndex,							// queueFamilyIndex
1533 			queueCount,									// queueCount
1534 			&queuePriority								// pQueuePriorities
1535 		};
1536 		VkPhysicalDeviceFeatures2 deviceFeatures2 =
1537 		{
1538 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,	// sType
1539 			&structCopy,									// pNext
1540 			physicalDeviceFeaturesCopy						// features
1541 		};
1542 
1543 		void* pNext												= &deviceFeatures2;
1544 #ifdef CTS_USES_VULKANSC
1545 		VkDeviceObjectReservationCreateInfo memReservationInfo	= isSubProcess? memReservationStatMax : resetDeviceObjectReservationCreateInfo();
1546 		memReservationInfo.pNext								= pNext;
1547 		pNext													= &memReservationInfo;
1548 
1549 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1550 		sc10Features.pNext										= pNext;
1551 		pNext													= &sc10Features;
1552 #else
1553 		DE_UNREF(isSubProcess);
1554 #endif // CTS_USES_VULKANSC
1555 
1556 		const VkDeviceCreateInfo		deviceCreateInfo		=
1557 		{
1558 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,											// sType
1559 			pNext,																			// pNext
1560 			(VkDeviceCreateFlags)0u,														// flags
1561 			1,																				// queueCreateInfoCount
1562 			&deviceQueueCreateInfo,															// pQueueCreateInfos
1563 			0u,																				// enabledLayerCount
1564 			DE_NULL,																		// ppEnabledLayerNames
1565 			static_cast<deUint32>(extensionNames == DE_NULL ? 0 : extensionNames->size()),	// enabledExtensionCount
1566 			extensionNames == DE_NULL ? DE_NULL : extensionNames->data(),					// ppEnabledExtensionNames
1567 			DE_NULL																			// pEnabledFeatures
1568 		};
1569 
1570 		VkDevice		device = (VkDevice)DE_NULL;
1571 		const VkResult	res	= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1572 
1573 		if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1574 		{
1575 			numErrors++;
1576 			resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1577 				+ de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
1578 		}
1579 		if (device != (VkDevice)DE_NULL)
1580 		{
1581 			DeviceDriver deviceDriver(vkp, instance, device);
1582 			deviceDriver.destroyDevice(device, DE_NULL);
1583 		}
1584 	}
1585 }
1586 
removeExtensions(const vector<string> & a,const vector<const char * > & b)1587 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
1588 {
1589 	vector<string>	res;
1590 	set<string>		removeExts	(b.begin(), b.end());
1591 
1592 	for (const auto & aIter : a)
1593 	{
1594 		if (!de::contains(removeExts, aIter))
1595 			res.push_back(aIter);
1596 	}
1597 
1598 	return res;
1599 }
1600 
createDeviceWithUnsupportedFeaturesTest(Context & context)1601 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
1602 {
1603 	const PlatformInterface&				vkp						= context.getPlatformInterface();
1604 	tcu::TestLog&							log						= context.getTestContext().getLog();
1605 	tcu::ResultCollector					resultCollector			(log);
1606 	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
1607 	const InstanceDriver&					instanceDriver			(instance.getDriver());
1608 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1609 	const deUint32							queueFamilyIndex		= 0;
1610 	const deUint32							queueCount				= 1;
1611 	const float								queuePriority			= 1.0f;
1612 	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
1613 	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
1614 	const VkPhysicalDeviceFeatures			deviceFeatures			= deviceFeatures2.features;
1615 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
1616 
1617 	// Test features listed in VkPhysicalDeviceFeatures structure
1618 	{
1619 		static const Feature features[] =
1620 		{
1621 			// robustBufferAccess is removed, because it's always supported.
1622 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
1623 			FEATURE_ITEM(VkPhysicalDeviceFeatures, imageCubeArray),
1624 			FEATURE_ITEM(VkPhysicalDeviceFeatures, independentBlend),
1625 			FEATURE_ITEM(VkPhysicalDeviceFeatures, geometryShader),
1626 			FEATURE_ITEM(VkPhysicalDeviceFeatures, tessellationShader),
1627 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sampleRateShading),
1628 			FEATURE_ITEM(VkPhysicalDeviceFeatures, dualSrcBlend),
1629 			FEATURE_ITEM(VkPhysicalDeviceFeatures, logicOp),
1630 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiDrawIndirect),
1631 			FEATURE_ITEM(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
1632 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthClamp),
1633 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBiasClamp),
1634 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fillModeNonSolid),
1635 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBounds),
1636 			FEATURE_ITEM(VkPhysicalDeviceFeatures, wideLines),
1637 			FEATURE_ITEM(VkPhysicalDeviceFeatures, largePoints),
1638 			FEATURE_ITEM(VkPhysicalDeviceFeatures, alphaToOne),
1639 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiViewport),
1640 			FEATURE_ITEM(VkPhysicalDeviceFeatures, samplerAnisotropy),
1641 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionETC2),
1642 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
1643 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionBC),
1644 			FEATURE_ITEM(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
1645 			FEATURE_ITEM(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
1646 			FEATURE_ITEM(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
1647 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
1648 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
1649 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
1650 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
1651 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
1652 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
1653 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
1654 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
1655 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
1656 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
1657 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
1658 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderClipDistance),
1659 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderCullDistance),
1660 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderFloat64),
1661 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt64),
1662 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt16),
1663 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceResidency),
1664 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceMinLod),
1665 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseBinding),
1666 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
1667 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
1668 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
1669 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency2Samples),
1670 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency4Samples),
1671 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency8Samples),
1672 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency16Samples),
1673 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyAliased),
1674 			FEATURE_ITEM(VkPhysicalDeviceFeatures, variableMultisampleRate),
1675 			FEATURE_ITEM(VkPhysicalDeviceFeatures, inheritedQueries)
1676 		};
1677 
1678 		for (const auto& feature : features)
1679 		{
1680 			// Test only features that are not supported.
1681 			if (*(((VkBool32*)((deUint8*)(&deviceFeatures) + feature.offset))))
1682 				continue;
1683 
1684 			VkPhysicalDeviceFeatures		enabledFeatures			= deviceFeatures;
1685 			*((VkBool32*)((deUint8*)(&enabledFeatures) + feature.offset)) = VK_TRUE;
1686 
1687 			const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1688 			{
1689 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1690 				DE_NULL,
1691 				(VkDeviceQueueCreateFlags)0u,
1692 				queueFamilyIndex,
1693 				queueCount,
1694 				&queuePriority
1695 			};
1696 
1697 			void* pNext												= DE_NULL;
1698 #ifdef CTS_USES_VULKANSC
1699 			VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1700 			memReservationInfo.pNext								= pNext;
1701 			pNext													= &memReservationInfo;
1702 
1703 			VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1704 			sc10Features.pNext										= pNext;
1705 			pNext													= &sc10Features;
1706 #endif // CTS_USES_VULKANSC
1707 
1708 			const VkDeviceCreateInfo		deviceCreateInfo		=
1709 			{
1710 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1711 				pNext,
1712 				(VkDeviceCreateFlags)0u,
1713 				1,
1714 				&deviceQueueCreateInfo,
1715 				0u,
1716 				DE_NULL,
1717 				0,
1718 				DE_NULL,
1719 				&enabledFeatures
1720 			};
1721 
1722 			VkDevice		device	= DE_NULL;
1723 			const VkResult	res		= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1724 
1725 			if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1726 			{
1727 				resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1728 				+ de::toString(feature.name) + ", which was reported as unsupported.");
1729 			}
1730 
1731 			if (device != DE_NULL)
1732 			{
1733 				DeviceDriver deviceDriver(vkp, instance, device);
1734 				deviceDriver.destroyDevice(device, DE_NULL);
1735 			}
1736 		}
1737 	}
1738 
1739 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
1740 }
1741 
1742 #include "vkDeviceFeatureTest.inl"
1743 
createDeviceQueue2Test(Context & context)1744 tcu::TestStatus createDeviceQueue2Test (Context& context)
1745 {
1746 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1747 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1748 
1749 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1750 	const CustomInstance					instance				(createCustomInstanceFromContext(context));
1751 	const InstanceDriver&					instanceDriver			(instance.getDriver());
1752 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1753 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1754 	const deUint32							queueCount				= 1;
1755 	const deUint32							queueIndex				= 0;
1756 	const float								queuePriority			= 1.0f;
1757 
1758 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1759 	{
1760 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1761 		DE_NULL,														// void*							pNext;
1762 		VK_FALSE														// VkBool32							protectedMemory;
1763 	};
1764 
1765 	VkPhysicalDeviceFeatures2				features2;
1766 	deMemset(&features2, 0, sizeof(features2));
1767 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1768 	features2.pNext													= &protectedMemoryFeature;
1769 
1770 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1771 	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1772 		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1773 
1774 	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
1775 	{
1776 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
1777 		DE_NULL,														// const void*						pNext;
1778 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1779 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1780 		queueCount,														// deUint32							queueCount;
1781 		&queuePriority,													// const float*						pQueuePriorities;
1782 	};
1783 
1784 	void* pNext												= &features2;
1785 #ifdef CTS_USES_VULKANSC
1786 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1787 	memReservationInfo.pNext								= pNext;
1788 	pNext													= &memReservationInfo;
1789 
1790 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1791 	sc10Features.pNext										= pNext;
1792 	pNext													= &sc10Features;
1793 #endif // CTS_USES_VULKANSC
1794 
1795 	const VkDeviceCreateInfo				deviceCreateInfo		=
1796 	{
1797 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
1798 		pNext,															// const void*						pNext;
1799 		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
1800 		1,																// deUint32							queueCreateInfoCount;
1801 		&deviceQueueCreateInfo,											// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1802 		0,																// deUint32							enabledLayerCount;
1803 		DE_NULL,														// const char* const*				ppEnabledLayerNames;
1804 		0,																// deUint32							enabledExtensionCount;
1805 		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
1806 		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1807 	};
1808 
1809 	const VkDeviceQueueInfo2				deviceQueueInfo2		=
1810 	{
1811 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
1812 		DE_NULL,														// const void*						pNext;
1813 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1814 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1815 		queueIndex,														// deUint32							queueIndex;
1816 	};
1817 
1818 	{
1819 		const Unique<VkDevice>				device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1820 		const DeviceDriver					deviceDriver			(platformInterface, instance, device.get());
1821 		const VkQueue						queue2					= getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);
1822 
1823 		VK_CHECK(deviceDriver.queueWaitIdle(queue2));
1824 	}
1825 
1826 	return tcu::TestStatus::pass("Pass");
1827 }
1828 
findQueueFamiliesWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)1829 map<deUint32, VkQueueFamilyProperties> findQueueFamiliesWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
1830 {
1831 	const vector<VkQueueFamilyProperties>	queueProps				= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
1832 	map<deUint32, VkQueueFamilyProperties>	queueFamilies;
1833 
1834 	for (deUint32 queueNdx = 0; queueNdx < static_cast<deUint32>(queueProps.size()); queueNdx++)
1835 	{
1836 		const VkQueueFamilyProperties&		queueFamilyProperties	= queueProps[queueNdx];
1837 
1838 		if ((queueFamilyProperties.queueFlags & requiredCaps) == requiredCaps)
1839 			queueFamilies[queueNdx] = queueFamilyProperties;
1840 	}
1841 
1842 	if (queueFamilies.empty())
1843 		TCU_THROW(NotSupportedError, "No matching queue found");
1844 
1845 	return queueFamilies;
1846 }
1847 
checkProtectedMemorySupport(Context & context)1848 void checkProtectedMemorySupport (Context& context)
1849 {
1850 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1851 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1852 
1853 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
1854 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1855 
1856 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1857 	{
1858 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1859 		DE_NULL,														// void*							pNext;
1860 		VK_FALSE														// VkBool32							protectedMemory;
1861 	};
1862 
1863 	VkPhysicalDeviceFeatures2				features2;
1864 	deMemset(&features2, 0, sizeof(features2));
1865 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1866 	features2.pNext													= &protectedMemoryFeature;
1867 
1868 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1869 	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1870 		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1871 }
1872 
createProtectedDeviceWithQueueConfig(Context & context,const std::vector<VkDeviceQueueCreateInfo> & queueCreateInfos,bool dumpExtraInfo=false)1873 Move<VkDevice> createProtectedDeviceWithQueueConfig (Context& context, const std::vector<VkDeviceQueueCreateInfo>& queueCreateInfos, bool dumpExtraInfo=false)
1874 {
1875 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1876 	const VkInstance						instance				= context.getInstance();
1877 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
1878 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1879 
1880 	if (dumpExtraInfo)
1881 	{
1882 		tcu::TestLog&						log						= context.getTestContext().getLog();
1883 
1884 		log << tcu::TestLog::Message << "Creating VkDevice with the following Queue configuration:" << tcu::TestLog::EndMessage;
1885 
1886 		for (size_t idx = 0; idx < queueCreateInfos.size(); idx++)
1887 		{
1888 			const VkDeviceQueueCreateInfo&	queueCreateInfo			= queueCreateInfos[idx];
1889 
1890 			log << tcu::TestLog::Message << "QueueCreateInfo " << idx << ": "
1891 				<< "flags: " << queueCreateInfo.flags << " "
1892 				<< "family: " << queueCreateInfo.queueFamilyIndex << " "
1893 				<< "count: " << queueCreateInfo.queueCount
1894 				<< tcu::TestLog::EndMessage;
1895 		}
1896 	}
1897 
1898 	// Protected memory features availability should be already checked at this point.
1899 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1900 	{
1901 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1902 		DE_NULL,														// void*							pNext;
1903 		VK_TRUE															// VkBool32							protectedMemory;
1904 	};
1905 
1906 	VkPhysicalDeviceFeatures2				features2;
1907 	deMemset(&features2, 0, sizeof(features2));
1908 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1909 	features2.pNext													= &protectedMemoryFeature;
1910 
1911 #ifdef CTS_USES_VULKANSC
1912 	void* pNext														= DE_NULL;
1913 
1914 	VkDeviceObjectReservationCreateInfo memReservationInfo			= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1915 	memReservationInfo.pNext										= pNext;
1916 	pNext															= &memReservationInfo;
1917 
1918 	VkPhysicalDeviceVulkanSC10Features sc10Features					= createDefaultSC10Features();
1919 	sc10Features.pNext												= pNext;
1920 	pNext															= &sc10Features;
1921 #endif // CTS_USES_VULKANSC
1922 
1923 	const VkDeviceCreateInfo				deviceCreateInfo		=
1924 	{
1925 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
1926 #ifdef CTS_USES_VULKANSC
1927 		&sc10Features,													// const void*						pNext;
1928 #else
1929 		&features2,														// const void*						pNext;
1930 #endif // CTS_USES_VULKANSC
1931 		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
1932 		(deUint32)queueCreateInfos.size(),								// deUint32							queueCreateInfoCount;
1933 		queueCreateInfos.data(),										// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1934 		0,																// deUint32							enabledLayerCount;
1935 		DE_NULL,														// const char* const*				ppEnabledLayerNames;
1936 		0,																// deUint32							enabledExtensionCount;
1937 		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
1938 		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1939 	};
1940 
1941 	return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo);
1942 }
1943 
getDeviceQueue2WithOptions(const DeviceDriver & deviceDriver,const VkDevice device,VkDeviceQueueCreateFlags flags,deUint32 queueFamilyIndex,deUint32 queueIndex)1944 VkQueue getDeviceQueue2WithOptions (const DeviceDriver& deviceDriver, const VkDevice device, VkDeviceQueueCreateFlags flags, deUint32 queueFamilyIndex, deUint32 queueIndex)
1945 {
1946 	VkDeviceQueueInfo2						queueInfo2				=
1947 	{
1948 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
1949 		DE_NULL,														// const void*						pNext;
1950 		flags,															// VkDeviceQueueCreateFlags			flags;
1951 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1952 		queueIndex,														// deUint32							queueIndex;
1953 	};
1954 
1955 	return getDeviceQueue2(deviceDriver, device, &queueInfo2);
1956 }
1957 
1958 struct QueueCreationInfo
1959 {
1960 	deUint32						familyIndex;
1961 	VkDeviceQueueCreateFlags		flags;
1962 	deUint32						count;
1963 };
1964 
runQueueCreationTestCombination(Context & context,tcu::ResultCollector & results,const std::vector<QueueCreationInfo> & testCombination,bool dumpExtraInfo=false)1965 bool runQueueCreationTestCombination (Context& context, tcu::ResultCollector& results, const std::vector<QueueCreationInfo>& testCombination, bool dumpExtraInfo=false)
1966 {
1967 	deUint32								sumQueueCount			= 0u;
1968 	for (const QueueCreationInfo& info : testCombination)
1969 	{
1970 		sumQueueCount += info.count;
1971 	}
1972 
1973 	// 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).
1974 	const vector<float>						queuePriorities			(sumQueueCount, 1.0f);
1975 	vector<VkDeviceQueueCreateInfo>			queueCreateInfo;
1976 
1977 	for (const QueueCreationInfo& info : testCombination)
1978 	{
1979 		const VkDeviceQueueCreateInfo		queueInfo				=
1980 		{
1981 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
1982 			DE_NULL,														// const void*						pNext;
1983 			info.flags,														// VkDeviceQueueCreateFlags			flags;
1984 			info.familyIndex,												// deUint32							queueFamilyIndex;
1985 			info.count,														// deUint32							queueCount;
1986 			queuePriorities.data(),											// const float*						pQueuePriorities;
1987 		};
1988 		queueCreateInfo.push_back(queueInfo);
1989 	}
1990 
1991 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1992 	const VkInstance						instance				= context.getInstance();
1993 
1994 	const Unique<VkDevice>					device					(createProtectedDeviceWithQueueConfig(context, queueCreateInfo, dumpExtraInfo));
1995 	const DeviceDriver						deviceDriver			(platformInterface, instance, *device);
1996 
1997 	for (const QueueCreationInfo& info : testCombination)
1998 	{
1999 		// Query Queues (based on the test configuration)
2000 		for (deUint32 queueIdx = 0; queueIdx < info.count; queueIdx++)
2001 		{
2002 			const string					message					= "(queueFamilyIndex: " + de::toString(info.familyIndex) + ", flags: " + de::toString(info.flags) + ", queue Index: " + de::toString(queueIdx) + ")";
2003 			const VkQueue					queue					= getDeviceQueue2WithOptions(deviceDriver, *device, info.flags, info.familyIndex, queueIdx);
2004 
2005 			if (queue != DE_NULL)
2006 			{
2007 				VK_CHECK(deviceDriver.queueWaitIdle(queue));
2008 				results.addResult(QP_TEST_RESULT_PASS, "Found Queue. " + message);
2009 			} else
2010 				results.fail("Unable to access the Queue. " + message);
2011 		}
2012 	}
2013 
2014 	return results.getResult() == QP_TEST_RESULT_PASS;
2015 }
2016 
createDeviceQueue2WithTwoQueuesSmokeTest(Context & context)2017 tcu::TestStatus createDeviceQueue2WithTwoQueuesSmokeTest (Context& context)
2018 {
2019 	const bool								dumpExtraInfo			= true;
2020 
2021 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2022 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2023 	tcu::TestLog&							log						= context.getTestContext().getLog();
2024 
2025 	vector<VkQueueFamilyProperties>			queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
2026 
2027 	// Find the first protected-capabale queue with a queueCount >= 2 and use it for testing (smoke test)
2028 	constexpr deUint32						MAX_DEUINT32			= std::numeric_limits<deUint32>::max();
2029 	deUint32								queueFamilyIndex		= MAX_DEUINT32;
2030 	const VkQueueFlags						requiredCaps			= VK_QUEUE_PROTECTED_BIT;
2031 	const deUint32							requiredQueueCount		= 2;
2032 
2033 	for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); queueNdx++)
2034 	{
2035 		if ((queueFamilyProperties[queueNdx].queueFlags & requiredCaps) == requiredCaps && queueFamilyProperties[queueNdx].queueCount >= requiredQueueCount)
2036 		{
2037 			queueFamilyIndex = queueNdx;
2038 			break;
2039 		}
2040 	}
2041 
2042 	if (queueFamilyIndex == MAX_DEUINT32)
2043 		TCU_THROW(NotSupportedError, "Unable to find a queue family that is protected-capable and supports more than one queue.");
2044 
2045 	if (dumpExtraInfo)
2046 		log << tcu::TestLog::Message << "Selected VkQueueFamilyProperties index: " << queueFamilyIndex << tcu::TestLog::EndMessage;
2047 
2048 	// Use the previously selected queue family index to create 1 protected-capable and 1 unprotected queue.
2049 	const QueueCreationInfo					protectedQueueConfig	= { queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, 1 };
2050 	const QueueCreationInfo					unprotectedQueueConfig	= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, 1 };
2051 
2052 	tcu::ResultCollector					results					(log);
2053 	const std::vector<QueueCreationInfo>	testCombination			= { protectedQueueConfig, unprotectedQueueConfig };
2054 	bool									success					= runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2055 
2056 	if (success)
2057 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2058 
2059 	return tcu::TestStatus(results.getResult(), results.getMessage());
2060 }
2061 
createDeviceQueue2WithAllProtectedQueues(Context & context)2062 tcu::TestStatus createDeviceQueue2WithAllProtectedQueues (Context& context)
2063 {
2064 	const bool								dumpExtraInfo			= true;
2065 
2066 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2067 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2068 
2069 	// Select only protected-capable queue families
2070 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2071 
2072 	bool									success					= true;
2073 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2074 
2075 	// For each protected-capable queue family, create a device with the max number of queues available and all queues created as protected-capable.
2076 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2077 	{
2078 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2079 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2080 
2081 		const QueueCreationInfo				protectedQueueConfig	= { queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, queueCount };
2082 		const vector<QueueCreationInfo>		testCombination			= { protectedQueueConfig };
2083 
2084 		// Run current confugurations.
2085 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2086 	}
2087 
2088 	if (success)
2089 		return tcu::TestStatus::pass("All queues were queried correctly.");
2090 
2091 	return tcu::TestStatus(results.getResult(), results.getMessage());
2092 }
2093 
createDeviceQueue2WithAllUnprotectedQueues(Context & context)2094 tcu::TestStatus createDeviceQueue2WithAllUnprotectedQueues (Context& context)
2095 {
2096 	const bool								dumpExtraInfo			= true;
2097 
2098 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2099 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2100 
2101 	// Select all queue families with or without protected bit
2102 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, 0);
2103 
2104 	bool									success					= true;
2105 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2106 
2107 	// For each Queue Family create the max number of unprotected Queues.
2108 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2109 	{
2110 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2111 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2112 
2113 		const QueueCreationInfo				unprotectedQueueConfig	= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, queueCount };
2114 		const vector<QueueCreationInfo>		testCombination			= { unprotectedQueueConfig };
2115 
2116 		// Run current confugurations.
2117 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2118 	}
2119 
2120 	if (success)
2121 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2122 
2123 	return tcu::TestStatus(results.getResult(), results.getMessage());
2124 }
2125 
2126 typedef vector<QueueCreationInfo>					DeviceQueueConfig;
2127 typedef map<deUint32, vector<DeviceQueueConfig> >	QueueFamilyConfigurations;
2128 
buildQueueConfigurations(const map<deUint32,VkQueueFamilyProperties> & queueFamilyProperties)2129 QueueFamilyConfigurations buildQueueConfigurations (const map<deUint32, VkQueueFamilyProperties>& queueFamilyProperties)
2130 {
2131 	QueueFamilyConfigurations				queuesPerFamily;
2132 
2133 	// Build up the queue creation combinations (N protected and M unprotected queues where N+M == queueFamily.queueCount)
2134 	// on each protected-capable queue family
2135 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamily : queueFamilyProperties)
2136 	{
2137 		const deUint32						queueFamilyIndex		= queueFamily.first;
2138 		const VkQueueFamilyProperties		queueFamilyProperty		= queueFamily.second;
2139 		const deUint32						allowedQueueCount		= queueFamilyProperty.queueCount;
2140 
2141 		for (deUint32 splitCount = 0; splitCount <= allowedQueueCount; splitCount++)
2142 		{
2143 			const deUint32					protectedQueuesCount	= allowedQueueCount - splitCount;
2144 			const deUint32					unprotectedQueuesCount	= splitCount;
2145 
2146 			vector<QueueCreationInfo>		testCombination			= { };
2147 
2148 			if (protectedQueuesCount)
2149 				testCombination.push_back({ queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, protectedQueuesCount });
2150 
2151 			if (unprotectedQueuesCount)
2152 				testCombination.push_back({ queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, unprotectedQueuesCount });
2153 
2154 			queuesPerFamily[queueFamilyIndex].push_back(testCombination);
2155 		}
2156 	}
2157 
2158 	return queuesPerFamily;
2159 }
2160 
createDeviceQueue2WithNProtectedAndMUnprotectedQueues(Context & context)2161 tcu::TestStatus createDeviceQueue2WithNProtectedAndMUnprotectedQueues (Context& context)
2162 {
2163 	const bool								dumpExtraInfo			= true;
2164 
2165 	tcu::TestLog&							log						= context.getTestContext().getLog();
2166 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2167 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2168 
2169 	// Select only protected-capable queue families
2170 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2171 
2172 	// Build all protected-unprotected splits per queue family.
2173 	QueueFamilyConfigurations				queuesPerFamily			= buildQueueConfigurations(queueFamilyProperties);
2174 	vector<DeviceQueueConfig>				queueCreateCombinations;
2175 
2176 	// Transform configurations to a simple vector
2177 	for (const auto& item : queuesPerFamily)
2178 	{
2179 		const vector<DeviceQueueConfig>&	queueConfigs			= item.second;
2180 
2181 		std::copy(queueConfigs.begin(), queueConfigs.end(), std::back_inserter(queueCreateCombinations));
2182 	}
2183 
2184 	if (dumpExtraInfo)
2185 	{
2186 		for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2187 		{
2188 			ostringstream				queuesInfo;
2189 			for (const QueueCreationInfo& queueInfo : testCombination)
2190 			{
2191 				queuesInfo << "(Queue family: " << queueInfo.familyIndex << ", flags: " << queueInfo.flags << ", count: " << queueInfo.count << ")";
2192 			}
2193 
2194 			log << tcu::TestLog::Message << "Test Combination: " << queuesInfo.str() << tcu::TestLog::EndMessage;
2195 		}
2196 	}
2197 
2198 	bool									success					= true;
2199 	tcu::ResultCollector					results					(log);
2200 
2201 	// Based on the protected-unprotected queue combinations, run each test case.
2202 	for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2203 	{
2204 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2205 	}
2206 
2207 	// Run the test cases also in reverse order (so the unprotected queue creation info is at the start of the VkDeviceQueueCreateInfo vector).
2208 	for (vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2209 	{
2210 		std::reverse(testCombination.begin(), testCombination.end());
2211 
2212 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2213 	}
2214 
2215 	if (success)
2216 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2217 
2218 	return tcu::TestStatus(results.getResult(), results.getMessage());
2219 }
2220 
createDeviceQueue2WithMultipleQueueCombinations(Context & context)2221 tcu::TestStatus createDeviceQueue2WithMultipleQueueCombinations (Context& context)
2222 {
2223 	const bool								dumpExtraInfo			= true;
2224 
2225 	tcu::TestLog&							log						= context.getTestContext().getLog();
2226 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2227 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2228 
2229 	// Select only protected-capable queue families.
2230 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2231 
2232 	// Build all protected-unprotected splits per queue family.
2233 	QueueFamilyConfigurations				queuesPerFamily			= buildQueueConfigurations(queueFamilyProperties);
2234 
2235 	// Build up all combinations of queue families from the previous mapping.
2236 	vector<DeviceQueueConfig>				queueCreateCombinations;
2237 	{
2238 		vector<deUint32>					itemIndices				(queuesPerFamily.size(), 0u);
2239 
2240 		// Calculate the max number of combinations.
2241 		auto								multiplyConfigCounts	= [](deUint32& count, const typename QueueFamilyConfigurations::value_type& item) { return count * item.second.size(); };
2242 		const deUint32						itemCount				= accumulate(queuesPerFamily.begin(), queuesPerFamily.end(), 1u, multiplyConfigCounts);
2243 
2244 		for (deUint32 count = 0u; count < itemCount; count++)
2245 		{
2246 			DeviceQueueConfig				testCombination;
2247 
2248 			// Select queue configurations from each family
2249 			for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(itemIndices.size()); ndx++)
2250 			{
2251 				const auto&					familyConfigurations	= queuesPerFamily[ndx];
2252 				const DeviceQueueConfig&	targetQueueConfig		= familyConfigurations[ itemIndices[ndx] ];
2253 
2254 				std::copy(targetQueueConfig.begin(), targetQueueConfig.end(), std::back_inserter(testCombination));
2255 			}
2256 
2257 			queueCreateCombinations.push_back(testCombination);
2258 
2259 			// Increment the indices.
2260 			for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(itemIndices.size()); ndx++)
2261 			{
2262 				itemIndices[ndx]++;
2263 				if (itemIndices[ndx] < queuesPerFamily[ndx].size())
2264 				{
2265 					break;
2266 				}
2267 
2268 				// "overflow" happened in the given index, restart from zero and increment the next item index (restart loop).
2269 				itemIndices[ndx] = 0;
2270 			}
2271 		}
2272 	}
2273 
2274 	if (dumpExtraInfo)
2275 	{
2276 		for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2277 		{
2278 			ostringstream					queuesInfo;
2279 			for (const QueueCreationInfo& queueInfo : testCombination)
2280 			{
2281 				queuesInfo << "(Queue family: " << queueInfo.familyIndex << ", flags: " << queueInfo.flags << ", count: " << queueInfo.count << ")";
2282 			}
2283 
2284 			log << tcu::TestLog::Message << "Test Combination: " << queuesInfo.str() << tcu::TestLog::EndMessage;
2285 		}
2286 	}
2287 
2288 	bool									success					= true;
2289 	tcu::ResultCollector					results					(log);
2290 
2291 	// Based on the protected-unprotected queue combinations above run each test case.
2292 	for (const DeviceQueueConfig& testCombination : queueCreateCombinations)
2293 	{
2294 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2295 	}
2296 
2297 	// Run the test cases also in reverse queue order (so the unprotected queue creation info is at the start of the VkDeviceQueueCreateInfo vector).
2298 	for (DeviceQueueConfig& testCombination : queueCreateCombinations)
2299 	{
2300 		std::reverse(testCombination.begin(), testCombination.end());
2301 
2302 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2303 	}
2304 
2305 	if (success)
2306 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2307 
2308 	return tcu::TestStatus(results.getResult(), results.getMessage());
2309 }
2310 
createDeviceQueue2WithAllFamilies(Context & context)2311 tcu::TestStatus createDeviceQueue2WithAllFamilies (Context& context)
2312 {
2313 	const bool								dumpExtraInfo			= true;
2314 
2315 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2316 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2317 
2318 	// Get all queue families
2319 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, (VkDeviceQueueCreateFlags)0u);
2320 
2321 	// Create test configuration where for each queue family the maximum number of queues are created.
2322 	vector<QueueCreationInfo>				queueConfigurations;
2323 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2324 	{
2325 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2326 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2327 
2328 		const QueueCreationInfo				queueConfig				= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, queueCount };
2329 
2330 		queueConfigurations.push_back(queueConfig);
2331 	}
2332 
2333 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2334 
2335 	// Execute test to see if it possible to have all queue families created at the same time.
2336 	bool									success					= runQueueCreationTestCombination(context, results, queueConfigurations, dumpExtraInfo);
2337 
2338 	if (success)
2339 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2340 
2341 	return tcu::TestStatus(results.getResult(), results.getMessage());
2342 }
2343 
createDeviceQueue2WithAllFamiliesProtected(Context & context)2344 tcu::TestStatus createDeviceQueue2WithAllFamiliesProtected (Context& context)
2345 {
2346 	const bool								dumpExtraInfo			= true;
2347 
2348 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2349 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2350 
2351 	// Get all queue families
2352 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, (VkDeviceQueueCreateFlags)0u);
2353 
2354 	// Create test configuration where for each queue family the maximum number of queues are created.
2355 	// If a queue supports protected memory then create a protected-capable queue.
2356 	vector<QueueCreationInfo>				queueConfigurations;
2357 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2358 	{
2359 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2360 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2361 
2362 		VkDeviceQueueCreateFlags			useFlags				= (VkDeviceQueueCreateFlags)0u;
2363 		if ((queueFamilyProperty.second.queueFlags & VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT) == VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT)
2364 			useFlags |= VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
2365 
2366 		const QueueCreationInfo				queueConfig				= { queueFamilyIndex, useFlags, queueCount };
2367 
2368 		queueConfigurations.push_back(queueConfig);
2369 	}
2370 
2371 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2372 
2373 	// Execute test to see if it possible to have all queue families created at the same time.
2374 	bool									success					= runQueueCreationTestCombination(context, results, queueConfigurations, dumpExtraInfo);
2375 
2376 	if (success)
2377 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2378 
2379 	return tcu::TestStatus(results.getResult(), results.getMessage());
2380 }
2381 
2382 #ifndef CTS_USES_VULKANSC
2383 // Allocation tracking utilities
2384 struct	AllocTrack
2385 {
2386 	bool						active;
2387 	bool						wasAllocated;
2388 	void*						alignedStartAddress;
2389 	char*						actualStartAddress;
2390 	size_t						requestedSizeBytes;
2391 	size_t						actualSizeBytes;
2392 	VkSystemAllocationScope		allocScope;
2393 	deUint64					userData;
2394 
AllocTrackvkt::api::__anondb73e1c70111::AllocTrack2395 	AllocTrack()
2396 		: active				(false)
2397 		, wasAllocated			(false)
2398 		, alignedStartAddress	(DE_NULL)
2399 		, actualStartAddress	(DE_NULL)
2400 		, requestedSizeBytes	(0)
2401 		, actualSizeBytes		(0)
2402 		, allocScope			(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)
2403 		, userData(0)			{}
2404 };
2405 
2406 // Global vector to track allocations. This will be resized before each test and emptied after
2407 // However, we have to globally define it so the allocation callback functions work properly
2408 std::vector<AllocTrack>	g_allocatedVector;
2409 bool					g_intentionalFailEnabled	= false;
2410 deUint32				g_intenionalFailIndex		= 0;
2411 deUint32				g_intenionalFailCount		= 0;
2412 size_t					g_allocationsCount			= 0;
2413 
freeAllocTracker(void)2414 void freeAllocTracker(void)
2415 {
2416 	g_allocatedVector.clear();
2417 	g_allocationsCount = 0;
2418 }
2419 
initAllocTracker(size_t size,deUint32 intentionalFailIndex=(deUint32)~0)2420 void initAllocTracker (size_t size, deUint32 intentionalFailIndex = (deUint32)~0)
2421 {
2422 	if (g_allocatedVector.size() > 0)
2423 		freeAllocTracker();
2424 
2425 	g_allocatedVector.resize(size);
2426 
2427 	if (intentionalFailIndex != (deUint32)~0)
2428 	{
2429 		g_intentionalFailEnabled	= true;
2430 		g_intenionalFailIndex		= intentionalFailIndex;
2431 		g_intenionalFailCount		= 0;
2432 	}
2433 	else
2434 	{
2435 		g_intentionalFailEnabled	= false;
2436 		g_intenionalFailIndex		= 0;
2437 		g_intenionalFailCount		= 0;
2438 	}
2439 
2440 	g_allocationsCount = 0;
2441 }
2442 
isAllocTrackerEmpty()2443 bool isAllocTrackerEmpty ()
2444 {
2445 	bool success		= true;
2446 	bool wasAllocated	= false;
2447 
2448 	for (deUint32 vectorIdx	= 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2449 	{
2450 		if (g_allocatedVector[vectorIdx].active)
2451 			success = false;
2452 		else if (!wasAllocated && g_allocatedVector[vectorIdx].wasAllocated)
2453 			wasAllocated = true;
2454 	}
2455 
2456 	if (!g_intentionalFailEnabled && !wasAllocated)
2457 		success = false;
2458 
2459 	return success;
2460 }
2461 
allocCallbackFunc(void * pUserData,size_t size,size_t alignment,VkSystemAllocationScope allocationScope)2462 VKAPI_ATTR void *VKAPI_CALL allocCallbackFunc (void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
2463 {
2464 	if (g_intentionalFailEnabled)
2465 		if (++g_intenionalFailCount >= g_intenionalFailIndex)
2466 			return DE_NULL;
2467 
2468 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2469 	{
2470 		if (!g_allocatedVector[vectorIdx].active)
2471 		{
2472 			g_allocatedVector[vectorIdx].requestedSizeBytes		= size;
2473 			g_allocatedVector[vectorIdx].actualSizeBytes		= size + (alignment - 1);
2474 			g_allocatedVector[vectorIdx].alignedStartAddress	= DE_NULL;
2475 			g_allocatedVector[vectorIdx].actualStartAddress		= new char[g_allocatedVector[vectorIdx].actualSizeBytes];
2476 
2477 			if (g_allocatedVector[vectorIdx].actualStartAddress != DE_NULL)
2478 			{
2479 				deUint64 addr	=	(deUint64)g_allocatedVector[vectorIdx].actualStartAddress;
2480 				addr			+=	(alignment - 1);
2481 				addr			&=	~(alignment - 1);
2482 				g_allocatedVector[vectorIdx].alignedStartAddress	= (void *)addr;
2483 				g_allocatedVector[vectorIdx].allocScope				= allocationScope;
2484 				g_allocatedVector[vectorIdx].userData				= (deUint64)pUserData;
2485 				g_allocatedVector[vectorIdx].active					= true;
2486 				g_allocatedVector[vectorIdx].wasAllocated			= true;
2487 			}
2488 
2489 			g_allocationsCount++;
2490 			return g_allocatedVector[vectorIdx].alignedStartAddress;
2491 		}
2492 	}
2493 	return DE_NULL;
2494 }
2495 
freeCallbackFunc(void * pUserData,void * pMemory)2496 VKAPI_ATTR void VKAPI_CALL freeCallbackFunc (void *pUserData, void *pMemory)
2497 {
2498 	DE_UNREF(pUserData);
2499 
2500 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2501 	{
2502 		if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pMemory)
2503 		{
2504 			delete[] g_allocatedVector[vectorIdx].actualStartAddress;
2505 			g_allocatedVector[vectorIdx].active = false;
2506 			break;
2507 		}
2508 	}
2509 }
2510 
reallocCallbackFunc(void * pUserData,void * pOriginal,size_t size,size_t alignment,VkSystemAllocationScope allocationScope)2511 VKAPI_ATTR void *VKAPI_CALL reallocCallbackFunc (void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
2512 {
2513 	if (pOriginal != DE_NULL)
2514 	{
2515 		for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2516 		{
2517 			if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pOriginal)
2518 			{
2519 				if (size == 0)
2520 				{
2521 					freeCallbackFunc(pUserData, pOriginal);
2522 					return DE_NULL;
2523 				}
2524 				else if (size < g_allocatedVector[vectorIdx].requestedSizeBytes)
2525 					return pOriginal;
2526 				else
2527 				{
2528 					void *pNew = allocCallbackFunc(pUserData, size, alignment, allocationScope);
2529 
2530 					if (pNew != DE_NULL)
2531 					{
2532 						size_t copySize = size;
2533 
2534 						if (g_allocatedVector[vectorIdx].requestedSizeBytes < size)
2535 							copySize = g_allocatedVector[vectorIdx].requestedSizeBytes;
2536 
2537 						memcpy(pNew, pOriginal, copySize);
2538 						freeCallbackFunc(pUserData, pOriginal);
2539 					}
2540 					return pNew;
2541 				}
2542 			}
2543 		}
2544 		return DE_NULL;
2545 	}
2546 	else
2547 		return allocCallbackFunc(pUserData, size, alignment, allocationScope);
2548 }
2549 
createInstanceDeviceIntentionalAllocFail(Context & context)2550 tcu::TestStatus createInstanceDeviceIntentionalAllocFail (Context& context)
2551 {
2552 	const PlatformInterface&	vkp					= context.getPlatformInterface();
2553 	const deUint32				chosenDevice		= context.getTestContext().getCommandLine().getVKDeviceId() - 1;
2554 	VkInstance					instance			= DE_NULL;
2555 	VkDevice					device				= DE_NULL;
2556 	deUint32					physicalDeviceCount	= 0;
2557 	deUint32					queueFamilyCount	= 0;
2558 	deUint32					queueFamilyIndex	= 0;
2559 	const float					queuePriority		= 0.0f;
2560 	const VkAllocationCallbacks	allocationCallbacks	=
2561 	{
2562 		DE_NULL,								// userData
2563 		allocCallbackFunc,						// pfnAllocation
2564 		reallocCallbackFunc,					// pfnReallocation
2565 		freeCallbackFunc,						// pfnFree
2566 		DE_NULL,								// pfnInternalAllocation
2567 		DE_NULL									// pfnInternalFree
2568 	};
2569 	const VkApplicationInfo		appInfo				=
2570 	{
2571 		VK_STRUCTURE_TYPE_APPLICATION_INFO,		// sType
2572 		DE_NULL,								// pNext
2573 		"appName",								// pApplicationName
2574 		0u,										// applicationVersion
2575 		"engineName",							// pEngineName
2576 		0u,										// engineVersion
2577 		VK_API_VERSION_1_0						// apiVersion
2578 	};
2579 
2580 	const VkInstanceCreateInfo	instanceCreateInfo	=
2581 	{
2582 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// sType
2583 		DE_NULL,								// pNext
2584 		(VkInstanceCreateFlags)0u,				// flags
2585 		&appInfo,								// pApplicationInfo
2586 		0u,										// enabledLayerCount
2587 		DE_NULL,								// ppEnabledLayerNames
2588 		0u,										// enabledExtensionCount
2589 		DE_NULL									// ppEnabledExtensionNames
2590 	};
2591 
2592 	deUint32					failIndex			= 0;
2593 	VkResult					result				= VK_SUCCESS;
2594 	size_t						max_allowed_alloc	= 0;
2595 
2596 	do
2597 	{
2598 		if (max_allowed_alloc == 0)
2599 		{
2600 			if (result != VK_SUCCESS)
2601 				return tcu::TestStatus::fail("Could not create instance and device");
2602 
2603 			initAllocTracker(99999);
2604 		}
2605 		else
2606 		{
2607 			initAllocTracker(max_allowed_alloc, failIndex++);
2608 
2609 			if (failIndex >= static_cast<deUint32>(max_allowed_alloc))
2610 				return tcu::TestStatus::fail("Out of retries, could not create instance and device");
2611 		}
2612 
2613 		// if the number of allocations the driver makes is large, we may end up
2614 		// taking more than the watchdog timeout. touch here to avoid spurious
2615 		// failures.
2616 		if (failIndex % 128 == 0)
2617 			context.getTestContext().touchWatchdog();
2618 
2619 		result = vkp.createInstance(&instanceCreateInfo, &allocationCallbacks, &instance);
2620 
2621 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2622 		{
2623 			if (!isAllocTrackerEmpty())
2624 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2625 
2626 			freeAllocTracker();
2627 			continue;
2628 		}
2629 		else if (result != VK_SUCCESS)
2630 			return tcu::TestStatus::fail("createInstance returned " + de::toString(result));
2631 
2632 		const InstanceDriver		instanceDriver	(vkp, instance);
2633 		const InstanceInterface&	vki				(instanceDriver);
2634 
2635 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, DE_NULL);
2636 
2637 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2638 		{
2639 			vki.destroyInstance(instance, &allocationCallbacks);
2640 
2641 			if (!isAllocTrackerEmpty())
2642 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2643 
2644 			freeAllocTracker();
2645 			continue;
2646 		}
2647 		else if (result != VK_SUCCESS)
2648 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
2649 
2650 		vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
2651 
2652 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
2653 
2654 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2655 		{
2656 			vki.destroyInstance(instance, &allocationCallbacks);
2657 
2658 			if (!isAllocTrackerEmpty())
2659 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2660 
2661 			freeAllocTracker();
2662 			continue;
2663 		}
2664 		else if (result != VK_SUCCESS)
2665 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
2666 
2667 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, DE_NULL);
2668 
2669 		if (queueFamilyCount == 0u)
2670 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
2671 
2672 		vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
2673 
2674 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, queueFamilies.data());
2675 
2676 		if (queueFamilyCount == 0u)
2677 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
2678 
2679 		for (deUint32 i = 0; i < queueFamilyCount; i++)
2680 		{
2681 			if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
2682 			{
2683 				queueFamilyIndex = i;
2684 				break;
2685 			}
2686 		}
2687 
2688 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
2689 		{
2690 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
2691 			DE_NULL,									// pNext
2692 			(VkDeviceQueueCreateFlags)0u,				// flags
2693 			queueFamilyIndex,							// queueFamilyIndex
2694 			1u,											// queueCount
2695 			&queuePriority								// pQueuePriorities
2696 		};
2697 
2698 		void* pNext												= DE_NULL;
2699 #ifdef CTS_USES_VULKANSC
2700 		VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
2701 		memReservationInfo.pNext								= pNext;
2702 		pNext													= &memReservationInfo;
2703 
2704 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
2705 		sc10Features.pNext										= pNext;
2706 		pNext													= &sc10Features;
2707 #endif // CTS_USES_VULKANSC
2708 
2709 		const VkDeviceCreateInfo		deviceCreateInfo		=
2710 		{
2711 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// sType
2712 			pNext,										// pNext
2713 			(VkDeviceCreateFlags)0u,					// flags
2714 			1u,											// queueCreateInfoCount
2715 			&deviceQueueCreateInfo,						// pQueueCreateInfos
2716 			0u,											// enabledLayerCount
2717 			DE_NULL,									// ppEnabledLayerNames
2718 			0u,											// enabledExtensionCount
2719 			DE_NULL,									// ppEnabledExtensionNames
2720 			DE_NULL										// pEnabledFeatures
2721 		};
2722 
2723 		result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vki, physicalDevices[chosenDevice], &deviceCreateInfo, &allocationCallbacks, &device);
2724 
2725 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2726 		{
2727 			vki.destroyInstance(instance, &allocationCallbacks);
2728 
2729 			if (!isAllocTrackerEmpty())
2730 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2731 
2732 			freeAllocTracker();
2733 			continue;
2734 		}
2735 		else if (result != VK_SUCCESS)
2736 			return tcu::TestStatus::fail("VkCreateDevice returned " + de::toString(result));
2737 
2738 		DeviceDriver(vkp, instance, device).destroyDevice(device, &allocationCallbacks);
2739 		vki.destroyInstance(instance, &allocationCallbacks);
2740 		if (max_allowed_alloc == 0)
2741 		{
2742 			max_allowed_alloc	= g_allocationsCount + 100;
2743 			result				= VK_ERROR_OUT_OF_HOST_MEMORY;
2744 		}
2745 		freeAllocTracker();
2746 	}
2747 	while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
2748 
2749 	return tcu::TestStatus::pass("Pass");
2750 }
2751 
2752 #endif // CTS_USES_VULKANSC
2753 
2754 } // anonymous
2755 
addFunctionCaseInNewSubgroup(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,const std::string & subgroupName,const std::string & subgroupDescription,FunctionInstance0::Function testFunc)2756 static inline void addFunctionCaseInNewSubgroup (
2757 	tcu::TestContext&			testCtx,
2758 	tcu::TestCaseGroup*			group,
2759 	const std::string&			subgroupName,
2760 	const std::string&			subgroupDescription,
2761 	FunctionInstance0::Function		testFunc)
2762 {
2763 	de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2764 	addFunctionCase(subgroup.get(), "basic", "", testFunc);
2765 	group->addChild(subgroup.release());
2766 }
2767 
addFunctionCaseInNewSubgroup(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,const std::string & subgroupName,const std::string & subgroupDescription,FunctionSupport0::Function checkSupport,FunctionInstance0::Function testFunc)2768 static inline void addFunctionCaseInNewSubgroup (
2769 	tcu::TestContext&			testCtx,
2770 	tcu::TestCaseGroup*			group,
2771 	const std::string&			subgroupName,
2772 	const std::string&			subgroupDescription,
2773 	FunctionSupport0::Function		checkSupport,
2774 	FunctionInstance0::Function		testFunc)
2775 {
2776 	de::MovePtr<tcu::TestCaseGroup> subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2777 	addFunctionCase(subgroup.get(), "basic", "", checkSupport, testFunc);
2778 	group->addChild(subgroup.release());
2779 }
2780 
2781 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)2782 static void addFunctionCaseInNewSubgroup (
2783 	tcu::TestContext&							testCtx,
2784 	tcu::TestCaseGroup*							group,
2785 	const std::string&							subgroupName,
2786 	const std::string&							subgroupDescription,
2787 	typename FunctionSupport1<Arg0>::Function	checkSupport,
2788 	typename FunctionInstance1<Arg0>::Function	testFunc,
2789 	Arg0										arg0)
2790 {
2791 	de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2792 	subgroup->addChild(createFunctionCase<Arg0>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "basic", "", checkSupport, testFunc, arg0));
2793 	group->addChild(subgroup.release());
2794 }
2795 
createDeviceInitializationTests(tcu::TestContext & testCtx)2796 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
2797 {
2798 	de::MovePtr<tcu::TestCaseGroup>	deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));
2799 
2800 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_name_version",					"", createInstanceTest);
2801 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_invalid_api_version",			"", createInstanceWithInvalidApiVersionTest);
2802 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_null_appinfo",					"", createInstanceWithNullApplicationInfoTest);
2803 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_unsupported_extensions",		"", createInstanceWithUnsupportedExtensionsTest);
2804 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_extension_name_abuse",			"", createInstanceWithExtensionNameAbuseTest);
2805 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_layer_name_abuse",				"", createInstanceWithLayerNameAbuseTest);
2806 #ifndef CTS_USES_VULKANSC
2807 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "enumerate_devices_alloc_leak",					"", enumerateDevicesAllocLeakTest);
2808 #endif // CTS_USES_VULKANSC
2809 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device",									"", createDeviceTest);
2810 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_multiple_devices",						"", createMultipleDevicesTest);
2811 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_unsupported_extensions",			"", createDeviceWithUnsupportedExtensionsTest);
2812 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_various_queue_counts",			"", createDeviceWithVariousQueueCountsTest);
2813 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority",					"", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, false);
2814 #ifndef CTS_USES_VULKANSC
2815 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_khr",				"", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, true);
2816 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query",			"", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, false);
2817 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query_khr",		"", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, true);
2818 #endif // CTS_USES_VULKANSC
2819 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_features2",						"", createDeviceFeatures2Test);
2820 	{
2821 		de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, "create_device_unsupported_features", ""));
2822 		addFunctionCase(subgroup.get(), "core", "", createDeviceWithUnsupportedFeaturesTest);
2823 		addSeparateUnsupportedFeatureTests(subgroup.get());
2824 		deviceInitializationTests->addChild(subgroup.release());
2825 	}
2826 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2",							"", createDeviceQueue2Test);
2827 #ifndef CTS_USES_VULKANSC
2828 	// Removed because in main process this test does not really create any instance nor device and functions creating it always return VK_SUCCESS
2829 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_device_intentional_alloc_fail",	"", createInstanceDeviceIntentionalAllocFail);
2830 #endif // CTS_USES_VULKANSC
2831 
2832 	// Tests using a single Queue Family when creating a device.
2833 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_two_queues",					"", checkProtectedMemorySupport, createDeviceQueue2WithTwoQueuesSmokeTest);
2834 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_protected",				"", checkProtectedMemorySupport, createDeviceQueue2WithAllProtectedQueues);
2835 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_unprotected",			"", checkProtectedMemorySupport, createDeviceQueue2WithAllUnprotectedQueues);
2836 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_split",						"", checkProtectedMemorySupport, createDeviceQueue2WithNProtectedAndMUnprotectedQueues);
2837 
2838 	// Tests using multiple Queue Families when creating a device.
2839 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_families",				"", checkProtectedMemorySupport, createDeviceQueue2WithAllFamilies);
2840 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_families_protected",		"", checkProtectedMemorySupport, createDeviceQueue2WithAllFamiliesProtected);
2841 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_combinations",			"", checkProtectedMemorySupport, createDeviceQueue2WithMultipleQueueCombinations);
2842 
2843 	return deviceInitializationTests.release();
2844 }
2845 
2846 } // api
2847 } // vkt
2848