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