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