Fix global priority tests
[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
40 #include "tcuTestLog.hpp"
41 #include "tcuResultCollector.hpp"
42 #include "tcuCommandLine.hpp"
43
44 #include "deUniquePtr.hpp"
45 #include "deStringUtil.hpp"
46
47 #include <vector>
48 #include <set>
49
50 namespace vkt
51 {
52 namespace api
53 {
54
55 namespace
56 {
57
58 using namespace vk;
59 using namespace std;
60 using std::vector;
61 using tcu::TestLog;
62
63 tcu::TestStatus createInstanceTest (Context& context)
64 {
65         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
66         tcu::ResultCollector            resultCollector                 (log);
67         const char*                                     appNames[]                              = { "appName", DE_NULL, "",  "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" };
68         const char*                                     engineNames[]                   = { "engineName", DE_NULL, "",  "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" };
69         const int                                       patchNumbers[]                  = { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 };
70         const deUint32                          appVersions[]                   = { 0, 1, (deUint32)-1 };
71         const deUint32                          engineVersions[]                = { 0, 1, (deUint32)-1 };
72         const deUint32                          apiVersion                              = context.getUsedApiVersion();
73         vector<VkApplicationInfo>       appInfos;
74
75         // test over appName
76         for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++)
77         {
78                 const VkApplicationInfo appInfo =
79                 {
80                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
81                         DE_NULL,                                                                // const void*                                  pNext;
82                         appNames[appNameNdx],                                   // const char*                                  pAppName;
83                         0u,                                                                             // deUint32                                             appVersion;
84                         "engineName",                                                   // const char*                                  pEngineName;
85                         0u,                                                                             // deUint32                                             engineVersion;
86                         apiVersion,                                                             // deUint32                                             apiVersion;
87                 };
88
89                 appInfos.push_back(appInfo);
90         }
91
92         // test over engineName
93         for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++)
94         {
95                 const VkApplicationInfo appInfo =
96                 {
97                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
98                         DE_NULL,                                                                // const void*                                  pNext;
99                         "appName",                                                              // const char*                                  pAppName;
100                         0u,                                                                             // deUint32                                             appVersion;
101                         engineNames[engineNameNdx],                             // const char*                                  pEngineName;
102                         0u,                                                                             // deUint32                                             engineVersion;
103                         apiVersion,                                                             // deUint32                                             apiVersion;
104                 };
105
106                 appInfos.push_back(appInfo);
107         }
108
109         // test over appVersion
110         for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++)
111         {
112                 const VkApplicationInfo appInfo =
113                 {
114                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
115                         DE_NULL,                                                                // const void*                                  pNext;
116                         "appName",                                                              // const char*                                  pAppName;
117                         appVersions[appVersionNdx],                             // deUint32                                             appVersion;
118                         "engineName",                                                   // const char*                                  pEngineName;
119                         0u,                                                                             // deUint32                                             engineVersion;
120                         apiVersion,                                                             // deUint32                                             apiVersion;
121                 };
122
123                 appInfos.push_back(appInfo);
124         }
125
126         // test over engineVersion
127         for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++)
128         {
129                 const VkApplicationInfo appInfo =
130                 {
131                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
132                         DE_NULL,                                                                // const void*                                  pNext;
133                         "appName",                                                              // const char*                                  pAppName;
134                         0u,                                                                             // deUint32                                             appVersion;
135                         "engineName",                                                   // const char*                                  pEngineName;
136                         engineVersions[engineVersionNdx],               // deUint32                                             engineVersion;
137                         apiVersion,                                                             // deUint32                                             apiVersion;
138                 };
139
140                 appInfos.push_back(appInfo);
141         }
142         const deUint32  manjorNum       = unpackVersion(apiVersion).majorNum;
143         const deUint32  minorNum        = unpackVersion(apiVersion).minorNum;
144
145         // patch component of api version checking (should be ignored by implementation)
146         for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++)
147         {
148                 const VkApplicationInfo appInfo =
149                 {
150                         VK_STRUCTURE_TYPE_APPLICATION_INFO,                                                                     // VkStructureType                              sType;
151                         DE_NULL,                                                                                                                        // const void*                                  pNext;
152                         "appName",                                                                                                                      // const char*                                  pAppName;
153                         0u,                                                                                                                                     // deUint32                                             appVersion;
154                         "engineName",                                                                                                           // const char*                                  pEngineName;
155                         0u,                                                                                                                                     // deUint32                                             engineVersion;
156                         VK_MAKE_VERSION(manjorNum, minorNum, patchNumbers[patchVersion]),       // deUint32                                             apiVersion;
157                 };
158
159                 appInfos.push_back(appInfo);
160         }
161
162         // test when apiVersion is 0
163         {
164                 const VkApplicationInfo appInfo =
165                 {
166                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
167                         DE_NULL,                                                                // const void*                                  pNext;
168                         "appName",                                                              // const char*                                  pAppName;
169                         0u,                                                                             // deUint32                                             appVersion;
170                         "engineName",                                                   // const char*                                  pEngineName;
171                         0u,                                                                             // deUint32                                             engineVersion;
172                         0u,                                                                             // deUint32                                             apiVersion;
173                 };
174
175                 appInfos.push_back(appInfo);
176         }
177
178         // run the tests!
179         for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx)
180         {
181                 const VkApplicationInfo&                appInfo                                 = appInfos[appInfoNdx];
182                 const VkInstanceCreateInfo              instanceCreateInfo              =
183                 {
184                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType                              sType;
185                         DE_NULL,                                                                // const void*                                  pNext;
186                         (VkInstanceCreateFlags)0u,                              // VkInstanceCreateFlags                flags;
187                         &appInfo,                                                               // const VkApplicationInfo*             pAppInfo;
188                         0u,                                                                             // deUint32                                             layerCount;
189                         DE_NULL,                                                                // const char*const*                    ppEnabledLayernames;
190                         0u,                                                                             // deUint32                                             extensionCount;
191                         DE_NULL,                                                                // const char*const*                    ppEnabledExtensionNames;
192                 };
193
194                 log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage;
195
196                 try
197                 {
198                         CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
199                         log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
200                 }
201                 catch (const vk::Error& err)
202                 {
203                         resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
204                 }
205         }
206
207         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
208 }
209
210 tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context)
211 {
212         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
213         tcu::ResultCollector            resultCollector                 (log);
214         const PlatformInterface&        platformInterface               = context.getPlatformInterface();
215
216         deUint32                                        instanceApiVersion              = 0u;
217         platformInterface.enumerateInstanceVersion(&instanceApiVersion);
218
219         const ApiVersion                        apiVersion                              = unpackVersion(instanceApiVersion);
220
221         const deUint32                          invalidMajorVersion             = (1 << 10) - 1;
222         const deUint32                          invalidMinorVersion             = (1 << 10) - 1;
223         vector<ApiVersion>                      invalidApiVersions;
224
225         invalidApiVersions.push_back(ApiVersion(invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
226         invalidApiVersions.push_back(ApiVersion(apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum));
227
228         for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++)
229         {
230                 const VkApplicationInfo appInfo                                 =
231                 {
232                         VK_STRUCTURE_TYPE_APPLICATION_INFO,                     // VkStructureType                              sType;
233                         DE_NULL,                                                                        // const void*                                  pNext;
234                         "appName",                                                                      // const char*                                  pAppName;
235                         0u,                                                                                     // deUint32                                             appVersion;
236                         "engineName",                                                           // const char*                                  pEngineName;
237                         0u,                                                                                     // deUint32                                             engineVersion;
238                         pack(invalidApiVersions[apiVersionNdx]),        // deUint32                                             apiVersion;
239                 };
240                 const VkInstanceCreateInfo      instanceCreateInfo      =
241                 {
242                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,         // VkStructureType                              sType;
243                         DE_NULL,                                                                        // const void*                                  pNext;
244                         (VkInstanceCreateFlags)0u,                                      // VkInstanceCreateFlags                flags;
245                         &appInfo,                                                                       // const VkApplicationInfo*             pAppInfo;
246                         0u,                                                                                     // deUint32                                             layerCount;
247                         DE_NULL,                                                                        // const char*const*                    ppEnabledLayernames;
248                         0u,                                                                                     // deUint32                                             extensionCount;
249                         DE_NULL,                                                                        // const char*const*                    ppEnabledExtensionNames;
250                 };
251
252                 log << TestLog::Message
253                         << "API version reported by enumerateInstanceVersion: " << apiVersion
254                         << ", api version used to create instance: " << invalidApiVersions[apiVersionNdx]
255                         << TestLog::EndMessage;
256
257                 {
258                         UncheckedInstance       instance;
259                         const VkResult          result          = createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
260
261                         if (apiVersion.majorNum == 1 && apiVersion.minorNum == 0)
262                         {
263                                 if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
264                                 {
265                                         TCU_CHECK(!static_cast<bool>(instance));
266                                         log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
267                                 }
268                                 else
269                                         resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
270                         }
271                         else if (apiVersion.majorNum == 1 && apiVersion.minorNum >= 1)
272                         {
273                                 if (result == VK_SUCCESS)
274                                 {
275                                         TCU_CHECK(static_cast<bool>(instance));
276                                         log << TestLog::Message << "Pass, instance creation with nonstandard apiVersion succeeds for Vulkan 1.1" << TestLog::EndMessage;
277                                 }
278                                 else if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
279                                 {
280                                         resultCollector.fail("Fail, In Vulkan 1.1 instance creation must not return VK_ERROR_INCOMPATIBLE_DRIVER.");
281                                 }
282                                 else
283                                 {
284                                         std::ostringstream message;
285                                         message << "Fail, createInstance failed with " << result;
286                                         resultCollector.fail(message.str().c_str());
287                                 }
288                         }
289                 }
290         }
291
292         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
293 }
294
295 tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context)
296 {
297         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
298         tcu::ResultCollector            resultCollector                 (log);
299
300         const VkInstanceCreateInfo      instanceCreateInfo              =
301         {
302                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType                              sType;
303                 DE_NULL,                                                                // const void*                                  pNext;
304                 (VkInstanceCreateFlags)0u,                              // VkInstanceCreateFlags                flags;
305                 DE_NULL,                                                                // const VkApplicationInfo*             pAppInfo;
306                 0u,                                                                             // deUint32                                             layerCount;
307                 DE_NULL,                                                                // const char*const*                    ppEnabledLayernames;
308                 0u,                                                                             // deUint32                                             extensionCount;
309                 DE_NULL,                                                                // const char*const*                    ppEnabledExtensionNames;
310         };
311
312         log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage;
313
314         try
315         {
316                 CustomInstance instance = createCustomInstanceFromInfo(context, &instanceCreateInfo);
317                 log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
318         }
319         catch (const vk::Error& err)
320         {
321                 resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
322         }
323
324         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
325 }
326
327 tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context)
328 {
329         tcu::TestLog&                                           log                                             = context.getTestContext().getLog();
330         const char*                                                     enabledExtensions[]             = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"};
331         const deUint32                                          apiVersion                              = context.getUsedApiVersion();
332         const VkApplicationInfo                         appInfo                                 =
333         {
334                 VK_STRUCTURE_TYPE_APPLICATION_INFO,                                             // VkStructureType                              sType;
335                 DE_NULL,                                                                                                // const void*                                  pNext;
336                 "appName",                                                                                              // const char*                                  pAppName;
337                 0u,                                                                                                             // deUint32                                             appVersion;
338                 "engineName",                                                                                   // const char*                                  pEngineName;
339                 0u,                                                                                                             // deUint32                                             engineVersion;
340                 apiVersion,                                                                                             // deUint32                                             apiVersion;
341         };
342
343         const VkInstanceCreateInfo                      instanceCreateInfo              =
344         {
345                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,                                 // VkStructureType                              sType;
346                 DE_NULL,                                                                                                // const void*                                  pNext;
347                 (VkInstanceCreateFlags)0u,                                                              // VkInstanceCreateFlags                flags;
348                 &appInfo,                                                                                               // const VkApplicationInfo*             pAppInfo;
349                 0u,                                                                                                             // deUint32                                             layerCount;
350                 DE_NULL,                                                                                                // const char*const*                    ppEnabledLayernames;
351                 DE_LENGTH_OF_ARRAY(enabledExtensions),                                  // deUint32                                             extensionCount;
352                 enabledExtensions,                                                                              // const char*const*                    ppEnabledExtensionNames;
353         };
354
355         log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
356
357         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
358                 log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
359
360         {
361                 UncheckedInstance       instance;
362                 const VkResult          result          = createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
363
364                 if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
365                 {
366                         TCU_CHECK(!static_cast<bool>(instance));
367                         return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected.");
368                 }
369                 else
370                         return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded.");
371         }
372 }
373
374 enum
375 {
376         UTF8ABUSE_LONGNAME = 0,
377         UTF8ABUSE_BADNAMES,
378         UTF8ABUSE_OVERLONGNUL,
379         UTF8ABUSE_OVERLONG,
380         UTF8ABUSE_ZALGO,
381         UTF8ABUSE_CHINESE,
382         UTF8ABUSE_EMPTY,
383         UTF8ABUSE_MAX
384 };
385
386 string getUTF8AbuseString (int index)
387 {
388         switch (index)
389         {
390         case UTF8ABUSE_LONGNAME:
391                 // Generate a long name.
392                 {
393                         std::string longname;
394                         longname.resize(65535, 'k');
395                         return longname;
396                 }
397
398         case UTF8ABUSE_BADNAMES:
399                 // Various illegal code points in utf-8
400                 return string(
401                         "Illegal bytes in UTF-8: "
402                         "\xc0 \xc1 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff"
403                         "illegal surrogates: \xed\xad\xbf \xed\xbe\x80");
404
405         case UTF8ABUSE_OVERLONGNUL:
406                 // Zero encoded as overlong, not exactly legal but often supported to differentiate from terminating zero
407                 return string("UTF-8 encoded nul \xC0\x80 (should not end name)");
408
409         case UTF8ABUSE_OVERLONG:
410                 // Some overlong encodings
411                 return string(
412                         "UTF-8 overlong \xF0\x82\x82\xAC \xfc\x83\xbf\xbf\xbf\xbf \xf8\x87\xbf\xbf\xbf "
413                         "\xf0\x8f\xbf\xbf");
414
415         case UTF8ABUSE_ZALGO:
416                 // Internet "zalgo" meme "bleeding text"
417                 return string(
418                         "\x56\xcc\xb5\xcc\x85\xcc\x94\xcc\x88\xcd\x8a\xcc\x91\xcc\x88\xcd\x91\xcc\x83\xcd\x82"
419                         "\xcc\x83\xcd\x90\xcc\x8a\xcc\x92\xcc\x92\xcd\x8b\xcc\x94\xcd\x9d\xcc\x98\xcc\xab\xcc"
420                         "\xae\xcc\xa9\xcc\xad\xcc\x97\xcc\xb0\x75\xcc\xb6\xcc\xbe\xcc\x80\xcc\x82\xcc\x84\xcd"
421                         "\x84\xcc\x90\xcd\x86\xcc\x9a\xcd\x84\xcc\x9b\xcd\x86\xcd\x92\xcc\x9a\xcd\x99\xcd\x99"
422                         "\xcc\xbb\xcc\x98\xcd\x8e\xcd\x88\xcd\x9a\xcc\xa6\xcc\x9c\xcc\xab\xcc\x99\xcd\x94\xcd"
423                         "\x99\xcd\x95\xcc\xa5\xcc\xab\xcd\x89\x6c\xcc\xb8\xcc\x8e\xcc\x8b\xcc\x8b\xcc\x9a\xcc"
424                         "\x8e\xcd\x9d\xcc\x80\xcc\xa1\xcc\xad\xcd\x9c\xcc\xba\xcc\x96\xcc\xb3\xcc\xa2\xcd\x8e"
425                         "\xcc\xa2\xcd\x96\x6b\xcc\xb8\xcc\x84\xcd\x81\xcc\xbf\xcc\x8d\xcc\x89\xcc\x85\xcc\x92"
426                         "\xcc\x84\xcc\x90\xcd\x81\xcc\x93\xcd\x90\xcd\x92\xcd\x9d\xcc\x84\xcd\x98\xcd\x9d\xcd"
427                         "\xa0\xcd\x91\xcc\x94\xcc\xb9\xcd\x93\xcc\xa5\xcd\x87\xcc\xad\xcc\xa7\xcd\x96\xcd\x99"
428                         "\xcc\x9d\xcc\xbc\xcd\x96\xcd\x93\xcc\x9d\xcc\x99\xcc\xa8\xcc\xb1\xcd\x85\xcc\xba\xcc"
429                         "\xa7\x61\xcc\xb8\xcc\x8e\xcc\x81\xcd\x90\xcd\x84\xcd\x8c\xcc\x8c\xcc\x85\xcd\x86\xcc"
430                         "\x84\xcd\x84\xcc\x90\xcc\x84\xcc\x8d\xcd\x99\xcd\x8d\xcc\xb0\xcc\xa3\xcc\xa6\xcd\x89"
431                         "\xcd\x8d\xcd\x87\xcc\x98\xcd\x8d\xcc\xa4\xcd\x9a\xcd\x8e\xcc\xab\xcc\xb9\xcc\xac\xcc"
432                         "\xa2\xcd\x87\xcc\xa0\xcc\xb3\xcd\x89\xcc\xb9\xcc\xa7\xcc\xa6\xcd\x89\xcd\x95\x6e\xcc"
433                         "\xb8\xcd\x8a\xcc\x8a\xcd\x82\xcc\x9b\xcd\x81\xcd\x90\xcc\x85\xcc\x9b\xcd\x80\xcd\x91"
434                         "\xcd\x9b\xcc\x81\xcd\x81\xcc\x9a\xcc\xb3\xcd\x9c\xcc\x9e\xcc\x9d\xcd\x99\xcc\xa2\xcd"
435                         "\x93\xcd\x96\xcc\x97\xff");
436
437         case UTF8ABUSE_CHINESE:
438                 // Some Chinese glyphs.
439                 // "English equivalent: The devil is in the details", https://en.wikiquote.org/wiki/Chinese_proverbs
440                 return string(
441                         "\xe8\xaf\xbb\xe4\xb9\xa6\xe9\xa1\xbb\xe7\x94\xa8\xe6\x84\x8f\xef\xbc\x8c\xe4\xb8\x80"
442                         "\xe5\xad\x97\xe5\x80\xbc\xe5\x8d\x83\xe9\x87\x91\x20");
443
444         default:
445                 DE_ASSERT(index == UTF8ABUSE_EMPTY);
446                 // Also try an empty string.
447                 return string("");
448         }
449 }
450
451 tcu::TestStatus createInstanceWithExtensionNameAbuseTest (Context& context)
452 {
453         const char*                                     extensionList[1]        = { 0 };
454         const deUint32                          apiVersion                      = context.getUsedApiVersion();
455         deUint32                                        failCount                       = 0;
456
457         for (int i = 0; i < UTF8ABUSE_MAX; i++)
458         {
459                 string abuseString      = getUTF8AbuseString(i);
460                 extensionList[0]        = abuseString.c_str();
461
462                 const VkApplicationInfo         appInfo =
463                 {
464                         VK_STRUCTURE_TYPE_APPLICATION_INFO,                             // VkStructureType                      sType;
465                         DE_NULL,                                                                                // const void*                          pNext;
466                         "appName",                                                                              // const char*                          pAppName;
467                         0u,                                                                                             // deUint32                                     appVersion;
468                         "engineName",                                                                   // const char*                          pEngineName;
469                         0u,                                                                                             // deUint32                                     engineVersion;
470                         apiVersion,                                                                             // deUint32                                     apiVersion;
471                 };
472
473                 const VkInstanceCreateInfo      instanceCreateInfo =
474                 {
475                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,                 // VkStructureType                      sType;
476                         DE_NULL,                                                                                // const void*                          pNext;
477                         (VkInstanceCreateFlags)0u,                                              // VkInstanceCreateFlags        flags;
478                         &appInfo,                                                                               // const VkApplicationInfo*     pAppInfo;
479                         0u,                                                                                             // deUint32                                     layerCount;
480                         DE_NULL,                                                                                // const char*const*            ppEnabledLayernames;
481                         1u,                                                                                             // deUint32                                     extensionCount;
482                         extensionList,                                                                  // const char*const*            ppEnabledExtensionNames;
483                 };
484
485                 {
486                         UncheckedInstance       instance;
487                         const VkResult          result          = createUncheckedInstance(context, &instanceCreateInfo, DE_NULL, &instance);
488
489                         if (result != VK_ERROR_EXTENSION_NOT_PRESENT)
490                                 failCount++;
491
492                         TCU_CHECK(!static_cast<bool>(instance));
493                 }
494         }
495
496         if (failCount > 0)
497                 return tcu::TestStatus::fail("Fail, creating instances with unsupported extensions succeeded.");
498
499         return tcu::TestStatus::pass("Pass, creating instances with unsupported extensions were rejected.");
500 }
501
502 tcu::TestStatus createInstanceWithLayerNameAbuseTest (Context& context)
503 {
504         const PlatformInterface&        platformInterface       = context.getPlatformInterface();
505         const char*                                     layerList[1]            = { 0 };
506         const deUint32                          apiVersion                      = context.getUsedApiVersion();
507         deUint32                                        failCount                       = 0;
508
509         for (int i = 0; i < UTF8ABUSE_MAX; i++)
510         {
511                 string abuseString      = getUTF8AbuseString(i);
512                 layerList[0]            = abuseString.c_str();
513
514                 const VkApplicationInfo         appInfo =
515                 {
516                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                      sType;
517                         DE_NULL,                                                                // const void*                          pNext;
518                         "appName",                                                              // const char*                          pAppName;
519                         0u,                                                                             // deUint32                                     appVersion;
520                         "engineName",                                                   // const char*                          pEngineName;
521                         0u,                                                                             // deUint32                                     engineVersion;
522                         apiVersion,                                                             // deUint32                                     apiVersion;
523                 };
524
525                 const VkInstanceCreateInfo      instanceCreateInfo =
526                 {
527                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType                      sType;
528                         DE_NULL,                                                                // const void*                          pNext;
529                         (VkInstanceCreateFlags)0u,                              // VkInstanceCreateFlags        flags;
530                         &appInfo,                                                               // const VkApplicationInfo*     pAppInfo;
531                         1u,                                                                             // deUint32                                     layerCount;
532                         layerList,                                                              // const char*const*            ppEnabledLayernames;
533                         0u,                                                                             // deUint32                                     extensionCount;
534                         DE_NULL,                                                                // const char*const*            ppEnabledExtensionNames;
535                 };
536
537                 {
538                         VkInstance              instance        = (VkInstance)0;
539                         const VkResult  result          = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
540                         const bool              gotInstance     = !!instance;
541
542                         if (instance)
543                         {
544                                 const InstanceDriver instanceIface(platformInterface, instance);
545                                 instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
546                         }
547
548                         if (result != VK_ERROR_LAYER_NOT_PRESENT)
549                                 failCount++;
550
551                         TCU_CHECK(!gotInstance);
552                 }
553         }
554
555         if (failCount > 0)
556                 return tcu::TestStatus::fail("Fail, creating instances with unsupported layers succeeded.");
557
558         return tcu::TestStatus::pass("Pass, creating instances with unsupported layers were rejected.");
559 }
560
561 tcu::TestStatus enumerateDevicesAllocLeakTest(Context& context)
562 {
563         // enumeratePhysicalDevices uses instance-provided allocator
564         // and this test checks if all alocated memory is freed
565
566         typedef AllocationCallbackRecorder::RecordIterator RecordIterator;
567
568         DeterministicFailAllocator      objAllocator    (getSystemAllocator(), DeterministicFailAllocator::MODE_DO_NOT_COUNT, 0);
569         AllocationCallbackRecorder      recorder                (objAllocator.getCallbacks(), 128);
570         const auto                                      instance                = createCustomInstanceFromContext(context, recorder.getCallbacks(), true);
571         const auto&                                     vki                             = instance.getDriver();
572         vector<VkPhysicalDevice>        devices                 (enumeratePhysicalDevices(vki, instance));
573         RecordIterator                          recordToCheck   (recorder.getRecordsEnd());
574
575         try
576         {
577                 devices = enumeratePhysicalDevices(vki, instance);
578         }
579         catch (const vk::OutOfMemoryError& e)
580         {
581                 if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY)
582                         return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Got out of memory error - leaks in enumeratePhysicalDevices not tested.");
583         }
584
585         // make sure that same number of allocations and frees was done
586         deInt32                 allocationRecords       (0);
587         RecordIterator  lastRecordToCheck       (recorder.getRecordsEnd());
588         while (recordToCheck != lastRecordToCheck)
589         {
590                 const AllocationCallbackRecord& record = *recordToCheck;
591                 switch (record.type)
592                 {
593                 case AllocationCallbackRecord::TYPE_ALLOCATION:
594                         ++allocationRecords;
595                         break;
596                 case AllocationCallbackRecord::TYPE_FREE:
597                         if (record.data.free.mem != DE_NULL)
598                                 --allocationRecords;
599                         break;
600                 default:
601                         break;
602                 }
603                 ++recordToCheck;
604         }
605
606         if (allocationRecords)
607                 return tcu::TestStatus::fail("enumeratePhysicalDevices leaked memory");
608         return tcu::TestStatus::pass("Ok");
609 }
610
611 tcu::TestStatus createDeviceTest (Context& context)
612 {
613         const PlatformInterface&                platformInterface               = context.getPlatformInterface();
614         const CustomInstance                    instance                                (createCustomInstanceFromContext(context));
615         const InstanceDriver&                   instanceDriver                  (instance.getDriver());
616         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
617         const deUint32                                  queueFamilyIndex                = 0;
618         const deUint32                                  queueCount                              = 1;
619         const deUint32                                  queueIndex                              = 0;
620         const float                                             queuePriority                   = 1.0f;
621
622         const vector<VkQueueFamilyProperties> queueFamilyProperties     = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
623
624         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
625         {
626                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
627                 DE_NULL,
628                 (VkDeviceQueueCreateFlags)0u,
629                 queueFamilyIndex,                                               //queueFamilyIndex;
630                 queueCount,                                                             //queueCount;
631                 &queuePriority,                                                 //pQueuePriorities;
632         };
633
634         const VkDeviceCreateInfo                deviceCreateInfo        =
635         {
636                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
637                 DE_NULL,                                                                //pNext;
638                 (VkDeviceCreateFlags)0u,
639                 1,                                                                              //queueRecordCount;
640                 &deviceQueueCreateInfo,                                 //pRequestedQueues;
641                 0,                                                                              //layerCount;
642                 DE_NULL,                                                                //ppEnabledLayerNames;
643                 0,                                                                              //extensionCount;
644                 DE_NULL,                                                                //ppEnabledExtensionNames;
645                 DE_NULL,                                                                //pEnabledFeatures;
646         };
647
648         const Unique<VkDevice>                  device                                  (createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
649         const DeviceDriver                              deviceDriver                    (platformInterface, instance, device.get());
650         const VkQueue                                   queue                                   = getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
651
652         VK_CHECK(deviceDriver.queueWaitIdle(queue));
653
654         return tcu::TestStatus::pass("Pass");
655 }
656
657 tcu::TestStatus createMultipleDevicesTest (Context& context)
658 {
659         tcu::TestLog&                                                                           log                                             = context.getTestContext().getLog();
660         tcu::ResultCollector                                                            resultCollector                 (log);
661         const int                                                                                       numDevices                              = 5;
662         const PlatformInterface&                                                        platformInterface               = context.getPlatformInterface();
663         const CustomInstance                                                            instance                                (createCustomInstanceFromContext(context));
664         const InstanceDriver&                                                           instanceDriver                  (instance.getDriver());
665         const VkPhysicalDevice                                                          physicalDevice                  = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
666         const vector<VkQueueFamilyProperties>                           queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
667         const deUint32                                                                          queueFamilyIndex                = 0;
668         const deUint32                                                                          queueCount                              = 1;
669         const deUint32                                                                          queueIndex                              = 0;
670         const float                                                                                     queuePriority                   = 1.0f;
671         const VkDeviceQueueCreateInfo                                           deviceQueueCreateInfo   =
672         {
673                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
674                 DE_NULL,
675                 (VkDeviceQueueCreateFlags)0u,                                   //flags;
676                 queueFamilyIndex,                                                               //queueFamilyIndex;
677                 queueCount,                                                                             //queueCount;
678                 &queuePriority,                                                                 //pQueuePriorities;
679         };
680
681         const VkDeviceCreateInfo                                                        deviceCreateInfo                =
682         {
683                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                   //sType;
684                 DE_NULL,                                                                                //pNext;
685                 (VkDeviceCreateFlags)0u,
686                 1,                                                                                              //queueRecordCount;
687                 &deviceQueueCreateInfo,                                                 //pRequestedQueues;
688                 0,                                                                                              //layerCount;
689                 DE_NULL,                                                                                //ppEnabledLayerNames;
690                 0,                                                                                              //extensionCount;
691                 DE_NULL,                                                                                //ppEnabledExtensionNames;
692                 DE_NULL,                                                                                //pEnabledFeatures;
693         };
694
695         vector<VkDevice>                                                                        devices(numDevices, (VkDevice)DE_NULL);
696
697         try
698         {
699                 for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++)
700                 {
701                         const VkResult result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]);
702
703                         if (result != VK_SUCCESS)
704                         {
705                                 resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result));
706                                 break;
707                         }
708
709                         {
710                                 const DeviceDriver      deviceDriver    (platformInterface, instance, devices[deviceNdx]);
711                                 const VkQueue           queue                   = getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex);
712
713                                 VK_CHECK(deviceDriver.queueWaitIdle(queue));
714                         }
715                 }
716         }
717         catch (const vk::Error& error)
718         {
719                 resultCollector.fail(de::toString(error.getError()));
720         }
721         catch (...)
722         {
723                 for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
724                 {
725                         if (devices[deviceNdx] != (VkDevice)DE_NULL)
726                         {
727                                 DeviceDriver deviceDriver(platformInterface, instance, devices[deviceNdx]);
728                                 deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
729                         }
730                 }
731
732                 throw;
733         }
734
735         for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
736         {
737                 if (devices[deviceNdx] != (VkDevice)DE_NULL)
738                 {
739                         DeviceDriver deviceDriver(platformInterface, instance, devices[deviceNdx]);
740                         deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
741                 }
742         }
743
744         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
745 }
746
747 tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context)
748 {
749         tcu::TestLog&                                   log                                             = context.getTestContext().getLog();
750         const PlatformInterface&                platformInterface               = context.getPlatformInterface();
751         const CustomInstance                    instance                                (createCustomInstanceFromContext(context, DE_NULL, false));
752         const InstanceDriver&                   instanceDriver                  (instance.getDriver());
753         const char*                                             enabledExtensions[]             = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"};
754         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
755         const float                                             queuePriority                   = 1.0f;
756         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
757         {
758                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
759                 DE_NULL,
760                 (VkDeviceQueueCreateFlags)0u,
761                 0,                                                                              //queueFamilyIndex;
762                 1,                                                                              //queueCount;
763                 &queuePriority,                                                 //pQueuePriorities;
764         };
765
766         const VkDeviceCreateInfo                deviceCreateInfo                =
767         {
768                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
769                 DE_NULL,                                                                //pNext;
770                 (VkDeviceCreateFlags)0u,
771                 1,                                                                              //queueRecordCount;
772                 &deviceQueueCreateInfo,                                 //pRequestedQueues;
773                 0,                                                                              //layerCount;
774                 DE_NULL,                                                                //ppEnabledLayerNames;
775                 DE_LENGTH_OF_ARRAY(enabledExtensions),  //extensionCount;
776                 enabledExtensions,                                              //ppEnabledExtensionNames;
777                 DE_NULL,                                                                //pEnabledFeatures;
778         };
779
780         log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
781
782         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
783                 log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
784
785         {
786                 VkDevice                device          = (VkDevice)0;
787                 const VkResult  result          = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device);
788                 const bool              gotDevice       = !!device;
789
790                 if (device)
791                 {
792                         const DeviceDriver      deviceIface     (platformInterface, instance, device);
793                         deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
794                 }
795
796                 if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
797                 {
798                         TCU_CHECK(!gotDevice);
799                         return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected.");
800                 }
801                 else
802                         return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed.");
803         }
804 }
805
806 deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)
807 {
808         deUint32 maxQueueCount = 0;
809
810         for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
811         {
812                 maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount);
813         }
814
815         return maxQueueCount;
816 }
817
818 tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context)
819 {
820         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
821         const int                                                               queueCountDiff                  = 1;
822         const PlatformInterface&                                platformInterface               = context.getPlatformInterface();
823         const CustomInstance                                    instance                                (createCustomInstanceFromContext(context));
824         const InstanceDriver&                                   instanceDriver                  (instance.getDriver());
825         const VkPhysicalDevice                                  physicalDevice                  = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
826         const vector<VkQueueFamilyProperties>   queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
827         const vector<float>                                             queuePriorities                 (getGlobalMaxQueueCount(queueFamilyProperties), 1.0f);
828         vector<VkDeviceQueueCreateInfo>                 deviceQueueCreateInfos;
829
830         for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
831         {
832                 const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount;
833
834                 for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff)
835                 {
836                         const VkDeviceQueueCreateInfo queueCreateInfo =
837                         {
838                                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
839                                 DE_NULL,
840                                 (VkDeviceQueueCreateFlags)0u,
841                                 queueFamilyNdx,
842                                 queueCount,
843                                 queuePriorities.data()
844                         };
845
846                         deviceQueueCreateInfos.push_back(queueCreateInfo);
847                 }
848         }
849
850         for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++)
851         {
852                 const VkDeviceQueueCreateInfo&  queueCreateInfo         = deviceQueueCreateInfos[testNdx];
853                 const VkDeviceCreateInfo                deviceCreateInfo        =
854                 {
855                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
856                         DE_NULL,                                                                //pNext;
857                         (VkDeviceCreateFlags)0u,
858                         1,                                                                              //queueRecordCount;
859                         &queueCreateInfo,                                               //pRequestedQueues;
860                         0,                                                                              //layerCount;
861                         DE_NULL,                                                                //ppEnabledLayerNames;
862                         0,                                                                              //extensionCount;
863                         DE_NULL,                                                                //ppEnabledExtensionNames;
864                         DE_NULL,                                                                //pEnabledFeatures;
865                 };
866
867                 const Unique<VkDevice>                  device                          (createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
868                 const DeviceDriver                              deviceDriver            (platformInterface, instance, device.get());
869                 const deUint32                                  queueFamilyIndex        = deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
870                 const deUint32                                  queueCount                      = deviceCreateInfo.pQueueCreateInfos->queueCount;
871
872                 for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++)
873                 {
874                         const VkQueue           queue   = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex);
875                         VkResult                        result;
876
877                         TCU_CHECK(!!queue);
878
879                         result = deviceDriver.queueWaitIdle(queue);
880                         if (result != VK_SUCCESS)
881                         {
882                                 log << TestLog::Message
883                                         << "vkQueueWaitIdle failed"
884                                         << ",  queueIndex = " << queueIndex
885                                         << ", queueCreateInfo " << queueCreateInfo
886                                         << ", Error Code: " << result
887                                         << TestLog::EndMessage;
888                                 return tcu::TestStatus::fail("Fail");
889                         }
890                 }
891         }
892         return tcu::TestStatus::pass("Pass");
893 }
894
895 void checkGlobalPrioritySupport (Context& context, bool useKhrGlobalPriority)
896 {
897         const std::string extName = (useKhrGlobalPriority ? "VK_KHR_global_priority" : "VK_EXT_global_priority");
898         context.requireDeviceFunctionality(extName);
899 }
900
901 tcu::TestStatus createDeviceWithGlobalPriorityTest (Context& context, bool useKhrGlobalPriority)
902 {
903         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
904         const PlatformInterface&                                platformInterface               = context.getPlatformInterface();
905         const CustomInstance                                    instance                                (createCustomInstanceFromContext(context));
906         const InstanceDriver&                                   instanceDriver                  (instance.getDriver());
907         const VkPhysicalDevice                                  physicalDevice                  = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
908         const vector<float>                                             queuePriorities                 (1, 1.0f);
909         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 };
910
911         deUint32                                                queueFamilyPropertyCount        = ~0u;
912
913         instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, DE_NULL);
914         TCU_CHECK(queueFamilyPropertyCount > 0);
915
916         std::vector<VkQueueFamilyProperties2>                                   queueFamilyProperties2          (queueFamilyPropertyCount);
917         std::vector<VkQueueFamilyGlobalPriorityPropertiesKHR>   globalPriorityProperties        (queueFamilyPropertyCount);
918
919         if (useKhrGlobalPriority)
920         {
921                 for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
922                 {
923                         globalPriorityProperties[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR;
924                         globalPriorityProperties[ndx].pNext = DE_NULL;
925                         queueFamilyProperties2[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
926                         queueFamilyProperties2[ndx].pNext = &globalPriorityProperties[ndx];
927                 }
928
929                 instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
930                 TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());
931         }
932
933         std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority" };
934         if (useKhrGlobalPriority)
935                 enabledExtensions = { "VK_KHR_global_priority" };
936
937         if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
938         {
939                 enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
940         }
941
942         const VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT    globalPriorityQueryFeatures =
943         {
944                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,   //sType;
945                 DE_NULL,                                                                                                                                //pNext;
946                 VK_TRUE                                                                                                                                 //globalPriorityQuery;
947         };
948
949         for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
950         {
951                 const VkDeviceQueueGlobalPriorityCreateInfoEXT  queueGlobalPriority             =
952                 {
953                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT, //sType;
954                         DE_NULL,                                                                                                                //pNext;
955                         globalPriority                                                                                                  //globalPriority;
956                 };
957
958                 const VkDeviceQueueCreateInfo   queueCreateInfo         =
959                 {
960                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,     //sType;
961                         &queueGlobalPriority,                                           //pNext;
962                         (VkDeviceQueueCreateFlags)0u,                           //flags;
963                         0,                                                                                      //queueFamilyIndex;
964                         1,                                                                                      //queueCount;
965                         queuePriorities.data()                                          //pQueuePriorities;
966                 };
967
968                 const VkDeviceCreateInfo                deviceCreateInfo        =
969                 {
970                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                                   //sType;
971                         useKhrGlobalPriority ? &globalPriorityQueryFeatures : DE_NULL,  //pNext;
972                         (VkDeviceCreateFlags)0u,                                                                                //flags;
973                         1,                                                                                                                              //queueRecordCount;
974                         &queueCreateInfo,                                                                                               //pRequestedQueues;
975                         0,                                                                                                                              //layerCount;
976                         DE_NULL,                                                                                                                //ppEnabledLayerNames;
977                         (deUint32)enabledExtensions.size(),                                                             //extensionCount;
978                         enabledExtensions.data(),                                                                               //ppEnabledExtensionNames;
979                         DE_NULL,                                                                                                                //pEnabledFeatures;
980                 };
981
982                 const bool              mayBeDenied                             = globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
983                 const bool              mustFail                                = useKhrGlobalPriority && (globalPriority < globalPriorityProperties[0].priorities[0] || globalPriority > globalPriorityProperties[0].priorities[globalPriorityProperties[0].priorityCount - 1]);
984
985                 try
986                 {
987                         const Unique<VkDevice>          device                          (createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
988                         const DeviceDriver                      deviceDriver            (platformInterface, instance, device.get());
989                         const deUint32                          queueFamilyIndex        = deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
990                         const VkQueue                           queue                           = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, 0);
991                         VkResult                                        result;
992
993                         TCU_CHECK(!!queue);
994
995                         result = deviceDriver.queueWaitIdle(queue);
996                         if (result == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied)
997                         {
998                                 continue;
999                         }
1000
1001                         if (result == VK_ERROR_INITIALIZATION_FAILED && mustFail)
1002                         {
1003                                 continue;
1004                         }
1005
1006                         if (mustFail)
1007                         {
1008                                 log << TestLog::Message
1009                                         << "device creation must fail but not"
1010                                         << ", globalPriority = " << globalPriority
1011                                         << ", queueCreateInfo " << queueCreateInfo
1012                                         << TestLog::EndMessage;
1013                                 return tcu::TestStatus::fail("Fail");
1014                         }
1015
1016                         if (result != VK_SUCCESS)
1017                         {
1018                                 log << TestLog::Message
1019                                         << "vkQueueWaitIdle failed"
1020                                         << ", globalPriority = " << globalPriority
1021                                         << ", queueCreateInfo " << queueCreateInfo
1022                                         << ", Error Code: " << result
1023                                         << TestLog::EndMessage;
1024                                 return tcu::TestStatus::fail("Fail");
1025                         }
1026                 }
1027                 catch (const Error& error)
1028                 {
1029                         if ((error.getError() == VK_ERROR_INITIALIZATION_FAILED && mustFail) || (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied))
1030                         {
1031                                 continue;
1032                         }
1033                         else
1034                         {
1035                                 log << TestLog::Message
1036                                         << "exception thrown " << error.getMessage()
1037                                         << ", globalPriority = " << globalPriority
1038                                         << ", queueCreateInfo " << queueCreateInfo
1039                                         << ", Error Code: " << error.getError()
1040                                         << TestLog::EndMessage;
1041                                 return tcu::TestStatus::fail("Fail");
1042                         }
1043                 }
1044         }
1045
1046         return tcu::TestStatus::pass("Pass");
1047 }
1048
1049 void checkGlobalPriorityQuerySupport (Context& context, bool useKhrGlobalPriority)
1050 {
1051         const std::string extName = (useKhrGlobalPriority ? "VK_KHR_global_priority" : "VK_EXT_global_priority_query");
1052         context.requireDeviceFunctionality(extName);
1053 }
1054
1055 deBool isValidGlobalPriority(VkQueueGlobalPriorityEXT priority)
1056 {
1057         switch (priority) {
1058                 case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:
1059                 case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:
1060                 case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:
1061                 case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:
1062                         return DE_TRUE;
1063                 default:
1064                         return DE_FALSE;
1065         }
1066 }
1067
1068 void checkGlobalPriorityProperties(const VkQueueFamilyGlobalPriorityPropertiesEXT& properties)
1069 {
1070         TCU_CHECK(properties.priorityCount > 0);
1071         TCU_CHECK(properties.priorityCount <= VK_MAX_GLOBAL_PRIORITY_SIZE_EXT);
1072         TCU_CHECK(isValidGlobalPriority(properties.priorities[0]));
1073
1074         for (deUint32 ndx = 1; ndx < properties.priorityCount; ndx++)
1075         {
1076                 TCU_CHECK(isValidGlobalPriority(properties.priorities[ndx]));
1077                 TCU_CHECK(properties.priorities[ndx] == (properties.priorities[ndx - 1] << 1));
1078         }
1079 }
1080
1081 tcu::TestStatus createDeviceWithQueriedGlobalPriorityTest (Context& context, bool useKhrGlobalPriority)
1082 {
1083         tcu::TestLog&                                   log                                                     = context.getTestContext().getLog();
1084         const PlatformInterface&                platformInterface                       = context.getPlatformInterface();
1085         const CustomInstance                    instance                                        (createCustomInstanceFromContext(context));
1086         const InstanceDriver&                   instanceDriver                          (instance.getDriver());
1087         const VkPhysicalDevice                  physicalDevice                          = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1088         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 };
1089         const vector<float>                             queuePriorities                         (1, 1.0f);
1090         deUint32                                                queueFamilyPropertyCount        = ~0u;
1091
1092         instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, DE_NULL);
1093         TCU_CHECK(queueFamilyPropertyCount > 0);
1094
1095         std::vector<VkQueueFamilyProperties2>                                   queueFamilyProperties2          (queueFamilyPropertyCount);
1096         std::vector<VkQueueFamilyGlobalPriorityPropertiesEXT>   globalPriorityProperties        (queueFamilyPropertyCount);
1097
1098         for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1099         {
1100                 globalPriorityProperties[ndx].sType     = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT;
1101                 globalPriorityProperties[ndx].pNext     = DE_NULL;
1102                 queueFamilyProperties2[ndx].sType       = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1103                 queueFamilyProperties2[ndx].pNext       = &globalPriorityProperties[ndx];
1104         }
1105
1106         instanceDriver.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyPropertyCount, queueFamilyProperties2.data());
1107         TCU_CHECK((size_t)queueFamilyPropertyCount == queueFamilyProperties2.size());
1108
1109         std::vector<const char*> enabledExtensions = { "VK_EXT_global_priority", "VK_EXT_global_priority_query" };
1110         if (useKhrGlobalPriority)
1111                 enabledExtensions = { "VK_KHR_global_priority" };
1112
1113         if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
1114         {
1115                 enabledExtensions.emplace_back("VK_KHR_get_physical_device_properties2");
1116         }
1117
1118         for (deUint32 ndx = 0; ndx < queueFamilyPropertyCount; ndx++)
1119         {
1120                 checkGlobalPriorityProperties(globalPriorityProperties[ndx]);
1121
1122                 for (VkQueueGlobalPriorityEXT globalPriority : globalPriorities)
1123                 {
1124                         const VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT    globalPriorityQueryFeatures             =
1125                         {
1126                                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT,   //sType;
1127                                 DE_NULL,                                                                                                                                //pNext;
1128                                 VK_TRUE                                                                                                                                 //globalPriorityQuery;
1129                         };
1130                         const VkDeviceQueueGlobalPriorityCreateInfoEXT                  queueGlobalPriorityCreateInfo   =
1131                         {
1132                                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT,                 //sType;
1133                                 DE_NULL,                                                                                                                                //pNext;
1134                                 globalPriority,                                                                                                                 //globalPriority;
1135                         };
1136                         const VkDeviceQueueCreateInfo                                                   queueCreateInfo                                 =
1137                         {
1138                                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,                                                             //sType;
1139                                 &queueGlobalPriorityCreateInfo,                                                                                 //pNext;
1140                                 (VkDeviceQueueCreateFlags)0u,                                                                                   //flags;
1141                                 ndx,                                                                                                                                    //queueFamilyIndex;
1142                                 1,                                                                                                                                              //queueCount;
1143                                 queuePriorities.data()                                                                                                  //pQueuePriorities;
1144                         };
1145                         const VkDeviceCreateInfo                                                                deviceCreateInfo                                =
1146                         {
1147                                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                                                   //sType;
1148                                 &globalPriorityQueryFeatures,                                                                                   //pNext;
1149                                 (VkDeviceCreateFlags)0u,                                                                                                //flags;
1150                                 1,                                                                                                                                              //queueRecordCount;
1151                                 &queueCreateInfo,                                                                                                               //pRequestedQueues;
1152                                 0,                                                                                                                                              //layerCount;
1153                                 DE_NULL,                                                                                                                                //ppEnabledLayerNames;
1154                                 (deUint32)enabledExtensions.size(),                                                                             //extensionCount;
1155                                 enabledExtensions.data(),                                                                                               //ppEnabledExtensionNames;
1156                                 DE_NULL,                                                                                                                                //pEnabledFeatures;
1157                         };
1158                         const bool                                                                                              mayBeDenied                                             = globalPriority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;
1159                         const bool                                                                                              mustFail                                                = globalPriority < globalPriorityProperties[ndx].priorities[0] || globalPriority > globalPriorityProperties[ndx].priorities[globalPriorityProperties[ndx].priorityCount - 1];
1160
1161                         try
1162                         {
1163                                 const Unique<VkDevice>          device                          (createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1164                                 const DeviceDriver                      deviceDriver            (platformInterface, instance, device.get());
1165                                 const VkQueue                           queue                           = getDeviceQueue(deviceDriver, *device, ndx, 0);
1166
1167                                 TCU_CHECK(!!queue);
1168
1169                                 if (mustFail)
1170                                 {
1171                                         log << TestLog::Message
1172                                                 << "device creation must fail but not"
1173                                                 << ", globalPriority = " << globalPriority
1174                                                 << ", queueCreateInfo " << queueCreateInfo
1175                                                 << TestLog::EndMessage;
1176                                         return tcu::TestStatus::fail("Fail");
1177                                 }
1178                         }
1179                         catch (const Error& error)
1180                         {
1181                                 if (mustFail || (error.getError() == VK_ERROR_NOT_PERMITTED_EXT && mayBeDenied))
1182                                 {
1183                                         continue;
1184                                 }
1185                                 else
1186                                 {
1187                                         log << TestLog::Message
1188                                                 << "exception thrown " << error.getMessage()
1189                                                 << ", globalPriority = " << globalPriority
1190                                                 << ", queueCreateInfo " << queueCreateInfo
1191                                                 << ", Error Code: " << error.getError()
1192                                                 << TestLog::EndMessage;
1193                                         return tcu::TestStatus::fail("Fail");
1194                                 }
1195                         }
1196                 }
1197         }
1198
1199         return tcu::TestStatus::pass("Pass");
1200 }
1201
1202 tcu::TestStatus createDeviceFeatures2Test (Context& context)
1203 {
1204         const PlatformInterface&                                vkp                                             = context.getPlatformInterface();
1205         const CustomInstance                                    instance                                (createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
1206         const InstanceDriver&                                   vki                                             (instance.getDriver());
1207         const VkPhysicalDevice                                  physicalDevice                  = chooseDevice(vki, instance, context.getTestContext().getCommandLine());
1208         const deUint32                                                  queueFamilyIndex                = 0;
1209         const deUint32                                                  queueCount                              = 1;
1210         const deUint32                                                  queueIndex                              = 0;
1211         const float                                                             queuePriority                   = 1.0f;
1212         const vector<VkQueueFamilyProperties>   queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
1213
1214         VkPhysicalDeviceFeatures2               enabledFeatures;
1215         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
1216         {
1217                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1218                 DE_NULL,
1219                 (VkDeviceQueueCreateFlags)0u,
1220                 queueFamilyIndex,
1221                 queueCount,
1222                 &queuePriority,
1223         };
1224
1225         const VkDeviceCreateInfo                deviceCreateInfo        =
1226         {
1227                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1228                 &enabledFeatures,
1229                 (VkDeviceCreateFlags)0u,
1230                 1,
1231                 &deviceQueueCreateInfo,
1232                 0u,
1233                 DE_NULL,
1234                 0,
1235                 DE_NULL,
1236                 DE_NULL,
1237         };
1238
1239         // Populate enabledFeatures
1240         enabledFeatures.sType           = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1241         enabledFeatures.pNext           = DE_NULL;
1242
1243         vki.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
1244
1245         {
1246                 const Unique<VkDevice>  device          (createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceCreateInfo));
1247                 const DeviceDriver              vkd                     (vkp, instance, device.get());
1248                 const VkQueue                   queue           = getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);
1249
1250                 VK_CHECK(vkd.queueWaitIdle(queue));
1251         }
1252
1253         return tcu::TestStatus::pass("Pass");
1254 }
1255
1256 struct Feature
1257 {
1258         const char*     name;
1259         size_t          offset;
1260 };
1261
1262 #define FEATURE_ITEM(STRUCT, MEMBER) {#MEMBER, DE_OFFSET_OF(STRUCT, MEMBER)}
1263 // This macro is used to avoid the "out of array bounds" compiler warnings/errors in the checkFeatures function.
1264 #define SAFE_OFFSET(LIMITING_STRUCT, STRUCT, MEMBER) std::min(static_cast<deUint32>(sizeof(LIMITING_STRUCT) - sizeof(VkBool32)), DE_OFFSET_OF(STRUCT, MEMBER))
1265
1266 template<typename StructType>
1267 void checkFeatures (const PlatformInterface& vkp, const VkInstance& instance, const InstanceDriver& instanceDriver, const VkPhysicalDevice physicalDevice, int numFeatures, const Feature features[], const StructType* supportedFeatures, const deUint32 queueFamilyIndex, const deUint32 queueCount, const float queuePriority, int& numErrors, tcu::ResultCollector& resultCollector, const vector<const char*>* extensionNames, const VkPhysicalDeviceFeatures& defaultPhysicalDeviceFeatures)
1268 {
1269         struct StructureBase
1270         {
1271                 VkStructureType         sType;
1272                 void*                           pNext;
1273         };
1274
1275         for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
1276         {
1277                 // Test only features that are not supported.
1278                 if (*(((VkBool32*)((deUint8*)(supportedFeatures) + features[featureNdx].offset))))
1279                         continue;
1280
1281                 StructType structCopy;
1282                 deMemset(&structCopy, 0, sizeof(StructType));
1283
1284                 auto* structBase = reinterpret_cast<StructureBase*>(&structCopy);
1285                 VkStructureType structureType = reinterpret_cast<const StructureBase*>(supportedFeatures)->sType;
1286                 structBase->sType = structureType;
1287                 structBase->pNext = DE_NULL;
1288
1289                 VkPhysicalDeviceFeatures physicalDeviceFeaturesCopy = defaultPhysicalDeviceFeatures;
1290
1291                 // Some features require that other feature(s) are also enabled.
1292
1293                 // If rayTracingPipelineShaderGroupHandleCaptureReplayMixed is VK_TRUE, rayTracingPipelineShaderGroupHandleCaptureReplay must also be VK_TRUE.
1294                 if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR &&
1295                         features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplayMixed))
1296                 {
1297                         DE_ASSERT((std::is_same<VkPhysicalDeviceRayTracingPipelineFeaturesKHR, StructType>::value));
1298                         auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceRayTracingPipelineFeaturesKHR, rayTracingPipelineShaderGroupHandleCaptureReplay));
1299                         *memberPtr = VK_TRUE;
1300                 }
1301                 else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES)
1302                 {
1303                         DE_ASSERT((std::is_same<VkPhysicalDeviceVulkan11Features, StructType>::value));
1304                         // If multiviewGeometryShader is enabled then multiview must also be enabled.
1305                         // If multiviewTessellationShader is enabled then multiview must also be enabled.
1306                         if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader) ||
1307                                 features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader))
1308                         {
1309                                 auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, multiview));
1310                                 *memberPtr = VK_TRUE;
1311                         }
1312
1313                         // If variablePointers is enabled then variablePointersStorageBuffer must also be enabled.
1314                         if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceVulkan11Features, variablePointers))
1315                         {
1316                                 auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer));
1317                                 *memberPtr = VK_TRUE;
1318                         }
1319                 }
1320                 else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES)
1321                 {
1322                         DE_ASSERT((std::is_same<VkPhysicalDeviceMultiviewFeatures, StructType>::value));
1323                         // If multiviewGeometryShader is enabled then multiview must also be enabled.
1324                         // If multiviewTessellationShader is enabled then multiview must also be enabled.
1325                         if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewGeometryShader) ||
1326                         features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceMultiviewFeatures, multiviewTessellationShader))
1327                         {
1328                                 auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceMultiviewFeatures, multiview));
1329                                 *memberPtr = VK_TRUE;
1330                         }
1331                 }
1332                 else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
1333                 {
1334                         DE_ASSERT((std::is_same<VkPhysicalDeviceRobustness2FeaturesEXT, StructType>::value));
1335                         // If robustBufferAccess2 is enabled then robustBufferAccess must also be enabled.
1336                         if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceRobustness2FeaturesEXT, robustBufferAccess2))
1337                         {
1338                                 physicalDeviceFeaturesCopy.robustBufferAccess = true;
1339                         }
1340                 }
1341                 else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT)
1342                 {
1343                         DE_ASSERT((std::is_same<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, StructType>::value));
1344                         // If sparseImageInt64Atomics is enabled, shaderImageInt64Atomics must be enabled.
1345                         if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, sparseImageInt64Atomics))
1346                         {
1347                                 auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT, shaderImageInt64Atomics));
1348                                 *memberPtr = VK_TRUE;
1349                         }
1350                 }
1351                 else if (structureType == vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT)
1352                 {
1353                         DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, StructType>::value));
1354                         // If sparseImageFloat32Atomics is enabled, shaderImageFloat32Atomics must be enabled.
1355                         if (features[featureNdx].offset ==
1356                                 DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32Atomics)) {
1357                                 auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32Atomics));
1358                                 *memberPtr = VK_TRUE;
1359                         }
1360
1361                         // If sparseImageFloat32AtomicAdd is enabled, shaderImageFloat32AtomicAdd must be enabled.
1362                         if (features[featureNdx].offset ==
1363                                 DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, sparseImageFloat32AtomicAdd)) {
1364                                 auto *memberPtr = reinterpret_cast<VkBool32 *>(reinterpret_cast<deUint8 *>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloatFeaturesEXT, shaderImageFloat32AtomicAdd));
1365                                 *memberPtr = VK_TRUE;
1366                         }
1367                 }
1368                 else if (structureType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT)
1369                 {
1370                         DE_ASSERT((std::is_same<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, StructType>::value));
1371                         // If sparseImageFloat32AtomicMinMax is enabled, shaderImageFloat32AtomicMinMax must be enabled.
1372                         if (features[featureNdx].offset == DE_OFFSET_OF(VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, sparseImageFloat32AtomicMinMax))
1373                         {
1374                                 auto* memberPtr = reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + SAFE_OFFSET(StructType, VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT, shaderImageFloat32AtomicMinMax));
1375                                 *memberPtr = VK_TRUE;
1376                         }
1377                 }
1378
1379                 // Enable the feature we're testing.
1380                 *reinterpret_cast<VkBool32*>(reinterpret_cast<deUint8*>(&structCopy) + features[featureNdx].offset) = VK_TRUE;
1381
1382                 const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
1383                 {
1384                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,     // sType
1385                         DE_NULL,                                                                        // pNext
1386                         (VkDeviceQueueCreateFlags)0u,                           // flags
1387                         queueFamilyIndex,                                                       // queueFamilyIndex
1388                         queueCount,                                                                     // queueCount
1389                         &queuePriority                                                          // pQueuePriorities
1390                 };
1391                 const VkPhysicalDeviceFeatures2 deviceFeatures2 =
1392                 {
1393                         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,   // sType
1394                         &structCopy,                                                                    // pNext
1395                         physicalDeviceFeaturesCopy                                              // features
1396                 };
1397                 const VkDeviceCreateInfo                deviceCreateInfo                =
1398                 {
1399                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                                                                   // sType
1400                         &deviceFeatures2,                                                                                                                               // pNext
1401                         (VkDeviceCreateFlags)0u,                                                                                                                // flags
1402                         1,                                                                                                                                                              // queueCreateInfoCount
1403                         &deviceQueueCreateInfo,                                                                                                                 // pQueueCreateInfos
1404                         0u,                                                                                                                                                             // enabledLayerCount
1405                         DE_NULL,                                                                                                                                                // ppEnabledLayerNames
1406                         static_cast<deUint32>(extensionNames == DE_NULL ? 0 : extensionNames->size()),  // enabledExtensionCount
1407                         extensionNames == DE_NULL ? DE_NULL : extensionNames->data(),                                   // ppEnabledExtensionNames
1408                         DE_NULL                                                                                                                                                 // pEnabledFeatures
1409                 };
1410
1411                 VkDevice                device = (VkDevice)DE_NULL;
1412                 const VkResult  res     = createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1413
1414                 if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1415                 {
1416                         numErrors++;
1417                         resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1418                                 + de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
1419                 }
1420                 if (device != (VkDevice)DE_NULL)
1421                 {
1422                         DeviceDriver deviceDriver(vkp, instance, device);
1423                         deviceDriver.destroyDevice(device, DE_NULL);
1424                 }
1425         }
1426 }
1427
1428 vector<string> removeExtensions (const vector<string>& a, const vector<const char*>& b)
1429 {
1430         vector<string>  res;
1431         set<string>             removeExts      (b.begin(), b.end());
1432
1433         for (const auto & aIter : a)
1434         {
1435                 if (!de::contains(removeExts, aIter))
1436                         res.push_back(aIter);
1437         }
1438
1439         return res;
1440 }
1441
1442 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
1443 {
1444         const PlatformInterface&                                vkp                                             = context.getPlatformInterface();
1445         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
1446         tcu::ResultCollector                                    resultCollector                 (log);
1447         const CustomInstance                                    instance                                (createCustomInstanceWithExtensions(context, context.getInstanceExtensions(), DE_NULL, true));
1448         const InstanceDriver&                                   instanceDriver                  (instance.getDriver());
1449         const VkPhysicalDevice                                  physicalDevice                  = chooseDevice(instanceDriver, instance, context.getTestContext().getCommandLine());
1450         const deUint32                                                  queueFamilyIndex                = 0;
1451         const deUint32                                                  queueCount                              = 1;
1452         const float                                                             queuePriority                   = 1.0f;
1453         const DeviceFeatures                                    deviceFeaturesAll               (context.getInstanceInterface(), context.getUsedApiVersion(), physicalDevice, context.getInstanceExtensions(), context.getDeviceExtensions(), DE_TRUE);
1454         const VkPhysicalDeviceFeatures2                 deviceFeatures2                 = deviceFeaturesAll.getCoreFeatures2();
1455         const VkPhysicalDeviceFeatures                  deviceFeatures                  = deviceFeatures2.features;
1456         const vector<VkQueueFamilyProperties>   queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
1457         int                                                                             numErrors                               = 0;
1458
1459         // Test features listed in VkPhysicalDeviceFeatures structure
1460         {
1461                 static const Feature features[] =
1462                 {
1463                         // robustBufferAccess is removed, because it's always supported.
1464                         FEATURE_ITEM(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
1465                         FEATURE_ITEM(VkPhysicalDeviceFeatures, imageCubeArray),
1466                         FEATURE_ITEM(VkPhysicalDeviceFeatures, independentBlend),
1467                         FEATURE_ITEM(VkPhysicalDeviceFeatures, geometryShader),
1468                         FEATURE_ITEM(VkPhysicalDeviceFeatures, tessellationShader),
1469                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sampleRateShading),
1470                         FEATURE_ITEM(VkPhysicalDeviceFeatures, dualSrcBlend),
1471                         FEATURE_ITEM(VkPhysicalDeviceFeatures, logicOp),
1472                         FEATURE_ITEM(VkPhysicalDeviceFeatures, multiDrawIndirect),
1473                         FEATURE_ITEM(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
1474                         FEATURE_ITEM(VkPhysicalDeviceFeatures, depthClamp),
1475                         FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBiasClamp),
1476                         FEATURE_ITEM(VkPhysicalDeviceFeatures, fillModeNonSolid),
1477                         FEATURE_ITEM(VkPhysicalDeviceFeatures, depthBounds),
1478                         FEATURE_ITEM(VkPhysicalDeviceFeatures, wideLines),
1479                         FEATURE_ITEM(VkPhysicalDeviceFeatures, largePoints),
1480                         FEATURE_ITEM(VkPhysicalDeviceFeatures, alphaToOne),
1481                         FEATURE_ITEM(VkPhysicalDeviceFeatures, multiViewport),
1482                         FEATURE_ITEM(VkPhysicalDeviceFeatures, samplerAnisotropy),
1483                         FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionETC2),
1484                         FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
1485                         FEATURE_ITEM(VkPhysicalDeviceFeatures, textureCompressionBC),
1486                         FEATURE_ITEM(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
1487                         FEATURE_ITEM(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
1488                         FEATURE_ITEM(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
1489                         FEATURE_ITEM(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
1490                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
1491                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
1492                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
1493                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
1494                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
1495                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
1496                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
1497                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
1498                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
1499                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
1500                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderClipDistance),
1501                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderCullDistance),
1502                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderFloat64),
1503                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt64),
1504                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderInt16),
1505                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceResidency),
1506                         FEATURE_ITEM(VkPhysicalDeviceFeatures, shaderResourceMinLod),
1507                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseBinding),
1508                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
1509                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
1510                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
1511                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency2Samples),
1512                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency4Samples),
1513                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency8Samples),
1514                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidency16Samples),
1515                         FEATURE_ITEM(VkPhysicalDeviceFeatures, sparseResidencyAliased),
1516                         FEATURE_ITEM(VkPhysicalDeviceFeatures, variableMultisampleRate),
1517                         FEATURE_ITEM(VkPhysicalDeviceFeatures, inheritedQueries)
1518                 };
1519
1520                 for (const auto& feature : features)
1521                 {
1522                         // Test only features that are not supported.
1523                         if (*(((VkBool32*)((deUint8*)(&deviceFeatures) + feature.offset))))
1524                                 continue;
1525
1526                         VkPhysicalDeviceFeatures                enabledFeatures                 = deviceFeatures;
1527                         *((VkBool32*)((deUint8*)(&enabledFeatures) + feature.offset)) = VK_TRUE;
1528
1529                         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
1530                         {
1531                                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1532                                 DE_NULL,
1533                                 (VkDeviceQueueCreateFlags)0u,
1534                                 queueFamilyIndex,
1535                                 queueCount,
1536                                 &queuePriority
1537                         };
1538                         const VkDeviceCreateInfo                deviceCreateInfo                =
1539                         {
1540                                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1541                                 DE_NULL,
1542                                 (VkDeviceCreateFlags)0u,
1543                                 1,
1544                                 &deviceQueueCreateInfo,
1545                                 0u,
1546                                 DE_NULL,
1547                                 0,
1548                                 DE_NULL,
1549                                 &enabledFeatures
1550                         };
1551
1552                         VkDevice                device  = DE_NULL;
1553                         const VkResult  res             = createUncheckedDevice(false, instanceDriver, physicalDevice, &deviceCreateInfo, DE_NULL, &device);
1554
1555                         if (res != VK_ERROR_FEATURE_NOT_PRESENT)
1556                         {
1557                                 numErrors++;
1558                                 resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
1559                                 + de::toString(feature.name) + ", which was reported as unsupported.");
1560                         }
1561
1562                         if (device != DE_NULL)
1563                         {
1564                                 DeviceDriver deviceDriver(vkp, instance, device);
1565                                 deviceDriver.destroyDevice(device, DE_NULL);
1566                         }
1567                 }
1568         }
1569
1570         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
1571 }
1572
1573 #include "vkDeviceFeatureTest.inl"
1574
1575 tcu::TestStatus createDeviceQueue2Test (Context& context)
1576 {
1577         if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
1578                 TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
1579
1580         const PlatformInterface&                                platformInterface               = context.getPlatformInterface();
1581         const VkInstance                                                instance                                = context.getInstance();
1582         const InstanceInterface&                                instanceDriver                  = context.getInstanceInterface();
1583         const VkPhysicalDevice                                  physicalDevice                  = context.getPhysicalDevice();
1584         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1585         const deUint32                                                  queueCount                              = 1;
1586         const deUint32                                                  queueIndex                              = 0;
1587         const float                                                             queuePriority                   = 1.0f;
1588
1589         VkPhysicalDeviceProtectedMemoryFeatures protectedMemoryFeature  =
1590         {
1591                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,    // VkStructureType                                      sType;
1592                 DE_NULL,                                                                                                                // void*                                                        pNext;
1593                 VK_FALSE                                                                                                                // VkBool32                                                     protectedMemory;
1594         };
1595
1596         VkPhysicalDeviceFeatures2                               features2;
1597         deMemset(&features2, 0, sizeof(features2));
1598         features2.sType                                                                                                 = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1599         features2.pNext                                                                                                 = &protectedMemoryFeature;
1600
1601         instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1602         if (protectedMemoryFeature.protectedMemory == VK_FALSE)
1603                 TCU_THROW(NotSupportedError, "Protected memory feature is not supported");
1604
1605         const VkDeviceQueueCreateInfo                   deviceQueueCreateInfo   =
1606         {
1607                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,                                             // VkStructureType                                      sType;
1608                 DE_NULL,                                                                                                                // const void*                                          pNext;
1609                 VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,                                                   // VkDeviceQueueCreateFlags                     flags;
1610                 queueFamilyIndex,                                                                                               // deUint32                                                     queueFamilyIndex;
1611                 queueCount,                                                                                                             // deUint32                                                     queueCount;
1612                 &queuePriority,                                                                                                 // const float*                                         pQueuePriorities;
1613         };
1614         const VkDeviceCreateInfo                                deviceCreateInfo                =
1615         {
1616                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                                   // VkStructureType                                      sType;
1617                 &features2,                                                                                                             // const void*                                          pNext;
1618                 (VkDeviceCreateFlags)0u,                                                                                // VkDeviceCreateFlags                          flags;
1619                 1,                                                                                                                              // deUint32                                                     queueCreateInfoCount;
1620                 &deviceQueueCreateInfo,                                                                                 // const VkDeviceQueueCreateInfo*       pQueueCreateInfos;
1621                 0,                                                                                                                              // deUint32                                                     enabledLayerCount;
1622                 DE_NULL,                                                                                                                // const char* const*                           ppEnabledLayerNames;
1623                 0,                                                                                                                              // deUint32                                                     enabledExtensionCount;
1624                 DE_NULL,                                                                                                                // const char* const*                           ppEnabledExtensionNames;
1625                 DE_NULL,                                                                                                                // const VkPhysicalDeviceFeatures*      pEnabledFeatures;
1626         };
1627
1628         const VkDeviceQueueInfo2                                deviceQueueInfo2                =
1629         {
1630                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,                                                  // VkStructureType                                      sType;
1631                 DE_NULL,                                                                                                                // const void*                                          pNext;
1632                 VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,                                                   // VkDeviceQueueCreateFlags                     flags;
1633                 queueFamilyIndex,                                                                                               // deUint32                                                     queueFamilyIndex;
1634                 queueIndex,                                                                                                             // deUint32                                                     queueIndex;
1635         };
1636
1637         {
1638                 const Unique<VkDevice>                          device                                  (createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), platformInterface, instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1639                 const DeviceDriver                                      deviceDriver                    (platformInterface, instance, device.get());
1640                 const VkQueue                                           queue2                                  = getDeviceQueue2(deviceDriver, *device, &deviceQueueInfo2);
1641
1642                 VK_CHECK(deviceDriver.queueWaitIdle(queue2));
1643         }
1644
1645         return tcu::TestStatus::pass("Pass");
1646 }
1647
1648 // Allocation tracking utilities
1649 struct  AllocTrack
1650 {
1651         bool                                            active;
1652         bool                                            wasAllocated;
1653         void*                                           alignedStartAddress;
1654         char*                                           actualStartAddress;
1655         size_t                                          requestedSizeBytes;
1656         size_t                                          actualSizeBytes;
1657         VkSystemAllocationScope         allocScope;
1658         deUint64                                        userData;
1659
1660         AllocTrack()
1661                 : active                                (false)
1662                 , wasAllocated                  (false)
1663                 , alignedStartAddress   (DE_NULL)
1664                 , actualStartAddress    (DE_NULL)
1665                 , requestedSizeBytes    (0)
1666                 , actualSizeBytes               (0)
1667                 , allocScope                    (VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)
1668                 , userData(0)                   {}
1669 };
1670
1671 // Global vector to track allocations. This will be resized before each test and emptied after
1672 // However, we have to globally define it so the allocation callback functions work properly
1673 std::vector<AllocTrack> g_allocatedVector;
1674 bool                                    g_intentionalFailEnabled        = false;
1675 deUint32                                g_intenionalFailIndex           = 0;
1676 deUint32                                g_intenionalFailCount           = 0;
1677 size_t                                  g_allocationsCount                      = 0;
1678
1679 void freeAllocTracker (void)
1680 {
1681         g_allocatedVector.clear();
1682         g_allocationsCount = 0;
1683 }
1684
1685 void initAllocTracker (size_t size, deUint32 intentionalFailIndex = (deUint32)~0)
1686 {
1687         if (g_allocatedVector.size() > 0)
1688                 freeAllocTracker();
1689
1690         g_allocatedVector.resize(size);
1691
1692         if (intentionalFailIndex != (deUint32)~0)
1693         {
1694                 g_intentionalFailEnabled        = true;
1695                 g_intenionalFailIndex           = intentionalFailIndex;
1696                 g_intenionalFailCount           = 0;
1697         }
1698         else
1699         {
1700                 g_intentionalFailEnabled        = false;
1701                 g_intenionalFailIndex           = 0;
1702                 g_intenionalFailCount           = 0;
1703         }
1704
1705         g_allocationsCount = 0;
1706 }
1707
1708 bool isAllocTrackerEmpty ()
1709 {
1710         bool success            = true;
1711         bool wasAllocated       = false;
1712
1713         for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1714         {
1715                 if (g_allocatedVector[vectorIdx].active)
1716                         success = false;
1717                 else if (!wasAllocated && g_allocatedVector[vectorIdx].wasAllocated)
1718                         wasAllocated = true;
1719         }
1720
1721         if (!g_intentionalFailEnabled && !wasAllocated)
1722                 success = false;
1723
1724         return success;
1725 }
1726
1727 VKAPI_ATTR void *VKAPI_CALL allocCallbackFunc (void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
1728 {
1729         if (g_intentionalFailEnabled)
1730                 if (++g_intenionalFailCount >= g_intenionalFailIndex)
1731                         return DE_NULL;
1732
1733         for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1734         {
1735                 if (!g_allocatedVector[vectorIdx].active)
1736                 {
1737                         g_allocatedVector[vectorIdx].requestedSizeBytes         = size;
1738                         g_allocatedVector[vectorIdx].actualSizeBytes            = size + (alignment - 1);
1739                         g_allocatedVector[vectorIdx].alignedStartAddress        = DE_NULL;
1740                         g_allocatedVector[vectorIdx].actualStartAddress         = new char[g_allocatedVector[vectorIdx].actualSizeBytes];
1741
1742                         if (g_allocatedVector[vectorIdx].actualStartAddress != DE_NULL)
1743                         {
1744                                 deUint64 addr   =       (deUint64)g_allocatedVector[vectorIdx].actualStartAddress;
1745                                 addr                    +=      (alignment - 1);
1746                                 addr                    &=      ~(alignment - 1);
1747                                 g_allocatedVector[vectorIdx].alignedStartAddress        = (void *)addr;
1748                                 g_allocatedVector[vectorIdx].allocScope                         = allocationScope;
1749                                 g_allocatedVector[vectorIdx].userData                           = (deUint64)pUserData;
1750                                 g_allocatedVector[vectorIdx].active                                     = true;
1751                                 g_allocatedVector[vectorIdx].wasAllocated                       = true;
1752                         }
1753
1754                         g_allocationsCount++;
1755                         return g_allocatedVector[vectorIdx].alignedStartAddress;
1756                 }
1757         }
1758         return DE_NULL;
1759 }
1760
1761 VKAPI_ATTR void VKAPI_CALL freeCallbackFunc (void *pUserData, void *pMemory)
1762 {
1763         DE_UNREF(pUserData);
1764
1765         for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1766         {
1767                 if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pMemory)
1768                 {
1769                         delete[] g_allocatedVector[vectorIdx].actualStartAddress;
1770                         g_allocatedVector[vectorIdx].active = false;
1771                         break;
1772                 }
1773         }
1774 }
1775
1776 VKAPI_ATTR void *VKAPI_CALL reallocCallbackFunc (void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
1777 {
1778         if (pOriginal != DE_NULL)
1779         {
1780                 for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
1781                 {
1782                         if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pOriginal)
1783                         {
1784                                 if (size == 0)
1785                                 {
1786                                         freeCallbackFunc(pUserData, pOriginal);
1787                                         return DE_NULL;
1788                                 }
1789                                 else if (size < g_allocatedVector[vectorIdx].requestedSizeBytes)
1790                                         return pOriginal;
1791                                 else
1792                                 {
1793                                         void *pNew = allocCallbackFunc(pUserData, size, alignment, allocationScope);
1794
1795                                         if (pNew != DE_NULL)
1796                                         {
1797                                                 size_t copySize = size;
1798
1799                                                 if (g_allocatedVector[vectorIdx].requestedSizeBytes < size)
1800                                                         copySize = g_allocatedVector[vectorIdx].requestedSizeBytes;
1801
1802                                                 memcpy(pNew, pOriginal, copySize);
1803                                                 freeCallbackFunc(pUserData, pOriginal);
1804                                         }
1805                                         return pNew;
1806                                 }
1807                         }
1808                 }
1809                 return DE_NULL;
1810         }
1811         else
1812                 return allocCallbackFunc(pUserData, size, alignment, allocationScope);
1813 }
1814
1815 tcu::TestStatus createInstanceDeviceIntentionalAllocFail (Context& context)
1816 {
1817         const PlatformInterface&        vkp                                     = context.getPlatformInterface();
1818         const deUint32                          chosenDevice            = context.getTestContext().getCommandLine().getVKDeviceId() - 1;
1819         VkInstance                                      instance                        = DE_NULL;
1820         VkDevice                                        device                          = DE_NULL;
1821         deUint32                                        physicalDeviceCount     = 0;
1822         deUint32                                        queueFamilyCount        = 0;
1823         deUint32                                        queueFamilyIndex        = 0;
1824         const float                                     queuePriority           = 0.0f;
1825         const VkAllocationCallbacks     allocationCallbacks     =
1826         {
1827                 DE_NULL,                                                                // userData
1828                 allocCallbackFunc,                                              // pfnAllocation
1829                 reallocCallbackFunc,                                    // pfnReallocation
1830                 freeCallbackFunc,                                               // pfnFree
1831                 DE_NULL,                                                                // pfnInternalAllocation
1832                 DE_NULL                                                                 // pfnInternalFree
1833         };
1834         const VkApplicationInfo         appInfo                         =
1835         {
1836                 VK_STRUCTURE_TYPE_APPLICATION_INFO,             // sType
1837                 DE_NULL,                                                                // pNext
1838                 "appName",                                                              // pApplicationName
1839                 0u,                                                                             // applicationVersion
1840                 "engineName",                                                   // pEngineName
1841                 0u,                                                                             // engineVersion
1842                 VK_API_VERSION_1_0                                              // apiVersion
1843         };
1844
1845         const VkInstanceCreateInfo      instanceCreateInfo      =
1846         {
1847                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
1848                 DE_NULL,                                                                // pNext
1849                 (VkInstanceCreateFlags)0u,                              // flags
1850                 &appInfo,                                                               // pApplicationInfo
1851                 0u,                                                                             // enabledLayerCount
1852                 DE_NULL,                                                                // ppEnabledLayerNames
1853                 0u,                                                                             // enabledExtensionCount
1854                 DE_NULL                                                                 // ppEnabledExtensionNames
1855         };
1856
1857         deUint32                                        failIndex                       = 0;
1858         VkResult                                        result                          = VK_SUCCESS;
1859         size_t                                          max_allowed_alloc       = 0;
1860
1861         do
1862         {
1863                 if (max_allowed_alloc == 0)
1864                 {
1865                         if (result != VK_SUCCESS)
1866                                 return tcu::TestStatus::fail("Could not create instance and device");
1867
1868                         initAllocTracker(99999);
1869                 }
1870                 else
1871                 {
1872                         initAllocTracker(max_allowed_alloc, failIndex++);
1873
1874                         if (failIndex >= static_cast<deUint32>(max_allowed_alloc))
1875                                 return tcu::TestStatus::fail("Out of retries, could not create instance and device");
1876                 }
1877
1878                 // if the number of allocations the driver makes is large, we may end up
1879                 // taking more than the watchdog timeout. touch here to avoid spurious
1880                 // failures.
1881                 if (failIndex % 128 == 0)
1882                         context.getTestContext().touchWatchdog();
1883
1884                 result = vkp.createInstance(&instanceCreateInfo, &allocationCallbacks, &instance);
1885
1886                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1887                 {
1888                         if (!isAllocTrackerEmpty())
1889                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1890
1891                         freeAllocTracker();
1892                         continue;
1893                 }
1894                 else if (result != VK_SUCCESS)
1895                         return tcu::TestStatus::fail("createInstance returned " + de::toString(result));
1896
1897                 const InstanceDriver            instanceDriver  (vkp, instance);
1898                 const InstanceInterface&        vki                             (instanceDriver);
1899
1900                 result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, DE_NULL);
1901
1902                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1903                 {
1904                         vki.destroyInstance(instance, &allocationCallbacks);
1905
1906                         if (!isAllocTrackerEmpty())
1907                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1908
1909                         freeAllocTracker();
1910                         continue;
1911                 }
1912                 else if (result != VK_SUCCESS)
1913                         return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
1914
1915                 vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
1916
1917                 result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
1918
1919                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1920                 {
1921                         vki.destroyInstance(instance, &allocationCallbacks);
1922
1923                         if (!isAllocTrackerEmpty())
1924                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1925
1926                         freeAllocTracker();
1927                         continue;
1928                 }
1929                 else if (result != VK_SUCCESS)
1930                         return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
1931
1932                 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, DE_NULL);
1933
1934                 if (queueFamilyCount == 0u)
1935                         return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
1936
1937                 vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
1938
1939                 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, queueFamilies.data());
1940
1941                 if (queueFamilyCount == 0u)
1942                         return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
1943
1944                 for (deUint32 i = 0; i < queueFamilyCount; i++)
1945                 {
1946                         if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
1947                         {
1948                                 queueFamilyIndex = i;
1949                                 break;
1950                         }
1951                 }
1952
1953                 const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
1954                 {
1955                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,     // sType
1956                         DE_NULL,                                                                        // pNext
1957                         (VkDeviceQueueCreateFlags)0u,                           // flags
1958                         queueFamilyIndex,                                                       // queueFamilyIndex
1959                         1u,                                                                                     // queueCount
1960                         &queuePriority                                                          // pQueuePriorities
1961                 };
1962
1963                 const VkDeviceCreateInfo                deviceCreateInfo                =
1964                 {
1965                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,           // sType
1966                         DE_NULL,                                                                        // pNext
1967                         (VkDeviceCreateFlags)0u,                                        // flags
1968                         1u,                                                                                     // queueCreateInfoCount
1969                         &deviceQueueCreateInfo,                                         // pQueueCreateInfos
1970                         0u,                                                                                     // enabledLayerCount
1971                         DE_NULL,                                                                        // ppEnabledLayerNames
1972                         0u,                                                                                     // enabledExtensionCount
1973                         DE_NULL,                                                                        // ppEnabledExtensionNames
1974                         DE_NULL                                                                         // pEnabledFeatures
1975                 };
1976
1977                 result = createUncheckedDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vki, physicalDevices[chosenDevice], &deviceCreateInfo, &allocationCallbacks, &device);
1978
1979                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1980                 {
1981                         vki.destroyInstance(instance, &allocationCallbacks);
1982
1983                         if (!isAllocTrackerEmpty())
1984                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1985
1986                         freeAllocTracker();
1987                         continue;
1988                 }
1989                 else if (result != VK_SUCCESS)
1990                         return tcu::TestStatus::fail("VkCreateDevice returned " + de::toString(result));
1991
1992                 DeviceDriver(vkp, instance, device).destroyDevice(device, &allocationCallbacks);
1993                 vki.destroyInstance(instance, &allocationCallbacks);
1994                 if (max_allowed_alloc == 0)
1995                 {
1996                         max_allowed_alloc       = g_allocationsCount + 100;
1997                         result                          = VK_ERROR_OUT_OF_HOST_MEMORY;
1998                 }
1999                 freeAllocTracker();
2000         }
2001         while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
2002
2003         return tcu::TestStatus::pass("Pass");
2004 }
2005
2006 } // anonymous
2007
2008 static inline void addFunctionCaseInNewSubgroup (
2009         tcu::TestContext&                       testCtx,
2010         tcu::TestCaseGroup*                     group,
2011         const std::string&                      subgroupName,
2012         const std::string&                      subgroupDescription,
2013         FunctionInstance0::Function     testFunc)
2014 {
2015         de::MovePtr<tcu::TestCaseGroup> subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2016         addFunctionCase(subgroup.get(), "basic", "", testFunc);
2017         group->addChild(subgroup.release());
2018 }
2019
2020 template<typename Arg0>
2021 static void addFunctionCaseInNewSubgroup (
2022         tcu::TestContext&                                                       testCtx,
2023         tcu::TestCaseGroup*                                                     group,
2024         const std::string&                                                      subgroupName,
2025         const std::string&                                                      subgroupDescription,
2026         typename FunctionSupport1<Arg0>::Function       checkSupport,
2027         typename FunctionInstance1<Arg0>::Function      testFunc,
2028         Arg0                                                                            arg0)
2029 {
2030         de::MovePtr<tcu::TestCaseGroup> subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str(), subgroupDescription.c_str()));
2031         subgroup->addChild(createFunctionCase<Arg0>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "basic", "", checkSupport, testFunc, arg0));
2032         group->addChild(subgroup.release());
2033 }
2034
2035 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
2036 {
2037         de::MovePtr<tcu::TestCaseGroup> deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));
2038
2039         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_name_version",                                  "", createInstanceTest);
2040         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_invalid_api_version",                   "", createInstanceWithInvalidApiVersionTest);
2041         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_null_appinfo",                                  "", createInstanceWithNullApplicationInfoTest);
2042         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_unsupported_extensions",                "", createInstanceWithUnsupportedExtensionsTest);
2043         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_extension_name_abuse",                  "", createInstanceWithExtensionNameAbuseTest);
2044         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_layer_name_abuse",                              "", createInstanceWithLayerNameAbuseTest);
2045         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "enumerate_devices_alloc_leak",                                  "", enumerateDevicesAllocLeakTest);
2046         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device",                                                                 "", createDeviceTest);
2047         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_multiple_devices",                                               "", createMultipleDevicesTest);
2048         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_unsupported_extensions",                  "", createDeviceWithUnsupportedExtensionsTest);
2049         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_various_queue_counts",                    "", createDeviceWithVariousQueueCountsTest);
2050         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority",                                 "", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, false);
2051         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_khr",                             "", checkGlobalPrioritySupport, createDeviceWithGlobalPriorityTest, true);
2052         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query",                   "", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, false);
2053         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_global_priority_query_khr",               "", checkGlobalPriorityQuerySupport, createDeviceWithQueriedGlobalPriorityTest, true);
2054         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_features2",                                               "", createDeviceFeatures2Test);
2055         {
2056                 de::MovePtr<tcu::TestCaseGroup> subgroup(new tcu::TestCaseGroup(testCtx, "create_device_unsupported_features", ""));
2057                 addFunctionCase(subgroup.get(), "core", "", createDeviceWithUnsupportedFeaturesTest);
2058                 addSeparateUnsupportedFeatureTests(subgroup.get());
2059                 deviceInitializationTests->addChild(subgroup.release());
2060         }
2061         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_device_queue2",                                                  "", createDeviceQueue2Test);
2062         addFunctionCaseInNewSubgroup(testCtx, deviceInitializationTests.get(), "create_instance_device_intentional_alloc_fail", "", createInstanceDeviceIntentionalAllocFail);
2063
2064         return deviceInitializationTests.release();
2065 }
2066
2067 } // api
2068 } // vkt