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