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