Test creating device when out of host memory
[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
27 #include "vkDefs.hpp"
28 #include "vkPlatform.hpp"
29 #include "vkStrUtil.hpp"
30 #include "vkRef.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkDeviceUtil.hpp"
35 #include "vkApiVersion.hpp"
36
37 #include "tcuTestLog.hpp"
38 #include "tcuResultCollector.hpp"
39 #include "tcuCommandLine.hpp"
40
41 #include "deUniquePtr.hpp"
42 #include "deStringUtil.hpp"
43
44 #include <vector>
45
46 namespace vkt
47 {
48 namespace api
49 {
50
51 namespace
52 {
53
54 using namespace vk;
55 using namespace std;
56 using std::vector;
57 using tcu::TestLog;
58
59 tcu::TestStatus createInstanceTest (Context& context)
60 {
61         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
62         tcu::ResultCollector            resultCollector                 (log);
63         const char*                                     appNames[]                              = { "appName", DE_NULL, "",  "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" };
64         const char*                                     engineNames[]                   = { "engineName", DE_NULL, "",  "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" };
65         const int                   patchNumbers[]          = { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 };
66         const deUint32                          appVersions[]                   = { 0, 1, (deUint32)-1 };
67         const deUint32                          engineVersions[]                = { 0, 1, (deUint32)-1 };
68         const PlatformInterface&        platformInterface               = context.getPlatformInterface();
69         vector<VkApplicationInfo>       appInfos;
70
71         // test over appName
72         for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++)
73         {
74                 const VkApplicationInfo appInfo =
75                 {
76                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
77                         DE_NULL,                                                                // const void*                                  pNext;
78                         appNames[appNameNdx],                                   // const char*                                  pAppName;
79                         0u,                                                                             // deUint32                                             appVersion;
80                         "engineName",                                                   // const char*                                  pEngineName;
81                         0u,                                                                             // deUint32                                             engineVersion;
82                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
83                 };
84
85                 appInfos.push_back(appInfo);
86         }
87
88         // test over engineName
89         for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++)
90         {
91                 const VkApplicationInfo appInfo =
92                 {
93                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
94                         DE_NULL,                                                                // const void*                                  pNext;
95                         "appName",                                                              // const char*                                  pAppName;
96                         0u,                                                                             // deUint32                                             appVersion;
97                         engineNames[engineNameNdx],                             // const char*                                  pEngineName;
98                         0u,                                                                             // deUint32                                             engineVersion;
99                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
100                 };
101
102                 appInfos.push_back(appInfo);
103         }
104
105         // test over appVersion
106         for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++)
107         {
108                 const VkApplicationInfo appInfo =
109                 {
110                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
111                         DE_NULL,                                                                // const void*                                  pNext;
112                         "appName",                                                              // const char*                                  pAppName;
113                         appVersions[appVersionNdx],                             // deUint32                                             appVersion;
114                         "engineName",                                                   // const char*                                  pEngineName;
115                         0u,                                                                             // deUint32                                             engineVersion;
116                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
117                 };
118
119                 appInfos.push_back(appInfo);
120         }
121
122         // test over engineVersion
123         for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++)
124         {
125                 const VkApplicationInfo appInfo =
126                 {
127                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
128                         DE_NULL,                                                                // const void*                                  pNext;
129                         "appName",                                                              // const char*                                  pAppName;
130                         0u,                                                                             // deUint32                                             appVersion;
131                         "engineName",                                                   // const char*                                  pEngineName;
132                         engineVersions[engineVersionNdx],               // deUint32                                             engineVersion;
133                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
134                 };
135
136                 appInfos.push_back(appInfo);
137         }
138         // patch component of api version checking (should be ignored by implementation)
139         for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++)
140         {
141                 const VkApplicationInfo appInfo =
142                 {
143                         VK_STRUCTURE_TYPE_APPLICATION_INFO,                                     // VkStructureType                              sType;
144                         DE_NULL,                                                                                        // const void*                                  pNext;
145                         "appName",                                                                                      // const char*                                  pAppName;
146                         0u,                                                                                                     // deUint32                                             appVersion;
147                         "engineName",                                                                           // const char*                                  pEngineName;
148                         0u,                                                                                                     // deUint32                                             engineVersion;
149                         VK_MAKE_VERSION(1, 0, patchNumbers[patchVersion]),      // deUint32                                             apiVersion;
150                 };
151
152                 appInfos.push_back(appInfo);
153         }
154
155         // test when apiVersion is 0
156         {
157                 const VkApplicationInfo appInfo =
158                 {
159                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
160                         DE_NULL,                                                                // const void*                                  pNext;
161                         "appName",                                                              // const char*                                  pAppName;
162                         0u,                                                                             // deUint32                                             appVersion;
163                         "engineName",                                                   // const char*                                  pEngineName;
164                         0u,                                                                             // deUint32                                             engineVersion;
165                         0u,                                                                             // deUint32                                             apiVersion;
166                 };
167
168                 appInfos.push_back(appInfo);
169         }
170
171         // run the tests!
172         for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx)
173         {
174                 const VkApplicationInfo&                appInfo                                 = appInfos[appInfoNdx];
175                 const VkInstanceCreateInfo              instanceCreateInfo              =
176                 {
177                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType                              sType;
178                         DE_NULL,                                                                // const void*                                  pNext;
179                         (VkInstanceCreateFlags)0u,                              // VkInstanceCreateFlags                flags;
180                         &appInfo,                                                               // const VkApplicationInfo*             pAppInfo;
181                         0u,                                                                             // deUint32                                             layerCount;
182                         DE_NULL,                                                                // const char*const*                    ppEnabledLayernames;
183                         0u,                                                                             // deUint32                                             extensionCount;
184                         DE_NULL,                                                                // const char*const*                    ppEnabledExtensionNames;
185                 };
186
187                 log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage;
188
189                 try
190                 {
191                         const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo));
192                         log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
193                 }
194                 catch (const vk::Error& err)
195                 {
196                         resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
197                 }
198         }
199
200         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
201 }
202
203 tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context)
204 {
205         tcu::TestLog&                           log                                     = context.getTestContext().getLog();
206         tcu::ResultCollector            resultCollector         (log);
207         const PlatformInterface&        platformInterface       = context.getPlatformInterface();
208         const ApiVersion                        apiVersion                      = unpackVersion(VK_API_VERSION);
209         const deUint32                          invalidMajorVersion     = (1 << 10) - 1;
210         const deUint32                          invalidMinorVersion     = (1 << 10) - 1;
211         vector<ApiVersion>                      invalidApiVersions;
212
213         invalidApiVersions.push_back(ApiVersion(invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
214         invalidApiVersions.push_back(ApiVersion(apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum));
215
216         for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++)
217         {
218                 const VkApplicationInfo appInfo                                 =
219                 {
220                         VK_STRUCTURE_TYPE_APPLICATION_INFO,                     // VkStructureType                              sType;
221                         DE_NULL,                                                                        // const void*                                  pNext;
222                         "appName",                                                                      // const char*                                  pAppName;
223                         0u,                                                                                     // deUint32                                             appVersion;
224                         "engineName",                                                           // const char*                                  pEngineName;
225                         0u,                                                                                     // deUint32                                             engineVersion;
226                         pack(invalidApiVersions[apiVersionNdx]),        // deUint32                                             apiVersion;
227                 };
228                 const VkInstanceCreateInfo instanceCreateInfo   =
229                 {
230                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,         // VkStructureType                              sType;
231                         DE_NULL,                                                                        // const void*                                  pNext;
232                         (VkInstanceCreateFlags)0u,                                      // VkInstanceCreateFlags                flags;
233                         &appInfo,                                                                       // const VkApplicationInfo*             pAppInfo;
234                         0u,                                                                                     // deUint32                                             layerCount;
235                         DE_NULL,                                                                        // const char*const*                    ppEnabledLayernames;
236                         0u,                                                                                     // deUint32                                             extensionCount;
237                         DE_NULL,                                                                        // const char*const*                    ppEnabledExtensionNames;
238                 };
239
240
241                 log << TestLog::Message
242                         <<"VK_API_VERSION defined in vulkan.h: " << apiVersion
243                         << ", api version used to create instance: " << invalidApiVersions[apiVersionNdx]
244                         << TestLog::EndMessage;
245
246                 {
247                         VkInstance              instance        = (VkInstance)0;
248                         const VkResult  result          = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
249                         const bool              gotInstance     = !!instance;
250
251                         if (instance)
252                         {
253                                 const InstanceDriver    instanceIface   (platformInterface, instance);
254                                 instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
255                         }
256
257                         if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
258                         {
259                                 TCU_CHECK(!gotInstance);
260                                 log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
261                         }
262                         else
263                                 resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
264                 }
265         }
266
267         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
268 }
269
270 tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context)
271 {
272         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
273         tcu::ResultCollector            resultCollector                 (log);
274         const PlatformInterface&        platformInterface               = context.getPlatformInterface();
275
276         const VkInstanceCreateInfo              instanceCreateInfo              =
277         {
278                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType                              sType;
279                 DE_NULL,                                                                // const void*                                  pNext;
280                 (VkInstanceCreateFlags)0u,                              // VkInstanceCreateFlags                flags;
281                 DE_NULL,                                                                // const VkApplicationInfo*             pAppInfo;
282                 0u,                                                                             // deUint32                                             layerCount;
283                 DE_NULL,                                                                // const char*const*                    ppEnabledLayernames;
284                 0u,                                                                             // deUint32                                             extensionCount;
285                 DE_NULL,                                                                // const char*const*                    ppEnabledExtensionNames;
286         };
287
288         log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage;
289
290         try
291         {
292                 const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo));
293                 log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
294         }
295         catch (const vk::Error& err)
296         {
297                 resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
298         }
299
300         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
301 }
302
303 tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context)
304 {
305         tcu::TestLog&                                           log                                             = context.getTestContext().getLog();
306         const PlatformInterface&                        platformInterface               = context.getPlatformInterface();
307         const char*                                                     enabledExtensions[]             = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"};
308         const VkApplicationInfo                         appInfo                                 =
309         {
310                 VK_STRUCTURE_TYPE_APPLICATION_INFO,                                             // VkStructureType                              sType;
311                 DE_NULL,                                                                                                // const void*                                  pNext;
312                 "appName",                                                                                              // const char*                                  pAppName;
313                 0u,                                                                                                             // deUint32                                             appVersion;
314                 "engineName",                                                                                   // const char*                                  pEngineName;
315                 0u,                                                                                                             // deUint32                                             engineVersion;
316                 VK_API_VERSION,                                                                                 // deUint32                                             apiVersion;
317         };
318         const VkInstanceCreateInfo                      instanceCreateInfo              =
319         {
320                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,                                 // VkStructureType                              sType;
321                 DE_NULL,                                                                                                // const void*                                  pNext;
322                 (VkInstanceCreateFlags)0u,                                                              // VkInstanceCreateFlags                flags;
323                 &appInfo,                                                                                               // const VkApplicationInfo*             pAppInfo;
324                 0u,                                                                                                             // deUint32                                             layerCount;
325                 DE_NULL,                                                                                                // const char*const*                    ppEnabledLayernames;
326                 DE_LENGTH_OF_ARRAY(enabledExtensions),                                  // deUint32                                             extensionCount;
327                 enabledExtensions,                                                                              // const char*const*                    ppEnabledExtensionNames;
328         };
329
330         log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
331
332         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
333                 log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
334
335         {
336                 VkInstance              instance        = (VkInstance)0;
337                 const VkResult  result          = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
338                 const bool              gotInstance     = !!instance;
339
340                 if (instance)
341                 {
342                         const InstanceDriver    instanceIface   (platformInterface, instance);
343                         instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
344                 }
345
346                 if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
347                 {
348                         TCU_CHECK(!gotInstance);
349                         return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected.");
350                 }
351                 else
352                         return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded.");
353         }
354 }
355
356 tcu::TestStatus createDeviceTest (Context& context)
357 {
358         const PlatformInterface&                platformInterface               = context.getPlatformInterface();
359         const Unique<VkInstance>                instance                                (createDefaultInstance(platformInterface));
360         const InstanceDriver                    instanceDriver                  (platformInterface, instance.get());
361         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
362         const deUint32                                  queueFamilyIndex                = 0;
363         const deUint32                                  queueCount                              = 1;
364         const deUint32                                  queueIndex                              = 0;
365         const float                                             queuePriority                   = 1.0f;
366         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
367         {
368                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
369                 DE_NULL,
370                 (VkDeviceQueueCreateFlags)0u,
371                 queueFamilyIndex,                                               //queueFamilyIndex;
372                 queueCount,                                                             //queueCount;
373                 &queuePriority,                                                 //pQueuePriorities;
374         };
375         const VkDeviceCreateInfo                deviceCreateInfo        =
376         {
377                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
378                 DE_NULL,                                                                //pNext;
379                 (VkDeviceCreateFlags)0u,
380                 1,                                                                              //queueRecordCount;
381                 &deviceQueueCreateInfo,                                 //pRequestedQueues;
382                 0,                                                                              //layerCount;
383                 DE_NULL,                                                                //ppEnabledLayerNames;
384                 0,                                                                              //extensionCount;
385                 DE_NULL,                                                                //ppEnabledExtensionNames;
386                 DE_NULL,                                                                //pEnabledFeatures;
387         };
388
389         const Unique<VkDevice>                  device                                  (createDevice(instanceDriver, physicalDevice, &deviceCreateInfo));
390         const DeviceDriver                              deviceDriver                    (instanceDriver, device.get());
391         const VkQueue                                   queue                                   = getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
392
393         VK_CHECK(deviceDriver.queueWaitIdle(queue));
394
395         return tcu::TestStatus::pass("Pass");
396 }
397
398 tcu::TestStatus createMultipleDevicesTest (Context& context)
399 {
400         tcu::TestLog&                                                                           log                                             = context.getTestContext().getLog();
401         tcu::ResultCollector                                                            resultCollector                 (log);
402         const int                                                                                       numDevices                              = 5;
403         const PlatformInterface&                                                        platformInterface               = context.getPlatformInterface();
404         const Unique<VkInstance>                                                        instance                                (createDefaultInstance(platformInterface));
405         const InstanceDriver                                                            instanceDriver                  (platformInterface, instance.get());
406         const VkPhysicalDevice                                                          physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
407         const deUint32                                                                          queueFamilyIndex                = 0;
408         const deUint32                                                                          queueCount                              = 1;
409         const deUint32                                                                          queueIndex                              = 0;
410         const float                                                                                     queuePriority                   = 1.0f;
411         const VkDeviceQueueCreateInfo                                           deviceQueueCreateInfo   =
412         {
413                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
414                 DE_NULL,
415                 (VkDeviceQueueCreateFlags)0u,                                   //flags;
416                 queueFamilyIndex,                                                               //queueFamilyIndex;
417                 queueCount,                                                                             //queueCount;
418                 &queuePriority,                                                                 //pQueuePriorities;
419         };
420         const VkDeviceCreateInfo                                                        deviceCreateInfo                =
421         {
422                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                   //sType;
423                 DE_NULL,                                                                                //pNext;
424                 (VkDeviceCreateFlags)0u,
425                 1,                                                                                              //queueRecordCount;
426                 &deviceQueueCreateInfo,                                                 //pRequestedQueues;
427                 0,                                                                                              //layerCount;
428                 DE_NULL,                                                                                //ppEnabledLayerNames;
429                 0,                                                                                              //extensionCount;
430                 DE_NULL,                                                                                //ppEnabledExtensionNames;
431                 DE_NULL,                                                                                //pEnabledFeatures;
432         };
433         vector<VkDevice>                                                                        devices(numDevices, (VkDevice)DE_NULL);
434
435         try
436         {
437                 for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++)
438                 {
439                         const VkResult result = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]);
440
441                         if (result != VK_SUCCESS)
442                         {
443                                 resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result));
444                                 break;
445                         }
446
447                         {
448                                 const DeviceDriver      deviceDriver    (instanceDriver, devices[deviceNdx]);
449                                 const VkQueue           queue                   = getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex);
450
451                                 VK_CHECK(deviceDriver.queueWaitIdle(queue));
452                         }
453                 }
454         }
455         catch (const vk::Error& error)
456         {
457                 resultCollector.fail(de::toString(error.getError()));
458         }
459         catch (...)
460         {
461                 for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
462                 {
463                         if (devices[deviceNdx] != (VkDevice)DE_NULL)
464                         {
465                                 DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]);
466                                 deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
467                         }
468                 }
469
470                 throw;
471         }
472
473         for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
474         {
475                 if (devices[deviceNdx] != (VkDevice)DE_NULL)
476                 {
477                         DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]);
478                         deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
479                 }
480         }
481
482         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
483 }
484
485 tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context)
486 {
487         tcu::TestLog&                                   log                                             = context.getTestContext().getLog();
488         const PlatformInterface&                platformInterface               = context.getPlatformInterface();
489         const Unique<VkInstance>                instance                                (createDefaultInstance(platformInterface));
490         const InstanceDriver                    instanceDriver                  (platformInterface, instance.get());
491         const char*                                             enabledExtensions[]             = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"};
492         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
493         const float                                             queuePriority                   = 1.0f;
494         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
495         {
496                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
497                 DE_NULL,
498                 (VkDeviceQueueCreateFlags)0u,
499                 0,                                                                              //queueFamilyIndex;
500                 1,                                                                              //queueCount;
501                 &queuePriority,                                                 //pQueuePriorities;
502         };
503         const VkDeviceCreateInfo                deviceCreateInfo                =
504         {
505                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
506                 DE_NULL,                                                                //pNext;
507                 (VkDeviceCreateFlags)0u,
508                 1,                                                                              //queueRecordCount;
509                 &deviceQueueCreateInfo,                                 //pRequestedQueues;
510                 0,                                                                              //layerCount;
511                 DE_NULL,                                                                //ppEnabledLayerNames;
512                 DE_LENGTH_OF_ARRAY(enabledExtensions),  //extensionCount;
513                 enabledExtensions,                                              //ppEnabledExtensionNames;
514                 DE_NULL,                                                                //pEnabledFeatures;
515         };
516
517         log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
518
519         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
520                 log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
521
522         {
523                 VkDevice                device          = (VkDevice)0;
524                 const VkResult  result          = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device);
525                 const bool              gotDevice       = !!device;
526
527                 if (device)
528                 {
529                         const DeviceDriver      deviceIface     (instanceDriver, device);
530                         deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
531                 }
532
533                 if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
534                 {
535                         TCU_CHECK(!gotDevice);
536                         return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected.");
537                 }
538                 else
539                         return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed.");
540         }
541 }
542
543 deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)
544 {
545         deUint32 maxQueueCount = 0;
546
547         for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
548         {
549                 maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount);
550         }
551
552         return maxQueueCount;
553 }
554
555 tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context)
556 {
557         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
558         const int                                                               queueCountDiff                  = 1;
559         const PlatformInterface&                                platformInterface               = context.getPlatformInterface();
560         const Unique<VkInstance>                                instance                                (createDefaultInstance(platformInterface));
561         const InstanceDriver                                    instanceDriver                  (platformInterface, instance.get());
562         const VkPhysicalDevice                                  physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
563         const vector<VkQueueFamilyProperties>   queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
564         const vector<float>                                             queuePriorities                 (getGlobalMaxQueueCount(queueFamilyProperties), 1.0f);
565         vector<VkDeviceQueueCreateInfo>                 deviceQueueCreateInfos;
566
567         for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
568         {
569                 const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount;
570
571                 for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff)
572                 {
573                         const VkDeviceQueueCreateInfo queueCreateInfo =
574                         {
575                                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
576                                 DE_NULL,
577                                 (VkDeviceQueueCreateFlags)0u,
578                                 queueFamilyNdx,
579                                 queueCount,
580                                 queuePriorities.data()
581                         };
582
583                         deviceQueueCreateInfos.push_back(queueCreateInfo);
584                 }
585         }
586
587         for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++)
588         {
589                 const VkDeviceQueueCreateInfo&  queueCreateInfo         = deviceQueueCreateInfos[testNdx];
590                 const VkDeviceCreateInfo                deviceCreateInfo        =
591                 {
592                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
593                         DE_NULL,                                                                //pNext;
594                         (VkDeviceCreateFlags)0u,
595                         1,                                                                              //queueRecordCount;
596                         &queueCreateInfo,                                               //pRequestedQueues;
597                         0,                                                                              //layerCount;
598                         DE_NULL,                                                                //ppEnabledLayerNames;
599                         0,                                                                              //extensionCount;
600                         DE_NULL,                                                                //ppEnabledExtensionNames;
601                         DE_NULL,                                                                //pEnabledFeatures;
602                 };
603                 const Unique<VkDevice>                  device                          (createDevice(instanceDriver, physicalDevice, &deviceCreateInfo));
604                 const DeviceDriver                              deviceDriver            (instanceDriver, device.get());
605                 const deUint32                                  queueFamilyIndex        = deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
606                 const deUint32                                  queueCount                      = deviceCreateInfo.pQueueCreateInfos->queueCount;
607
608                 for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++)
609                 {
610                         const VkQueue           queue   = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex);
611                         VkResult                        result;
612
613                         TCU_CHECK(!!queue);
614
615                         result = deviceDriver.queueWaitIdle(queue);
616                         if (result != VK_SUCCESS)
617                         {
618                                 log << TestLog::Message
619                                         << "vkQueueWaitIdle failed"
620                                         << ",  queueIndex = " << queueIndex
621                                         << ", queueCreateInfo " << queueCreateInfo
622                                         << ", Error Code: " << result
623                                         << TestLog::EndMessage;
624                                 return tcu::TestStatus::fail("Fail");
625                         }
626                 }
627         }
628         return tcu::TestStatus::pass("Pass");
629 }
630
631 Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, const char* extensionName)
632 {
633         const vector<VkExtensionProperties>     instanceExts    = enumerateInstanceExtensionProperties(vkp, DE_NULL);
634         vector<string>                                          enabledExts;
635
636         if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName)))
637                 TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str());
638
639         enabledExts.push_back(extensionName);
640
641         return createDefaultInstance(vkp, vector<string>() /* layers */, enabledExts);
642 }
643
644 tcu::TestStatus createDeviceFeatures2Test (Context& context)
645 {
646         const PlatformInterface&                vkp                                             = context.getPlatformInterface();
647         const Unique<VkInstance>                instance                                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2"));
648         const InstanceDriver                    vki                                             (vkp, instance.get());
649         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(vki, instance.get(), context.getTestContext().getCommandLine());
650         const deUint32                                  queueFamilyIndex                = 0;
651         const deUint32                                  queueCount                              = 1;
652         const deUint32                                  queueIndex                              = 0;
653         const float                                             queuePriority                   = 1.0f;
654
655         VkPhysicalDeviceFeatures2KHR    enabledFeatures;
656         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
657         {
658                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
659                 DE_NULL,
660                 (VkDeviceQueueCreateFlags)0u,
661                 queueFamilyIndex,
662                 queueCount,
663                 &queuePriority,
664         };
665         const VkDeviceCreateInfo                deviceCreateInfo        =
666         {
667                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
668                 &enabledFeatures,
669                 (VkDeviceCreateFlags)0u,
670                 1,
671                 &deviceQueueCreateInfo,
672                 0,
673                 DE_NULL,
674                 0,
675                 DE_NULL,
676                 DE_NULL,
677         };
678
679         // Populate enabledFeatures
680         enabledFeatures.sType           = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
681         enabledFeatures.pNext           = DE_NULL;
682
683         vki.getPhysicalDeviceFeatures2KHR(physicalDevice, &enabledFeatures);
684
685         {
686                 const Unique<VkDevice>  device          (createDevice(vki, physicalDevice, &deviceCreateInfo));
687                 const DeviceDriver              vkd                     (vki, device.get());
688                 const VkQueue                   queue           = getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);
689
690                 VK_CHECK(vkd.queueWaitIdle(queue));
691         }
692
693         return tcu::TestStatus::pass("Pass");
694 }
695
696 struct Feature
697 {
698         const char*     name;
699         size_t          offset;
700 };
701
702 #define FEATURE_ITEM(MEMBER) {#MEMBER, DE_OFFSET_OF(VkPhysicalDeviceFeatures, MEMBER)}
703
704 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
705 {
706         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
707         tcu::ResultCollector            resultCollector                 (log);
708         const PlatformInterface&        platformInterface               = context.getPlatformInterface();
709         const Unique<VkInstance>        instance                                (createDefaultInstance(platformInterface));
710         const InstanceDriver            instanceDriver                  (platformInterface, instance.get());
711         const VkPhysicalDevice          physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
712         const deUint32                          queueFamilyIndex                = 0;
713         const deUint32                          queueCount                              = 1;
714         const float                                     queuePriority                   = 1.0f;
715         VkPhysicalDeviceFeatures        physicalDeviceFeatures;
716
717         instanceDriver.getPhysicalDeviceFeatures(physicalDevice, &physicalDeviceFeatures);
718
719         static const Feature features[] =
720         {
721                 FEATURE_ITEM(robustBufferAccess),
722                 FEATURE_ITEM(fullDrawIndexUint32),
723                 FEATURE_ITEM(imageCubeArray),
724                 FEATURE_ITEM(independentBlend),
725                 FEATURE_ITEM(geometryShader),
726                 FEATURE_ITEM(tessellationShader),
727                 FEATURE_ITEM(sampleRateShading),
728                 FEATURE_ITEM(dualSrcBlend),
729                 FEATURE_ITEM(logicOp),
730                 FEATURE_ITEM(multiDrawIndirect),
731                 FEATURE_ITEM(drawIndirectFirstInstance),
732                 FEATURE_ITEM(depthClamp),
733                 FEATURE_ITEM(depthBiasClamp),
734                 FEATURE_ITEM(fillModeNonSolid),
735                 FEATURE_ITEM(depthBounds),
736                 FEATURE_ITEM(wideLines),
737                 FEATURE_ITEM(largePoints),
738                 FEATURE_ITEM(alphaToOne),
739                 FEATURE_ITEM(multiViewport),
740                 FEATURE_ITEM(samplerAnisotropy),
741                 FEATURE_ITEM(textureCompressionETC2),
742                 FEATURE_ITEM(textureCompressionASTC_LDR),
743                 FEATURE_ITEM(textureCompressionBC),
744                 FEATURE_ITEM(occlusionQueryPrecise),
745                 FEATURE_ITEM(pipelineStatisticsQuery),
746                 FEATURE_ITEM(vertexPipelineStoresAndAtomics),
747                 FEATURE_ITEM(fragmentStoresAndAtomics),
748                 FEATURE_ITEM(shaderTessellationAndGeometryPointSize),
749                 FEATURE_ITEM(shaderImageGatherExtended),
750                 FEATURE_ITEM(shaderStorageImageExtendedFormats),
751                 FEATURE_ITEM(shaderStorageImageMultisample),
752                 FEATURE_ITEM(shaderStorageImageReadWithoutFormat),
753                 FEATURE_ITEM(shaderStorageImageWriteWithoutFormat),
754                 FEATURE_ITEM(shaderUniformBufferArrayDynamicIndexing),
755                 FEATURE_ITEM(shaderSampledImageArrayDynamicIndexing),
756                 FEATURE_ITEM(shaderStorageBufferArrayDynamicIndexing),
757                 FEATURE_ITEM(shaderStorageImageArrayDynamicIndexing),
758                 FEATURE_ITEM(shaderClipDistance),
759                 FEATURE_ITEM(shaderCullDistance),
760                 FEATURE_ITEM(shaderFloat64),
761                 FEATURE_ITEM(shaderInt64),
762                 FEATURE_ITEM(shaderInt16),
763                 FEATURE_ITEM(shaderResourceResidency),
764                 FEATURE_ITEM(shaderResourceMinLod),
765                 FEATURE_ITEM(sparseBinding),
766                 FEATURE_ITEM(sparseResidencyBuffer),
767                 FEATURE_ITEM(sparseResidencyImage2D),
768                 FEATURE_ITEM(sparseResidencyImage3D),
769                 FEATURE_ITEM(sparseResidency2Samples),
770                 FEATURE_ITEM(sparseResidency4Samples),
771                 FEATURE_ITEM(sparseResidency8Samples),
772                 FEATURE_ITEM(sparseResidency16Samples),
773                 FEATURE_ITEM(sparseResidencyAliased),
774                 FEATURE_ITEM(variableMultisampleRate),
775                 FEATURE_ITEM(inheritedQueries)
776         };
777
778         const int       numFeatures             = DE_LENGTH_OF_ARRAY(features);
779         int                     numErrors               = 0;
780
781         for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
782         {
783                 // Test only features that are not supported.
784                 if (*(((VkBool32*)((deUint8*)(&physicalDeviceFeatures) + features[featureNdx].offset))))
785                         continue;
786
787                 VkPhysicalDeviceFeatures enabledFeatures;
788
789                 for (int i = 0; i < numFeatures; i++)
790                         *((VkBool32*)((deUint8*)(&enabledFeatures) + features[i].offset)) = (i == featureNdx ? VK_TRUE : VK_FALSE);
791
792                 const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
793                 {
794                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
795                         DE_NULL,
796                         (VkDeviceQueueCreateFlags)0u,
797                         queueFamilyIndex,
798                         queueCount,
799                         &queuePriority
800                 };
801                 const VkDeviceCreateInfo                deviceCreateInfo                =
802                 {
803                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
804                         DE_NULL,
805                         (VkDeviceCreateFlags)0u,
806                         1,
807                         &deviceQueueCreateInfo,
808                         0,
809                         DE_NULL,
810                         0,
811                         DE_NULL,
812                         &enabledFeatures
813                 };
814
815                 VkDevice                device;
816                 const VkResult  res     = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL, &device);
817
818                 if (res != VK_ERROR_FEATURE_NOT_PRESENT)
819                 {
820                         numErrors++;
821                         resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
822                                                                  + de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
823                 }
824         }
825
826         if (numErrors > 1)
827                 return tcu::TestStatus(resultCollector.getResult(), "Enabling " + de::toString(numErrors) + " unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
828         else
829                 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
830 }
831
832 // Allocation tracking utilities
833 struct  AllocTrack
834 {
835         bool                                            active;
836         bool                                            wasAllocated;
837         void*                                           alignedStartAddress;
838         char*                                           actualStartAddress;
839         size_t                                          requestedSizeBytes;
840         size_t                                          actualSizeBytes;
841         VkSystemAllocationScope         allocScope;
842         deUint64                                        userData;
843
844         AllocTrack()
845                 : active                                (false)
846                 , wasAllocated                  (false)
847                 , alignedStartAddress   (DE_NULL)
848                 , actualStartAddress    (DE_NULL)
849                 , requestedSizeBytes    (0)
850                 , actualSizeBytes               (0)
851                 , allocScope                    (VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)
852                 , userData(0)                   {}
853 };
854
855 // Global vector to track allocations. This will be resized before each test and emptied after
856 // However, we have to globally define it so the allocation callback functions work properly
857 std::vector<AllocTrack> g_allocatedVector;
858 bool                                    g_intentionalFailEnabled        = false;
859 deUint32                                g_intenionalFailIndex           = 0;
860 deUint32                                g_intenionalFailCount           = 0;
861
862 void freeAllocTracker (void)
863 {
864         g_allocatedVector.clear();
865 }
866
867 void initAllocTracker (size_t size, deUint32 intentionalFailIndex = (deUint32)~0)
868 {
869         if (g_allocatedVector.size() > 0)
870                 freeAllocTracker();
871
872         g_allocatedVector.resize(size);
873
874         if (intentionalFailIndex != (deUint32)~0)
875         {
876                 g_intentionalFailEnabled        = true;
877                 g_intenionalFailIndex           = intentionalFailIndex;
878                 g_intenionalFailCount           = 0;
879         }
880         else
881         {
882                 g_intentionalFailEnabled        = false;
883                 g_intenionalFailIndex           = 0;
884                 g_intenionalFailCount           = 0;
885         }
886 }
887
888 bool isAllocTrackerEmpty ()
889 {
890         bool success            = true;
891         bool wasAllocated       = false;
892
893         for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
894         {
895                 if (g_allocatedVector[vectorIdx].active)
896                         success = false;
897                 else if (!wasAllocated && g_allocatedVector[vectorIdx].wasAllocated)
898                         wasAllocated = true;
899         }
900
901         if (!g_intentionalFailEnabled && !wasAllocated)
902                 success = false;
903
904         return success;
905 }
906
907 VKAPI_ATTR void *VKAPI_CALL allocCallbackFunc (void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
908 {
909         if (g_intentionalFailEnabled)
910                 if (++g_intenionalFailCount >= g_intenionalFailIndex)
911                         return DE_NULL;
912
913         for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
914         {
915                 if (!g_allocatedVector[vectorIdx].active)
916                 {
917                         g_allocatedVector[vectorIdx].requestedSizeBytes         = size;
918                         g_allocatedVector[vectorIdx].actualSizeBytes            = size + (alignment - 1);
919                         g_allocatedVector[vectorIdx].alignedStartAddress        = DE_NULL;
920                         g_allocatedVector[vectorIdx].actualStartAddress         = new char[g_allocatedVector[vectorIdx].actualSizeBytes];
921
922                         if (g_allocatedVector[vectorIdx].actualStartAddress != DE_NULL)
923                         {
924                                 deUint64 addr   =       (deUint64)g_allocatedVector[vectorIdx].actualStartAddress;
925                                 addr                    +=      (alignment - 1);
926                                 addr                    &=      ~(alignment - 1);
927                                 g_allocatedVector[vectorIdx].alignedStartAddress        = (void *)addr;
928                                 g_allocatedVector[vectorIdx].allocScope                         = allocationScope;
929                                 g_allocatedVector[vectorIdx].userData                           = (deUint64)pUserData;
930                                 g_allocatedVector[vectorIdx].active                                     = true;
931                                 g_allocatedVector[vectorIdx].wasAllocated                       = true;
932                         }
933
934                         return g_allocatedVector[vectorIdx].alignedStartAddress;
935                 }
936         }
937         return DE_NULL;
938 }
939
940 VKAPI_ATTR void VKAPI_CALL freeCallbackFunc (void *pUserData, void *pMemory)
941 {
942         DE_UNREF(pUserData);
943
944         for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
945         {
946                 if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pMemory)
947                 {
948                         delete[] g_allocatedVector[vectorIdx].actualStartAddress;
949                         g_allocatedVector[vectorIdx].active = false;
950                         break;
951                 }
952         }
953 }
954
955 VKAPI_ATTR void *VKAPI_CALL reallocCallbackFunc (void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
956 {
957         if (pOriginal != DE_NULL)
958         {
959                 for (deUint32 vectorIdx = 0; vectorIdx < g_allocatedVector.size(); vectorIdx++)
960                 {
961                         if (g_allocatedVector[vectorIdx].active && g_allocatedVector[vectorIdx].alignedStartAddress == pOriginal)
962                         {
963                                 if (size == 0)
964                                 {
965                                         freeCallbackFunc(pUserData, pOriginal);
966                                         return DE_NULL;
967                                 }
968                                 else if (size < g_allocatedVector[vectorIdx].requestedSizeBytes)
969                                         return pOriginal;
970                                 else
971                                 {
972                                         void *pNew = allocCallbackFunc(pUserData, size, alignment, allocationScope);
973
974                                         if (pNew != DE_NULL)
975                                         {
976                                                 size_t copySize = size;
977
978                                                 if (g_allocatedVector[vectorIdx].requestedSizeBytes < size)
979                                                         copySize = g_allocatedVector[vectorIdx].requestedSizeBytes;
980
981                                                 memcpy(pNew, pOriginal, copySize);
982                                                 freeCallbackFunc(pUserData, pOriginal);
983                                         }
984                                         return pNew;
985                                 }
986                         }
987                 }
988                 return DE_NULL;
989         }
990         else
991                 return allocCallbackFunc(pUserData, size, alignment, allocationScope);
992 }
993
994 tcu::TestStatus createInstanceDeviceIntentionalAllocFail (Context& context)
995 {
996         const PlatformInterface&        vkp                                     = context.getPlatformInterface();
997         const deUint32                          chosenDevice            = context.getTestContext().getCommandLine().getVKDeviceId() - 1;
998         VkInstance                                      instance                        = DE_NULL;
999         VkDevice                                        device                          = DE_NULL;
1000         deUint32                                        physicalDeviceCount     = 0;
1001         deUint32                                        queueFamilyCount        = 0;
1002         deUint32                                        queueFamilyIndex        = 0;
1003         const float                                     queuePriority           = 0.0f;
1004         const VkAllocationCallbacks     allocationCallbacks     =
1005         {
1006                 DE_NULL,                                                                // userData
1007                 allocCallbackFunc,                                              // pfnAllocation
1008                 reallocCallbackFunc,                                    // pfnReallocation
1009                 freeCallbackFunc,                                               // pfnFree
1010                 DE_NULL,                                                                // pfnInternalAllocation
1011                 DE_NULL                                                                 // pfnInternalFree
1012         };
1013         const VkApplicationInfo         appInfo                         =
1014         {
1015                 VK_STRUCTURE_TYPE_APPLICATION_INFO,             // sType
1016                 DE_NULL,                                                                // pNext
1017                 "appName",                                                              // pApplicationName
1018                 0u,                                                                             // applicationVersion
1019                 "engineName",                                                   // pEngineName
1020                 0u,                                                                             // engineVersion
1021                 VK_API_VERSION                                                  // apiVersion
1022         };
1023         const VkInstanceCreateInfo      instanceCreateInfo      =
1024         {
1025                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
1026                 DE_NULL,                                                                // pNext
1027                 (VkInstanceCreateFlags)0u,                              // flags
1028                 &appInfo,                                                               // pApplicationInfo
1029                 0u,                                                                             // enabledLayerCount
1030                 DE_NULL,                                                                // ppEnabledLayerNames
1031                 0u,                                                                             // enabledExtensionCount
1032                 DE_NULL                                                                 // ppEnabledExtensionNames
1033         };
1034         deUint32                                        failIndex                       = 0;
1035         VkResult                                        result                          = VK_ERROR_OUT_OF_HOST_MEMORY;
1036
1037         while (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1038         {
1039                 initAllocTracker(9999, failIndex++);
1040
1041                 if (failIndex >= 9999u)
1042                         return tcu::TestStatus::fail("Out of retries, could not create instance and device");
1043
1044                 result = vkp.createInstance(&instanceCreateInfo, &allocationCallbacks, &instance);
1045
1046                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1047                 {
1048                         if (!isAllocTrackerEmpty())
1049                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1050
1051                         freeAllocTracker();
1052                         continue;
1053                 }
1054                 else if (result != VK_SUCCESS)
1055                         return tcu::TestStatus::fail("createInstance returned " + de::toString(result));
1056
1057                 const InstanceDriver            instanceDriver  (vkp, instance);
1058                 const InstanceInterface&        vki                             (instanceDriver);
1059
1060                 result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, DE_NULL);
1061
1062                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1063                 {
1064                         vki.destroyInstance(instance, &allocationCallbacks);
1065
1066                         if (!isAllocTrackerEmpty())
1067                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1068
1069                         freeAllocTracker();
1070                         continue;
1071                 }
1072                 else if (result != VK_SUCCESS)
1073                         return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
1074
1075                 vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
1076
1077                 result = vki.enumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
1078
1079                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1080                 {
1081                         vki.destroyInstance(instance, &allocationCallbacks);
1082
1083                         if (!isAllocTrackerEmpty())
1084                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1085
1086                         freeAllocTracker();
1087                         continue;
1088                 }
1089                 else if (result != VK_SUCCESS)
1090                         return tcu::TestStatus::fail("enumeratePhysicalDevices returned " + de::toString(result));
1091
1092                 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, DE_NULL);
1093
1094                 if (queueFamilyCount == 0u)
1095                         return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
1096
1097                 vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
1098
1099                 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevices[chosenDevice], &queueFamilyCount, queueFamilies.data());
1100
1101                 if (queueFamilyCount == 0u)
1102                         return tcu::TestStatus::fail("getPhysicalDeviceQueueFamilyProperties returned zero queue families");
1103
1104                 for (deUint32 i = 0; i < queueFamilyCount; i++)
1105                 {
1106                         if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
1107                         {
1108                                 queueFamilyIndex = i;
1109                                 break;
1110                         }
1111                 }
1112
1113                 const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
1114                 {
1115                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,     // sType
1116                         DE_NULL,                                                                        // pNext
1117                         (VkDeviceQueueCreateFlags)0u,                           // flags
1118                         queueFamilyIndex,                                                       // queueFamilyIndex
1119                         1u,                                                                                     // queueCount
1120                         &queuePriority                                                          // pQueuePriorities
1121                 };
1122                 const VkDeviceCreateInfo                deviceCreateInfo                =
1123                 {
1124                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,           // sType
1125                         DE_NULL,                                                                        // pNext
1126                         (VkDeviceCreateFlags)0u,                                        // flags
1127                         1u,                                                                                     // queueCreateInfoCount
1128                         &deviceQueueCreateInfo,                                         // pQueueCreateInfos
1129                         0u,                                                                                     // enabledLayerCount
1130                         DE_NULL,                                                                        // ppEnabledLayerNames
1131                         0u,                                                                                     // enabledExtensionCount
1132                         DE_NULL,                                                                        // ppEnabledExtensionNames
1133                         DE_NULL                                                                         // pEnabledFeatures
1134                 };
1135
1136                 result = vki.createDevice(physicalDevices[chosenDevice], &deviceCreateInfo, &allocationCallbacks, &device);
1137
1138                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY)
1139                 {
1140                         vki.destroyInstance(instance, &allocationCallbacks);
1141
1142                         if (!isAllocTrackerEmpty())
1143                                 return tcu::TestStatus::fail("Allocations still remain, failed on index " + de::toString(failIndex));
1144
1145                         freeAllocTracker();
1146                         continue;
1147                 }
1148                 else if (result != VK_SUCCESS)
1149                         return tcu::TestStatus::fail("VkCreateDevice returned " + de::toString(result));
1150
1151                 DeviceDriver(vki, device).destroyDevice(device, &allocationCallbacks);
1152                 vki.destroyInstance(instance, &allocationCallbacks);
1153                 freeAllocTracker();
1154         }
1155
1156         return tcu::TestStatus::pass("Pass");
1157 }
1158
1159 } // anonymous
1160
1161 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
1162 {
1163         de::MovePtr<tcu::TestCaseGroup> deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));
1164
1165         addFunctionCase(deviceInitializationTests.get(), "create_instance_name_version",                                        "", createInstanceTest);
1166         addFunctionCase(deviceInitializationTests.get(), "create_instance_invalid_api_version",                         "", createInstanceWithInvalidApiVersionTest);
1167         addFunctionCase(deviceInitializationTests.get(), "create_instance_null_appinfo",                                        "", createInstanceWithNullApplicationInfoTest);
1168         addFunctionCase(deviceInitializationTests.get(), "create_instance_unsupported_extensions",                      "", createInstanceWithUnsupportedExtensionsTest);
1169         addFunctionCase(deviceInitializationTests.get(), "create_device",                                                                       "", createDeviceTest);
1170         addFunctionCase(deviceInitializationTests.get(), "create_multiple_devices",                                                     "", createMultipleDevicesTest);
1171         addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_extensions",                        "", createDeviceWithUnsupportedExtensionsTest);
1172         addFunctionCase(deviceInitializationTests.get(), "create_device_various_queue_counts",                          "", createDeviceWithVariousQueueCountsTest);
1173         addFunctionCase(deviceInitializationTests.get(), "create_device_features2",                                                     "", createDeviceFeatures2Test);
1174         addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_features",                          "", createDeviceWithUnsupportedFeaturesTest);
1175         addFunctionCase(deviceInitializationTests.get(), "create_instance_device_intentional_alloc_fail",       "", createInstanceDeviceIntentionalAllocFail);
1176
1177         return deviceInitializationTests.release();
1178 }
1179
1180 } // api
1181 } // vkt