Merge "Merge "Fix color change verification in dithering tests" into nougat-cts-dev...
[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
40 #include "deUniquePtr.hpp"
41 #include "deStringUtil.hpp"
42
43 #include <vector>
44
45 namespace vkt
46 {
47 namespace api
48 {
49
50 namespace
51 {
52
53 using namespace vk;
54 using namespace std;
55 using std::vector;
56 using tcu::TestLog;
57
58 tcu::TestStatus createInstanceTest (Context& context)
59 {
60         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
61         tcu::ResultCollector            resultCollector                 (log);
62         const char*                                     appNames[]                              = { "appName", DE_NULL, "",  "app, name", "app(\"name\"", "app~!@#$%^&*()_+name", "app\nName", "app\r\nName" };
63         const char*                                     engineNames[]                   = { "engineName", DE_NULL, "",  "engine. name", "engine\"(name)", "eng~!@#$%^&*()_+name", "engine\nName", "engine\r\nName" };
64         const int                   patchNumbers[]          = { 0, 1, 2, 3, 4, 5, 13, 4094, 4095 };
65         const deUint32                          appVersions[]                   = { 0, 1, (deUint32)-1 };
66         const deUint32                          engineVersions[]                = { 0, 1, (deUint32)-1 };
67         const PlatformInterface&        platformInterface               = context.getPlatformInterface();
68         vector<VkApplicationInfo>       appInfos;
69
70         // test over appName
71         for (int appNameNdx = 0; appNameNdx < DE_LENGTH_OF_ARRAY(appNames); appNameNdx++)
72         {
73                 const VkApplicationInfo appInfo =
74                 {
75                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
76                         DE_NULL,                                                                // const void*                                  pNext;
77                         appNames[appNameNdx],                                   // const char*                                  pAppName;
78                         0u,                                                                             // deUint32                                             appVersion;
79                         "engineName",                                                   // const char*                                  pEngineName;
80                         0u,                                                                             // deUint32                                             engineVersion;
81                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
82                 };
83
84                 appInfos.push_back(appInfo);
85         }
86
87         // test over engineName
88         for (int engineNameNdx = 0; engineNameNdx < DE_LENGTH_OF_ARRAY(engineNames); engineNameNdx++)
89         {
90                 const VkApplicationInfo appInfo =
91                 {
92                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
93                         DE_NULL,                                                                // const void*                                  pNext;
94                         "appName",                                                              // const char*                                  pAppName;
95                         0u,                                                                             // deUint32                                             appVersion;
96                         engineNames[engineNameNdx],                             // const char*                                  pEngineName;
97                         0u,                                                                             // deUint32                                             engineVersion;
98                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
99                 };
100
101                 appInfos.push_back(appInfo);
102         }
103
104         // test over appVersion
105         for (int appVersionNdx = 0; appVersionNdx < DE_LENGTH_OF_ARRAY(appVersions); appVersionNdx++)
106         {
107                 const VkApplicationInfo appInfo =
108                 {
109                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
110                         DE_NULL,                                                                // const void*                                  pNext;
111                         "appName",                                                              // const char*                                  pAppName;
112                         appVersions[appVersionNdx],                             // deUint32                                             appVersion;
113                         "engineName",                                                   // const char*                                  pEngineName;
114                         0u,                                                                             // deUint32                                             engineVersion;
115                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
116                 };
117
118                 appInfos.push_back(appInfo);
119         }
120
121         // test over engineVersion
122         for (int engineVersionNdx = 0; engineVersionNdx < DE_LENGTH_OF_ARRAY(engineVersions); engineVersionNdx++)
123         {
124                 const VkApplicationInfo appInfo =
125                 {
126                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
127                         DE_NULL,                                                                // const void*                                  pNext;
128                         "appName",                                                              // const char*                                  pAppName;
129                         0u,                                                                             // deUint32                                             appVersion;
130                         "engineName",                                                   // const char*                                  pEngineName;
131                         engineVersions[engineVersionNdx],               // deUint32                                             engineVersion;
132                         VK_API_VERSION,                                                 // deUint32                                             apiVersion;
133                 };
134
135                 appInfos.push_back(appInfo);
136         }
137         // patch component of api version checking (should be ignored by implementation)
138         for (int patchVersion = 0; patchVersion < DE_LENGTH_OF_ARRAY(patchNumbers); patchVersion++)
139         {
140                 const VkApplicationInfo appInfo =
141                 {
142                         VK_STRUCTURE_TYPE_APPLICATION_INFO,                                     // VkStructureType                              sType;
143                         DE_NULL,                                                                                        // const void*                                  pNext;
144                         "appName",                                                                                      // const char*                                  pAppName;
145                         0u,                                                                                                     // deUint32                                             appVersion;
146                         "engineName",                                                                           // const char*                                  pEngineName;
147                         0u,                                                                                                     // deUint32                                             engineVersion;
148                         VK_MAKE_VERSION(1, 0, patchNumbers[patchVersion]),      // deUint32                                             apiVersion;
149                 };
150
151                 appInfos.push_back(appInfo);
152         }
153
154         // test when apiVersion is 0
155         {
156                 const VkApplicationInfo appInfo =
157                 {
158                         VK_STRUCTURE_TYPE_APPLICATION_INFO,             // VkStructureType                              sType;
159                         DE_NULL,                                                                // const void*                                  pNext;
160                         "appName",                                                              // const char*                                  pAppName;
161                         0u,                                                                             // deUint32                                             appVersion;
162                         "engineName",                                                   // const char*                                  pEngineName;
163                         0u,                                                                             // deUint32                                             engineVersion;
164                         0u,                                                                             // deUint32                                             apiVersion;
165                 };
166
167                 appInfos.push_back(appInfo);
168         }
169
170         // run the tests!
171         for (size_t appInfoNdx = 0; appInfoNdx < appInfos.size(); ++appInfoNdx)
172         {
173                 const VkApplicationInfo&                appInfo                                 = appInfos[appInfoNdx];
174                 const VkInstanceCreateInfo              instanceCreateInfo              =
175                 {
176                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType                              sType;
177                         DE_NULL,                                                                // const void*                                  pNext;
178                         (VkInstanceCreateFlags)0u,                              // VkInstanceCreateFlags                flags;
179                         &appInfo,                                                               // const VkApplicationInfo*             pAppInfo;
180                         0u,                                                                             // deUint32                                             layerCount;
181                         DE_NULL,                                                                // const char*const*                    ppEnabledLayernames;
182                         0u,                                                                             // deUint32                                             extensionCount;
183                         DE_NULL,                                                                // const char*const*                    ppEnabledExtensionNames;
184                 };
185
186                 log << TestLog::Message << "Creating instance with appInfo: " << appInfo << TestLog::EndMessage;
187
188                 try
189                 {
190                         const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo));
191                         log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
192                 }
193                 catch (const vk::Error& err)
194                 {
195                         resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
196                 }
197         }
198
199         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
200 }
201
202 tcu::TestStatus createInstanceWithInvalidApiVersionTest (Context& context)
203 {
204         tcu::TestLog&                           log                                     = context.getTestContext().getLog();
205         tcu::ResultCollector            resultCollector         (log);
206         const PlatformInterface&        platformInterface       = context.getPlatformInterface();
207         const ApiVersion                        apiVersion                      = unpackVersion(VK_API_VERSION);
208         const deUint32                          invalidMajorVersion     = (1 << 10) - 1;
209         const deUint32                          invalidMinorVersion     = (1 << 10) - 1;
210         vector<ApiVersion>                      invalidApiVersions;
211
212         invalidApiVersions.push_back(ApiVersion(invalidMajorVersion, apiVersion.minorNum, apiVersion.patchNum));
213         invalidApiVersions.push_back(ApiVersion(apiVersion.majorNum, invalidMinorVersion, apiVersion.patchNum));
214
215         for (size_t apiVersionNdx = 0; apiVersionNdx < invalidApiVersions.size(); apiVersionNdx++)
216         {
217                 const VkApplicationInfo appInfo                                 =
218                 {
219                         VK_STRUCTURE_TYPE_APPLICATION_INFO,                     // VkStructureType                              sType;
220                         DE_NULL,                                                                        // const void*                                  pNext;
221                         "appName",                                                                      // const char*                                  pAppName;
222                         0u,                                                                                     // deUint32                                             appVersion;
223                         "engineName",                                                           // const char*                                  pEngineName;
224                         0u,                                                                                     // deUint32                                             engineVersion;
225                         pack(invalidApiVersions[apiVersionNdx]),        // deUint32                                             apiVersion;
226                 };
227                 const VkInstanceCreateInfo instanceCreateInfo   =
228                 {
229                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,         // VkStructureType                              sType;
230                         DE_NULL,                                                                        // const void*                                  pNext;
231                         (VkInstanceCreateFlags)0u,                                      // VkInstanceCreateFlags                flags;
232                         &appInfo,                                                                       // const VkApplicationInfo*             pAppInfo;
233                         0u,                                                                                     // deUint32                                             layerCount;
234                         DE_NULL,                                                                        // const char*const*                    ppEnabledLayernames;
235                         0u,                                                                                     // deUint32                                             extensionCount;
236                         DE_NULL,                                                                        // const char*const*                    ppEnabledExtensionNames;
237                 };
238
239
240                 log << TestLog::Message
241                         <<"VK_API_VERSION defined in vulkan.h: " << apiVersion
242                         << ", api version used to create instance: " << invalidApiVersions[apiVersionNdx]
243                         << TestLog::EndMessage;
244
245                 {
246                         VkInstance              instance        = (VkInstance)0;
247                         const VkResult  result          = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
248                         const bool              gotInstance     = !!instance;
249
250                         if (instance)
251                         {
252                                 const InstanceDriver    instanceIface   (platformInterface, instance);
253                                 instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
254                         }
255
256                         if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
257                         {
258                                 TCU_CHECK(!gotInstance);
259                                 log << TestLog::Message << "Pass, instance creation with invalid apiVersion is rejected" << TestLog::EndMessage;
260                         }
261                         else
262                                 resultCollector.fail("Fail, instance creation with invalid apiVersion is not rejected");
263                 }
264         }
265
266         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
267 }
268
269 tcu::TestStatus createInstanceWithNullApplicationInfoTest (Context& context)
270 {
271         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
272         tcu::ResultCollector            resultCollector                 (log);
273         const PlatformInterface&        platformInterface               = context.getPlatformInterface();
274
275         const VkInstanceCreateInfo              instanceCreateInfo              =
276         {
277                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType                              sType;
278                 DE_NULL,                                                                // const void*                                  pNext;
279                 (VkInstanceCreateFlags)0u,                              // VkInstanceCreateFlags                flags;
280                 DE_NULL,                                                                // const VkApplicationInfo*             pAppInfo;
281                 0u,                                                                             // deUint32                                             layerCount;
282                 DE_NULL,                                                                // const char*const*                    ppEnabledLayernames;
283                 0u,                                                                             // deUint32                                             extensionCount;
284                 DE_NULL,                                                                // const char*const*                    ppEnabledExtensionNames;
285         };
286
287         log << TestLog::Message << "Creating instance with NULL pApplicationInfo" << TestLog::EndMessage;
288
289         try
290         {
291                 const Unique<VkInstance> instance(createInstance(platformInterface, &instanceCreateInfo));
292                 log << TestLog::Message << "Succeeded" << TestLog::EndMessage;
293         }
294         catch (const vk::Error& err)
295         {
296                 resultCollector.fail("Failed, Error code: " + de::toString(err.getMessage()));
297         }
298
299         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
300 }
301
302 tcu::TestStatus createInstanceWithUnsupportedExtensionsTest (Context& context)
303 {
304         tcu::TestLog&                                           log                                             = context.getTestContext().getLog();
305         const PlatformInterface&                        platformInterface               = context.getPlatformInterface();
306         const char*                                                     enabledExtensions[]             = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION"};
307         const VkApplicationInfo                         appInfo                                 =
308         {
309                 VK_STRUCTURE_TYPE_APPLICATION_INFO,                                             // VkStructureType                              sType;
310                 DE_NULL,                                                                                                // const void*                                  pNext;
311                 "appName",                                                                                              // const char*                                  pAppName;
312                 0u,                                                                                                             // deUint32                                             appVersion;
313                 "engineName",                                                                                   // const char*                                  pEngineName;
314                 0u,                                                                                                             // deUint32                                             engineVersion;
315                 VK_API_VERSION,                                                                                 // deUint32                                             apiVersion;
316         };
317         const VkInstanceCreateInfo                      instanceCreateInfo              =
318         {
319                 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,                                 // VkStructureType                              sType;
320                 DE_NULL,                                                                                                // const void*                                  pNext;
321                 (VkInstanceCreateFlags)0u,                                                              // VkInstanceCreateFlags                flags;
322                 &appInfo,                                                                                               // const VkApplicationInfo*             pAppInfo;
323                 0u,                                                                                                             // deUint32                                             layerCount;
324                 DE_NULL,                                                                                                // const char*const*                    ppEnabledLayernames;
325                 DE_LENGTH_OF_ARRAY(enabledExtensions),                                  // deUint32                                             extensionCount;
326                 enabledExtensions,                                                                              // const char*const*                    ppEnabledExtensionNames;
327         };
328
329         log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
330
331         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
332                 log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
333
334         {
335                 VkInstance              instance        = (VkInstance)0;
336                 const VkResult  result          = platformInterface.createInstance(&instanceCreateInfo, DE_NULL/*pAllocator*/, &instance);
337                 const bool              gotInstance     = !!instance;
338
339                 if (instance)
340                 {
341                         const InstanceDriver    instanceIface   (platformInterface, instance);
342                         instanceIface.destroyInstance(instance, DE_NULL/*pAllocator*/);
343                 }
344
345                 if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
346                 {
347                         TCU_CHECK(!gotInstance);
348                         return tcu::TestStatus::pass("Pass, creating instance with unsupported extension was rejected.");
349                 }
350                 else
351                         return tcu::TestStatus::fail("Fail, creating instance with unsupported extensions succeeded.");
352         }
353 }
354
355 tcu::TestStatus createDeviceTest (Context& context)
356 {
357         const PlatformInterface&                platformInterface               = context.getPlatformInterface();
358         const Unique<VkInstance>                instance                                (createDefaultInstance(platformInterface));
359         const InstanceDriver                    instanceDriver                  (platformInterface, instance.get());
360         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
361         const deUint32                                  queueFamilyIndex                = 0;
362         const deUint32                                  queueCount                              = 1;
363         const deUint32                                  queueIndex                              = 0;
364         const float                                             queuePriority                   = 1.0f;
365         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
366         {
367                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
368                 DE_NULL,
369                 (VkDeviceQueueCreateFlags)0u,
370                 queueFamilyIndex,                                               //queueFamilyIndex;
371                 queueCount,                                                             //queueCount;
372                 &queuePriority,                                                 //pQueuePriorities;
373         };
374         const VkDeviceCreateInfo                deviceCreateInfo        =
375         {
376                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
377                 DE_NULL,                                                                //pNext;
378                 (VkDeviceCreateFlags)0u,
379                 1,                                                                              //queueRecordCount;
380                 &deviceQueueCreateInfo,                                 //pRequestedQueues;
381                 0,                                                                              //layerCount;
382                 DE_NULL,                                                                //ppEnabledLayerNames;
383                 0,                                                                              //extensionCount;
384                 DE_NULL,                                                                //ppEnabledExtensionNames;
385                 DE_NULL,                                                                //pEnabledFeatures;
386         };
387
388         const Unique<VkDevice>                  device                                  (createDevice(instanceDriver, physicalDevice, &deviceCreateInfo));
389         const DeviceDriver                              deviceDriver                    (instanceDriver, device.get());
390         const VkQueue                                   queue                                   = getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
391
392         VK_CHECK(deviceDriver.queueWaitIdle(queue));
393
394         return tcu::TestStatus::pass("Pass");
395 }
396
397 tcu::TestStatus createMultipleDevicesTest (Context& context)
398 {
399         tcu::TestLog&                                                                           log                                             = context.getTestContext().getLog();
400         tcu::ResultCollector                                                            resultCollector                 (log);
401         const int                                                                                       numDevices                              = 5;
402         const PlatformInterface&                                                        platformInterface               = context.getPlatformInterface();
403         const Unique<VkInstance>                                                        instance                                (createDefaultInstance(platformInterface));
404         const InstanceDriver                                                            instanceDriver                  (platformInterface, instance.get());
405         const VkPhysicalDevice                                                          physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
406         const deUint32                                                                          queueFamilyIndex                = 0;
407         const deUint32                                                                          queueCount                              = 1;
408         const deUint32                                                                          queueIndex                              = 0;
409         const float                                                                                     queuePriority                   = 1.0f;
410         const VkDeviceQueueCreateInfo                                           deviceQueueCreateInfo   =
411         {
412                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
413                 DE_NULL,
414                 (VkDeviceQueueCreateFlags)0u,                                   //flags;
415                 queueFamilyIndex,                                                               //queueFamilyIndex;
416                 queueCount,                                                                             //queueCount;
417                 &queuePriority,                                                                 //pQueuePriorities;
418         };
419         const VkDeviceCreateInfo                                                        deviceCreateInfo                =
420         {
421                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                   //sType;
422                 DE_NULL,                                                                                //pNext;
423                 (VkDeviceCreateFlags)0u,
424                 1,                                                                                              //queueRecordCount;
425                 &deviceQueueCreateInfo,                                                 //pRequestedQueues;
426                 0,                                                                                              //layerCount;
427                 DE_NULL,                                                                                //ppEnabledLayerNames;
428                 0,                                                                                              //extensionCount;
429                 DE_NULL,                                                                                //ppEnabledExtensionNames;
430                 DE_NULL,                                                                                //pEnabledFeatures;
431         };
432         vector<VkDevice>                                                                        devices(numDevices, (VkDevice)DE_NULL);
433
434         try
435         {
436                 for (int deviceNdx = 0; deviceNdx < numDevices; deviceNdx++)
437                 {
438                         const VkResult result = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &devices[deviceNdx]);
439
440                         if (result != VK_SUCCESS)
441                         {
442                                 resultCollector.fail("Failed to create Device No." + de::toString(deviceNdx) + ", Error Code: " + de::toString(result));
443                                 break;
444                         }
445
446                         {
447                                 const DeviceDriver      deviceDriver    (instanceDriver, devices[deviceNdx]);
448                                 const VkQueue           queue                   = getDeviceQueue(deviceDriver, devices[deviceNdx], queueFamilyIndex, queueIndex);
449
450                                 VK_CHECK(deviceDriver.queueWaitIdle(queue));
451                         }
452                 }
453         }
454         catch (const vk::Error& error)
455         {
456                 resultCollector.fail(de::toString(error.getError()));
457         }
458         catch (...)
459         {
460                 for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
461                 {
462                         if (devices[deviceNdx] != (VkDevice)DE_NULL)
463                         {
464                                 DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]);
465                                 deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
466                         }
467                 }
468
469                 throw;
470         }
471
472         for (int deviceNdx = (int)devices.size()-1; deviceNdx >= 0; deviceNdx--)
473         {
474                 if (devices[deviceNdx] != (VkDevice)DE_NULL)
475                 {
476                         DeviceDriver deviceDriver(instanceDriver, devices[deviceNdx]);
477                         deviceDriver.destroyDevice(devices[deviceNdx], DE_NULL/*pAllocator*/);
478                 }
479         }
480
481         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
482 }
483
484 tcu::TestStatus createDeviceWithUnsupportedExtensionsTest (Context& context)
485 {
486         tcu::TestLog&                                   log                                             = context.getTestContext().getLog();
487         const PlatformInterface&                platformInterface               = context.getPlatformInterface();
488         const Unique<VkInstance>                instance                                (createDefaultInstance(platformInterface));
489         const InstanceDriver                    instanceDriver                  (platformInterface, instance.get());
490         const char*                                             enabledExtensions[]             = {"VK_UNSUPPORTED_EXTENSION", "THIS_IS_NOT_AN_EXTENSION", "VK_DONT_SUPPORT_ME"};
491         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
492         const float                                             queuePriority                   = 1.0f;
493         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
494         {
495                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
496                 DE_NULL,
497                 (VkDeviceQueueCreateFlags)0u,
498                 0,                                                                              //queueFamilyIndex;
499                 1,                                                                              //queueCount;
500                 &queuePriority,                                                 //pQueuePriorities;
501         };
502         const VkDeviceCreateInfo                deviceCreateInfo                =
503         {
504                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
505                 DE_NULL,                                                                //pNext;
506                 (VkDeviceCreateFlags)0u,
507                 1,                                                                              //queueRecordCount;
508                 &deviceQueueCreateInfo,                                 //pRequestedQueues;
509                 0,                                                                              //layerCount;
510                 DE_NULL,                                                                //ppEnabledLayerNames;
511                 DE_LENGTH_OF_ARRAY(enabledExtensions),  //extensionCount;
512                 enabledExtensions,                                              //ppEnabledExtensionNames;
513                 DE_NULL,                                                                //pEnabledFeatures;
514         };
515
516         log << TestLog::Message << "Enabled extensions are: " << TestLog::EndMessage;
517
518         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(enabledExtensions); ndx++)
519                 log << TestLog::Message << enabledExtensions[ndx] <<  TestLog::EndMessage;
520
521         {
522                 VkDevice                device          = (VkDevice)0;
523                 const VkResult  result          = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL/*pAllocator*/, &device);
524                 const bool              gotDevice       = !!device;
525
526                 if (device)
527                 {
528                         const DeviceDriver      deviceIface     (instanceDriver, device);
529                         deviceIface.destroyDevice(device, DE_NULL/*pAllocator*/);
530                 }
531
532                 if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
533                 {
534                         TCU_CHECK(!gotDevice);
535                         return tcu::TestStatus::pass("Pass, create device with unsupported extension is rejected.");
536                 }
537                 else
538                         return tcu::TestStatus::fail("Fail, create device with unsupported extension but succeed.");
539         }
540 }
541
542 deUint32 getGlobalMaxQueueCount(const vector<VkQueueFamilyProperties>& queueFamilyProperties)
543 {
544         deUint32 maxQueueCount = 0;
545
546         for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
547         {
548                 maxQueueCount = de::max(maxQueueCount, queueFamilyProperties[queueFamilyNdx].queueCount);
549         }
550
551         return maxQueueCount;
552 }
553
554 tcu::TestStatus createDeviceWithVariousQueueCountsTest (Context& context)
555 {
556         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
557         const int                                                               queueCountDiff                  = 1;
558         const PlatformInterface&                                platformInterface               = context.getPlatformInterface();
559         const Unique<VkInstance>                                instance                                (createDefaultInstance(platformInterface));
560         const InstanceDriver                                    instanceDriver                  (platformInterface, instance.get());
561         const VkPhysicalDevice                                  physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
562         const vector<VkQueueFamilyProperties>   queueFamilyProperties   = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
563         const vector<float>                                             queuePriorities                 (getGlobalMaxQueueCount(queueFamilyProperties), 1.0f);
564         vector<VkDeviceQueueCreateInfo>                 deviceQueueCreateInfos;
565
566         for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < (deUint32)queueFamilyProperties.size(); queueFamilyNdx++)
567         {
568                 const deUint32 maxQueueCount = queueFamilyProperties[queueFamilyNdx].queueCount;
569
570                 for (deUint32 queueCount = 1; queueCount <= maxQueueCount; queueCount += queueCountDiff)
571                 {
572                         const VkDeviceQueueCreateInfo queueCreateInfo =
573                         {
574                                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
575                                 DE_NULL,
576                                 (VkDeviceQueueCreateFlags)0u,
577                                 queueFamilyNdx,
578                                 queueCount,
579                                 queuePriorities.data()
580                         };
581
582                         deviceQueueCreateInfos.push_back(queueCreateInfo);
583                 }
584         }
585
586         for (size_t testNdx = 0; testNdx < deviceQueueCreateInfos.size(); testNdx++)
587         {
588                 const VkDeviceQueueCreateInfo&  queueCreateInfo         = deviceQueueCreateInfos[testNdx];
589                 const VkDeviceCreateInfo                deviceCreateInfo        =
590                 {
591                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,   //sType;
592                         DE_NULL,                                                                //pNext;
593                         (VkDeviceCreateFlags)0u,
594                         1,                                                                              //queueRecordCount;
595                         &queueCreateInfo,                                               //pRequestedQueues;
596                         0,                                                                              //layerCount;
597                         DE_NULL,                                                                //ppEnabledLayerNames;
598                         0,                                                                              //extensionCount;
599                         DE_NULL,                                                                //ppEnabledExtensionNames;
600                         DE_NULL,                                                                //pEnabledFeatures;
601                 };
602                 const Unique<VkDevice>                  device                          (createDevice(instanceDriver, physicalDevice, &deviceCreateInfo));
603                 const DeviceDriver                              deviceDriver            (instanceDriver, device.get());
604                 const deUint32                                  queueFamilyIndex        = deviceCreateInfo.pQueueCreateInfos->queueFamilyIndex;
605                 const deUint32                                  queueCount                      = deviceCreateInfo.pQueueCreateInfos->queueCount;
606
607                 for (deUint32 queueIndex = 0; queueIndex < queueCount; queueIndex++)
608                 {
609                         const VkQueue           queue   = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex);
610                         VkResult                        result;
611
612                         TCU_CHECK(!!queue);
613
614                         result = deviceDriver.queueWaitIdle(queue);
615                         if (result != VK_SUCCESS)
616                         {
617                                 log << TestLog::Message
618                                         << "vkQueueWaitIdle failed"
619                                         << ",  queueIndex = " << queueIndex
620                                         << ", queueCreateInfo " << queueCreateInfo
621                                         << ", Error Code: " << result
622                                         << TestLog::EndMessage;
623                                 return tcu::TestStatus::fail("Fail");
624                         }
625                 }
626         }
627         return tcu::TestStatus::pass("Pass");
628 }
629
630 Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, const char* extensionName)
631 {
632         const vector<VkExtensionProperties>     instanceExts    = enumerateInstanceExtensionProperties(vkp, DE_NULL);
633         vector<string>                                          enabledExts;
634
635         if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName)))
636                 TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str());
637
638         enabledExts.push_back(extensionName);
639
640         return createDefaultInstance(vkp, vector<string>() /* layers */, enabledExts);
641 }
642
643 tcu::TestStatus createDeviceFeatures2Test (Context& context)
644 {
645         const PlatformInterface&                vkp                                             = context.getPlatformInterface();
646         const Unique<VkInstance>                instance                                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2"));
647         const InstanceDriver                    vki                                             (vkp, instance.get());
648         const VkPhysicalDevice                  physicalDevice                  = chooseDevice(vki, instance.get(), context.getTestContext().getCommandLine());
649         const deUint32                                  queueFamilyIndex                = 0;
650         const deUint32                                  queueCount                              = 1;
651         const deUint32                                  queueIndex                              = 0;
652         const float                                             queuePriority                   = 1.0f;
653
654         VkPhysicalDeviceFeatures2KHR    enabledFeatures;
655         const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
656         {
657                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
658                 DE_NULL,
659                 (VkDeviceQueueCreateFlags)0u,
660                 queueFamilyIndex,
661                 queueCount,
662                 &queuePriority,
663         };
664         const VkDeviceCreateInfo                deviceCreateInfo        =
665         {
666                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
667                 &enabledFeatures,
668                 (VkDeviceCreateFlags)0u,
669                 1,
670                 &deviceQueueCreateInfo,
671                 0,
672                 DE_NULL,
673                 0,
674                 DE_NULL,
675                 DE_NULL,
676         };
677
678         // Populate enabledFeatures
679         enabledFeatures.sType           = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
680         enabledFeatures.pNext           = DE_NULL;
681
682         vki.getPhysicalDeviceFeatures2KHR(physicalDevice, &enabledFeatures);
683
684         {
685                 const Unique<VkDevice>  device          (createDevice(vki, physicalDevice, &deviceCreateInfo));
686                 const DeviceDriver              vkd                     (vki, device.get());
687                 const VkQueue                   queue           = getDeviceQueue(vkd, *device, queueFamilyIndex, queueIndex);
688
689                 VK_CHECK(vkd.queueWaitIdle(queue));
690         }
691
692         return tcu::TestStatus::pass("Pass");
693 }
694
695 struct Feature
696 {
697         const char*     name;
698         size_t          offset;
699 };
700
701 #define FEATURE_ITEM(MEMBER) {#MEMBER, DE_OFFSET_OF(VkPhysicalDeviceFeatures, MEMBER)}
702
703 tcu::TestStatus createDeviceWithUnsupportedFeaturesTest (Context& context)
704 {
705         tcu::TestLog&                           log                                             = context.getTestContext().getLog();
706         tcu::ResultCollector            resultCollector                 (log);
707         const PlatformInterface&        platformInterface               = context.getPlatformInterface();
708         const Unique<VkInstance>        instance                                (createDefaultInstance(platformInterface));
709         const InstanceDriver            instanceDriver                  (platformInterface, instance.get());
710         const VkPhysicalDevice          physicalDevice                  = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
711         const deUint32                          queueFamilyIndex                = 0;
712         const deUint32                          queueCount                              = 1;
713         const float                                     queuePriority                   = 1.0f;
714         VkPhysicalDeviceFeatures        physicalDeviceFeatures;
715
716         instanceDriver.getPhysicalDeviceFeatures(physicalDevice, &physicalDeviceFeatures);
717
718         static const Feature features[] =
719         {
720                 FEATURE_ITEM(robustBufferAccess),
721                 FEATURE_ITEM(fullDrawIndexUint32),
722                 FEATURE_ITEM(imageCubeArray),
723                 FEATURE_ITEM(independentBlend),
724                 FEATURE_ITEM(geometryShader),
725                 FEATURE_ITEM(tessellationShader),
726                 FEATURE_ITEM(sampleRateShading),
727                 FEATURE_ITEM(dualSrcBlend),
728                 FEATURE_ITEM(logicOp),
729                 FEATURE_ITEM(multiDrawIndirect),
730                 FEATURE_ITEM(drawIndirectFirstInstance),
731                 FEATURE_ITEM(depthClamp),
732                 FEATURE_ITEM(depthBiasClamp),
733                 FEATURE_ITEM(fillModeNonSolid),
734                 FEATURE_ITEM(depthBounds),
735                 FEATURE_ITEM(wideLines),
736                 FEATURE_ITEM(largePoints),
737                 FEATURE_ITEM(alphaToOne),
738                 FEATURE_ITEM(multiViewport),
739                 FEATURE_ITEM(samplerAnisotropy),
740                 FEATURE_ITEM(textureCompressionETC2),
741                 FEATURE_ITEM(textureCompressionASTC_LDR),
742                 FEATURE_ITEM(textureCompressionBC),
743                 FEATURE_ITEM(occlusionQueryPrecise),
744                 FEATURE_ITEM(pipelineStatisticsQuery),
745                 FEATURE_ITEM(vertexPipelineStoresAndAtomics),
746                 FEATURE_ITEM(fragmentStoresAndAtomics),
747                 FEATURE_ITEM(shaderTessellationAndGeometryPointSize),
748                 FEATURE_ITEM(shaderImageGatherExtended),
749                 FEATURE_ITEM(shaderStorageImageExtendedFormats),
750                 FEATURE_ITEM(shaderStorageImageMultisample),
751                 FEATURE_ITEM(shaderStorageImageReadWithoutFormat),
752                 FEATURE_ITEM(shaderStorageImageWriteWithoutFormat),
753                 FEATURE_ITEM(shaderUniformBufferArrayDynamicIndexing),
754                 FEATURE_ITEM(shaderSampledImageArrayDynamicIndexing),
755                 FEATURE_ITEM(shaderStorageBufferArrayDynamicIndexing),
756                 FEATURE_ITEM(shaderStorageImageArrayDynamicIndexing),
757                 FEATURE_ITEM(shaderClipDistance),
758                 FEATURE_ITEM(shaderCullDistance),
759                 FEATURE_ITEM(shaderFloat64),
760                 FEATURE_ITEM(shaderInt64),
761                 FEATURE_ITEM(shaderInt16),
762                 FEATURE_ITEM(shaderResourceResidency),
763                 FEATURE_ITEM(shaderResourceMinLod),
764                 FEATURE_ITEM(sparseBinding),
765                 FEATURE_ITEM(sparseResidencyBuffer),
766                 FEATURE_ITEM(sparseResidencyImage2D),
767                 FEATURE_ITEM(sparseResidencyImage3D),
768                 FEATURE_ITEM(sparseResidency2Samples),
769                 FEATURE_ITEM(sparseResidency4Samples),
770                 FEATURE_ITEM(sparseResidency8Samples),
771                 FEATURE_ITEM(sparseResidency16Samples),
772                 FEATURE_ITEM(sparseResidencyAliased),
773                 FEATURE_ITEM(variableMultisampleRate),
774                 FEATURE_ITEM(inheritedQueries)
775         };
776
777         const int       numFeatures             = DE_LENGTH_OF_ARRAY(features);
778         int                     numErrors               = 0;
779
780         for (int featureNdx = 0; featureNdx < numFeatures; featureNdx++)
781         {
782                 // Test only features that are not supported.
783                 if (*(((VkBool32*)((deUint8*)(&physicalDeviceFeatures) + features[featureNdx].offset))))
784                         continue;
785
786                 VkPhysicalDeviceFeatures enabledFeatures;
787
788                 for (int i = 0; i < numFeatures; i++)
789                         *((VkBool32*)((deUint8*)(&enabledFeatures) + features[i].offset)) = (i == featureNdx ? VK_TRUE : VK_FALSE);
790
791                 const VkDeviceQueueCreateInfo   deviceQueueCreateInfo   =
792                 {
793                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
794                         DE_NULL,
795                         (VkDeviceQueueCreateFlags)0u,
796                         queueFamilyIndex,
797                         queueCount,
798                         &queuePriority
799                 };
800                 const VkDeviceCreateInfo                deviceCreateInfo                =
801                 {
802                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
803                         DE_NULL,
804                         (VkDeviceCreateFlags)0u,
805                         1,
806                         &deviceQueueCreateInfo,
807                         0,
808                         DE_NULL,
809                         0,
810                         DE_NULL,
811                         &enabledFeatures
812                 };
813
814                 VkDevice                device;
815                 const VkResult  res     = instanceDriver.createDevice(physicalDevice, &deviceCreateInfo, DE_NULL, &device);
816
817                 if (res != VK_ERROR_FEATURE_NOT_PRESENT)
818                 {
819                         numErrors++;
820                         resultCollector.fail("Not returning VK_ERROR_FEATURE_NOT_PRESENT when creating device with feature "
821                                                                  + de::toString(features[featureNdx].name) + ", which was reported as unsupported.");
822                 }
823         }
824
825         if (numErrors > 1)
826                 return tcu::TestStatus(resultCollector.getResult(), "Enabling " + de::toString(numErrors) + " unsupported features didn't return VK_ERROR_FEATURE_NOT_PRESENT.");
827         else
828                 return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
829 }
830
831 } // anonymous
832
833 tcu::TestCaseGroup* createDeviceInitializationTests (tcu::TestContext& testCtx)
834 {
835         de::MovePtr<tcu::TestCaseGroup> deviceInitializationTests (new tcu::TestCaseGroup(testCtx, "device_init", "Device Initialization Tests"));
836
837         addFunctionCase(deviceInitializationTests.get(), "create_instance_name_version",                        "", createInstanceTest);
838         addFunctionCase(deviceInitializationTests.get(), "create_instance_invalid_api_version",         "", createInstanceWithInvalidApiVersionTest);
839         addFunctionCase(deviceInitializationTests.get(), "create_instance_null_appinfo",                    "", createInstanceWithNullApplicationInfoTest);
840         addFunctionCase(deviceInitializationTests.get(), "create_instance_unsupported_extensions",      "", createInstanceWithUnsupportedExtensionsTest);
841         addFunctionCase(deviceInitializationTests.get(), "create_device",                                                       "", createDeviceTest);
842         addFunctionCase(deviceInitializationTests.get(), "create_multiple_devices",                                     "", createMultipleDevicesTest);
843         addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_extensions",        "", createDeviceWithUnsupportedExtensionsTest);
844         addFunctionCase(deviceInitializationTests.get(), "create_device_various_queue_counts",          "", createDeviceWithVariousQueueCountsTest);
845         addFunctionCase(deviceInitializationTests.get(), "create_device_features2",                                     "", createDeviceFeatures2Test);
846         addFunctionCase(deviceInitializationTests.get(), "create_device_unsupported_features",          "", createDeviceWithUnsupportedFeaturesTest);
847
848         return deviceInitializationTests.release();
849 }
850
851 } // api
852 } // vkt