• 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(), context.getUsedApiVersion());
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], context.getUsedApiVersion());
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], context.getUsedApiVersion());
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], context.getUsedApiVersion());
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, context.getUsedApiVersion());
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(), context.getUsedApiVersion());
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(), context.getUsedApiVersion());
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(), context.getUsedApiVersion());
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(), context.getUsedApiVersion());
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<size_t>(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,uint32_t usedApiVersion)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 					uint32_t								usedApiVersion
1409 	)
1410 {
1411 	struct StructureBase
1412 	{
1413 		VkStructureType		sType;
1414 		void*				pNext;
1415 	};
1416 
1417 	for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
1418 	{
1419 		// Test only features that are not supported.
1420 		if (*(((VkBool32*)((deUint8*)(supportedFeatures) + features[featureNdx].offset))))
1421 			continue;
1422 
1423 		StructType structCopy;
1424 		deMemset(&structCopy, 0, sizeof(StructType));
1425 
1426 		auto* structBase = reinterpret_cast<StructureBase*>(&structCopy);
1427 		VkStructureType structureType = reinterpret_cast<const StructureBase*>(supportedFeatures)->sType;
1428 		structBase->sType = structureType;
1429 		structBase->pNext = DE_NULL;
1430 
1431 		VkPhysicalDeviceFeatures physicalDeviceFeaturesCopy = defaultPhysicalDeviceFeatures;
1432 
1433 		// Some features require that other feature(s) are also enabled.
1434 
1435 		if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES)
1436 		{
1437 			DE_ASSERT((std::is_same<VkPhysicalDeviceVulkan11Features, StructType>::value));
1438 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1439 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1440 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader) ||
1441 				features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader))
1442 			{
1443 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, multiview));
1444 				*memberPtr = VK_TRUE;
1445 			}
1446 
1447 			// If variablePointers is enabled then variablePointersStorageBuffer must also be enabled.
1448 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, variablePointers))
1449 			{
1450 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer));
1451 				*memberPtr = VK_TRUE;
1452 			}
1453 		}
1454 #ifndef CTS_USES_VULKANSC
1455 		// If rayTracingPipelineShaderGroupHandleCaptureReplayMixed is VK_TRUE, rayTracingPipelineShaderGroupHandleCaptureReplay must also be VK_TRUE.
1456 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR &&
1457 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplayMixed))
1458 		{
1459 			DE_ASSERT((std::is_same<VkPhysicalDeviceRayTracingPipelineFeaturesKHR, StructType>::value));
1460 			auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplay));
1461 			*memberPtr = VK_TRUE;
1462 		}
1463 #endif // CTS_USES_VULKANSC
1464 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES)
1465 		{
1466 			DE_ASSERT((std::is_same<VkPhysicalDeviceMultiviewFeatures, StructType>::value));
1467 			// If multiviewGeometryShader is enabled then multiview must also be enabled.
1468 			// If multiviewTessellationShader is enabled then multiview must also be enabled.
1469 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewGeometryShader) ||
1470 			features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewTessellationShader))
1471 			{
1472 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceMultiviewFeatures, multiview));
1473 				*memberPtr = VK_TRUE;
1474 			}
1475 		}
1476 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
1477 		{
1478 			DE_ASSERT((std::is_same<VkPhysicalDeviceRobustness2FeaturesEXT, StructType>::value));
1479 			// If robustBufferAccess2 is enabled then robustBufferAccess must also be enabled.
1480 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRobustness2FeaturesEXT, robustBufferAccess2))
1481 			{
1482 				physicalDeviceFeaturesCopy.robustBufferAccess = true;
1483 			}
1484 		}
1485 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT)
1486 		{
1487 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, StructType>::value));
1488 			// If sparseImageInt64Atomics is enabled, shaderImageInt64Atomics must be enabled.
1489 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, sparseImageInt64Atomics))
1490 			{
1491 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, shaderImageInt64Atomics));
1492 				*memberPtr = VK_TRUE;
1493 			}
1494 		}
1495 		else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT)
1496 		{
1497 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, StructType>::value));
1498 			// If sparseImageFloat32Atomics is enabled, shaderImageFloat32Atomics must be enabled.
1499 			if (features[featureNdx].offset ==
1500 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32Atomics)) {
1501 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32Atomics));
1502 				*memberPtr = VK_TRUE;
1503 			}
1504 
1505 			// If sparseImageFloat32AtomicAdd is enabled, shaderImageFloat32AtomicAdd must be enabled.
1506 			if (features[featureNdx].offset ==
1507 				DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32AtomicAdd)) {
1508 				auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32AtomicAdd));
1509 				*memberPtr = VK_TRUE;
1510 			}
1511 		}
1512 #ifndef CTS_USES_VULKANSC
1513 		else if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT)
1514 		{
1515 			DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, StructType>::value));
1516 			// If sparseImageFloat32AtomicMinMax is enabled, shaderImageFloat32AtomicMinMax must be enabled.
1517 			if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, sparseImageFloat32AtomicMinMax))
1518 			{
1519 				auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderImageFloat32AtomicMinMax));
1520 				*memberPtr = VK_TRUE;
1521 			}
1522 		}
1523 #endif // CTS_USES_VULKANSC
1524 
1525 		// Enable the feature we're testing.
1526 		*reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + features[featureNdx].offset) = VK_TRUE;
1527 
1528 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1529 		{
1530 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
1531 			DE_NULL,									// pNext
1532 			(VkDeviceQueueCreateFlags)0u,				// flags
1533 			queueFamilyIndex,							// queueFamilyIndex
1534 			queueCount,									// queueCount
1535 			&queuePriority								// pQueuePriorities
1536 		};
1537 		VkPhysicalDeviceFeatures2 deviceFeatures2 =
1538 		{
1539 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,	// sType
1540 			&structCopy,									// pNext
1541 			physicalDeviceFeaturesCopy						// features
1542 		};
1543 
1544 		void* pNext												= &deviceFeatures2;
1545 #ifdef CTS_USES_VULKANSC
1546 		VkDeviceObjectReservationCreateInfo memReservationInfo	= isSubProcess? memReservationStatMax : resetDeviceObjectReservationCreateInfo();
1547 		memReservationInfo.pNext								= pNext;
1548 		pNext													= &memReservationInfo;
1549 
1550 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1551 		sc10Features.pNext										= pNext;
1552 		pNext													= &sc10Features;
1553 #else
1554 		DE_UNREF(isSubProcess);
1555 #endif // CTS_USES_VULKANSC
1556 
1557 		const VkDeviceCreateInfo		deviceCreateInfo		=
1558 		{
1559 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,											// sType
1560 			pNext,																			// pNext
1561 			(VkDeviceCreateFlags)0u,														// flags
1562 			1,																				// queueCreateInfoCount
1563 			&deviceQueueCreateInfo,															// pQueueCreateInfos
1564 			0u,																				// enabledLayerCount
1565 			DE_NULL,																		// ppEnabledLayerNames
1566 			static_cast<deUint32>(extensionNames == DE_NULL ? 0 : extensionNames->size()),	// enabledExtensionCount
1567 			extensionNames == DE_NULL ? DE_NULL : extensionNames->data(),					// ppEnabledExtensionNames
1568 			DE_NULL																			// pEnabledFeatures
1569 		};
1570 
1571 		VkDevice		device = (VkDevice)DE_NULL;
1572 		const VkResult	res	= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1573 
1574 		if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1575 		{
1576 			numErrors++;
1577 			resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1578 				+ de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
1579 		}
1580 		if (device != (VkDevice)DE_NULL)
1581 		{
1582 			DeviceDriver deviceDriver(vkp, instance, device, usedApiVersion);
1583 			deviceDriver.destroyDevice(device, DE_NULL);
1584 		}
1585 	}
1586 }
1587 
createDeviceWithUnsupportedFeaturesTest(Context & context)1588 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
1589 {
1590 	const PlatformInterface&				vkp						= context.getPlatformInterface();
1591 	tcu::TestLog&							log						= context.getTestContext().getLog();
1592 	tcu::ResultCollector					resultCollector			(log);
1593 	const CustomInstance					instance				(createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
1594 	const InstanceDriver&					instanceDriver			(instance.getDriver());
1595 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1596 	const deUint32							queueFamilyIndex		= 0;
1597 	const deUint32							queueCount				= 1;
1598 	const float								queuePriority			= 1.0f;
1599 	const DeviceFeatures					deviceFeaturesAll		(context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
1600 	const VkPhysicalDeviceFeatures2			deviceFeatures2			= deviceFeaturesAll.getCoreFeatures2();
1601 	const VkPhysicalDeviceFeatures			deviceFeatures			= deviceFeatures2.features;
1602 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
1603 
1604 	// Test features listed in VkPhysicalDeviceFeatures structure
1605 	{
1606 		static const Feature features[] =
1607 		{
1608 			// robustBufferAccess is removed, because it's always supported.
1609 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
1610 			FEATURE_ITEM(VkPhysicalDeviceFeatures, imageCubeArray),
1611 			FEATURE_ITEM(VkPhysicalDeviceFeatures, independentBlend),
1612 			FEATURE_ITEM(VkPhysicalDeviceFeatures, geometryShader),
1613 			FEATURE_ITEM(VkPhysicalDeviceFeatures, tessellationShader),
1614 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sampleRateShading),
1615 			FEATURE_ITEM(VkPhysicalDeviceFeatures, dualSrcBlend),
1616 			FEATURE_ITEM(VkPhysicalDeviceFeatures, logicOp),
1617 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiDrawIndirect),
1618 			FEATURE_ITEM(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
1619 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthClamp),
1620 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBiasClamp),
1621 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fillModeNonSolid),
1622 			FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBounds),
1623 			FEATURE_ITEM(VkPhysicalDeviceFeatures, wideLines),
1624 			FEATURE_ITEM(VkPhysicalDeviceFeatures, largePoints),
1625 			FEATURE_ITEM(VkPhysicalDeviceFeatures, alphaToOne),
1626 			FEATURE_ITEM(VkPhysicalDeviceFeatures, multiViewport),
1627 			FEATURE_ITEM(VkPhysicalDeviceFeatures, samplerAnisotropy),
1628 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionETC2),
1629 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
1630 			FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionBC),
1631 			FEATURE_ITEM(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
1632 			FEATURE_ITEM(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
1633 			FEATURE_ITEM(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
1634 			FEATURE_ITEM(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
1635 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
1636 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
1637 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
1638 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
1639 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
1640 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
1641 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
1642 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
1643 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
1644 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
1645 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderClipDistance),
1646 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderCullDistance),
1647 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderFloat64),
1648 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt64),
1649 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt16),
1650 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceResidency),
1651 			FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceMinLod),
1652 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseBinding),
1653 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
1654 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
1655 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
1656 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency2Samples),
1657 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency4Samples),
1658 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency8Samples),
1659 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency16Samples),
1660 			FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyAliased),
1661 			FEATURE_ITEM(VkPhysicalDeviceFeatures, variableMultisampleRate),
1662 			FEATURE_ITEM(VkPhysicalDeviceFeatures, inheritedQueries)
1663 		};
1664 
1665 		for (const auto& feature : features)
1666 		{
1667 			// Test only features that are not supported.
1668 			if (*(((VkBool32*)((deUint8*)(&deviceFeatures) + feature.offset))))
1669 				continue;
1670 
1671 			VkPhysicalDeviceFeatures		enabledFeatures			= deviceFeatures;
1672 			*((VkBool32*)((deUint8*)(&enabledFeatures) + feature.offset)) = VK_TRUE;
1673 
1674 			const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
1675 			{
1676 				VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1677 				DE_NULL,
1678 				(VkDeviceQueueCreateFlags)0u,
1679 				queueFamilyIndex,
1680 				queueCount,
1681 				&queuePriority
1682 			};
1683 
1684 			void* pNext												= DE_NULL;
1685 #ifdef CTS_USES_VULKANSC
1686 			VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1687 			memReservationInfo.pNext								= pNext;
1688 			pNext													= &memReservationInfo;
1689 
1690 			VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1691 			sc10Features.pNext										= pNext;
1692 			pNext													= &sc10Features;
1693 #endif // CTS_USES_VULKANSC
1694 
1695 			const VkDeviceCreateInfo		deviceCreateInfo		=
1696 			{
1697 				VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1698 				pNext,
1699 				(VkDeviceCreateFlags)0u,
1700 				1,
1701 				&deviceQueueCreateInfo,
1702 				0u,
1703 				DE_NULL,
1704 				0,
1705 				DE_NULL,
1706 				&enabledFeatures
1707 			};
1708 
1709 			VkDevice		device	= DE_NULL;
1710 			const VkResult	res		= createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1711 
1712 			if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1713 			{
1714 				resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1715 				+ de::toString(feature.name) + ", which was reported as unsupported.");
1716 			}
1717 
1718 			if (device != DE_NULL)
1719 			{
1720 				DeviceDriver deviceDriver(vkp, instance, device, context.getUsedApiVersion());
1721 				deviceDriver.destroyDevice(device, DE_NULL);
1722 			}
1723 		}
1724 	}
1725 
1726 	return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
1727 }
1728 
1729 #include "vkDeviceFeatureTest.inl"
1730 
createDeviceQueue2Test(Context & context)1731 tcu::TestStatus createDeviceQueue2Test (Context& context)
1732 {
1733 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1734 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1735 
1736 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1737 	const CustomInstance					instance				(createCustomInstanceFromContext(context));
1738 	const InstanceDriver&					instanceDriver			(instance.getDriver());
1739 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1740 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1741 	const deUint32							queueCount				= 1;
1742 	const deUint32							queueIndex				= 0;
1743 	const float								queuePriority			= 1.0f;
1744 
1745 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1746 	{
1747 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1748 		DE_NULL,														// void*							pNext;
1749 		VK_FALSE														// VkBool32							protectedMemory;
1750 	};
1751 
1752 	VkPhysicalDeviceFeatures2				features2;
1753 	deMemset(&features2, 0, sizeof(features2));
1754 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1755 	features2.pNext													= &protectedMemoryFeature;
1756 
1757 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1758 	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1759 		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1760 
1761 	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
1762 	{
1763 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
1764 		DE_NULL,														// const void*						pNext;
1765 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1766 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1767 		queueCount,														// deUint32							queueCount;
1768 		&queuePriority,													// const float*						pQueuePriorities;
1769 	};
1770 
1771 	void* pNext												= &features2;
1772 #ifdef CTS_USES_VULKANSC
1773 	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1774 	memReservationInfo.pNext								= pNext;
1775 	pNext													= &memReservationInfo;
1776 
1777 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
1778 	sc10Features.pNext										= pNext;
1779 	pNext													= &sc10Features;
1780 #endif // CTS_USES_VULKANSC
1781 
1782 	const VkDeviceCreateInfo				deviceCreateInfo		=
1783 	{
1784 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
1785 		pNext,															// const void*						pNext;
1786 		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
1787 		1,																// deUint32							queueCreateInfoCount;
1788 		&deviceQueueCreateInfo,											// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1789 		0,																// deUint32							enabledLayerCount;
1790 		DE_NULL,														// const char* const*				ppEnabledLayerNames;
1791 		0,																// deUint32							enabledExtensionCount;
1792 		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
1793 		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1794 	};
1795 
1796 	const VkDeviceQueueInfo2				deviceQueueInfo2		=
1797 	{
1798 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
1799 		DE_NULL,														// const void*						pNext;
1800 		VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,							// VkDeviceQueueCreateFlags			flags;
1801 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1802 		queueIndex,														// deUint32							queueIndex;
1803 	};
1804 
1805 	{
1806 		const Unique<VkDevice>				device					(createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1807 		const DeviceDriver					deviceDriver			(platformInterface, instance, device.get(), context.getUsedApiVersion());
1808 		const VkQueue						queue2					= getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);
1809 
1810 		VK_CHECK(deviceDriver.queueWaitIdle(queue2));
1811 	}
1812 
1813 	return tcu::TestStatus::pass("Pass");
1814 }
1815 
findQueueFamiliesWithCaps(const InstanceInterface & vkInstance,VkPhysicalDevice physicalDevice,VkQueueFlags requiredCaps)1816 map<deUint32, VkQueueFamilyProperties> findQueueFamiliesWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps)
1817 {
1818 	const vector<VkQueueFamilyProperties>	queueProps				= getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
1819 	map<deUint32, VkQueueFamilyProperties>	queueFamilies;
1820 
1821 	for (deUint32 queueNdx = 0; queueNdx < static_cast<deUint32>(queueProps.size()); queueNdx++)
1822 	{
1823 		const VkQueueFamilyProperties&		queueFamilyProperties	= queueProps[queueNdx];
1824 
1825 		if ((queueFamilyProperties.queueFlags & requiredCaps) == requiredCaps)
1826 			queueFamilies[queueNdx] = queueFamilyProperties;
1827 	}
1828 
1829 	if (queueFamilies.empty())
1830 		TCU_THROW(NotSupportedError, "No matching queue found");
1831 
1832 	return queueFamilies;
1833 }
1834 
checkProtectedMemorySupport(Context & context)1835 void checkProtectedMemorySupport (Context& context)
1836 {
1837 	if (!context.contextSupports(vk::ApiVersion(0, 1, 1, 0)))
1838 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1839 
1840 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
1841 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1842 
1843 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1844 	{
1845 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1846 		DE_NULL,														// void*							pNext;
1847 		VK_FALSE														// VkBool32							protectedMemory;
1848 	};
1849 
1850 	VkPhysicalDeviceFeatures2				features2;
1851 	deMemset(&features2, 0, sizeof(features2));
1852 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1853 	features2.pNext													= &protectedMemoryFeature;
1854 
1855 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1856 	if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1857 		TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1858 }
1859 
createProtectedDeviceWithQueueConfig(Context & context,const std::vector<VkDeviceQueueCreateInfo> & queueCreateInfos,bool dumpExtraInfo=false)1860 Move<VkDevice> createProtectedDeviceWithQueueConfig (Context& context, const std::vector<VkDeviceQueueCreateInfo>& queueCreateInfos, bool dumpExtraInfo=false)
1861 {
1862 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1863 	const VkInstance						instance				= context.getInstance();
1864 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
1865 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1866 
1867 	if (dumpExtraInfo)
1868 	{
1869 		tcu::TestLog&						log						= context.getTestContext().getLog();
1870 
1871 		log << tcu::TestLog::Message << "Creating VkDevice with the following Queue configuration:" << tcu::TestLog::EndMessage;
1872 
1873 		for (size_t idx = 0; idx < queueCreateInfos.size(); idx++)
1874 		{
1875 			const VkDeviceQueueCreateInfo&	queueCreateInfo			= queueCreateInfos[idx];
1876 
1877 			log << tcu::TestLog::Message << "QueueCreateInfo " << idx << ": "
1878 				<< "flags: " << queueCreateInfo.flags << " "
1879 				<< "family: " << queueCreateInfo.queueFamilyIndex << " "
1880 				<< "count: " << queueCreateInfo.queueCount
1881 				<< tcu::TestLog::EndMessage;
1882 		}
1883 	}
1884 
1885 	// Protected memory features availability should be already checked at this point.
1886 	VkPhysicalDeviceProtectedMemoryFeatures	protectedMemoryFeature	=
1887 	{
1888 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType					sType;
1889 		DE_NULL,														// void*							pNext;
1890 		VK_TRUE															// VkBool32							protectedMemory;
1891 	};
1892 
1893 	VkPhysicalDeviceFeatures2				features2;
1894 	deMemset(&features2, 0, sizeof(features2));
1895 	features2.sType													= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1896 	features2.pNext													= &protectedMemoryFeature;
1897 
1898 #ifdef CTS_USES_VULKANSC
1899 	void* pNext														= DE_NULL;
1900 
1901 	VkDeviceObjectReservationCreateInfo memReservationInfo			= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1902 	memReservationInfo.pNext										= pNext;
1903 	pNext															= &memReservationInfo;
1904 
1905 	VkPhysicalDeviceVulkanSC10Features sc10Features					= createDefaultSC10Features();
1906 	sc10Features.pNext												= pNext;
1907 	pNext															= &sc10Features;
1908 #endif // CTS_USES_VULKANSC
1909 
1910 	const VkDeviceCreateInfo				deviceCreateInfo		=
1911 	{
1912 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							// VkStructureType					sType;
1913 #ifdef CTS_USES_VULKANSC
1914 		&sc10Features,													// const void*						pNext;
1915 #else
1916 		&features2,														// const void*						pNext;
1917 #endif // CTS_USES_VULKANSC
1918 		(VkDeviceCreateFlags)0u,										// VkDeviceCreateFlags				flags;
1919 		(deUint32)queueCreateInfos.size(),								// deUint32							queueCreateInfoCount;
1920 		queueCreateInfos.data(),										// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1921 		0,																// deUint32							enabledLayerCount;
1922 		DE_NULL,														// const char* const*				ppEnabledLayerNames;
1923 		0,																// deUint32							enabledExtensionCount;
1924 		DE_NULL,														// const char* const*				ppEnabledExtensionNames;
1925 		DE_NULL,														// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1926 	};
1927 
1928 	return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo);
1929 }
1930 
getDeviceQueue2WithOptions(const DeviceDriver & deviceDriver,const VkDevice device,VkDeviceQueueCreateFlags flags,deUint32 queueFamilyIndex,deUint32 queueIndex)1931 VkQueue getDeviceQueue2WithOptions (const DeviceDriver& deviceDriver, const VkDevice device, VkDeviceQueueCreateFlags flags, deUint32 queueFamilyIndex, deUint32 queueIndex)
1932 {
1933 	VkDeviceQueueInfo2						queueInfo2				=
1934 	{
1935 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,							// VkStructureType					sType;
1936 		DE_NULL,														// const void*						pNext;
1937 		flags,															// VkDeviceQueueCreateFlags			flags;
1938 		queueFamilyIndex,												// deUint32							queueFamilyIndex;
1939 		queueIndex,														// deUint32							queueIndex;
1940 	};
1941 
1942 	return getDeviceQueue2(deviceDriver, device, &queueInfo2);
1943 }
1944 
1945 struct QueueCreationInfo
1946 {
1947 	deUint32						familyIndex;
1948 	VkDeviceQueueCreateFlags		flags;
1949 	deUint32						count;
1950 };
1951 
runQueueCreationTestCombination(Context & context,tcu::ResultCollector & results,const std::vector<QueueCreationInfo> & testCombination,bool dumpExtraInfo=false)1952 bool runQueueCreationTestCombination (Context& context, tcu::ResultCollector& results, const std::vector<QueueCreationInfo>& testCombination, bool dumpExtraInfo=false)
1953 {
1954 	deUint32								sumQueueCount			= 0u;
1955 	for (const QueueCreationInfo& info : testCombination)
1956 	{
1957 		sumQueueCount += info.count;
1958 	}
1959 
1960 	// 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).
1961 	const vector<float>						queuePriorities			(sumQueueCount, 1.0f);
1962 	vector<VkDeviceQueueCreateInfo>			queueCreateInfo;
1963 
1964 	for (const QueueCreationInfo& info : testCombination)
1965 	{
1966 		const VkDeviceQueueCreateInfo		queueInfo				=
1967 		{
1968 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,						// VkStructureType					sType;
1969 			DE_NULL,														// const void*						pNext;
1970 			info.flags,														// VkDeviceQueueCreateFlags			flags;
1971 			info.familyIndex,												// deUint32							queueFamilyIndex;
1972 			info.count,														// deUint32							queueCount;
1973 			queuePriorities.data(),											// const float*						pQueuePriorities;
1974 		};
1975 		queueCreateInfo.push_back(queueInfo);
1976 	}
1977 
1978 	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1979 	const VkInstance						instance				= context.getInstance();
1980 
1981 	const Unique<VkDevice>					device					(createProtectedDeviceWithQueueConfig(context, queueCreateInfo, dumpExtraInfo));
1982 	const DeviceDriver						deviceDriver			(platformInterface, instance, *device, context.getUsedApiVersion());
1983 
1984 	for (const QueueCreationInfo& info : testCombination)
1985 	{
1986 		// Query Queues (based on the test configuration)
1987 		for (deUint32 queueIdx = 0; queueIdx < info.count; queueIdx++)
1988 		{
1989 			const string					message					= "(queueFamilyIndex: " + de::toString(info.familyIndex) + ", flags: " + de::toString(info.flags) + ", queue Index: " + de::toString(queueIdx) + ")";
1990 			const VkQueue					queue					= getDeviceQueue2WithOptions(deviceDriver, *device, info.flags, info.familyIndex, queueIdx);
1991 
1992 			if (queue != DE_NULL)
1993 			{
1994 				VK_CHECK(deviceDriver.queueWaitIdle(queue));
1995 				results.addResult(QP_TEST_RESULT_PASS, "Found Queue. " + message);
1996 			} else
1997 				results.fail("Unable to access the Queue. " + message);
1998 		}
1999 	}
2000 
2001 	return results.getResult() == QP_TEST_RESULT_PASS;
2002 }
2003 
createDeviceQueue2WithTwoQueuesSmokeTest(Context & context)2004 tcu::TestStatus createDeviceQueue2WithTwoQueuesSmokeTest (Context& context)
2005 {
2006 	const bool								dumpExtraInfo			= true;
2007 
2008 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2009 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2010 	tcu::TestLog&							log						= context.getTestContext().getLog();
2011 
2012 	vector<VkQueueFamilyProperties>			queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
2013 
2014 	// Find the first protected-capabale queue with a queueCount >= 2 and use it for testing (smoke test)
2015 	constexpr deUint32						MAX_DEUINT32			= std::numeric_limits<deUint32>::max();
2016 	deUint32								queueFamilyIndex		= MAX_DEUINT32;
2017 	const VkQueueFlags						requiredCaps			= VK_QUEUE_PROTECTED_BIT;
2018 	const deUint32							requiredQueueCount		= 2;
2019 
2020 	for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); queueNdx++)
2021 	{
2022 		if ((queueFamilyProperties[queueNdx].queueFlags & requiredCaps) == requiredCaps && queueFamilyProperties[queueNdx].queueCount >= requiredQueueCount)
2023 		{
2024 			queueFamilyIndex = queueNdx;
2025 			break;
2026 		}
2027 	}
2028 
2029 	if (queueFamilyIndex == MAX_DEUINT32)
2030 		TCU_THROW(NotSupportedError, "Unable to find a queue family that is protected-capable and supports more than one queue.");
2031 
2032 	if (dumpExtraInfo)
2033 		log << tcu::TestLog::Message << "Selected VkQueueFamilyProperties index: " << queueFamilyIndex << tcu::TestLog::EndMessage;
2034 
2035 	// Use the previously selected queue family index to create 1 protected-capable and 1 unprotected queue.
2036 	const QueueCreationInfo					protectedQueueConfig	= { queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, 1 };
2037 	const QueueCreationInfo					unprotectedQueueConfig	= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, 1 };
2038 
2039 	tcu::ResultCollector					results					(log);
2040 	const std::vector<QueueCreationInfo>	testCombination			= { protectedQueueConfig, unprotectedQueueConfig };
2041 	bool									success					= runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2042 
2043 	if (success)
2044 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2045 
2046 	return tcu::TestStatus(results.getResult(), results.getMessage());
2047 }
2048 
createDeviceQueue2WithAllProtectedQueues(Context & context)2049 tcu::TestStatus createDeviceQueue2WithAllProtectedQueues (Context& context)
2050 {
2051 	const bool								dumpExtraInfo			= true;
2052 
2053 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2054 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2055 
2056 	// Select only protected-capable queue families
2057 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2058 
2059 	bool									success					= true;
2060 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2061 
2062 	// For each protected-capable queue family, create a device with the max number of queues available and all queues created as protected-capable.
2063 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2064 	{
2065 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2066 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2067 
2068 		const QueueCreationInfo				protectedQueueConfig	= { queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, queueCount };
2069 		const vector<QueueCreationInfo>		testCombination			= { protectedQueueConfig };
2070 
2071 		// Run current confugurations.
2072 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2073 	}
2074 
2075 	if (success)
2076 		return tcu::TestStatus::pass("All queues were queried correctly.");
2077 
2078 	return tcu::TestStatus(results.getResult(), results.getMessage());
2079 }
2080 
createDeviceQueue2WithAllUnprotectedQueues(Context & context)2081 tcu::TestStatus createDeviceQueue2WithAllUnprotectedQueues (Context& context)
2082 {
2083 	const bool								dumpExtraInfo			= true;
2084 
2085 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2086 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2087 
2088 	// Select all queue families with or without protected bit
2089 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, 0);
2090 
2091 	bool									success					= true;
2092 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2093 
2094 	// For each Queue Family create the max number of unprotected Queues.
2095 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2096 	{
2097 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2098 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2099 
2100 		const QueueCreationInfo				unprotectedQueueConfig	= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, queueCount };
2101 		const vector<QueueCreationInfo>		testCombination			= { unprotectedQueueConfig };
2102 
2103 		// Run current confugurations.
2104 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2105 	}
2106 
2107 	if (success)
2108 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2109 
2110 	return tcu::TestStatus(results.getResult(), results.getMessage());
2111 }
2112 
2113 typedef vector<QueueCreationInfo>					DeviceQueueConfig;
2114 typedef map<deUint32, vector<DeviceQueueConfig> >	QueueFamilyConfigurations;
2115 
buildQueueConfigurations(const map<deUint32,VkQueueFamilyProperties> & queueFamilyProperties)2116 QueueFamilyConfigurations buildQueueConfigurations (const map<deUint32, VkQueueFamilyProperties>& queueFamilyProperties)
2117 {
2118 	QueueFamilyConfigurations				queuesPerFamily;
2119 
2120 	// Build up the queue creation combinations (N protected and M unprotected queues where N+M == queueFamily.queueCount)
2121 	// on each protected-capable queue family
2122 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamily : queueFamilyProperties)
2123 	{
2124 		const deUint32						queueFamilyIndex		= queueFamily.first;
2125 		const VkQueueFamilyProperties		queueFamilyProperty		= queueFamily.second;
2126 		const deUint32						allowedQueueCount		= queueFamilyProperty.queueCount;
2127 
2128 		for (deUint32 splitCount = 0; splitCount <= allowedQueueCount; splitCount++)
2129 		{
2130 			const deUint32					protectedQueuesCount	= allowedQueueCount - splitCount;
2131 			const deUint32					unprotectedQueuesCount	= splitCount;
2132 
2133 			vector<QueueCreationInfo>		testCombination			= { };
2134 
2135 			if (protectedQueuesCount)
2136 				testCombination.push_back({ queueFamilyIndex, VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, protectedQueuesCount });
2137 
2138 			if (unprotectedQueuesCount)
2139 				testCombination.push_back({ queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, unprotectedQueuesCount });
2140 
2141 			queuesPerFamily[queueFamilyIndex].push_back(testCombination);
2142 		}
2143 	}
2144 
2145 	return queuesPerFamily;
2146 }
2147 
createDeviceQueue2WithNProtectedAndMUnprotectedQueues(Context & context)2148 tcu::TestStatus createDeviceQueue2WithNProtectedAndMUnprotectedQueues (Context& context)
2149 {
2150 	const bool								dumpExtraInfo			= true;
2151 
2152 	tcu::TestLog&							log						= context.getTestContext().getLog();
2153 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2154 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2155 
2156 	// Select only protected-capable queue families
2157 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2158 
2159 	// Build all protected-unprotected splits per queue family.
2160 	QueueFamilyConfigurations				queuesPerFamily			= buildQueueConfigurations(queueFamilyProperties);
2161 	vector<DeviceQueueConfig>				queueCreateCombinations;
2162 
2163 	// Transform configurations to a simple vector
2164 	for (const auto& item : queuesPerFamily)
2165 	{
2166 		const vector<DeviceQueueConfig>&	queueConfigs			= item.second;
2167 
2168 		std::copy(queueConfigs.begin(), queueConfigs.end(), std::back_inserter(queueCreateCombinations));
2169 	}
2170 
2171 	if (dumpExtraInfo)
2172 	{
2173 		for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2174 		{
2175 			ostringstream				queuesInfo;
2176 			for (const QueueCreationInfo& queueInfo : testCombination)
2177 			{
2178 				queuesInfo << "(Queue family: " << queueInfo.familyIndex << ", flags: " << queueInfo.flags << ", count: " << queueInfo.count << ")";
2179 			}
2180 
2181 			log << tcu::TestLog::Message << "Test Combination: " << queuesInfo.str() << tcu::TestLog::EndMessage;
2182 		}
2183 	}
2184 
2185 	bool									success					= true;
2186 	tcu::ResultCollector					results					(log);
2187 
2188 	// Based on the protected-unprotected queue combinations, run each test case.
2189 	for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2190 	{
2191 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2192 	}
2193 
2194 	// Run the test cases also in reverse order (so the unprotected queue creation info is at the start of the VkDeviceQueueCreateInfo vector).
2195 	for (vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2196 	{
2197 		std::reverse(testCombination.begin(), testCombination.end());
2198 
2199 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2200 	}
2201 
2202 	if (success)
2203 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2204 
2205 	return tcu::TestStatus(results.getResult(), results.getMessage());
2206 }
2207 
createDeviceQueue2WithMultipleQueueCombinations(Context & context)2208 tcu::TestStatus createDeviceQueue2WithMultipleQueueCombinations (Context& context)
2209 {
2210 	const bool								dumpExtraInfo			= true;
2211 
2212 	tcu::TestLog&							log						= context.getTestContext().getLog();
2213 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2214 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2215 
2216 	// Select only protected-capable queue families.
2217 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, VK_QUEUE_PROTECTED_BIT);
2218 
2219 	// Build all protected-unprotected splits per queue family.
2220 	QueueFamilyConfigurations				queuesPerFamily			= buildQueueConfigurations(queueFamilyProperties);
2221 
2222 	// Build up all combinations of queue families from the previous mapping.
2223 	vector<DeviceQueueConfig>				queueCreateCombinations;
2224 	{
2225 		vector<deUint32>					itemIndices				(queuesPerFamily.size(), 0u);
2226 
2227 		// Calculate the max number of combinations.
2228 		auto								multiplyConfigCounts	= [](deUint32& count, const typename QueueFamilyConfigurations::value_type& item) { return count * item.second.size(); };
2229 		const deUint32						itemCount				= accumulate(queuesPerFamily.begin(), queuesPerFamily.end(), 1u, multiplyConfigCounts);
2230 
2231 		for (deUint32 count = 0u; count < itemCount; count++)
2232 		{
2233 			DeviceQueueConfig				testCombination;
2234 
2235 			// Select queue configurations from each family
2236 			for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(itemIndices.size()); ndx++)
2237 			{
2238 				const auto&					familyConfigurations	= queuesPerFamily[ndx];
2239 				const DeviceQueueConfig&	targetQueueConfig		= familyConfigurations[ itemIndices[ndx] ];
2240 
2241 				std::copy(targetQueueConfig.begin(), targetQueueConfig.end(), std::back_inserter(testCombination));
2242 			}
2243 
2244 			queueCreateCombinations.push_back(testCombination);
2245 
2246 			// Increment the indices.
2247 			for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(itemIndices.size()); ndx++)
2248 			{
2249 				itemIndices[ndx]++;
2250 				if (itemIndices[ndx] < queuesPerFamily[ndx].size())
2251 				{
2252 					break;
2253 				}
2254 
2255 				// "overflow" happened in the given index, restart from zero and increment the next item index (restart loop).
2256 				itemIndices[ndx] = 0;
2257 			}
2258 		}
2259 	}
2260 
2261 	if (dumpExtraInfo)
2262 	{
2263 		for (const vector<QueueCreationInfo>& testCombination : queueCreateCombinations)
2264 		{
2265 			ostringstream					queuesInfo;
2266 			for (const QueueCreationInfo& queueInfo : testCombination)
2267 			{
2268 				queuesInfo << "(Queue family: " << queueInfo.familyIndex << ", flags: " << queueInfo.flags << ", count: " << queueInfo.count << ")";
2269 			}
2270 
2271 			log << tcu::TestLog::Message << "Test Combination: " << queuesInfo.str() << tcu::TestLog::EndMessage;
2272 		}
2273 	}
2274 
2275 	bool									success					= true;
2276 	tcu::ResultCollector					results					(log);
2277 
2278 	// Based on the protected-unprotected queue combinations above run each test case.
2279 	for (const DeviceQueueConfig& testCombination : queueCreateCombinations)
2280 	{
2281 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2282 	}
2283 
2284 	// Run the test cases also in reverse queue order (so the unprotected queue creation info is at the start of the VkDeviceQueueCreateInfo vector).
2285 	for (DeviceQueueConfig& testCombination : queueCreateCombinations)
2286 	{
2287 		std::reverse(testCombination.begin(), testCombination.end());
2288 
2289 		success = success && runQueueCreationTestCombination(context, results, testCombination, dumpExtraInfo);
2290 	}
2291 
2292 	if (success)
2293 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2294 
2295 	return tcu::TestStatus(results.getResult(), results.getMessage());
2296 }
2297 
createDeviceQueue2WithAllFamilies(Context & context)2298 tcu::TestStatus createDeviceQueue2WithAllFamilies (Context& context)
2299 {
2300 	const bool								dumpExtraInfo			= true;
2301 
2302 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2303 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2304 
2305 	// Get all queue families
2306 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, (VkDeviceQueueCreateFlags)0u);
2307 
2308 	// Create test configuration where for each queue family the maximum number of queues are created.
2309 	vector<QueueCreationInfo>				queueConfigurations;
2310 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2311 	{
2312 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2313 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2314 
2315 		const QueueCreationInfo				queueConfig				= { queueFamilyIndex, (VkDeviceQueueCreateFlags)0u, queueCount };
2316 
2317 		queueConfigurations.push_back(queueConfig);
2318 	}
2319 
2320 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2321 
2322 	// Execute test to see if it possible to have all queue families created at the same time.
2323 	bool									success					= runQueueCreationTestCombination(context, results, queueConfigurations, dumpExtraInfo);
2324 
2325 	if (success)
2326 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2327 
2328 	return tcu::TestStatus(results.getResult(), results.getMessage());
2329 }
2330 
createDeviceQueue2WithAllFamiliesProtected(Context & context)2331 tcu::TestStatus createDeviceQueue2WithAllFamiliesProtected (Context& context)
2332 {
2333 	const bool								dumpExtraInfo			= true;
2334 
2335 	const InstanceInterface&				instanceDriver			= context.getInstanceInterface();
2336 	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
2337 
2338 	// Get all queue families
2339 	map<deUint32, VkQueueFamilyProperties>	queueFamilyProperties	= findQueueFamiliesWithCaps(instanceDriver, physicalDevice, (VkDeviceQueueCreateFlags)0u);
2340 
2341 	// Create test configuration where for each queue family the maximum number of queues are created.
2342 	// If a queue supports protected memory then create a protected-capable queue.
2343 	vector<QueueCreationInfo>				queueConfigurations;
2344 	for (const pair<deUint32, VkQueueFamilyProperties> queueFamilyProperty : queueFamilyProperties)
2345 	{
2346 		const deUint32						queueFamilyIndex		= queueFamilyProperty.first;
2347 		const deUint32						queueCount				= queueFamilyProperty.second.queueCount;
2348 
2349 		VkDeviceQueueCreateFlags			useFlags				= (VkDeviceQueueCreateFlags)0u;
2350 		if ((queueFamilyProperty.second.queueFlags & VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT) == VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT)
2351 			useFlags |= VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
2352 
2353 		const QueueCreationInfo				queueConfig				= { queueFamilyIndex, useFlags, queueCount };
2354 
2355 		queueConfigurations.push_back(queueConfig);
2356 	}
2357 
2358 	tcu::ResultCollector					results					(context.getTestContext().getLog());
2359 
2360 	// Execute test to see if it possible to have all queue families created at the same time.
2361 	bool									success					= runQueueCreationTestCombination(context, results, queueConfigurations, dumpExtraInfo);
2362 
2363 	if (success)
2364 		return tcu::TestStatus::pass("All Queues were queried correctly.");
2365 
2366 	return tcu::TestStatus(results.getResult(), results.getMessage());
2367 }
2368 
2369 #ifndef CTS_USES_VULKANSC
2370 // Allocation tracking utilities
2371 struct	AllocTrack
2372 {
2373 	bool						active;
2374 	bool						wasAllocated;
2375 	void*						alignedStartAddress;
2376 	char*						actualStartAddress;
2377 	size_t						requestedSizeBytes;
2378 	size_t						actualSizeBytes;
2379 	VkSystemAllocationScope		allocScope;
2380 	deUint64					userData;
2381 
AllocTrackvkt::api::__anond8509dc10111::AllocTrack2382 	AllocTrack()
2383 		: active				(false)
2384 		, wasAllocated			(false)
2385 		, alignedStartAddress	(DE_NULL)
2386 		, actualStartAddress	(DE_NULL)
2387 		, requestedSizeBytes	(0)
2388 		, actualSizeBytes		(0)
2389 		, allocScope			(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)
2390 		, userData(0)			{}
2391 };
2392 
2393 // Global vector to track allocations. This will be resized before each test and emptied after
2394 // However, we have to globally define it so the allocation callback functions work properly
2395 std::vector<AllocTrack>	g_allocatedVector;
2396 bool					g_intentionalFailEnabled	= false;
2397 deUint32				g_intenionalFailIndex		= 0;
2398 deUint32				g_intenionalFailCount		= 0;
2399 size_t					g_allocationsCount			= 0;
2400 
freeAllocTracker(void)2401 void freeAllocTracker(void)
2402 {
2403 	g_allocatedVector.clear();
2404 	g_allocationsCount = 0;
2405 }
2406 
initAllocTracker(size_t size,deUint32 intentionalFailIndex=(deUint32)~0)2407 void initAllocTracker (size_t size, deUint32 intentionalFailIndex = (deUint32)~0)
2408 {
2409 	if (g_allocatedVector.size() > 0)
2410 		freeAllocTracker();
2411 
2412 	g_allocatedVector.resize(size);
2413 
2414 	if (intentionalFailIndex != (deUint32)~0)
2415 	{
2416 		g_intentionalFailEnabled	= true;
2417 		g_intenionalFailIndex		= intentionalFailIndex;
2418 		g_intenionalFailCount		= 0;
2419 	}
2420 	else
2421 	{
2422 		g_intentionalFailEnabled	= false;
2423 		g_intenionalFailIndex		= 0;
2424 		g_intenionalFailCount		= 0;
2425 	}
2426 
2427 	g_allocationsCount = 0;
2428 }
2429 
isAllocTrackerEmpty()2430 bool isAllocTrackerEmpty ()
2431 {
2432 	bool success		= true;
2433 	bool wasAllocated	= false;
2434 
2435 	for (deUint32 vectorIdx	= 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2436 	{
2437 		if (g_allocatedVector[vectorIdx].active)
2438 			success = false;
2439 		else if (!wasAllocated && g_allocatedVector[vectorIdx].wasAllocated)
2440 			wasAllocated = true;
2441 	}
2442 
2443 	if (!g_intentionalFailEnabled && !wasAllocated)
2444 		success = false;
2445 
2446 	return success;
2447 }
2448 
allocCallbackFunc(void * pUserData,size_t size,size_t alignment,VkSystemAllocationScope allocationScope)2449 VKAPI_ATTR void *VKAPI_CALL allocCallbackFunc (void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
2450 {
2451 	if (g_intentionalFailEnabled)
2452 		if (++g_intenionalFailCount >= g_intenionalFailIndex)
2453 			return DE_NULL;
2454 
2455 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2456 	{
2457 		if (!g_allocatedVector[vectorIdx].active)
2458 		{
2459 			g_allocatedVector[vectorIdx].requestedSizeBytes		= size;
2460 			g_allocatedVector[vectorIdx].actualSizeBytes		= size + (alignment - 1);
2461 			g_allocatedVector[vectorIdx].alignedStartAddress	= DE_NULL;
2462 			g_allocatedVector[vectorIdx].actualStartAddress		= new char[g_allocatedVector[vectorIdx].actualSizeBytes];
2463 
2464 			if (g_allocatedVector[vectorIdx].actualStartAddress != DE_NULL)
2465 			{
2466 				deUint64 addr	=	(deUint64)g_allocatedVector[vectorIdx].actualStartAddress;
2467 				addr			+=	(alignment - 1);
2468 				addr			&=	~(alignment - 1);
2469 				g_allocatedVector[vectorIdx].alignedStartAddress	= (void *)addr;
2470 				g_allocatedVector[vectorIdx].allocScope				= allocationScope;
2471 				g_allocatedVector[vectorIdx].userData				= (deUint64)pUserData;
2472 				g_allocatedVector[vectorIdx].active					= true;
2473 				g_allocatedVector[vectorIdx].wasAllocated			= true;
2474 			}
2475 
2476 			g_allocationsCount++;
2477 			return g_allocatedVector[vectorIdx].alignedStartAddress;
2478 		}
2479 	}
2480 	return DE_NULL;
2481 }
2482 
freeCallbackFunc(void * pUserData,void * pMemory)2483 VKAPI_ATTR void VKAPI_CALL freeCallbackFunc (void *pUserData, void *pMemory)
2484 {
2485 	DE_UNREF(pUserData);
2486 
2487 	for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2488 	{
2489 		if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pMemory)
2490 		{
2491 			delete[] g_allocatedVector[vectorIdx].actualStartAddress;
2492 			g_allocatedVector[vectorIdx].active = false;
2493 			break;
2494 		}
2495 	}
2496 }
2497 
reallocCallbackFunc(void * pUserData,void * pOriginal,size_t size,size_t alignment,VkSystemAllocationScope allocationScope)2498 VKAPI_ATTR void *VKAPI_CALL reallocCallbackFunc (void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
2499 {
2500 	if (pOriginal != DE_NULL)
2501 	{
2502 		for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
2503 		{
2504 			if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pOriginal)
2505 			{
2506 				if (size == 0)
2507 				{
2508 					freeCallbackFunc(pUserData, pOriginal);
2509 					return DE_NULL;
2510 				}
2511 				else if (size < g_allocatedVector[vectorIdx].requestedSizeBytes)
2512 					return pOriginal;
2513 				else
2514 				{
2515 					void *pNew = allocCallbackFunc(pUserData, size, alignment, allocationScope);
2516 
2517 					if (pNew != DE_NULL)
2518 					{
2519 						size_t copySize = size;
2520 
2521 						if (g_allocatedVector[vectorIdx].requestedSizeBytes < size)
2522 							copySize = g_allocatedVector[vectorIdx].requestedSizeBytes;
2523 
2524 						memcpy(pNew, pOriginal, copySize);
2525 						freeCallbackFunc(pUserData, pOriginal);
2526 					}
2527 					return pNew;
2528 				}
2529 			}
2530 		}
2531 		return DE_NULL;
2532 	}
2533 	else
2534 		return allocCallbackFunc(pUserData, size, alignment, allocationScope);
2535 }
2536 
createInstanceDeviceIntentionalAllocFail(Context & context)2537 tcu::TestStatus createInstanceDeviceIntentionalAllocFail (Context& context)
2538 {
2539 	const PlatformInterface&	vkp					= context.getPlatformInterface();
2540 	const deUint32				chosenDevice		= context.getTestContext().getCommandLine().getVKDeviceId() - 1;
2541 	VkInstance					instance			= DE_NULL;
2542 	VkDevice					device				= DE_NULL;
2543 	deUint32					physicalDeviceCount	= 0;
2544 	deUint32					queueFamilyCount	= 0;
2545 	deUint32					queueFamilyIndex	= 0;
2546 	const float					queuePriority		= 0.0f;
2547 	const VkAllocationCallbacks	allocationCallbacks	=
2548 	{
2549 		DE_NULL,								// userData
2550 		allocCallbackFunc,						// pfnAllocation
2551 		reallocCallbackFunc,					// pfnReallocation
2552 		freeCallbackFunc,						// pfnFree
2553 		DE_NULL,								// pfnInternalAllocation
2554 		DE_NULL									// pfnInternalFree
2555 	};
2556 	const VkApplicationInfo		appInfo				=
2557 	{
2558 		VK_STRUCTURE_TYPE_APPLICATION_INFO,		// sType
2559 		DE_NULL,								// pNext
2560 		"appName",								// pApplicationName
2561 		0u,										// applicationVersion
2562 		"engineName",							// pEngineName
2563 		0u,										// engineVersion
2564 		VK_API_VERSION_1_0						// apiVersion
2565 	};
2566 
2567 	const VkInstanceCreateInfo	instanceCreateInfo	=
2568 	{
2569 		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// sType
2570 		DE_NULL,								// pNext
2571 		(VkInstanceCreateFlags)0u,				// flags
2572 		&appInfo,								// pApplicationInfo
2573 		0u,										// enabledLayerCount
2574 		DE_NULL,								// ppEnabledLayerNames
2575 		0u,										// enabledExtensionCount
2576 		DE_NULL									// ppEnabledExtensionNames
2577 	};
2578 
2579 	deUint32					failIndex			= 0;
2580 	VkResult					result				= VK_SUCCESS;
2581 	size_t						max_allowed_alloc	= 0;
2582 
2583 	do
2584 	{
2585 		if (max_allowed_alloc == 0)
2586 		{
2587 			if (result != VK_SUCCESS)
2588 				return tcu::TestStatus::fail("Could not create instance and device");
2589 
2590 			initAllocTracker(99999);
2591 		}
2592 		else
2593 		{
2594 			initAllocTracker(max_allowed_alloc, failIndex++);
2595 
2596 			if (failIndex >= static_cast<deUint32>(max_allowed_alloc))
2597 				return tcu::TestStatus::fail("Out of retries, could not create instance and device");
2598 		}
2599 
2600 		// if the number of allocations the driver makes is large, we may end up
2601 		// taking more than the watchdog timeout. touch here to avoid spurious
2602 		// failures.
2603 		if (failIndex % 128 == 0)
2604 			context.getTestContext().touchWatchdog();
2605 
2606 		result = vkp.createInstance(&instanceCreateInfo, &allocationCallbacks, &instance);
2607 
2608 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2609 		{
2610 			if (!isAllocTrackerEmpty())
2611 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2612 
2613 			freeAllocTracker();
2614 			continue;
2615 		}
2616 		else if (result != VK_SUCCESS)
2617 			return tcu::TestStatus::fail("createInstance returned " + de::toString(result));
2618 
2619 		const InstanceDriver		instanceDriver	(vkp, instance);
2620 		const InstanceInterface&	vki				(instanceDriver);
2621 
2622 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, DE_NULL);
2623 
2624 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2625 		{
2626 			vki.destroyInstance(instance, &allocationCallbacks);
2627 
2628 			if (!isAllocTrackerEmpty())
2629 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2630 
2631 			freeAllocTracker();
2632 			continue;
2633 		}
2634 		else if (result != VK_SUCCESS)
2635 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
2636 
2637 		vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
2638 
2639 		result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
2640 
2641 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2642 		{
2643 			vki.destroyInstance(instance, &allocationCallbacks);
2644 
2645 			if (!isAllocTrackerEmpty())
2646 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2647 
2648 			freeAllocTracker();
2649 			continue;
2650 		}
2651 		else if (result != VK_SUCCESS)
2652 			return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
2653 
2654 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, DE_NULL);
2655 
2656 		if (queueFamilyCount == 0u)
2657 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
2658 
2659 		vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
2660 
2661 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, queueFamilies.data());
2662 
2663 		if (queueFamilyCount == 0u)
2664 			return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
2665 
2666 		for (deUint32 i = 0; i < queueFamilyCount; i++)
2667 		{
2668 			if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
2669 			{
2670 				queueFamilyIndex = i;
2671 				break;
2672 			}
2673 		}
2674 
2675 		const VkDeviceQueueCreateInfo	deviceQueueCreateInfo	=
2676 		{
2677 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// sType
2678 			DE_NULL,									// pNext
2679 			(VkDeviceQueueCreateFlags)0u,				// flags
2680 			queueFamilyIndex,							// queueFamilyIndex
2681 			1u,											// queueCount
2682 			&queuePriority								// pQueuePriorities
2683 		};
2684 
2685 		void* pNext												= DE_NULL;
2686 #ifdef CTS_USES_VULKANSC
2687 		VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
2688 		memReservationInfo.pNext								= pNext;
2689 		pNext													= &memReservationInfo;
2690 
2691 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
2692 		sc10Features.pNext										= pNext;
2693 		pNext													= &sc10Features;
2694 #endif // CTS_USES_VULKANSC
2695 
2696 		const VkDeviceCreateInfo		deviceCreateInfo		=
2697 		{
2698 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		// sType
2699 			pNext,										// pNext
2700 			(VkDeviceCreateFlags)0u,					// flags
2701 			1u,											// queueCreateInfoCount
2702 			&deviceQueueCreateInfo,						// pQueueCreateInfos
2703 			0u,											// enabledLayerCount
2704 			DE_NULL,									// ppEnabledLayerNames
2705 			0u,											// enabledExtensionCount
2706 			DE_NULL,									// ppEnabledExtensionNames
2707 			DE_NULL										// pEnabledFeatures
2708 		};
2709 
2710 		result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vki, physicalDevices[chosenDevice], &deviceCreateInfo, &allocationCallbacks, &device);
2711 
2712 		if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
2713 		{
2714 			vki.destroyInstance(instance, &allocationCallbacks);
2715 
2716 			if (!isAllocTrackerEmpty())
2717 				return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
2718 
2719 			freeAllocTracker();
2720 			continue;
2721 		}
2722 		else if (result != VK_SUCCESS)
2723 			return tcu::TestStatus::fail("VkCreateDevice returned " + de::toString(result));
2724 
2725 		DeviceDriver(vkp, instance, device, context.getUsedApiVersion()).destroyDevice(device, &allocationCallbacks);
2726 		vki.destroyInstance(instance, &allocationCallbacks);
2727 		if (max_allowed_alloc == 0)
2728 		{
2729 			max_allowed_alloc	= g_allocationsCount + 100;
2730 			result				= VK_ERROR_OUT_OF_HOST_MEMORY;
2731 		}
2732 		freeAllocTracker();
2733 	}
2734 	while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
2735 
2736 	return tcu::TestStatus::pass("Pass");
2737 }
2738 
2739 #endif // CTS_USES_VULKANSC
2740 
2741 } // anonymous
2742 
addFunctionCaseInNewSubgroup(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,const std::string & subgroupName,FunctionInstance0::Function testFunc)2743 static inline void addFunctionCaseInNewSubgroup (
2744 	tcu::TestContext&			testCtx,
2745 	tcu::TestCaseGroup*			group,
2746 	const std::string&			subgroupName,
2747 	FunctionInstance0::Function		testFunc)
2748 {
2749 	de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str()));
2750 	addFunctionCase(subgroup.get(), "basic", testFunc);
2751 	group->addChild(subgroup.release());
2752 }
2753 
addFunctionCaseInNewSubgroup(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,const std::string & subgroupName,FunctionSupport0::Function checkSupport,FunctionInstance0::Function testFunc)2754 static inline void addFunctionCaseInNewSubgroup (
2755 	tcu::TestContext&			testCtx,
2756 	tcu::TestCaseGroup*			group,
2757 	const std::string&			subgroupName,
2758 	FunctionSupport0::Function		checkSupport,
2759 	FunctionInstance0::Function		testFunc)
2760 {
2761 	de::MovePtr<tcu::TestCaseGroup> subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str()));
2762 	addFunctionCase(subgroup.get(), "basic", checkSupport, testFunc);
2763 	group->addChild(subgroup.release());
2764 }
2765 
2766 template<typename Arg0>
addFunctionCaseInNewSubgroup(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,const std::string & subgroupName,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)2767 static void addFunctionCaseInNewSubgroup (
2768 	tcu::TestContext&							testCtx,
2769 	tcu::TestCaseGroup*							group,
2770 	const std::string&							subgroupName,
2771 	typename FunctionSupport1<Arg0>::Function	checkSupport,
2772 	typename FunctionInstance1<Arg0>::Function	testFunc,
2773 	Arg0										arg0)
2774 {
2775 	de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str()));
2776 	subgroup->addChild(createFunctionCase<Arg0>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "basic", checkSupport, testFunc, arg0));
2777 	group->addChild(subgroup.release());
2778 }
2779 
createDeviceInitializationTests(tcu::TestContext & testCtx)2780 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
2781 {
2782 	de::MovePtr<tcu::TestCaseGroup>	deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init"));
2783 
2784 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_name_version",			createInstanceTest);
2785 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_invalid_api_version",		createInstanceWithInvalidApiVersionTest);
2786 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_null_appinfo",			createInstanceWithNullApplicationInfoTest);
2787 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_unsupported_extensions",	createInstanceWithUnsupportedExtensionsTest);
2788 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_extension_name_abuse",	createInstanceWithExtensionNameAbuseTest);
2789 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_layer_name_abuse",		createInstanceWithLayerNameAbuseTest);
2790 #ifndef CTS_USES_VULKANSC
2791 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "enumerate_devices_alloc_leak",			enumerateDevicesAllocLeakTest);
2792 #endif // CTS_USES_VULKANSC
2793 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device",							createDeviceTest);
2794 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_multiple_devices",					createMultipleDevicesTest);
2795 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_unsupported_extensions",	createDeviceWithUnsupportedExtensionsTest);
2796 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_various_queue_counts",		createDeviceWithVariousQueueCountsTest);
2797 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority",		checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, false);
2798 #ifndef CTS_USES_VULKANSC
2799 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_khr",		checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, true);
2800 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query",		checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, false);
2801 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query_khr",	checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, true);
2802 #endif // CTS_USES_VULKANSC
2803 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_features2",					createDeviceFeatures2Test);
2804 	{
2805 		de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, "create_device_unsupported_features"));
2806 		addFunctionCase(subgroup.get(), "core", createDeviceWithUnsupportedFeaturesTest);
2807 		addSeparateUnsupportedFeatureTests(subgroup.get());
2808 		deviceInitializationTests->addChild(subgroup.release());
2809 	}
2810 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2",						createDeviceQueue2Test);
2811 #ifndef CTS_USES_VULKANSC
2812 	// Removed because in main process this test does not really create any instance nor device and functions creating it always return VK_SUCCESS
2813 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_device_intentional_alloc_fail",createInstanceDeviceIntentionalAllocFail);
2814 #endif // CTS_USES_VULKANSC
2815 
2816 	// Tests using a single Queue Family when creating a device.
2817 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_two_queues",				checkProtectedMemorySupport, createDeviceQueue2WithTwoQueuesSmokeTest);
2818 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_protected",			checkProtectedMemorySupport, createDeviceQueue2WithAllProtectedQueues);
2819 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_unprotected",		checkProtectedMemorySupport, createDeviceQueue2WithAllUnprotectedQueues);
2820 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_split",					checkProtectedMemorySupport, createDeviceQueue2WithNProtectedAndMUnprotectedQueues);
2821 
2822 	// Tests using multiple Queue Families when creating a device.
2823 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_families",			checkProtectedMemorySupport, createDeviceQueue2WithAllFamilies);
2824 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_families_protected",	checkProtectedMemorySupport, createDeviceQueue2WithAllFamiliesProtected);
2825 	addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2_all_combinations",		checkProtectedMemorySupport, createDeviceQueue2WithMultipleQueueCombinations);
2826 
2827 	return deviceInitializationTests.release();
2828 }
2829 
2830 } // api
2831 } // vkt
2832