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