xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/api/vktApiObjectManagementTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Object management tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktApiObjectManagementTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktCustomInstancesDevices.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkPlatform.hpp"
36 #include "vkStrUtil.hpp"
37 #include "vkAllocationCallbackUtil.hpp"
38 #include "vkObjTypeImpl.inl"
39 #include "vkObjUtil.hpp"
40 #include "vkBuilderUtil.hpp"
41 #include "vkSafetyCriticalUtil.hpp"
42 
43 #include "vktTestGroupUtil.hpp"
44 
45 #include "tcuVector.hpp"
46 #include "tcuResultCollector.hpp"
47 #include "tcuCommandLine.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuPlatform.hpp"
50 
51 #include "deUniquePtr.hpp"
52 #include "deSharedPtr.hpp"
53 #include "deArrayUtil.hpp"
54 #include "deSpinBarrier.hpp"
55 #include "deThread.hpp"
56 #include "deInt32.h"
57 
58 #include <limits>
59 #include <algorithm>
60 #include <unordered_map>
61 
62 #define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1)
63 
64 namespace vkt
65 {
66 namespace api
67 {
68 
69 namespace
70 {
71 
72 using namespace vk;
73 
74 using de::MovePtr;
75 using de::SharedPtr;
76 using de::UniquePtr;
77 
78 using tcu::IVec3;
79 using tcu::ResultCollector;
80 using tcu::TestLog;
81 using tcu::TestStatus;
82 using tcu::UVec3;
83 
84 using std::string;
85 using std::vector;
86 
87 typedef SharedPtr<Move<VkPipeline>> VkPipelineSp; // Move so it's possible to disown the handle
88 typedef SharedPtr<Move<VkDescriptorSet>> VkDescriptorSetSp;
89 typedef SharedPtr<Move<VkCommandBuffer>> VkCommandBufferSp;
90 
91 class ThreadGroupThread;
92 
93 /*--------------------------------------------------------------------*//*!
94  * \brief Thread group
95  *
96  * Thread group manages collection of threads that are expected to be
97  * launched simultaneously as a group.
98  *
99  * Shared barrier is provided for synchronizing execution. Terminating thread
100  * early either by returning from ThreadGroupThread::runThread() or throwing
101  * an exception is safe, and other threads will continue execution. The
102  * thread that has been terminated is simply removed from the synchronization
103  * group.
104  *
105  * TestException-based exceptions are collected and translated into a
106  * tcu::TestStatus by using tcu::ResultCollector.
107  *
108  * Use cases for ThreadGroup include for example testing thread-safety of
109  * certain API operations by poking API simultaneously from multiple
110  * threads.
111  *//*--------------------------------------------------------------------*/
112 
113 class ThreadGroup
114 {
115 public:
116     ThreadGroup(void);
117     ~ThreadGroup(void);
118 
119     void add(de::MovePtr<ThreadGroupThread> thread);
120     TestStatus run(void);
121 
122 private:
123     typedef std::vector<de::SharedPtr<ThreadGroupThread>> ThreadVector;
124 
125     ThreadVector m_threads;
126     de::SpinBarrier m_barrier;
127 } DE_WARN_UNUSED_TYPE;
128 
129 class ThreadGroupThread : private de::Thread
130 {
131 public:
132     ThreadGroupThread(void);
133     virtual ~ThreadGroupThread(void);
134 
135     void start(de::SpinBarrier *groupBarrier);
136 
getResultCollector(void)137     ResultCollector &getResultCollector(void)
138     {
139         return m_resultCollector;
140     }
141 
142     using de::Thread::join;
143 
144 protected:
145     virtual void runThread(void) = 0;
146 
147     void barrier(void);
148 
149 private:
150     ThreadGroupThread(const ThreadGroupThread &);
151     ThreadGroupThread &operator=(const ThreadGroupThread &);
152 
153     void run(void);
154 
155     ResultCollector m_resultCollector;
156     de::SpinBarrier *m_barrier;
157 };
158 
159 // ThreadGroup
160 
ThreadGroup(void)161 ThreadGroup::ThreadGroup(void) : m_barrier(1)
162 {
163 }
164 
~ThreadGroup(void)165 ThreadGroup::~ThreadGroup(void)
166 {
167 }
168 
add(de::MovePtr<ThreadGroupThread> thread)169 void ThreadGroup::add(de::MovePtr<ThreadGroupThread> thread)
170 {
171     m_threads.push_back(de::SharedPtr<ThreadGroupThread>(thread.release()));
172 }
173 
run(void)174 tcu::TestStatus ThreadGroup::run(void)
175 {
176     tcu::ResultCollector resultCollector;
177 
178     m_barrier.reset((int)m_threads.size());
179 
180     for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
181         (*threadIter)->start(&m_barrier);
182 
183     for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
184     {
185         tcu::ResultCollector &threadResult = (*threadIter)->getResultCollector();
186         (*threadIter)->join();
187         resultCollector.addResult(threadResult.getResult(), threadResult.getMessage());
188     }
189 
190     return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
191 }
192 
193 // ThreadGroupThread
194 
ThreadGroupThread(void)195 ThreadGroupThread::ThreadGroupThread(void) : m_barrier(DE_NULL)
196 {
197 }
198 
~ThreadGroupThread(void)199 ThreadGroupThread::~ThreadGroupThread(void)
200 {
201 }
202 
start(de::SpinBarrier * groupBarrier)203 void ThreadGroupThread::start(de::SpinBarrier *groupBarrier)
204 {
205     m_barrier = groupBarrier;
206     de::Thread::start();
207 }
208 
run(void)209 void ThreadGroupThread::run(void)
210 {
211     try
212     {
213         runThread();
214     }
215     catch (const tcu::TestException &e)
216     {
217         getResultCollector().addResult(e.getTestResult(), e.getMessage());
218     }
219     catch (const std::exception &e)
220     {
221         getResultCollector().addResult(QP_TEST_RESULT_FAIL, e.what());
222     }
223     catch (...)
224     {
225         getResultCollector().addResult(QP_TEST_RESULT_FAIL, "Exception");
226     }
227 
228     m_barrier->removeThread(de::SpinBarrier::WAIT_MODE_AUTO);
229 }
230 
barrier(void)231 inline void ThreadGroupThread::barrier(void)
232 {
233     m_barrier->sync(de::SpinBarrier::WAIT_MODE_AUTO);
234 }
235 
getDefaultTestThreadCount(void)236 uint32_t getDefaultTestThreadCount(void)
237 {
238 #ifndef CTS_USES_VULKANSC
239     return de::clamp(deGetNumAvailableLogicalCores(), 2u, 8u);
240 #else
241     return 2u;
242 #endif // CTS_USES_VULKANSC
243 }
244 
245 // Utilities
246 
247 struct Environment
248 {
249     const PlatformInterface &vkp;
250     uint32_t apiVersion;
251     const InstanceInterface &instanceInterface;
252     VkInstance instance;
253     const DeviceInterface &vkd;
254     VkDevice device;
255     uint32_t queueFamilyIndex;
256     const BinaryCollection &programBinaries;
257     const VkAllocationCallbacks *allocationCallbacks;
258     uint32_t maxResourceConsumers; // Maximum number of objects using same Object::Resources concurrently
259 #ifdef CTS_USES_VULKANSC
260     de::SharedPtr<ResourceInterface> resourceInterface;
261     VkPhysicalDeviceVulkanSC10Properties vulkanSC10Properties;
262     VkPhysicalDeviceProperties properties;
263 #endif // CTS_USES_VULKANSC
264     const tcu::CommandLine &commandLine;
265 
Environmentvkt::api::__anonc97e7d540111::Environment266     Environment(Context &context, uint32_t maxResourceConsumers_)
267         : vkp(context.getPlatformInterface())
268         , apiVersion(context.getUsedApiVersion())
269         , instanceInterface(context.getInstanceInterface())
270         , instance(context.getInstance())
271         , vkd(context.getDeviceInterface())
272         , device(context.getDevice())
273         , queueFamilyIndex(context.getUniversalQueueFamilyIndex())
274         , programBinaries(context.getBinaryCollection())
275         , allocationCallbacks(DE_NULL)
276         , maxResourceConsumers(maxResourceConsumers_)
277 #ifdef CTS_USES_VULKANSC
278         , resourceInterface(context.getResourceInterface())
279         , vulkanSC10Properties(context.getDeviceVulkanSC10Properties())
280         , properties(context.getDeviceProperties())
281 #endif // CTS_USES_VULKANSC
282         , commandLine(context.getTestContext().getCommandLine())
283     {
284     }
285 
Environmentvkt::api::__anonc97e7d540111::Environment286     Environment(const PlatformInterface &vkp_, uint32_t apiVersion_, const InstanceInterface &instanceInterface_,
287                 VkInstance instance_, const DeviceInterface &vkd_, VkDevice device_, uint32_t queueFamilyIndex_,
288                 const BinaryCollection &programBinaries_, const VkAllocationCallbacks *allocationCallbacks_,
289                 uint32_t maxResourceConsumers_,
290 #ifdef CTS_USES_VULKANSC
291                 de::SharedPtr<ResourceInterface> resourceInterface_,
292                 const VkPhysicalDeviceVulkanSC10Properties &vulkanSC10Properties_,
293 #endif // CTS_USES_VULKANSC
294                 const tcu::CommandLine &commandLine_)
295         : vkp(vkp_)
296         , apiVersion(apiVersion_)
297         , instanceInterface(instanceInterface_)
298         , instance(instance_)
299         , vkd(vkd_)
300         , device(device_)
301         , queueFamilyIndex(queueFamilyIndex_)
302         , programBinaries(programBinaries_)
303 #ifdef CTS_USES_VULKANSC
304         , allocationCallbacks(DE_NULL)
305 #else
306         , allocationCallbacks(allocationCallbacks_)
307 #endif // CTS_USES_VULKANSC
308         , maxResourceConsumers(maxResourceConsumers_)
309 #ifdef CTS_USES_VULKANSC
310         , resourceInterface(resourceInterface_)
311         , vulkanSC10Properties(vulkanSC10Properties_)
312 #endif // CTS_USES_VULKANSC
313         , commandLine(commandLine_)
314     {
315 #ifdef CTS_USES_VULKANSC
316         DE_UNREF(allocationCallbacks_);
317 #endif // CTS_USES_VULKANSC
318     }
319 };
320 
321 template <typename Case>
322 struct Dependency
323 {
324     typename Case::Resources resources;
325     Unique<typename Case::Type> object;
326 
Dependencyvkt::api::__anonc97e7d540111::Dependency327     Dependency(const Environment &env, const typename Case::Parameters &params)
328         : resources(env, params)
329         , object(Case::create(env, resources, params))
330     {
331     }
332 };
333 
334 template <typename T>
roundUpToNextMultiple(T value,T multiple)335 T roundUpToNextMultiple(T value, T multiple)
336 {
337     if (value % multiple == 0)
338         return value;
339     else
340         return value + multiple - (value % multiple);
341 }
342 
343 #if defined(DE_DEBUG)
344 template <typename T>
isPowerOfTwo(T value)345 bool isPowerOfTwo(T value)
346 {
347     return ((value & (value - T(1))) == 0);
348 }
349 #endif
350 
351 template <typename T>
alignToPowerOfTwo(T value,T align)352 T alignToPowerOfTwo(T value, T align)
353 {
354     DE_ASSERT(isPowerOfTwo(align));
355     return (value + align - T(1)) & ~(align - T(1));
356 }
357 #ifndef CTS_USES_VULKANSC
hasDeviceExtension(Context & context,const string name)358 inline bool hasDeviceExtension(Context &context, const string name)
359 {
360     return context.isDeviceFunctionalitySupported(name);
361 }
362 #endif
363 
getPageTableSize(const tcu::PlatformMemoryLimits & limits,VkDeviceSize allocationSize)364 VkDeviceSize getPageTableSize(const tcu::PlatformMemoryLimits &limits, VkDeviceSize allocationSize)
365 {
366     VkDeviceSize totalSize = 0;
367 
368     for (size_t levelNdx = 0; levelNdx < limits.devicePageTableHierarchyLevels; ++levelNdx)
369     {
370         const VkDeviceSize coveredAddressSpaceSize = limits.devicePageSize << levelNdx;
371         const VkDeviceSize numPagesNeeded =
372             alignToPowerOfTwo(allocationSize, coveredAddressSpaceSize) / coveredAddressSpaceSize;
373 
374         totalSize += numPagesNeeded * limits.devicePageTableEntrySize;
375     }
376 
377     return totalSize;
378 }
379 
getCurrentSystemMemoryUsage(const AllocationCallbackRecorder & allocRecoder)380 size_t getCurrentSystemMemoryUsage(const AllocationCallbackRecorder &allocRecoder)
381 {
382     const size_t systemAllocationOverhead = sizeof(void *) * 2;
383     AllocationCallbackValidationResults validationResults;
384 
385     validateAllocationCallbacks(allocRecoder, &validationResults);
386     TCU_CHECK(validationResults.violations.empty());
387 
388     return getLiveSystemAllocationTotal(validationResults) +
389            systemAllocationOverhead * validationResults.liveAllocations.size();
390 }
391 
392 template <typename Object>
computeSystemMemoryUsage(Context & context,const typename Object::Parameters & params)393 size_t computeSystemMemoryUsage(Context &context, const typename Object::Parameters &params)
394 {
395     AllocationCallbackRecorder allocRecorder(getSystemAllocator());
396     const Environment env(context.getPlatformInterface(), context.getUsedApiVersion(), context.getInstanceInterface(),
397                           context.getInstance(), context.getDeviceInterface(), context.getDevice(),
398                           context.getUniversalQueueFamilyIndex(), context.getBinaryCollection(),
399                           allocRecorder.getCallbacks(), 1u,
400 #ifdef CTS_USES_VULKANSC
401                           context.getResourceInterface(), context.getDeviceVulkanSC10Properties(),
402 #endif // CTS_USES_VULKANSC
403                           context.getTestContext().getCommandLine());
404     const typename Object::Resources res(env, params);
405     const size_t resourceMemoryUsage = getCurrentSystemMemoryUsage(allocRecorder);
406 
407     {
408         Unique<typename Object::Type> obj(Object::create(env, res, params));
409         const size_t totalMemoryUsage = getCurrentSystemMemoryUsage(allocRecorder);
410 
411         return totalMemoryUsage - resourceMemoryUsage;
412     }
413 }
414 
getSafeObjectCount(const tcu::PlatformMemoryLimits & memoryLimits,size_t objectSystemMemoryUsage,VkDeviceSize objectDeviceMemoryUsage=0)415 size_t getSafeObjectCount(const tcu::PlatformMemoryLimits &memoryLimits, size_t objectSystemMemoryUsage,
416                           VkDeviceSize objectDeviceMemoryUsage = 0)
417 {
418     const VkDeviceSize roundedUpDeviceMemory =
419         roundUpToNextMultiple(objectDeviceMemoryUsage, memoryLimits.deviceMemoryAllocationGranularity);
420 
421     if (memoryLimits.totalDeviceLocalMemory > 0 && roundedUpDeviceMemory > 0)
422     {
423         if (objectSystemMemoryUsage > 0)
424             return de::min(memoryLimits.totalSystemMemory / objectSystemMemoryUsage,
425                            (size_t)(memoryLimits.totalDeviceLocalMemory / roundedUpDeviceMemory));
426         else
427             return (size_t)(memoryLimits.totalDeviceLocalMemory / roundedUpDeviceMemory);
428     }
429     else if (objectSystemMemoryUsage + roundedUpDeviceMemory > 0)
430     {
431         DE_ASSERT(roundedUpDeviceMemory <= std::numeric_limits<size_t>::max() - objectSystemMemoryUsage);
432         return memoryLimits.totalSystemMemory / (objectSystemMemoryUsage + (size_t)roundedUpDeviceMemory);
433     }
434     else
435     {
436         // Warning: at this point driver has probably not implemented allocation callbacks correctly
437         return std::numeric_limits<size_t>::max();
438     }
439 }
440 
getPlatformMemoryLimits(Context & context)441 tcu::PlatformMemoryLimits getPlatformMemoryLimits(Context &context)
442 {
443     tcu::PlatformMemoryLimits memoryLimits;
444 
445     context.getTestContext().getPlatform().getMemoryLimits(memoryLimits);
446 
447     return memoryLimits;
448 }
449 
getSafeObjectCount(Context & context,size_t objectSystemMemoryUsage,VkDeviceSize objectDeviceMemorySize=0)450 size_t getSafeObjectCount(Context &context, size_t objectSystemMemoryUsage, VkDeviceSize objectDeviceMemorySize = 0)
451 {
452     return getSafeObjectCount(getPlatformMemoryLimits(context), objectSystemMemoryUsage, objectDeviceMemorySize);
453 }
454 
getPageTableSize(Context & context,VkDeviceSize allocationSize)455 VkDeviceSize getPageTableSize(Context &context, VkDeviceSize allocationSize)
456 {
457     return getPageTableSize(getPlatformMemoryLimits(context), allocationSize);
458 }
459 
460 template <typename Object>
getSafeObjectCount(Context & context,const typename Object::Parameters & params,uint32_t hardCountLimit,VkDeviceSize deviceMemoryUsage=0)461 uint32_t getSafeObjectCount(Context &context, const typename Object::Parameters &params, uint32_t hardCountLimit,
462                             VkDeviceSize deviceMemoryUsage = 0)
463 {
464     return (uint32_t)de::min(
465         (size_t)hardCountLimit,
466         getSafeObjectCount(context, computeSystemMemoryUsage<Object>(context, params), deviceMemoryUsage));
467 }
468 
469 // Object definitions
470 
471 enum
472 {
473     MAX_CONCURRENT_INSTANCES       = 32,
474     MAX_CONCURRENT_DEVICES         = 32,
475     MAX_CONCURRENT_SYNC_PRIMITIVES = 100,
476     MAX_CONCURRENT_PIPELINE_CACHES = 128,
477     MAX_CONCURRENT_QUERY_POOLS     = 8192,
478     DEFAULT_MAX_CONCURRENT_OBJECTS = 16 * 1024,
479 };
480 
481 struct Instance
482 {
483     typedef VkInstance Type;
484 
485     struct Parameters
486     {
487         const vector<string> instanceExtensions;
488 
Parametersvkt::api::__anonc97e7d540111::Instance::Parameters489         Parameters(void)
490         {
491         }
492 
Parametersvkt::api::__anonc97e7d540111::Instance::Parameters493         Parameters(vector<string> extensions) : instanceExtensions(extensions)
494         {
495         }
496     };
497 
498     struct Resources
499     {
Resourcesvkt::api::__anonc97e7d540111::Instance::Resources500         Resources(const Environment &, const Parameters &)
501         {
502         }
503     };
504 
getMaxConcurrentvkt::api::__anonc97e7d540111::Instance505     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
506     {
507         return getSafeObjectCount<Instance>(context, params, MAX_CONCURRENT_INSTANCES);
508     }
509 
createvkt::api::__anonc97e7d540111::Instance510     static Move<VkInstance> create(const Environment &env, const Resources &, const Parameters &params)
511     {
512         VkInstanceCreateFlags instanceFlags              = 0u;
513         const vector<VkExtensionProperties> instanceExts = enumerateInstanceExtensionProperties(env.vkp, DE_NULL);
514         vector<const char *> extensionNamePtrs;
515         for (const auto &extName : params.instanceExtensions)
516         {
517             bool extNotInCore = !isCoreInstanceExtension(env.apiVersion, extName);
518             if (extNotInCore &&
519                 !isExtensionStructSupported(instanceExts.begin(), instanceExts.end(), RequiredExtension(extName)))
520                 TCU_THROW(NotSupportedError, (extName + " is not supported").c_str());
521 
522             if (extNotInCore)
523                 extensionNamePtrs.push_back(extName.c_str());
524         }
525 
526 #ifndef CTS_USES_VULKANSC
527         // Enable portability if available. Needed for portability drivers, otherwise loader will complain and make tests fail
528         if (vk::isExtensionStructSupported(instanceExts, vk::RequiredExtension("VK_KHR_portability_enumeration")))
529         {
530             extensionNamePtrs.emplace_back("VK_KHR_portability_enumeration");
531             instanceFlags |= vk::VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
532         }
533 #endif // CTS_USES_VULKANSC
534 
535         const VkApplicationInfo appInfo = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
536                                            DE_NULL,
537                                            DE_NULL, // pApplicationName
538                                            0u,      // applicationVersion
539                                            DE_NULL, // pEngineName
540                                            0u,      // engineVersion
541                                            env.apiVersion};
542 
543         const VkInstanceCreateInfo instanceInfo = {
544             VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
545             DE_NULL,
546             instanceFlags,
547             &appInfo,
548             0u,                                                          // enabledLayerNameCount
549             DE_NULL,                                                     // ppEnabledLayerNames
550             (uint32_t)extensionNamePtrs.size(),                          // enabledExtensionNameCount
551             extensionNamePtrs.empty() ? DE_NULL : &extensionNamePtrs[0], // ppEnabledExtensionNames
552         };
553 
554         return createInstance(env.vkp, &instanceInfo, env.allocationCallbacks);
555     }
556 };
557 
558 struct Device
559 {
560     typedef VkDevice Type;
561 
562     struct Parameters
563     {
564         uint32_t deviceIndex;
565         VkQueueFlags queueFlags;
566 
Parametersvkt::api::__anonc97e7d540111::Device::Parameters567         Parameters(uint32_t deviceIndex_, VkQueueFlags queueFlags_) : deviceIndex(deviceIndex_), queueFlags(queueFlags_)
568         {
569         }
570     };
571 
572     struct Resources
573     {
574         Dependency<Instance> instance;
575 #ifndef CTS_USES_VULKANSC
576         InstanceDriver vki;
577 #else
578         InstanceDriverSC vki;
579 #endif // CTS_USES_VULKANSC
580 
581         VkPhysicalDevice physicalDevice;
582         uint32_t queueFamilyIndex;
583 
Resourcesvkt::api::__anonc97e7d540111::Device::Resources584         Resources(const Environment &env, const Parameters &params)
585             : instance(env, Instance::Parameters(vector<string>{string{"VK_KHR_get_physical_device_properties2"}}))
586 #ifndef CTS_USES_VULKANSC
587             , vki(env.vkp, *instance.object)
588 #else
589             , vki(env.vkp, *instance.object, env.commandLine, env.resourceInterface)
590 #endif // CTS_USES_VULKANSC
591             , physicalDevice(0)
592             , queueFamilyIndex(~0u)
593         {
594             {
595                 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(vki, *instance.object);
596 
597                 if (physicalDevices.size() <= (size_t)params.deviceIndex)
598                     TCU_THROW(NotSupportedError, "Device not found");
599 
600                 physicalDevice = physicalDevices[params.deviceIndex];
601             }
602 
603             {
604                 const vector<VkQueueFamilyProperties> queueProps =
605                     getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
606                 bool foundMatching = false;
607 
608                 for (size_t curQueueNdx = 0; curQueueNdx < queueProps.size(); curQueueNdx++)
609                 {
610                     if ((queueProps[curQueueNdx].queueFlags & params.queueFlags) == params.queueFlags)
611                     {
612                         queueFamilyIndex = (uint32_t)curQueueNdx;
613                         foundMatching    = true;
614                     }
615                 }
616 
617                 if (!foundMatching)
618                     TCU_THROW(NotSupportedError, "Matching queue not found");
619             }
620         }
621     };
622 
getMaxConcurrentvkt::api::__anonc97e7d540111::Device623     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
624     {
625         return getSafeObjectCount<Device>(context, params, MAX_CONCURRENT_DEVICES);
626     }
627 
createvkt::api::__anonc97e7d540111::Device628     static Move<VkDevice> create(const Environment &env, const Resources &res, const Parameters &)
629     {
630         const float queuePriority = 1.0;
631 
632         const VkDeviceQueueCreateInfo queues[] = {{
633             VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, DE_NULL, (VkDeviceQueueCreateFlags)0, res.queueFamilyIndex,
634             1u,             // queueCount
635             &queuePriority, // pQueuePriorities
636         }};
637 
638         void *pNext = DE_NULL;
639         std::vector<const char *> extensions;
640 #ifdef CTS_USES_VULKANSC
641         VkDeviceObjectReservationCreateInfo memReservationInfo = env.commandLine.isSubProcess() ?
642                                                                      env.resourceInterface->getStatMax() :
643                                                                      resetDeviceObjectReservationCreateInfo();
644         memReservationInfo.pNext                               = pNext;
645         pNext                                                  = &memReservationInfo;
646 
647         VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
648         sc10Features.pNext                              = pNext;
649         pNext                                           = &sc10Features;
650 
651         VkPipelineCacheCreateInfo pcCI;
652         std::vector<VkPipelinePoolSize> poolSizes;
653         if (env.commandLine.isSubProcess())
654         {
655             if (env.resourceInterface->getCacheDataSize() > 0)
656             {
657                 pcCI = {
658                     VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
659                     DE_NULL,                                      // const void* pNext;
660                     VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
661                         VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
662                     env.resourceInterface->getCacheDataSize(),                // uintptr_t initialDataSize;
663                     env.resourceInterface->getCacheData()                     // const void* pInitialData;
664                 };
665                 memReservationInfo.pipelineCacheCreateInfoCount = 1;
666                 memReservationInfo.pPipelineCacheCreateInfos    = &pcCI;
667             }
668 
669             poolSizes = env.resourceInterface->getPipelinePoolSizes();
670             if (!poolSizes.empty())
671             {
672                 memReservationInfo.pipelinePoolSizeCount = uint32_t(poolSizes.size());
673                 memReservationInfo.pPipelinePoolSizes    = poolSizes.data();
674             }
675         }
676 #else
677         VkPhysicalDevicePipelineCreationCacheControlFeatures pipelineCreationCacheControlFeatures =
678             vk::initVulkanStructure();
679         VkPhysicalDeviceVulkan13Features vulkan13Features = vk::initVulkanStructure();
680         if (env.apiVersion < VK_API_VERSION_1_3)
681         {
682             VkPhysicalDeviceFeatures2 features2 = vk::initVulkanStructure(&pipelineCreationCacheControlFeatures);
683             res.vki.getPhysicalDeviceFeatures2(res.physicalDevice, &features2);
684             pipelineCreationCacheControlFeatures.pNext = pNext;
685             pNext                                      = &pipelineCreationCacheControlFeatures;
686             extensions.push_back("VK_EXT_pipeline_creation_cache_control");
687         }
688         else
689         {
690             VkPhysicalDeviceFeatures2 features2 = vk::initVulkanStructure(&vulkan13Features);
691             res.vki.getPhysicalDeviceFeatures2(res.physicalDevice, &features2);
692             vulkan13Features.pNext = pNext;
693             pNext                  = &vulkan13Features;
694         }
695 #endif // CTS_USES_VULKANSC
696 
697         VkPhysicalDeviceFeatures2 enabledFeatures = getPhysicalDeviceFeatures2(res.vki, res.physicalDevice);
698         enabledFeatures.pNext                     = pNext;
699         pNext                                     = &enabledFeatures;
700 
701         const VkDeviceCreateInfo deviceInfo = {
702             VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
703             pNext,
704             (VkDeviceCreateFlags)0,
705             DE_LENGTH_OF_ARRAY(queues),
706             queues,
707             0u,      // enabledLayerNameCount
708             DE_NULL, // ppEnabledLayerNames
709             0u,      // enabledExtensionNameCount
710             DE_NULL, // ppEnabledExtensionNames
711             DE_NULL, // pEnabledFeatures
712         };
713 
714         return createCustomDevice(env.commandLine.isValidationEnabled(), env.vkp, env.instance, res.vki,
715                                   res.physicalDevice, &deviceInfo, env.allocationCallbacks);
716     }
717 };
718 
719 struct DeviceGroup
720 {
721     typedef VkDevice Type;
722 
723     struct Parameters
724     {
725         uint32_t deviceGroupIndex;
726         uint32_t deviceIndex;
727         VkQueueFlags queueFlags;
728 
Parametersvkt::api::__anonc97e7d540111::DeviceGroup::Parameters729         Parameters(uint32_t deviceGroupIndex_, uint32_t deviceIndex_, VkQueueFlags queueFlags_)
730             : deviceGroupIndex(deviceGroupIndex_)
731             , deviceIndex(deviceIndex_)
732             , queueFlags(queueFlags_)
733         {
734         }
735     };
736 
737     struct Resources
738     {
739         vector<string> extensions;
740         Dependency<Instance> instance;
741 #ifndef CTS_USES_VULKANSC
742         InstanceDriver vki;
743 #else
744         InstanceDriverSC vki;
745 #endif
746         vector<VkPhysicalDevice> physicalDevices;
747         uint32_t physicalDeviceCount;
748         uint32_t queueFamilyIndex;
749 
Resourcesvkt::api::__anonc97e7d540111::DeviceGroup::Resources750         Resources(const Environment &env, const Parameters &params)
751             : extensions(1, "VK_KHR_device_group_creation")
752             , instance(env, Instance::Parameters(extensions))
753 #ifndef CTS_USES_VULKANSC
754             , vki(env.vkp, *instance.object)
755 #else
756             , vki(env.vkp, *instance.object, env.commandLine, env.resourceInterface)
757 #endif
758             , physicalDeviceCount(0)
759             , queueFamilyIndex(~0u)
760         {
761             {
762                 const vector<VkPhysicalDeviceGroupProperties> devGroupProperties =
763                     enumeratePhysicalDeviceGroups(vki, *instance.object);
764 
765                 if (devGroupProperties.size() <= (size_t)params.deviceGroupIndex)
766                     TCU_THROW(NotSupportedError, "Device Group not found");
767 
768                 physicalDeviceCount = devGroupProperties[params.deviceGroupIndex].physicalDeviceCount;
769                 physicalDevices.resize(physicalDeviceCount);
770 
771                 for (uint32_t physicalDeviceIdx = 0; physicalDeviceIdx < physicalDeviceCount; physicalDeviceIdx++)
772                     physicalDevices[physicalDeviceIdx] =
773                         devGroupProperties[params.deviceGroupIndex].physicalDevices[physicalDeviceIdx];
774             }
775 
776             {
777                 const vector<VkQueueFamilyProperties> queueProps =
778                     getPhysicalDeviceQueueFamilyProperties(vki, physicalDevices[params.deviceIndex]);
779                 bool foundMatching = false;
780 
781                 for (size_t curQueueNdx = 0; curQueueNdx < queueProps.size(); curQueueNdx++)
782                 {
783                     if ((queueProps[curQueueNdx].queueFlags & params.queueFlags) == params.queueFlags)
784                     {
785                         queueFamilyIndex = (uint32_t)curQueueNdx;
786                         foundMatching    = true;
787                     }
788                 }
789 
790                 if (!foundMatching)
791                     TCU_THROW(NotSupportedError, "Matching queue not found");
792             }
793         }
794     };
795 
getMaxConcurrentvkt::api::__anonc97e7d540111::DeviceGroup796     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
797     {
798         const vector<VkPhysicalDeviceGroupProperties> devGroupProperties =
799             enumeratePhysicalDeviceGroups(context.getInstanceInterface(), context.getInstance());
800         return getSafeObjectCount<DeviceGroup>(
801             context, params, MAX_CONCURRENT_DEVICES / devGroupProperties[params.deviceGroupIndex].physicalDeviceCount);
802     }
803 
createvkt::api::__anonc97e7d540111::DeviceGroup804     static Move<VkDevice> create(const Environment &env, const Resources &res, const Parameters &params)
805     {
806         const float queuePriority = 1.0;
807 
808         const VkDeviceQueueCreateInfo queues[] = {{
809             VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
810             DE_NULL,                     // pNext
811             (VkDeviceQueueCreateFlags)0, // flags
812             res.queueFamilyIndex,        // queueFamilyIndex
813             1u,                          // queueCount
814             &queuePriority,              // pQueuePriorities
815         }};
816 
817         VkDeviceGroupDeviceCreateInfo deviceGroupInfo = {
818             VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, //stype
819             DE_NULL,                                           //pNext
820             res.physicalDeviceCount,                           //physicalDeviceCount
821             res.physicalDevices.data()                         //physicalDevices
822         };
823 
824         void *pNext = &deviceGroupInfo;
825 #ifdef CTS_USES_VULKANSC
826         VkDeviceObjectReservationCreateInfo memReservationInfo = env.commandLine.isSubProcess() ?
827                                                                      env.resourceInterface->getStatMax() :
828                                                                      resetDeviceObjectReservationCreateInfo();
829         memReservationInfo.pNext                               = pNext;
830         pNext                                                  = &memReservationInfo;
831 
832         VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
833         sc10Features.pNext                              = pNext;
834         pNext                                           = &sc10Features;
835 
836         VkPipelineCacheCreateInfo pcCI;
837         std::vector<VkPipelinePoolSize> poolSizes;
838         if (env.commandLine.isSubProcess())
839         {
840             if (env.resourceInterface->getCacheDataSize() > 0)
841             {
842                 pcCI = {
843                     VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
844                     DE_NULL,                                      // const void* pNext;
845                     VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
846                         VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
847                     env.resourceInterface->getCacheDataSize(),                // uintptr_t initialDataSize;
848                     env.resourceInterface->getCacheData()                     // const void* pInitialData;
849                 };
850                 memReservationInfo.pipelineCacheCreateInfoCount = 1;
851                 memReservationInfo.pPipelineCacheCreateInfos    = &pcCI;
852             }
853 
854             poolSizes = env.resourceInterface->getPipelinePoolSizes();
855             if (!poolSizes.empty())
856             {
857                 memReservationInfo.pipelinePoolSizeCount = uint32_t(poolSizes.size());
858                 memReservationInfo.pPipelinePoolSizes    = poolSizes.data();
859             }
860         }
861 #endif // CTS_USES_VULKANSC
862 
863         VkPhysicalDeviceFeatures enabledFeatures =
864             getPhysicalDeviceFeatures(res.vki, res.physicalDevices[params.deviceIndex]);
865 
866         const VkDeviceCreateInfo deviceGroupCreateInfo = {
867             VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
868             pNext,
869             (VkDeviceCreateFlags)0,
870             DE_LENGTH_OF_ARRAY(queues),
871             queues,
872             0u,               // enabledLayerNameCount
873             DE_NULL,          // ppEnabledLayerNames
874             0u,               // enabledExtensionNameCount
875             DE_NULL,          // ppEnabledExtensionNames
876             &enabledFeatures, // pEnabledFeatures
877         };
878 
879         return createCustomDevice(env.commandLine.isValidationEnabled(), env.vkp, env.instance, res.vki,
880                                   res.physicalDevices[params.deviceIndex], &deviceGroupCreateInfo,
881                                   env.allocationCallbacks);
882     }
883 };
884 
885 struct DeviceMemory
886 {
887     typedef VkDeviceMemory Type;
888 
889     struct Parameters
890     {
891         VkDeviceSize size;
892         uint32_t memoryTypeIndex;
893 
Parametersvkt::api::__anonc97e7d540111::DeviceMemory::Parameters894         Parameters(VkDeviceSize size_, uint32_t memoryTypeIndex_) : size(size_), memoryTypeIndex(memoryTypeIndex_)
895         {
896             DE_ASSERT(memoryTypeIndex < VK_MAX_MEMORY_TYPES);
897         }
898     };
899 
900     struct Resources
901     {
Resourcesvkt::api::__anonc97e7d540111::DeviceMemory::Resources902         Resources(const Environment &, const Parameters &)
903         {
904         }
905     };
906 
getMaxConcurrentvkt::api::__anonc97e7d540111::DeviceMemory907     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
908     {
909         const VkDeviceSize deviceMemoryUsage = params.size + getPageTableSize(context, params.size);
910 
911         return getSafeObjectCount<DeviceMemory>(context, params,
912                                                 de::min(context.getDeviceProperties().limits.maxMemoryAllocationCount,
913                                                         (uint32_t)DEFAULT_MAX_CONCURRENT_OBJECTS),
914                                                 deviceMemoryUsage);
915     }
916 
createvkt::api::__anonc97e7d540111::DeviceMemory917     static Move<VkDeviceMemory> create(const Environment &env, const Resources &, const Parameters &params)
918     {
919         const VkMemoryAllocateInfo allocInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, DE_NULL, params.size,
920                                                 params.memoryTypeIndex};
921 
922         return allocateMemory(env.vkd, env.device, &allocInfo, env.allocationCallbacks);
923     }
924 };
925 
getDeviceMemoryParameters(const VkMemoryRequirements & memReqs)926 DeviceMemory::Parameters getDeviceMemoryParameters(const VkMemoryRequirements &memReqs)
927 {
928     return DeviceMemory::Parameters(memReqs.size, deCtz32(memReqs.memoryTypeBits));
929 }
930 
getDeviceMemoryParameters(const Environment & env,VkImage image)931 DeviceMemory::Parameters getDeviceMemoryParameters(const Environment &env, VkImage image)
932 {
933     return getDeviceMemoryParameters(getImageMemoryRequirements(env.vkd, env.device, image));
934 }
935 
getDeviceMemoryParameters(const Environment & env,VkBuffer image)936 DeviceMemory::Parameters getDeviceMemoryParameters(const Environment &env, VkBuffer image)
937 {
938     return getDeviceMemoryParameters(getBufferMemoryRequirements(env.vkd, env.device, image));
939 }
940 
941 struct Buffer
942 {
943     typedef VkBuffer Type;
944 
945     struct Parameters
946     {
947         VkDeviceSize size;
948         VkBufferUsageFlags usage;
949 
Parametersvkt::api::__anonc97e7d540111::Buffer::Parameters950         Parameters(VkDeviceSize size_, VkBufferUsageFlags usage_) : size(size_), usage(usage_)
951         {
952         }
953     };
954 
955     struct Resources
956     {
Resourcesvkt::api::__anonc97e7d540111::Buffer::Resources957         Resources(const Environment &, const Parameters &)
958         {
959         }
960     };
961 
getMaxConcurrentvkt::api::__anonc97e7d540111::Buffer962     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
963     {
964         const Environment env(context, 1u);
965         const Resources res(env, params);
966         const Unique<VkBuffer> buffer(create(env, res, params));
967         const VkMemoryRequirements memReqs = getBufferMemoryRequirements(env.vkd, env.device, *buffer);
968 
969         return getSafeObjectCount<Buffer>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS,
970                                           getPageTableSize(context, memReqs.size));
971     }
972 
createvkt::api::__anonc97e7d540111::Buffer973     static Move<VkBuffer> create(const Environment &env, const Resources &, const Parameters &params)
974     {
975         const VkBufferCreateInfo bufferInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
976                                                DE_NULL,
977                                                (VkBufferCreateFlags)0,
978                                                params.size,
979                                                params.usage,
980                                                VK_SHARING_MODE_EXCLUSIVE,
981                                                1u,
982                                                &env.queueFamilyIndex};
983 
984         return createBuffer(env.vkd, env.device, &bufferInfo, env.allocationCallbacks);
985     }
986 };
987 
988 struct BufferView
989 {
990     typedef VkBufferView Type;
991 
992     struct Parameters
993     {
994         Buffer::Parameters buffer;
995         VkFormat format;
996         VkDeviceSize offset;
997         VkDeviceSize range;
998 
Parametersvkt::api::__anonc97e7d540111::BufferView::Parameters999         Parameters(const Buffer::Parameters &buffer_, VkFormat format_, VkDeviceSize offset_, VkDeviceSize range_)
1000             : buffer(buffer_)
1001             , format(format_)
1002             , offset(offset_)
1003             , range(range_)
1004         {
1005         }
1006     };
1007 
1008     struct Resources
1009     {
1010         Dependency<Buffer> buffer;
1011         Dependency<DeviceMemory> memory;
1012 
Resourcesvkt::api::__anonc97e7d540111::BufferView::Resources1013         Resources(const Environment &env, const Parameters &params)
1014             : buffer(env, params.buffer)
1015             , memory(env, getDeviceMemoryParameters(env, *buffer.object))
1016         {
1017             VK_CHECK(env.vkd.bindBufferMemory(env.device, *buffer.object, *memory.object, 0));
1018         }
1019     };
1020 
getMaxConcurrentvkt::api::__anonc97e7d540111::BufferView1021     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1022     {
1023         return getSafeObjectCount<BufferView>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1024     }
1025 
createvkt::api::__anonc97e7d540111::BufferView1026     static Move<VkBufferView> create(const Environment &env, const Resources &res, const Parameters &params)
1027     {
1028         const VkBufferViewCreateInfo bufferViewInfo = {VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
1029                                                        DE_NULL,
1030                                                        (VkBufferViewCreateFlags)0,
1031                                                        *res.buffer.object,
1032                                                        params.format,
1033                                                        params.offset,
1034                                                        params.range};
1035 
1036         return createBufferView(env.vkd, env.device, &bufferViewInfo, env.allocationCallbacks);
1037     }
1038 };
1039 
1040 struct Image
1041 {
1042     typedef VkImage Type;
1043 
1044     struct Parameters
1045     {
1046         VkImageCreateFlags flags;
1047         VkImageType imageType;
1048         VkFormat format;
1049         VkExtent3D extent;
1050         uint32_t mipLevels;
1051         uint32_t arraySize;
1052         VkSampleCountFlagBits samples;
1053         VkImageTiling tiling;
1054         VkImageUsageFlags usage;
1055         VkImageLayout initialLayout;
1056 
Parametersvkt::api::__anonc97e7d540111::Image::Parameters1057         Parameters(VkImageCreateFlags flags_, VkImageType imageType_, VkFormat format_, VkExtent3D extent_,
1058                    uint32_t mipLevels_, uint32_t arraySize_, VkSampleCountFlagBits samples_, VkImageTiling tiling_,
1059                    VkImageUsageFlags usage_, VkImageLayout initialLayout_)
1060             : flags(flags_)
1061             , imageType(imageType_)
1062             , format(format_)
1063             , extent(extent_)
1064             , mipLevels(mipLevels_)
1065             , arraySize(arraySize_)
1066             , samples(samples_)
1067             , tiling(tiling_)
1068             , usage(usage_)
1069             , initialLayout(initialLayout_)
1070         {
1071         }
1072     };
1073 
1074     struct Resources
1075     {
Resourcesvkt::api::__anonc97e7d540111::Image::Resources1076         Resources(const Environment &, const Parameters &)
1077         {
1078         }
1079     };
1080 
getMaxConcurrentvkt::api::__anonc97e7d540111::Image1081     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1082     {
1083         const Environment env(context, 1u);
1084         const Resources res(env, params);
1085         const Unique<VkImage> image(create(env, res, params));
1086         const VkMemoryRequirements memReqs = getImageMemoryRequirements(env.vkd, env.device, *image);
1087 
1088         return getSafeObjectCount<Image>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS,
1089                                          getPageTableSize(context, memReqs.size));
1090     }
1091 
createvkt::api::__anonc97e7d540111::Image1092     static Move<VkImage> create(const Environment &env, const Resources &, const Parameters &params)
1093     {
1094         const VkImageCreateInfo imageInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1095                                              DE_NULL,
1096                                              params.flags,
1097                                              params.imageType,
1098                                              params.format,
1099                                              params.extent,
1100                                              params.mipLevels,
1101                                              params.arraySize,
1102                                              params.samples,
1103                                              params.tiling,
1104                                              params.usage,
1105                                              VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1106                                              1u,                        // queueFamilyIndexCount
1107                                              &env.queueFamilyIndex,     // pQueueFamilyIndices
1108                                              params.initialLayout};
1109 
1110         return createImage(env.vkd, env.device, &imageInfo, env.allocationCallbacks);
1111     }
1112 };
1113 
1114 struct ImageView
1115 {
1116     typedef VkImageView Type;
1117 
1118     struct Parameters
1119     {
1120         Image::Parameters image;
1121         VkImageViewType viewType;
1122         VkFormat format;
1123         VkComponentMapping components;
1124         VkImageSubresourceRange subresourceRange;
1125 
Parametersvkt::api::__anonc97e7d540111::ImageView::Parameters1126         Parameters(const Image::Parameters &image_, VkImageViewType viewType_, VkFormat format_,
1127                    VkComponentMapping components_, VkImageSubresourceRange subresourceRange_)
1128             : image(image_)
1129             , viewType(viewType_)
1130             , format(format_)
1131             , components(components_)
1132             , subresourceRange(subresourceRange_)
1133         {
1134         }
1135     };
1136 
1137     struct Resources
1138     {
1139         Dependency<Image> image;
1140         Dependency<DeviceMemory> memory;
1141 
Resourcesvkt::api::__anonc97e7d540111::ImageView::Resources1142         Resources(const Environment &env, const Parameters &params)
1143             : image(env, params.image)
1144             , memory(env, getDeviceMemoryParameters(env, *image.object))
1145         {
1146             VK_CHECK(env.vkd.bindImageMemory(env.device, *image.object, *memory.object, 0));
1147         }
1148     };
1149 
getMaxConcurrentvkt::api::__anonc97e7d540111::ImageView1150     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1151     {
1152         return getSafeObjectCount<ImageView>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1153     }
1154 
createvkt::api::__anonc97e7d540111::ImageView1155     static Move<VkImageView> create(const Environment &env, const Resources &res, const Parameters &params)
1156     {
1157         const VkImageViewCreateInfo imageViewInfo = {
1158             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1159             DE_NULL,
1160             (VkImageViewCreateFlags)0,
1161             *res.image.object,
1162             params.viewType,
1163             params.format,
1164             params.components,
1165             params.subresourceRange,
1166         };
1167 
1168         return createImageView(env.vkd, env.device, &imageViewInfo, env.allocationCallbacks);
1169     }
1170 };
1171 
1172 struct Semaphore
1173 {
1174     typedef VkSemaphore Type;
1175 
1176     struct Parameters
1177     {
1178         VkSemaphoreCreateFlags flags;
1179 
Parametersvkt::api::__anonc97e7d540111::Semaphore::Parameters1180         Parameters(VkSemaphoreCreateFlags flags_) : flags(flags_)
1181         {
1182         }
1183     };
1184 
1185     struct Resources
1186     {
Resourcesvkt::api::__anonc97e7d540111::Semaphore::Resources1187         Resources(const Environment &, const Parameters &)
1188         {
1189         }
1190     };
1191 
getMaxConcurrentvkt::api::__anonc97e7d540111::Semaphore1192     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1193     {
1194         return getSafeObjectCount<Semaphore>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES);
1195     }
1196 
createvkt::api::__anonc97e7d540111::Semaphore1197     static Move<VkSemaphore> create(const Environment &env, const Resources &, const Parameters &params)
1198     {
1199         const VkSemaphoreCreateInfo semaphoreInfo = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, DE_NULL, params.flags};
1200 
1201         return createSemaphore(env.vkd, env.device, &semaphoreInfo, env.allocationCallbacks);
1202     }
1203 };
1204 
1205 struct Fence
1206 {
1207     typedef VkFence Type;
1208 
1209     struct Parameters
1210     {
1211         VkFenceCreateFlags flags;
1212 
Parametersvkt::api::__anonc97e7d540111::Fence::Parameters1213         Parameters(VkFenceCreateFlags flags_) : flags(flags_)
1214         {
1215         }
1216     };
1217 
1218     struct Resources
1219     {
Resourcesvkt::api::__anonc97e7d540111::Fence::Resources1220         Resources(const Environment &, const Parameters &)
1221         {
1222         }
1223     };
1224 
getMaxConcurrentvkt::api::__anonc97e7d540111::Fence1225     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1226     {
1227         return getSafeObjectCount<Fence>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES);
1228     }
1229 
createvkt::api::__anonc97e7d540111::Fence1230     static Move<VkFence> create(const Environment &env, const Resources &, const Parameters &params)
1231     {
1232         const VkFenceCreateInfo fenceInfo = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, DE_NULL, params.flags};
1233 
1234         return createFence(env.vkd, env.device, &fenceInfo, env.allocationCallbacks);
1235     }
1236 };
1237 
1238 struct Event
1239 {
1240     typedef VkEvent Type;
1241 
1242     struct Parameters
1243     {
1244         VkEventCreateFlags flags;
1245 
Parametersvkt::api::__anonc97e7d540111::Event::Parameters1246         Parameters(VkEventCreateFlags flags_) : flags(flags_)
1247         {
1248         }
1249     };
1250 
1251     struct Resources
1252     {
Resourcesvkt::api::__anonc97e7d540111::Event::Resources1253         Resources(const Environment &, const Parameters &)
1254         {
1255         }
1256     };
1257 
getMaxConcurrentvkt::api::__anonc97e7d540111::Event1258     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1259     {
1260         return getSafeObjectCount<Event>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES);
1261     }
1262 
createvkt::api::__anonc97e7d540111::Event1263     static Move<VkEvent> create(const Environment &env, const Resources &, const Parameters &params)
1264     {
1265         const VkEventCreateInfo eventInfo = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, DE_NULL, params.flags};
1266 
1267         return createEvent(env.vkd, env.device, &eventInfo, env.allocationCallbacks);
1268     }
1269 };
1270 
1271 struct QueryPool
1272 {
1273     typedef VkQueryPool Type;
1274 
1275     struct Parameters
1276     {
1277         VkQueryType queryType;
1278         uint32_t entryCount;
1279         VkQueryPipelineStatisticFlags pipelineStatistics;
1280 
Parametersvkt::api::__anonc97e7d540111::QueryPool::Parameters1281         Parameters(VkQueryType queryType_, uint32_t entryCount_, VkQueryPipelineStatisticFlags pipelineStatistics_)
1282             : queryType(queryType_)
1283             , entryCount(entryCount_)
1284             , pipelineStatistics(pipelineStatistics_)
1285         {
1286         }
1287     };
1288 
1289     struct Resources
1290     {
Resourcesvkt::api::__anonc97e7d540111::QueryPool::Resources1291         Resources(const Environment &, const Parameters &)
1292         {
1293         }
1294     };
1295 
getMaxConcurrentvkt::api::__anonc97e7d540111::QueryPool1296     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1297     {
1298         return getSafeObjectCount<QueryPool>(context, params, MAX_CONCURRENT_QUERY_POOLS);
1299     }
1300 
createvkt::api::__anonc97e7d540111::QueryPool1301     static Move<VkQueryPool> create(const Environment &env, const Resources &, const Parameters &params)
1302     {
1303         const VkQueryPoolCreateInfo queryPoolInfo = {VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
1304                                                      DE_NULL,
1305                                                      (VkQueryPoolCreateFlags)0,
1306                                                      params.queryType,
1307                                                      params.entryCount,
1308                                                      params.pipelineStatistics};
1309 
1310         return createQueryPool(env.vkd, env.device, &queryPoolInfo, env.allocationCallbacks);
1311     }
1312 };
1313 
1314 struct ShaderModule
1315 {
1316     typedef VkShaderModule Type;
1317 
1318     struct Parameters
1319     {
1320         VkShaderStageFlagBits shaderStage;
1321         string binaryName;
1322 
Parametersvkt::api::__anonc97e7d540111::ShaderModule::Parameters1323         Parameters(VkShaderStageFlagBits shaderStage_, const std::string &binaryName_)
1324             : shaderStage(shaderStage_)
1325             , binaryName(binaryName_)
1326         {
1327         }
1328     };
1329 
1330     struct Resources
1331     {
1332         const ProgramBinary &binary;
1333 
Resourcesvkt::api::__anonc97e7d540111::ShaderModule::Resources1334         Resources(const Environment &env, const Parameters &params) : binary(env.programBinaries.get(params.binaryName))
1335         {
1336         }
1337     };
1338 
getMaxConcurrentvkt::api::__anonc97e7d540111::ShaderModule1339     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1340     {
1341         return getSafeObjectCount<ShaderModule>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1342     }
1343 
getSourcevkt::api::__anonc97e7d540111::ShaderModule1344     static const char *getSource(VkShaderStageFlagBits stage)
1345     {
1346         switch (stage)
1347         {
1348         case VK_SHADER_STAGE_VERTEX_BIT:
1349             return "#version 310 es\n"
1350                    "layout(location = 0) in highp vec4 a_position;\n"
1351                    "void main () { gl_Position = a_position; }\n";
1352 
1353         case VK_SHADER_STAGE_FRAGMENT_BIT:
1354             return "#version 310 es\n"
1355                    "layout(location = 0) out mediump vec4 o_color;\n"
1356                    "void main () { o_color = vec4(1.0, 0.5, 0.25, 1.0); }";
1357 
1358         case VK_SHADER_STAGE_COMPUTE_BIT:
1359             return "#version 310 es\n"
1360                    "layout(binding = 0) buffer Input { highp uint dataIn[]; };\n"
1361                    "layout(binding = 1) buffer Output { highp uint dataOut[]; };\n"
1362                    "void main (void)\n"
1363                    "{\n"
1364                    "    dataOut[gl_GlobalInvocationID.x] = ~dataIn[gl_GlobalInvocationID.x];\n"
1365                    "}\n";
1366 
1367         default:
1368             DE_FATAL("Not implemented");
1369             return DE_NULL;
1370         }
1371     }
1372 
initProgramsvkt::api::__anonc97e7d540111::ShaderModule1373     static void initPrograms(SourceCollections &dst, Parameters params)
1374     {
1375         const char *const source = getSource(params.shaderStage);
1376 
1377         DE_ASSERT(source);
1378 
1379         dst.glslSources.add(params.binaryName) << glu::ShaderSource(getGluShaderType(params.shaderStage), source);
1380     }
1381 
createvkt::api::__anonc97e7d540111::ShaderModule1382     static Move<VkShaderModule> create(const Environment &env, const Resources &res, const Parameters &)
1383     {
1384         const VkShaderModuleCreateInfo shaderModuleInfo = {
1385             VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, DE_NULL, (VkShaderModuleCreateFlags)0, res.binary.getSize(),
1386             (const uint32_t *)res.binary.getBinary(),
1387         };
1388 
1389         return createShaderModule(env.vkd, env.device, &shaderModuleInfo, env.allocationCallbacks);
1390     }
1391 };
1392 
1393 struct PipelineCache
1394 {
1395     typedef VkPipelineCache Type;
1396 
1397     struct Parameters
1398     {
1399         bool externSync = false;
Parametersvkt::api::__anonc97e7d540111::PipelineCache::Parameters1400         Parameters(void)
1401         {
1402         }
Parametersvkt::api::__anonc97e7d540111::PipelineCache::Parameters1403         Parameters(bool externSync_) : externSync(externSync_)
1404         {
1405         }
1406     };
1407 
1408     struct Resources
1409     {
Resourcesvkt::api::__anonc97e7d540111::PipelineCache::Resources1410         Resources(const Environment &, const Parameters &)
1411         {
1412         }
1413     };
1414 
getMaxConcurrentvkt::api::__anonc97e7d540111::PipelineCache1415     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1416     {
1417         return getSafeObjectCount<PipelineCache>(context, params, MAX_CONCURRENT_PIPELINE_CACHES);
1418     }
1419 
initProgramsvkt::api::__anonc97e7d540111::PipelineCache1420     static void initPrograms(SourceCollections &dst, Parameters)
1421     {
1422         ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"));
1423     }
1424 
createvkt::api::__anonc97e7d540111::PipelineCache1425     static Move<VkPipelineCache> create(const Environment &env, const Resources &, const Parameters &params)
1426     {
1427         (void)params;
1428 #ifdef CTS_USES_VULKANSC
1429         // creating dummy compute pipeline to ensure pipeline cache is not empty
1430         if (!env.commandLine.isSubProcess())
1431         {
1432             const Unique<VkShaderModule> shaderModule(
1433                 createShaderModule(env.vkd, env.device, env.programBinaries.get("comp"), 0u));
1434 
1435             const Move<VkDescriptorSetLayout> descriptorSetLayout(
1436                 DescriptorSetLayoutBuilder()
1437                     .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
1438                     .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
1439                     .build(env.vkd, env.device));
1440 
1441             const Move<VkPipelineLayout> pipelineLayout(makePipelineLayout(env.vkd, env.device, *descriptorSetLayout));
1442 
1443             const VkPipelineShaderStageCreateInfo stageCreateInfo = {
1444                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1445                 DE_NULL,                                             // const void*                         pNext;
1446                 0u,                                                  // VkPipelineShaderStageCreateFlags    flags;
1447                 VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits               stage;
1448                 *shaderModule,                                       // VkShaderModule                      module;
1449                 "main",                                              // const char*                         pName;
1450                 DE_NULL, // const VkSpecializationInfo*         pSpecializationInfo;
1451             };
1452 
1453             const VkComputePipelineCreateInfo pipelineInfo = {
1454                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                    sType
1455                 DE_NULL,                                        // const void*                        pNext
1456                 (VkPipelineCreateFlags)0,                       // VkPipelineCreateFlags            flags
1457                 stageCreateInfo,                                // VkPipelineShaderStageCreateInfo    stage
1458                 *pipelineLayout,                                // VkPipelineLayout                    layout
1459                 DE_NULL,                                        // VkPipeline                        basePipelineHandle
1460                 0u                                              // int32_t                            basePipelineIndex
1461             };
1462 
1463             Move<VkPipeline> pipeline = createComputePipeline(env.vkd, env.device, DE_NULL, &pipelineInfo);
1464         }
1465 #else
1466         VkPipelineCacheCreateFlags pipelineCacheCreateFlags =
1467             params.externSync ? (VkPipelineCacheCreateFlags)VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT : 0u;
1468 #endif // CTS_USES_VULKANSC
1469 
1470         const VkPipelineCacheCreateInfo pipelineCacheInfo = {
1471             VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1472             DE_NULL,                                      // const void* pNext;
1473 #ifndef CTS_USES_VULKANSC
1474             pipelineCacheCreateFlags, // VkPipelineCacheCreateFlags flags;
1475             0u,                       // size_t initialDataSize;
1476             DE_NULL,                  // const void* pInitialData;
1477 #else
1478             VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
1479                 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
1480             env.resourceInterface->getCacheDataSize(),                // uintptr_t initialDataSize;
1481             env.resourceInterface->getCacheData()                     // const void* pInitialData;
1482 #endif // CTS_USES_VULKANSC
1483         };
1484 
1485         return createPipelineCache(env.vkd, env.device, &pipelineCacheInfo, env.allocationCallbacks);
1486     }
1487 };
1488 
1489 struct MergedPipelineCache
1490 {
1491     typedef VkPipelineCache Type;
1492 
1493     struct Parameters
1494     {
1495         bool srcExternSync;
1496         bool dstExternSync;
Parametersvkt::api::__anonc97e7d540111::MergedPipelineCache::Parameters1497         Parameters(bool srcExternSync_, bool dstExternSync_)
1498             : srcExternSync(srcExternSync_)
1499             , dstExternSync(dstExternSync_)
1500         {
1501         }
1502     };
1503 
1504     struct Resources
1505     {
1506         inline static std::unordered_map<VkDevice, SharedPtr<Dependency<PipelineCache>>> srcPipelineCaches;
Resourcesvkt::api::__anonc97e7d540111::MergedPipelineCache::Resources1507         Resources(const Environment &env, const Parameters &params)
1508         {
1509             if (srcPipelineCaches.find(env.device) == srcPipelineCaches.end())
1510             {
1511                 srcPipelineCaches[env.device] =
1512                     SharedPtr<Dependency<PipelineCache>>(new Dependency<PipelineCache>(env, {params.srcExternSync}));
1513             }
1514         }
~Resourcesvkt::api::__anonc97e7d540111::MergedPipelineCache::Resources1515         ~Resources()
1516         {
1517             if (!srcPipelineCaches.empty())
1518             {
1519                 srcPipelineCaches.clear();
1520             }
1521         }
1522     };
1523 
getMaxConcurrentvkt::api::__anonc97e7d540111::MergedPipelineCache1524     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1525     {
1526         return getSafeObjectCount<MergedPipelineCache>(context, params, MAX_CONCURRENT_PIPELINE_CACHES);
1527     }
1528 
initProgramsvkt::api::__anonc97e7d540111::MergedPipelineCache1529     static void initPrograms(SourceCollections &dst, Parameters)
1530     {
1531         ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"));
1532     }
1533 
createvkt::api::__anonc97e7d540111::MergedPipelineCache1534     static Move<VkPipelineCache> create(const Environment &env, const Resources &resources, const Parameters &params)
1535     {
1536         (void)resources;
1537         // creating dummy compute pipeline to ensure pipeline cache is not empty
1538         if (!env.commandLine.isSubProcess())
1539         {
1540             const Unique<VkShaderModule> shaderModule(
1541                 createShaderModule(env.vkd, env.device, env.programBinaries.get("comp"), 0u));
1542 
1543             const Move<VkDescriptorSetLayout> descriptorSetLayout(
1544                 DescriptorSetLayoutBuilder()
1545                     .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
1546                     .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
1547                     .build(env.vkd, env.device));
1548 
1549             const Move<VkPipelineLayout> pipelineLayout(makePipelineLayout(env.vkd, env.device, *descriptorSetLayout));
1550 
1551             const VkPipelineShaderStageCreateInfo stageCreateInfo = {
1552                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1553                 DE_NULL,                                             // const void*                         pNext;
1554                 0u,                                                  // VkPipelineShaderStageCreateFlags    flags;
1555                 VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits               stage;
1556                 *shaderModule,                                       // VkShaderModule                      module;
1557                 "main",                                              // const char*                         pName;
1558                 DE_NULL, // const VkSpecializationInfo*         pSpecializationInfo;
1559             };
1560 
1561             const VkComputePipelineCreateInfo pipelineInfo = {
1562                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                    sType
1563                 DE_NULL,                                        // const void*                        pNext
1564                 (VkPipelineCreateFlags)0,                       // VkPipelineCreateFlags            flags
1565                 stageCreateInfo,                                // VkPipelineShaderStageCreateInfo    stage
1566                 *pipelineLayout,                                // VkPipelineLayout                    layout
1567                 DE_NULL,                                        // VkPipeline                        basePipelineHandle
1568                 0u                                              // int32_t                            basePipelineIndex
1569             };
1570 
1571             Move<VkPipeline> pipeline = createComputePipeline(env.vkd, env.device, DE_NULL, &pipelineInfo);
1572         }
1573 
1574         VkPipelineCacheCreateFlags pipelineCacheCreateFlags =
1575             params.dstExternSync ? (VkPipelineCacheCreateFlags)VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT :
1576                                    0u;
1577 
1578         const VkPipelineCacheCreateInfo pipelineCacheInfo = {
1579             VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1580             DE_NULL,                                      // const void* pNext;
1581             pipelineCacheCreateFlags,                     // VkPipelineCacheCreateFlags flags;
1582             0u,                                           // size_t initialDataSize;
1583             DE_NULL,                                      // const void* pInitialData;
1584         };
1585 
1586         auto pipelineCache = createPipelineCache(env.vkd, env.device, &pipelineCacheInfo, env.allocationCallbacks);
1587 #ifndef CTS_USES_VULKANSC
1588         VkPipelineCache srcCache = resources.srcPipelineCaches[env.device]->object.get();
1589         env.vkd.mergePipelineCaches(env.device, pipelineCache.get(), 1u, &srcCache);
1590 #endif
1591         return pipelineCache;
1592     }
1593 };
1594 
1595 struct Sampler
1596 {
1597     typedef VkSampler Type;
1598 
1599     struct Parameters
1600     {
1601         VkFilter magFilter;
1602         VkFilter minFilter;
1603         VkSamplerMipmapMode mipmapMode;
1604         VkSamplerAddressMode addressModeU;
1605         VkSamplerAddressMode addressModeV;
1606         VkSamplerAddressMode addressModeW;
1607         float mipLodBias;
1608         VkBool32 anisotropyEnable;
1609         float maxAnisotropy;
1610         VkBool32 compareEnable;
1611         VkCompareOp compareOp;
1612         float minLod;
1613         float maxLod;
1614         VkBorderColor borderColor;
1615         VkBool32 unnormalizedCoordinates;
1616 
1617         // \todo [2015-09-17 pyry] Other configurations
Parametersvkt::api::__anonc97e7d540111::Sampler::Parameters1618         Parameters(void)
1619             : magFilter(VK_FILTER_NEAREST)
1620             , minFilter(VK_FILTER_NEAREST)
1621             , mipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
1622             , addressModeU(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1623             , addressModeV(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1624             , addressModeW(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1625             , mipLodBias(0.0f)
1626             , anisotropyEnable(VK_FALSE)
1627             , maxAnisotropy(1.0f)
1628             , compareEnable(VK_FALSE)
1629             , compareOp(VK_COMPARE_OP_ALWAYS)
1630             , minLod(-1000.f)
1631             , maxLod(+1000.f)
1632             , borderColor(VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK)
1633             , unnormalizedCoordinates(VK_FALSE)
1634         {
1635         }
1636     };
1637 
1638     struct Resources
1639     {
Resourcesvkt::api::__anonc97e7d540111::Sampler::Resources1640         Resources(const Environment &, const Parameters &)
1641         {
1642         }
1643     };
1644 
getMaxConcurrentvkt::api::__anonc97e7d540111::Sampler1645     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1646     {
1647         return getSafeObjectCount<Sampler>(context, params,
1648                                            de::min(context.getDeviceProperties().limits.maxSamplerAllocationCount,
1649                                                    (uint32_t)DEFAULT_MAX_CONCURRENT_OBJECTS));
1650     }
1651 
createvkt::api::__anonc97e7d540111::Sampler1652     static Move<VkSampler> create(const Environment &env, const Resources &, const Parameters &params)
1653     {
1654         const VkSamplerCreateInfo samplerInfo = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1655                                                  DE_NULL,
1656                                                  (VkSamplerCreateFlags)0,
1657                                                  params.magFilter,
1658                                                  params.minFilter,
1659                                                  params.mipmapMode,
1660                                                  params.addressModeU,
1661                                                  params.addressModeV,
1662                                                  params.addressModeW,
1663                                                  params.mipLodBias,
1664                                                  params.anisotropyEnable,
1665                                                  params.maxAnisotropy,
1666                                                  params.compareEnable,
1667                                                  params.compareOp,
1668                                                  params.minLod,
1669                                                  params.maxLod,
1670                                                  params.borderColor,
1671                                                  params.unnormalizedCoordinates};
1672 
1673         return createSampler(env.vkd, env.device, &samplerInfo, env.allocationCallbacks);
1674     }
1675 };
1676 
1677 struct DescriptorSetLayout
1678 {
1679     typedef VkDescriptorSetLayout Type;
1680 
1681     struct Parameters
1682     {
1683         struct Binding
1684         {
1685             uint32_t binding;
1686             VkDescriptorType descriptorType;
1687             uint32_t descriptorCount;
1688             VkShaderStageFlags stageFlags;
1689             bool useImmutableSampler;
1690 
Bindingvkt::api::__anonc97e7d540111::DescriptorSetLayout::Parameters::Binding1691             Binding(uint32_t binding_, VkDescriptorType descriptorType_, uint32_t descriptorCount_,
1692                     VkShaderStageFlags stageFlags_, bool useImmutableSampler_)
1693                 : binding(binding_)
1694                 , descriptorType(descriptorType_)
1695                 , descriptorCount(descriptorCount_)
1696                 , stageFlags(stageFlags_)
1697                 , useImmutableSampler(useImmutableSampler_)
1698             {
1699             }
1700 
Bindingvkt::api::__anonc97e7d540111::DescriptorSetLayout::Parameters::Binding1701             Binding(void)
1702             {
1703             }
1704         };
1705 
1706         vector<Binding> bindings;
1707 
Parametersvkt::api::__anonc97e7d540111::DescriptorSetLayout::Parameters1708         Parameters(const vector<Binding> &bindings_) : bindings(bindings_)
1709         {
1710         }
1711 
emptyvkt::api::__anonc97e7d540111::DescriptorSetLayout::Parameters1712         static Parameters empty(void)
1713         {
1714             return Parameters(vector<Binding>());
1715         }
1716 
singlevkt::api::__anonc97e7d540111::DescriptorSetLayout::Parameters1717         static Parameters single(uint32_t binding, VkDescriptorType descriptorType, uint32_t descriptorCount,
1718                                  VkShaderStageFlags stageFlags, bool useImmutableSampler = false)
1719         {
1720             vector<Binding> bindings;
1721             bindings.push_back(Binding(binding, descriptorType, descriptorCount, stageFlags, useImmutableSampler));
1722             return Parameters(bindings);
1723         }
1724     };
1725 
1726     struct Resources
1727     {
1728         vector<VkDescriptorSetLayoutBinding> bindings;
1729         MovePtr<Dependency<Sampler>> immutableSampler;
1730         vector<VkSampler> immutableSamplersPtr;
1731 
Resourcesvkt::api::__anonc97e7d540111::DescriptorSetLayout::Resources1732         Resources(const Environment &env, const Parameters &params)
1733         {
1734             // Create immutable sampler if needed
1735             for (vector<Parameters::Binding>::const_iterator cur = params.bindings.begin();
1736                  cur != params.bindings.end(); cur++)
1737             {
1738                 if (cur->useImmutableSampler && !immutableSampler)
1739                 {
1740                     immutableSampler = de::newMovePtr<Dependency<Sampler>>(env, Sampler::Parameters());
1741 
1742                     if (cur->useImmutableSampler && immutableSamplersPtr.size() < (size_t)cur->descriptorCount)
1743                         immutableSamplersPtr.resize(cur->descriptorCount, *immutableSampler->object);
1744                 }
1745             }
1746 
1747             for (vector<Parameters::Binding>::const_iterator cur = params.bindings.begin();
1748                  cur != params.bindings.end(); cur++)
1749             {
1750                 const VkDescriptorSetLayoutBinding binding = {
1751                     cur->binding, cur->descriptorType, cur->descriptorCount, cur->stageFlags,
1752                     (cur->useImmutableSampler ? &immutableSamplersPtr[0] : DE_NULL)};
1753 
1754                 bindings.push_back(binding);
1755             }
1756         }
1757     };
1758 
getMaxConcurrentvkt::api::__anonc97e7d540111::DescriptorSetLayout1759     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1760     {
1761         return getSafeObjectCount<DescriptorSetLayout>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1762     }
1763 
createvkt::api::__anonc97e7d540111::DescriptorSetLayout1764     static Move<VkDescriptorSetLayout> create(const Environment &env, const Resources &res, const Parameters &)
1765     {
1766         const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo = {
1767             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, DE_NULL, (VkDescriptorSetLayoutCreateFlags)0,
1768             (uint32_t)res.bindings.size(), (res.bindings.empty() ? DE_NULL : &res.bindings[0])};
1769 
1770         return createDescriptorSetLayout(env.vkd, env.device, &descriptorSetLayoutInfo, env.allocationCallbacks);
1771     }
1772 };
1773 
1774 struct PipelineLayout
1775 {
1776     typedef VkPipelineLayout Type;
1777 
1778     struct Parameters
1779     {
1780         vector<DescriptorSetLayout::Parameters> descriptorSetLayouts;
1781         vector<VkPushConstantRange> pushConstantRanges;
1782 
Parametersvkt::api::__anonc97e7d540111::PipelineLayout::Parameters1783         Parameters(void)
1784         {
1785         }
1786 
emptyvkt::api::__anonc97e7d540111::PipelineLayout::Parameters1787         static Parameters empty(void)
1788         {
1789             return Parameters();
1790         }
1791 
singleDescriptorSetvkt::api::__anonc97e7d540111::PipelineLayout::Parameters1792         static Parameters singleDescriptorSet(const DescriptorSetLayout::Parameters &descriptorSetLayout)
1793         {
1794             Parameters params;
1795             params.descriptorSetLayouts.push_back(descriptorSetLayout);
1796             return params;
1797         }
1798     };
1799 
1800     struct Resources
1801     {
1802         typedef SharedPtr<Dependency<DescriptorSetLayout>> DescriptorSetLayoutDepSp;
1803         typedef vector<DescriptorSetLayoutDepSp> DescriptorSetLayouts;
1804 
1805         DescriptorSetLayouts descriptorSetLayouts;
1806         vector<VkDescriptorSetLayout> pSetLayouts;
1807 
Resourcesvkt::api::__anonc97e7d540111::PipelineLayout::Resources1808         Resources(const Environment &env, const Parameters &params)
1809         {
1810             for (vector<DescriptorSetLayout::Parameters>::const_iterator dsParams = params.descriptorSetLayouts.begin();
1811                  dsParams != params.descriptorSetLayouts.end(); ++dsParams)
1812             {
1813                 descriptorSetLayouts.push_back(
1814                     DescriptorSetLayoutDepSp(new Dependency<DescriptorSetLayout>(env, *dsParams)));
1815                 pSetLayouts.push_back(*descriptorSetLayouts.back()->object);
1816             }
1817         }
1818     };
1819 
getMaxConcurrentvkt::api::__anonc97e7d540111::PipelineLayout1820     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1821     {
1822         return getSafeObjectCount<PipelineLayout>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1823     }
1824 
createvkt::api::__anonc97e7d540111::PipelineLayout1825     static Move<VkPipelineLayout> create(const Environment &env, const Resources &res, const Parameters &params)
1826     {
1827         const VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
1828             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1829             DE_NULL,
1830             (VkPipelineLayoutCreateFlags)0,
1831             (uint32_t)res.pSetLayouts.size(),
1832             (res.pSetLayouts.empty() ? DE_NULL : &res.pSetLayouts[0]),
1833             (uint32_t)params.pushConstantRanges.size(),
1834             (params.pushConstantRanges.empty() ? DE_NULL : &params.pushConstantRanges[0]),
1835         };
1836 
1837         return createPipelineLayout(env.vkd, env.device, &pipelineLayoutInfo, env.allocationCallbacks);
1838     }
1839 };
1840 
1841 struct RenderPass
1842 {
1843     typedef VkRenderPass Type;
1844 
1845     // \todo [2015-09-17 pyry] More interesting configurations
1846     struct Parameters
1847     {
Parametersvkt::api::__anonc97e7d540111::RenderPass::Parameters1848         Parameters(void)
1849         {
1850         }
1851     };
1852 
1853     struct Resources
1854     {
Resourcesvkt::api::__anonc97e7d540111::RenderPass::Resources1855         Resources(const Environment &, const Parameters &)
1856         {
1857         }
1858     };
1859 
getMaxConcurrentvkt::api::__anonc97e7d540111::RenderPass1860     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1861     {
1862         return getSafeObjectCount<RenderPass>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1863     }
1864 
createvkt::api::__anonc97e7d540111::RenderPass1865     static Move<VkRenderPass> create(const Environment &env, const Resources &, const Parameters &)
1866     {
1867         return makeRenderPass(env.vkd, env.device, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_D16_UNORM,
1868                               VK_ATTACHMENT_LOAD_OP_CLEAR, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1869                               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1870                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1871                               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, env.allocationCallbacks);
1872     }
1873 };
1874 
1875 struct GraphicsPipeline
1876 {
1877     typedef VkPipeline Type;
1878 
1879     // \todo [2015-09-17 pyry] More interesting configurations
1880     struct Parameters
1881     {
Parametersvkt::api::__anonc97e7d540111::GraphicsPipeline::Parameters1882         Parameters(void)
1883         {
1884         }
1885     };
1886 
1887     struct Resources
1888     {
1889         Dependency<ShaderModule> vertexShader;
1890         Dependency<ShaderModule> fragmentShader;
1891         Dependency<PipelineLayout> layout;
1892         Dependency<RenderPass> renderPass;
1893         Dependency<PipelineCache> pipelineCache;
1894 
Resourcesvkt::api::__anonc97e7d540111::GraphicsPipeline::Resources1895         Resources(const Environment &env, const Parameters &)
1896             : vertexShader(env, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert"))
1897             , fragmentShader(env, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag"))
1898             , layout(env, PipelineLayout::Parameters::singleDescriptorSet(DescriptorSetLayout::Parameters::single(
1899                               0u, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u, VK_SHADER_STAGE_FRAGMENT_BIT, true)))
1900             , renderPass(env, RenderPass::Parameters())
1901             , pipelineCache(env, PipelineCache::Parameters())
1902         {
1903         }
1904     };
1905 
getMaxConcurrentvkt::api::__anonc97e7d540111::GraphicsPipeline1906     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
1907     {
1908         return getSafeObjectCount<GraphicsPipeline>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1909     }
1910 
initProgramsvkt::api::__anonc97e7d540111::GraphicsPipeline1911     static void initPrograms(SourceCollections &dst, Parameters)
1912     {
1913 #ifdef CTS_USES_VULKANSC
1914         // Pipeline cache dependency uses compute shader to ensure that pipeline cache is not empty in subprocess.
1915         // We have to add this shader even if we don't plan to use it later in any *.graphics_pipeline test
1916         ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"));
1917 #endif // CTS_USES_VULKANSC
1918         ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert"));
1919         ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag"));
1920     }
1921 
createMultiplevkt::api::__anonc97e7d540111::GraphicsPipeline1922     static vector<VkPipelineSp> createMultiple(const Environment &env, const Resources &res, const Parameters &,
1923                                                vector<VkPipeline> *const pOutHandles, VkResult *const pOutResult)
1924     {
1925         DE_ASSERT(pOutResult);
1926         DE_ASSERT(pOutHandles);
1927         DE_ASSERT(pOutHandles->size() != 0);
1928 
1929         const VkPipelineShaderStageCreateInfo stages[] = {
1930             {
1931                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, (VkPipelineShaderStageCreateFlags)0,
1932                 VK_SHADER_STAGE_VERTEX_BIT, *res.vertexShader.object, "main",
1933                 DE_NULL, // pSpecializationInfo
1934             },
1935             {
1936                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, (VkPipelineShaderStageCreateFlags)0,
1937                 VK_SHADER_STAGE_FRAGMENT_BIT, *res.fragmentShader.object, "main",
1938                 DE_NULL, // pSpecializationInfo
1939             }};
1940         const VkVertexInputBindingDescription vertexBindings[]      = {{0u,  // binding
1941                                                                         16u, // stride
1942                                                                         VK_VERTEX_INPUT_RATE_VERTEX}};
1943         const VkVertexInputAttributeDescription vertexAttribs[]     = {{
1944             0u, // location
1945             0u, // binding
1946             VK_FORMAT_R32G32B32A32_SFLOAT,
1947             0u, // offset
1948         }};
1949         const VkPipelineVertexInputStateCreateInfo vertexInputState = {
1950             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1951             DE_NULL,
1952             (VkPipelineVertexInputStateCreateFlags)0,
1953             DE_LENGTH_OF_ARRAY(vertexBindings),
1954             vertexBindings,
1955             DE_LENGTH_OF_ARRAY(vertexAttribs),
1956             vertexAttribs};
1957         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
1958             VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, DE_NULL,
1959             (VkPipelineInputAssemblyStateCreateFlags)0, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1960             VK_FALSE // primitiveRestartEnable
1961         };
1962         const VkViewport viewport = makeViewport(tcu::UVec2(64));
1963         const VkRect2D scissor    = makeRect2D(tcu::UVec2(64));
1964 
1965         const VkPipelineViewportStateCreateInfo viewportState = {
1966             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1967             DE_NULL,
1968             (VkPipelineViewportStateCreateFlags)0,
1969             1u,
1970             &viewport,
1971             1u,
1972             &scissor,
1973         };
1974         const VkPipelineRasterizationStateCreateInfo rasterState = {
1975             VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1976             DE_NULL,
1977             (VkPipelineRasterizationStateCreateFlags)0,
1978             VK_FALSE, // depthClampEnable
1979             VK_FALSE, // rasterizerDiscardEnable
1980             VK_POLYGON_MODE_FILL,
1981             VK_CULL_MODE_BACK_BIT,
1982             VK_FRONT_FACE_COUNTER_CLOCKWISE,
1983             VK_FALSE, // depthBiasEnable
1984             0.0f,     // depthBiasConstantFactor
1985             0.0f,     // depthBiasClamp
1986             0.0f,     // depthBiasSlopeFactor
1987             1.0f,     // lineWidth
1988         };
1989         const VkPipelineMultisampleStateCreateInfo multisampleState = {
1990             VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1991             DE_NULL,
1992             (VkPipelineMultisampleStateCreateFlags)0,
1993             VK_SAMPLE_COUNT_1_BIT,
1994             VK_FALSE, // sampleShadingEnable
1995             1.0f,     // minSampleShading
1996             DE_NULL,  // pSampleMask
1997             VK_FALSE, // alphaToCoverageEnable
1998             VK_FALSE, // alphaToOneEnable
1999         };
2000         const VkPipelineDepthStencilStateCreateInfo depthStencilState = {
2001             VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
2002             DE_NULL,
2003             (VkPipelineDepthStencilStateCreateFlags)0,
2004             VK_TRUE,            // depthTestEnable
2005             VK_TRUE,            // depthWriteEnable
2006             VK_COMPARE_OP_LESS, // depthCompareOp
2007             VK_FALSE,           // depthBoundsTestEnable
2008             VK_FALSE,           // stencilTestEnable
2009             {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u},
2010             {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u},
2011             0.0f, // minDepthBounds
2012             1.0f, // maxDepthBounds
2013         };
2014         const VkPipelineColorBlendAttachmentState colorBlendAttState[] = {
2015             {VK_FALSE, // blendEnable
2016              VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO,
2017              VK_BLEND_OP_ADD,
2018              VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
2019                  VK_COLOR_COMPONENT_A_BIT}};
2020         const VkPipelineColorBlendStateCreateInfo colorBlendState = {
2021             VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
2022             DE_NULL,
2023             (VkPipelineColorBlendStateCreateFlags)0,
2024             VK_FALSE, // logicOpEnable
2025             VK_LOGIC_OP_COPY,
2026             DE_LENGTH_OF_ARRAY(colorBlendAttState),
2027             colorBlendAttState,
2028             {0.0f, 0.0f, 0.0f, 0.0f} // blendConstants
2029         };
2030         const VkGraphicsPipelineCreateInfo pipelineInfo = {
2031             VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
2032             DE_NULL,
2033             (VkPipelineCreateFlags)0,
2034             DE_LENGTH_OF_ARRAY(stages),
2035             stages,
2036             &vertexInputState,
2037             &inputAssemblyState,
2038             DE_NULL, // pTessellationState
2039             &viewportState,
2040             &rasterState,
2041             &multisampleState,
2042             &depthStencilState,
2043             &colorBlendState,
2044             (const VkPipelineDynamicStateCreateInfo *)DE_NULL,
2045             *res.layout.object,
2046             *res.renderPass.object,
2047             0u,            // subpass
2048             (VkPipeline)0, // basePipelineHandle
2049             0,             // basePipelineIndex
2050         };
2051 
2052         const uint32_t numPipelines = static_cast<uint32_t>(pOutHandles->size());
2053         VkPipeline *const pHandles  = &(*pOutHandles)[0];
2054         vector<VkGraphicsPipelineCreateInfo> pipelineInfos(numPipelines, pipelineInfo);
2055 
2056         *pOutResult = env.vkd.createGraphicsPipelines(env.device, *res.pipelineCache.object, numPipelines,
2057                                                       &pipelineInfos[0], env.allocationCallbacks, pHandles);
2058 
2059         vector<VkPipelineSp> pipelines;
2060 
2061         // Even if an error is returned, some pipelines may have been created successfully
2062         for (uint32_t i = 0; i < numPipelines; ++i)
2063         {
2064             if (pHandles[i] != DE_NULL)
2065                 pipelines.push_back(VkPipelineSp(
2066                     new Move<VkPipeline>(check<VkPipeline>(pHandles[i]),
2067                                          Deleter<VkPipeline>(env.vkd, env.device, env.allocationCallbacks))));
2068         }
2069 
2070         return pipelines;
2071     }
2072 
createvkt::api::__anonc97e7d540111::GraphicsPipeline2073     static Move<VkPipeline> create(const Environment &env, const Resources &res, const Parameters &)
2074     {
2075         vector<VkPipeline> handles(1, DE_NULL);
2076         VkResult result                    = VK_NOT_READY;
2077         vector<VkPipelineSp> scopedHandles = createMultiple(env, res, Parameters(), &handles, &result);
2078 
2079         VK_CHECK(result);
2080         return Move<VkPipeline>(check<VkPipeline>(scopedHandles.front()->disown()),
2081                                 Deleter<VkPipeline>(env.vkd, env.device, env.allocationCallbacks));
2082     }
2083 };
2084 
2085 struct ComputePipeline
2086 {
2087     typedef VkPipeline Type;
2088 
2089     // \todo [2015-09-17 pyry] More interesting configurations
2090     struct Parameters
2091     {
Parametersvkt::api::__anonc97e7d540111::ComputePipeline::Parameters2092         Parameters(void)
2093         {
2094         }
2095     };
2096 
2097     struct Resources
2098     {
2099         Dependency<ShaderModule> shaderModule;
2100         Dependency<PipelineLayout> layout;
2101         Dependency<PipelineCache> pipelineCache;
2102 
getDescriptorSetLayoutvkt::api::__anonc97e7d540111::ComputePipeline::Resources2103         static DescriptorSetLayout::Parameters getDescriptorSetLayout(void)
2104         {
2105             typedef DescriptorSetLayout::Parameters::Binding Binding;
2106 
2107             vector<Binding> bindings;
2108 
2109             bindings.push_back(Binding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false));
2110             bindings.push_back(Binding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false));
2111 
2112             return DescriptorSetLayout::Parameters(bindings);
2113         }
2114 
Resourcesvkt::api::__anonc97e7d540111::ComputePipeline::Resources2115         Resources(const Environment &env, const Parameters &)
2116             : shaderModule(env, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"))
2117             , layout(env, PipelineLayout::Parameters::singleDescriptorSet(getDescriptorSetLayout()))
2118             , pipelineCache(env, PipelineCache::Parameters())
2119         {
2120         }
2121     };
2122 
getMaxConcurrentvkt::api::__anonc97e7d540111::ComputePipeline2123     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
2124     {
2125         return getSafeObjectCount<ComputePipeline>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
2126     }
2127 
initProgramsvkt::api::__anonc97e7d540111::ComputePipeline2128     static void initPrograms(SourceCollections &dst, Parameters)
2129     {
2130         ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"));
2131     }
2132 
createvkt::api::__anonc97e7d540111::ComputePipeline2133     static Move<VkPipeline> create(const Environment &env, const Resources &res, const Parameters &)
2134     {
2135         const VkComputePipelineCreateInfo pipelineInfo = {
2136             VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2137             DE_NULL,
2138             (VkPipelineCreateFlags)0,
2139             {
2140                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, (VkPipelineShaderStageCreateFlags)0,
2141                 VK_SHADER_STAGE_COMPUTE_BIT, *res.shaderModule.object, "main",
2142                 DE_NULL // pSpecializationInfo
2143             },
2144             *res.layout.object,
2145             (VkPipeline)0, // basePipelineHandle
2146             0u,            // basePipelineIndex
2147         };
2148 
2149         return createComputePipeline(env.vkd, env.device, *res.pipelineCache.object, &pipelineInfo,
2150                                      env.allocationCallbacks);
2151     }
2152 
createMultiplevkt::api::__anonc97e7d540111::ComputePipeline2153     static vector<VkPipelineSp> createMultiple(const Environment &env, const Resources &res, const Parameters &,
2154                                                vector<VkPipeline> *const pOutHandles, VkResult *const pOutResult)
2155     {
2156         DE_ASSERT(pOutResult);
2157         DE_ASSERT(pOutHandles);
2158         DE_ASSERT(pOutHandles->size() != 0);
2159 
2160         const VkComputePipelineCreateInfo commonPipelineInfo = {
2161             VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2162             DE_NULL,
2163             (VkPipelineCreateFlags)0,
2164             {
2165                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, (VkPipelineShaderStageCreateFlags)0,
2166                 VK_SHADER_STAGE_COMPUTE_BIT, *res.shaderModule.object, "main",
2167                 DE_NULL // pSpecializationInfo
2168             },
2169             *res.layout.object,
2170             (VkPipeline)0, // basePipelineHandle
2171             0u,            // basePipelineIndex
2172         };
2173 
2174         const uint32_t numPipelines = static_cast<uint32_t>(pOutHandles->size());
2175         VkPipeline *const pHandles  = &(*pOutHandles)[0];
2176         vector<VkComputePipelineCreateInfo> pipelineInfos(numPipelines, commonPipelineInfo);
2177 
2178         *pOutResult = env.vkd.createComputePipelines(env.device, *res.pipelineCache.object, numPipelines,
2179                                                      &pipelineInfos[0], env.allocationCallbacks, pHandles);
2180 
2181         vector<VkPipelineSp> pipelines;
2182 
2183         // Even if an error is returned, some pipelines may have been created successfully
2184         for (uint32_t i = 0; i < numPipelines; ++i)
2185         {
2186             if (pHandles[i] != DE_NULL)
2187                 pipelines.push_back(VkPipelineSp(
2188                     new Move<VkPipeline>(check<VkPipeline>(pHandles[i]),
2189                                          Deleter<VkPipeline>(env.vkd, env.device, env.allocationCallbacks))));
2190         }
2191 
2192         return pipelines;
2193     }
2194 };
2195 
2196 struct DescriptorPool
2197 {
2198     typedef VkDescriptorPool Type;
2199 
2200     struct Parameters
2201     {
2202         VkDescriptorPoolCreateFlags flags;
2203         uint32_t maxSets;
2204         vector<VkDescriptorPoolSize> poolSizes;
2205 
Parametersvkt::api::__anonc97e7d540111::DescriptorPool::Parameters2206         Parameters(VkDescriptorPoolCreateFlags flags_, uint32_t maxSets_,
2207                    const vector<VkDescriptorPoolSize> &poolSizes_)
2208             : flags(flags_)
2209             , maxSets(maxSets_)
2210             , poolSizes(poolSizes_)
2211         {
2212         }
2213 
singleTypevkt::api::__anonc97e7d540111::DescriptorPool::Parameters2214         static Parameters singleType(VkDescriptorPoolCreateFlags flags, uint32_t maxSets, VkDescriptorType type,
2215                                      uint32_t count)
2216         {
2217             vector<VkDescriptorPoolSize> poolSizes;
2218             poolSizes.push_back(makeDescriptorPoolSize(type, count));
2219             return Parameters(flags, maxSets, poolSizes);
2220         }
2221     };
2222 
2223     struct Resources
2224     {
Resourcesvkt::api::__anonc97e7d540111::DescriptorPool::Resources2225         Resources(const Environment &, const Parameters &)
2226         {
2227         }
2228     };
2229 
getMaxConcurrentvkt::api::__anonc97e7d540111::DescriptorPool2230     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
2231     {
2232         return getSafeObjectCount<DescriptorPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
2233     }
2234 
createvkt::api::__anonc97e7d540111::DescriptorPool2235     static Move<VkDescriptorPool> create(const Environment &env, const Resources &, const Parameters &params)
2236     {
2237         const VkDescriptorPoolCreateInfo descriptorPoolInfo = {
2238             VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2239             DE_NULL,
2240             params.flags,
2241             params.maxSets,
2242             (uint32_t)params.poolSizes.size(),
2243             (params.poolSizes.empty() ? DE_NULL : &params.poolSizes[0])};
2244 
2245         return createDescriptorPool(env.vkd, env.device, &descriptorPoolInfo, env.allocationCallbacks);
2246     }
2247 };
2248 
2249 struct DescriptorSet
2250 {
2251     typedef VkDescriptorSet Type;
2252 
2253     struct Parameters
2254     {
2255         DescriptorSetLayout::Parameters descriptorSetLayout;
2256 
Parametersvkt::api::__anonc97e7d540111::DescriptorSet::Parameters2257         Parameters(const DescriptorSetLayout::Parameters &descriptorSetLayout_)
2258             : descriptorSetLayout(descriptorSetLayout_)
2259         {
2260         }
2261     };
2262 
2263     struct Resources
2264     {
2265         Dependency<DescriptorPool> descriptorPool;
2266         Dependency<DescriptorSetLayout> descriptorSetLayout;
2267 
computePoolSizesvkt::api::__anonc97e7d540111::DescriptorSet::Resources2268         static vector<VkDescriptorPoolSize> computePoolSizes(const DescriptorSetLayout::Parameters &layout, int maxSets)
2269         {
2270             uint32_t countByType[VK_DESCRIPTOR_TYPE_LAST];
2271             vector<VkDescriptorPoolSize> typeCounts;
2272 
2273             std::fill(DE_ARRAY_BEGIN(countByType), DE_ARRAY_END(countByType), 0u);
2274 
2275             for (vector<DescriptorSetLayout::Parameters::Binding>::const_iterator cur = layout.bindings.begin();
2276                  cur != layout.bindings.end(); ++cur)
2277             {
2278                 DE_ASSERT((uint32_t)cur->descriptorType < VK_DESCRIPTOR_TYPE_LAST);
2279                 countByType[cur->descriptorType] += cur->descriptorCount * maxSets;
2280             }
2281 
2282             for (uint32_t type = 0; type < VK_DESCRIPTOR_TYPE_LAST; ++type)
2283             {
2284                 if (countByType[type] > 0)
2285                     typeCounts.push_back(makeDescriptorPoolSize((VkDescriptorType)type, countByType[type]));
2286             }
2287 
2288             return typeCounts;
2289         }
2290 
Resourcesvkt::api::__anonc97e7d540111::DescriptorSet::Resources2291         Resources(const Environment &env, const Parameters &params)
2292             : descriptorPool(env, DescriptorPool::Parameters(
2293                                       VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, env.maxResourceConsumers,
2294                                       computePoolSizes(params.descriptorSetLayout, env.maxResourceConsumers)))
2295             , descriptorSetLayout(env, params.descriptorSetLayout)
2296         {
2297         }
2298     };
2299 
getMaxConcurrentvkt::api::__anonc97e7d540111::DescriptorSet2300     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
2301     {
2302         return getSafeObjectCount<DescriptorSet>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
2303     }
2304 
createvkt::api::__anonc97e7d540111::DescriptorSet2305     static Move<VkDescriptorSet> create(const Environment &env, const Resources &res, const Parameters &)
2306     {
2307         const VkDescriptorSetAllocateInfo allocateInfo = {
2308             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, DE_NULL, *res.descriptorPool.object, 1u,
2309             &res.descriptorSetLayout.object.get(),
2310         };
2311 
2312         return allocateDescriptorSet(env.vkd, env.device, &allocateInfo);
2313     }
2314 
createMultiplevkt::api::__anonc97e7d540111::DescriptorSet2315     static vector<VkDescriptorSetSp> createMultiple(const Environment &env, const Resources &res, const Parameters &,
2316                                                     vector<VkDescriptorSet> *const pOutHandles,
2317                                                     VkResult *const pOutResult)
2318     {
2319         DE_ASSERT(pOutResult);
2320         DE_ASSERT(pOutHandles);
2321         DE_ASSERT(pOutHandles->size() != 0);
2322 
2323         const uint32_t numDescriptorSets = static_cast<uint32_t>(pOutHandles->size());
2324         VkDescriptorSet *const pHandles  = &(*pOutHandles)[0];
2325         const vector<VkDescriptorSetLayout> descriptorSetLayouts(numDescriptorSets,
2326                                                                  res.descriptorSetLayout.object.get());
2327 
2328         const VkDescriptorSetAllocateInfo allocateInfo = {
2329             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2330             DE_NULL,
2331             *res.descriptorPool.object,
2332             numDescriptorSets,
2333             &descriptorSetLayouts[0],
2334         };
2335 
2336         *pOutResult = env.vkd.allocateDescriptorSets(env.device, &allocateInfo, pHandles);
2337 
2338         vector<VkDescriptorSetSp> descriptorSets;
2339 
2340         if (*pOutResult == VK_SUCCESS)
2341         {
2342             for (uint32_t i = 0; i < numDescriptorSets; ++i)
2343                 descriptorSets.push_back(VkDescriptorSetSp(new Move<VkDescriptorSet>(
2344                     check<VkDescriptorSet>(pHandles[i]),
2345                     Deleter<VkDescriptorSet>(env.vkd, env.device, *res.descriptorPool.object))));
2346         }
2347 
2348         return descriptorSets;
2349     }
2350 };
2351 
2352 struct Framebuffer
2353 {
2354     typedef VkFramebuffer Type;
2355 
2356     struct Parameters
2357     {
Parametersvkt::api::__anonc97e7d540111::Framebuffer::Parameters2358         Parameters(void)
2359         {
2360         }
2361     };
2362 
2363     struct Resources
2364     {
2365         Dependency<ImageView> colorAttachment;
2366         Dependency<ImageView> depthStencilAttachment;
2367         Dependency<RenderPass> renderPass;
2368 
Resourcesvkt::api::__anonc97e7d540111::Framebuffer::Resources2369         Resources(const Environment &env, const Parameters &)
2370             : colorAttachment(
2371                   env, ImageView::Parameters(
2372                            Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(256, 256, 1),
2373                                              1u, 1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
2374                                              VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_UNDEFINED),
2375                            VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeComponentMappingRGBA(),
2376                            makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)))
2377             , depthStencilAttachment(
2378                   env, ImageView::Parameters(
2379                            Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM, makeExtent3D(256, 256, 1), 1u,
2380                                              1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
2381                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_UNDEFINED),
2382                            VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM, makeComponentMappingRGBA(),
2383                            makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u)))
2384             , renderPass(env, RenderPass::Parameters())
2385         {
2386         }
2387     };
2388 
getMaxConcurrentvkt::api::__anonc97e7d540111::Framebuffer2389     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
2390     {
2391         // \todo [2016-03-23 pyry] Take into account attachment sizes
2392         return getSafeObjectCount<Framebuffer>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
2393     }
2394 
createvkt::api::__anonc97e7d540111::Framebuffer2395     static Move<VkFramebuffer> create(const Environment &env, const Resources &res, const Parameters &)
2396     {
2397         const VkImageView attachments[] = {
2398             *res.colorAttachment.object,
2399             *res.depthStencilAttachment.object,
2400         };
2401         const VkFramebufferCreateInfo framebufferInfo = {
2402             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
2403             DE_NULL,
2404             (VkFramebufferCreateFlags)0,
2405             *res.renderPass.object,
2406             (uint32_t)DE_LENGTH_OF_ARRAY(attachments),
2407             attachments,
2408             256u, // width
2409             256u, // height
2410             1u    // layers
2411         };
2412 
2413         return createFramebuffer(env.vkd, env.device, &framebufferInfo, env.allocationCallbacks);
2414     }
2415 };
2416 
2417 struct CommandPool
2418 {
2419     typedef VkCommandPool Type;
2420 
2421     struct Parameters
2422     {
2423         VkCommandPoolCreateFlags flags;
2424 
Parametersvkt::api::__anonc97e7d540111::CommandPool::Parameters2425         Parameters(VkCommandPoolCreateFlags flags_) : flags(flags_)
2426         {
2427         }
2428     };
2429 
2430     struct Resources
2431     {
Resourcesvkt::api::__anonc97e7d540111::CommandPool::Resources2432         Resources(const Environment &, const Parameters &)
2433         {
2434         }
2435     };
2436 
getMaxConcurrentvkt::api::__anonc97e7d540111::CommandPool2437     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
2438     {
2439         return getSafeObjectCount<CommandPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
2440     }
2441 
createvkt::api::__anonc97e7d540111::CommandPool2442     static Move<VkCommandPool> create(const Environment &env, const Resources &, const Parameters &params)
2443     {
2444         const VkCommandPoolCreateInfo cmdPoolInfo = {
2445             VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2446             DE_NULL,
2447             params.flags,
2448             env.queueFamilyIndex,
2449         };
2450 
2451         return createCommandPool(env.vkd, env.device, &cmdPoolInfo, env.allocationCallbacks);
2452     }
2453 };
2454 
2455 struct CommandBuffer
2456 {
2457     typedef VkCommandBuffer Type;
2458 
2459     struct Parameters
2460     {
2461         CommandPool::Parameters commandPool;
2462         VkCommandBufferLevel level;
2463 
Parametersvkt::api::__anonc97e7d540111::CommandBuffer::Parameters2464         Parameters(const CommandPool::Parameters &commandPool_, VkCommandBufferLevel level_)
2465             : commandPool(commandPool_)
2466             , level(level_)
2467         {
2468         }
2469     };
2470 
2471     struct Resources
2472     {
2473         Dependency<CommandPool> commandPool;
2474 
Resourcesvkt::api::__anonc97e7d540111::CommandBuffer::Resources2475         Resources(const Environment &env, const Parameters &params) : commandPool(env, params.commandPool)
2476         {
2477         }
2478     };
2479 
getMaxConcurrentvkt::api::__anonc97e7d540111::CommandBuffer2480     static uint32_t getMaxConcurrent(Context &context, const Parameters &params)
2481     {
2482         return getSafeObjectCount<CommandBuffer>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
2483     }
2484 
createvkt::api::__anonc97e7d540111::CommandBuffer2485     static Move<VkCommandBuffer> create(const Environment &env, const Resources &res, const Parameters &params)
2486     {
2487         const VkCommandBufferAllocateInfo cmdBufferInfo = {
2488             VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2489             DE_NULL,
2490             *res.commandPool.object,
2491             params.level,
2492             1, // bufferCount
2493         };
2494 
2495         return allocateCommandBuffer(env.vkd, env.device, &cmdBufferInfo);
2496     }
2497 
createMultiplevkt::api::__anonc97e7d540111::CommandBuffer2498     static vector<VkCommandBufferSp> createMultiple(const Environment &env, const Resources &res,
2499                                                     const Parameters &params,
2500                                                     vector<VkCommandBuffer> *const pOutHandles,
2501                                                     VkResult *const pOutResult)
2502     {
2503         DE_ASSERT(pOutResult);
2504         DE_ASSERT(pOutHandles);
2505         DE_ASSERT(pOutHandles->size() != 0);
2506 
2507         const uint32_t numCommandBuffers = static_cast<uint32_t>(pOutHandles->size());
2508         VkCommandBuffer *const pHandles  = &(*pOutHandles)[0];
2509 
2510         const VkCommandBufferAllocateInfo cmdBufferInfo = {
2511             VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2512             DE_NULL,
2513             *res.commandPool.object,
2514             params.level,
2515             numCommandBuffers,
2516         };
2517 
2518         *pOutResult = env.vkd.allocateCommandBuffers(env.device, &cmdBufferInfo, pHandles);
2519 
2520         vector<VkCommandBufferSp> commandBuffers;
2521 
2522         if (*pOutResult == VK_SUCCESS)
2523         {
2524             for (uint32_t i = 0; i < numCommandBuffers; ++i)
2525                 commandBuffers.push_back(VkCommandBufferSp(
2526                     new Move<VkCommandBuffer>(check<VkCommandBuffer>(pHandles[i]),
2527                                               Deleter<VkCommandBuffer>(env.vkd, env.device, *res.commandPool.object))));
2528         }
2529 
2530         return commandBuffers;
2531     }
2532 };
2533 
2534 // Test cases
2535 
2536 template <typename Object>
createSingleTest(Context & context,typename Object::Parameters params)2537 tcu::TestStatus createSingleTest(Context &context, typename Object::Parameters params)
2538 {
2539     const Environment env(context, 1u);
2540     const typename Object::Resources res(env, params);
2541 
2542     {
2543         Unique<typename Object::Type> obj(Object::create(env, res, params));
2544     }
2545 
2546     return tcu::TestStatus::pass("Ok");
2547 }
2548 
2549 template <typename Object>
createMultipleUniqueResourcesTest(Context & context,typename Object::Parameters params)2550 tcu::TestStatus createMultipleUniqueResourcesTest(Context &context, typename Object::Parameters params)
2551 {
2552     const Environment env(context, 1u);
2553     const typename Object::Resources res0(env, params);
2554     const typename Object::Resources res1(env, params);
2555     const typename Object::Resources res2(env, params);
2556     const typename Object::Resources res3(env, params);
2557 
2558     {
2559         Unique<typename Object::Type> obj0(Object::create(env, res0, params));
2560         Unique<typename Object::Type> obj1(Object::create(env, res1, params));
2561         Unique<typename Object::Type> obj2(Object::create(env, res2, params));
2562         Unique<typename Object::Type> obj3(Object::create(env, res3, params));
2563     }
2564 
2565     return tcu::TestStatus::pass("Ok");
2566 }
2567 
2568 #ifdef CTS_USES_VULKANSC
2569 template <>
createMultipleUniqueResourcesTest(Context & context,Instance::Parameters params)2570 tcu::TestStatus createMultipleUniqueResourcesTest<Instance>(Context &context, Instance::Parameters params)
2571 {
2572     const Environment env(context, 1u);
2573     const typename Instance::Resources res0(env, params);
2574     const typename Instance::Resources res1(env, params);
2575 
2576     {
2577         Unique<typename Instance::Type> obj0(Instance::create(env, res0, params));
2578         Unique<typename Instance::Type> obj1(Instance::create(env, res1, params));
2579     }
2580 
2581     return tcu::TestStatus::pass("Ok");
2582 }
2583 #endif // CTS_USES_VULKANSC
2584 
2585 template <typename Object>
createMultipleSharedResourcesTest(Context & context,typename Object::Parameters params)2586 tcu::TestStatus createMultipleSharedResourcesTest(Context &context, typename Object::Parameters params)
2587 {
2588     const Environment env(context, 4u);
2589     const typename Object::Resources res(env, params);
2590 
2591     {
2592         Unique<typename Object::Type> obj0(Object::create(env, res, params));
2593         Unique<typename Object::Type> obj1(Object::create(env, res, params));
2594         Unique<typename Object::Type> obj2(Object::create(env, res, params));
2595         Unique<typename Object::Type> obj3(Object::create(env, res, params));
2596     }
2597 
2598     return tcu::TestStatus::pass("Ok");
2599 }
2600 
2601 #ifndef CTS_USES_VULKANSC
2602 
2603 // Class to wrap singleton devices used by private_data tests
2604 class SingletonDevice
2605 {
createPrivateDataDevice(const Context & context,int idx)2606     Move<VkDevice> createPrivateDataDevice(const Context &context, int idx)
2607     {
2608         const int requestedSlots[NUM_DEVICES][2] = {
2609             {0, 0}, {1, 0}, {1, 1}, {4, 4}, {1, 100},
2610         };
2611 
2612         const float queuePriority              = 1.0;
2613         const VkDeviceQueueCreateInfo queues[] = {{
2614             VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, DE_NULL, (VkDeviceQueueCreateFlags)0,
2615             context.getUniversalQueueFamilyIndex(),
2616             1u,             // queueCount
2617             &queuePriority, // pQueuePriorities
2618         }};
2619 
2620         VkDevicePrivateDataCreateInfoEXT pdci0 = {
2621             VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT, // VkStructureType                       sType;
2622             DE_NULL,                                               // const void*                           pNext;
2623             0u, // uint32_t                              privateDataSlotRequestCount;
2624         };
2625         VkDevicePrivateDataCreateInfoEXT pdci1 = {
2626             VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT, // VkStructureType                       sType;
2627             DE_NULL,                                               // const void*                           pNext;
2628             0u, // uint32_t                              privateDataSlotRequestCount;
2629         };
2630         void *pNext = DE_NULL;
2631 
2632         if (requestedSlots[idx][0])
2633         {
2634             pNext                             = &pdci0;
2635             pdci0.privateDataSlotRequestCount = requestedSlots[idx][0];
2636             if (requestedSlots[idx][1])
2637             {
2638                 pdci0.pNext                       = &pdci1;
2639                 pdci1.privateDataSlotRequestCount = requestedSlots[idx][1];
2640             }
2641         }
2642 
2643         VkPhysicalDevicePrivateDataFeaturesEXT privateDataFeatures = {
2644             VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT, // VkStructureType    sType;
2645             pNext,                                                       // void*              pNext;
2646             VK_TRUE,                                                     // VkBool32           privateData;
2647         };
2648         pNext = &privateDataFeatures;
2649 
2650         const char *extName = "VK_EXT_private_data";
2651 
2652         VkPhysicalDeviceFeatures enabledFeatures =
2653             getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
2654 
2655         const VkDeviceCreateInfo deviceInfo = {
2656             VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
2657             pNext,
2658             (VkDeviceCreateFlags)0,
2659             DE_LENGTH_OF_ARRAY(queues),
2660             queues,
2661             0u,               // enabledLayerNameCount
2662             DE_NULL,          // ppEnabledLayerNames
2663             1u,               // enabledExtensionNameCount
2664             &extName,         // ppEnabledExtensionNames
2665             &enabledFeatures, // pEnabledFeatures
2666         };
2667 
2668         Move<VkDevice> device = createCustomDevice(
2669             context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(),
2670             context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceInfo, DE_NULL);
2671         return device;
2672     }
2673 
SingletonDevice(const Context & context,int idx)2674     SingletonDevice(const Context &context, int idx) : m_logicalDevice(createPrivateDataDevice(context, idx))
2675     {
2676     }
2677 
2678 public:
2679     static const int NUM_DEVICES = 5;
2680 
getDevice(const Context & context,int idx)2681     static const Unique<vk::VkDevice> &getDevice(const Context &context, int idx)
2682     {
2683         if (!m_singletonDevice[idx])
2684             m_singletonDevice[idx] = SharedPtr<SingletonDevice>(new SingletonDevice(context, idx));
2685 
2686         DE_ASSERT(m_singletonDevice[idx]);
2687         return m_singletonDevice[idx]->m_logicalDevice;
2688     }
2689 
destroy()2690     static void destroy()
2691     {
2692         for (int idx = 0; idx < NUM_DEVICES; ++idx)
2693             m_singletonDevice[idx].clear();
2694     }
2695 
2696 private:
2697     const Unique<vk::VkDevice> m_logicalDevice;
2698     static SharedPtr<SingletonDevice> m_singletonDevice[NUM_DEVICES];
2699 };
2700 
2701 SharedPtr<SingletonDevice> SingletonDevice::m_singletonDevice[NUM_DEVICES];
2702 
2703 template <typename T>
HandleToInt(T t)2704 static uint64_t HandleToInt(T t)
2705 {
2706     return t.getInternal();
2707 }
2708 template <typename T>
HandleToInt(T * t)2709 static uint64_t HandleToInt(T *t)
2710 {
2711     return (uint64_t)(uintptr_t)(t);
2712 }
2713 
2714 template <typename Object>
createPrivateDataTest(Context & context,typename Object::Parameters params)2715 tcu::TestStatus createPrivateDataTest(Context &context, typename Object::Parameters params)
2716 {
2717     if (!context.getPrivateDataFeatures().privateData)
2718         TCU_THROW(NotSupportedError, "privateData not supported");
2719 
2720     for (int d = 0; d < SingletonDevice::NUM_DEVICES; ++d)
2721     {
2722         const Unique<vk::VkDevice> &device = SingletonDevice::getDevice(context, d);
2723         const Environment env(context.getPlatformInterface(), context.getUsedApiVersion(),
2724                               context.getInstanceInterface(), context.getInstance(), context.getDeviceInterface(),
2725                               *device, context.getUniversalQueueFamilyIndex(), context.getBinaryCollection(), DE_NULL,
2726                               4u, context.getTestContext().getCommandLine());
2727 
2728         const typename Object::Resources res(env, params);
2729 
2730         const VkPrivateDataSlotCreateInfoEXT createInfo = {
2731             VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT, // VkStructureType                    sType;
2732             DE_NULL,                                             // const void*                        pNext;
2733             0u,                                                  // VkPrivateDataSlotCreateFlagsEXT    flags;
2734         };
2735 
2736         const int numSlots = 100;
2737 
2738         typedef Unique<VkPrivateDataSlot> PrivateDataSlotUp;
2739         typedef SharedPtr<PrivateDataSlotUp> PrivateDataSlotSp;
2740         vector<PrivateDataSlotSp> slots;
2741 
2742         // interleave allocating objects and slots
2743         for (int i = 0; i < numSlots / 2; ++i)
2744         {
2745             Move<VkPrivateDataSlot> s = createPrivateDataSlot(env.vkd, *device, &createInfo, DE_NULL);
2746             slots.push_back(PrivateDataSlotSp(new PrivateDataSlotUp(s)));
2747         }
2748 
2749         Unique<typename Object::Type> obj0(Object::create(env, res, params));
2750         Unique<typename Object::Type> obj1(Object::create(env, res, params));
2751 
2752         for (int i = numSlots / 2; i < numSlots; ++i)
2753         {
2754             Move<VkPrivateDataSlot> s = createPrivateDataSlot(env.vkd, *device, &createInfo, DE_NULL);
2755             slots.push_back(PrivateDataSlotSp(new PrivateDataSlotUp(s)));
2756         }
2757 
2758         Unique<typename Object::Type> obj2(Object::create(env, res, params));
2759         Unique<typename Object::Type> obj3(Object::create(env, res, params));
2760 
2761         Unique<typename Object::Type> *objs[4] = {&obj0, &obj1, &obj2, &obj3};
2762 
2763         for (int r = 0; r < 3; ++r)
2764         {
2765             uint64_t data;
2766 
2767             // Test private data for the objects
2768             for (int o = 0; o < 4; ++o)
2769             {
2770                 auto &obj = *objs[o];
2771                 for (int i = 0; i < numSlots; ++i)
2772                 {
2773                     data = 1234;
2774                     env.vkd.getPrivateData(*device, getObjectType<typename Object::Type>(), HandleToInt(obj.get()),
2775                                            **slots[i], &data);
2776                     if (data != 0)
2777                         return tcu::TestStatus::fail("Expected initial value of zero");
2778                 }
2779             }
2780             for (int o = 0; o < 4; ++o)
2781             {
2782                 auto &obj = *objs[o];
2783                 for (int i = 0; i < numSlots; ++i)
2784                     VK_CHECK(env.vkd.setPrivateData(*device, getObjectType<typename Object::Type>(),
2785                                                     HandleToInt(obj.get()), **slots[i], i * i * i + o * o + 1));
2786             }
2787             for (int o = 0; o < 4; ++o)
2788             {
2789                 auto &obj = *objs[o];
2790                 for (int i = 0; i < numSlots; ++i)
2791                 {
2792                     data = 1234;
2793                     env.vkd.getPrivateData(*device, getObjectType<typename Object::Type>(), HandleToInt(obj.get()),
2794                                            **slots[i], &data);
2795                     if (data != (uint64_t)(i * i * i + o * o + 1))
2796                         return tcu::TestStatus::fail("Didn't read back set value");
2797                 }
2798             }
2799 
2800             // Test private data for the private data objects
2801             for (int o = 0; o < numSlots; ++o)
2802             {
2803                 auto &obj = **slots[o];
2804                 for (int i = 0; i < numSlots; ++i)
2805                 {
2806                     data = 1234;
2807                     env.vkd.getPrivateData(*device, VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT,
2808                                            HandleToInt<VkPrivateDataSlotEXT>(obj), **slots[i], &data);
2809                     if (data != 0)
2810                         return tcu::TestStatus::fail("Expected initial value of zero");
2811                 }
2812             }
2813             for (int o = 0; o < numSlots; ++o)
2814             {
2815                 auto &obj = **slots[o];
2816                 for (int i = 0; i < numSlots; ++i)
2817                     VK_CHECK(env.vkd.setPrivateData(*device, VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT,
2818                                                     HandleToInt<VkPrivateDataSlotEXT>(obj), **slots[i],
2819                                                     i * i * i + o * o + 1));
2820             }
2821             for (int o = 0; o < numSlots; ++o)
2822             {
2823                 auto &obj = **slots[o];
2824                 for (int i = 0; i < numSlots; ++i)
2825                 {
2826                     data = 1234;
2827                     env.vkd.getPrivateData(*device, VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT,
2828                                            HandleToInt<VkPrivateDataSlotEXT>(obj), **slots[i], &data);
2829                     if (data != (uint64_t)(i * i * i + o * o + 1))
2830                         return tcu::TestStatus::fail("Didn't read back set value");
2831                 }
2832             }
2833 
2834             // Test private data for the device
2835             for (int i = 0; i < numSlots; ++i)
2836             {
2837                 data = 1234;
2838                 env.vkd.getPrivateData(*device, VK_OBJECT_TYPE_DEVICE, (uint64_t)(uintptr_t)(*device), **slots[i],
2839                                        &data);
2840                 if (data != 0)
2841                     return tcu::TestStatus::fail("Expected initial value of zero for device");
2842             }
2843             for (int i = 0; i < numSlots; ++i)
2844                 VK_CHECK(env.vkd.setPrivateData(*device, VK_OBJECT_TYPE_DEVICE, (uint64_t)(uintptr_t)(*device),
2845                                                 **slots[i], i * i * i + r * r + 1));
2846             for (int i = 0; i < numSlots; ++i)
2847             {
2848                 data = 1234;
2849                 env.vkd.getPrivateData(*device, VK_OBJECT_TYPE_DEVICE, (uint64_t)(uintptr_t)(*device), **slots[i],
2850                                        &data);
2851                 if (data != (uint64_t)(i * i * i + r * r + 1))
2852                     return tcu::TestStatus::fail("Didn't read back set value from device");
2853             }
2854 
2855             // Destroy and realloc slots for the next iteration
2856             slots.clear();
2857             for (int i = 0; i < numSlots; ++i)
2858             {
2859                 Move<VkPrivateDataSlotEXT> s = createPrivateDataSlot(env.vkd, *device, &createInfo, DE_NULL);
2860                 slots.push_back(PrivateDataSlotSp(new PrivateDataSlotUp(s)));
2861             }
2862         }
2863     }
2864 
2865     return tcu::TestStatus::pass("Ok");
2866 }
2867 
2868 template <typename Object>
createMaxConcurrentTest(Context & context,typename Object::Parameters params)2869 tcu::TestStatus createMaxConcurrentTest(Context &context, typename Object::Parameters params)
2870 {
2871     typedef Unique<typename Object::Type> UniqueObject;
2872     typedef SharedPtr<UniqueObject> ObjectPtr;
2873 
2874     const uint32_t numObjects = Object::getMaxConcurrent(context, params);
2875     const Environment env(context, numObjects);
2876     const typename Object::Resources res(env, params);
2877     vector<ObjectPtr> objects(numObjects);
2878     const uint32_t watchdogInterval = 1024;
2879 
2880     context.getTestContext().getLog() << TestLog::Message << "Creating " << numObjects << " "
2881                                       << getTypeName<typename Object::Type>() << " objects" << TestLog::EndMessage;
2882 
2883     for (uint32_t ndx = 0; ndx < numObjects; ndx++)
2884     {
2885         objects[ndx] = ObjectPtr(new UniqueObject(Object::create(env, res, params)));
2886 
2887         if ((ndx > 0) && ((ndx % watchdogInterval) == 0))
2888             context.getTestContext().touchWatchdog();
2889     }
2890 
2891     context.getTestContext().touchWatchdog();
2892     objects.clear();
2893 
2894     return tcu::TestStatus::pass("Ok");
2895 }
2896 
2897 #endif // CTS_USES_VULKANSC
2898 
2899 // How many objects to create per thread
2900 template <typename Object>
getCreateCount(void)2901 int getCreateCount(void)
2902 {
2903     return 100;
2904 }
2905 
2906 // Creating VkDevice and VkInstance can take significantly longer than other object types
2907 
2908 #ifndef CTS_USES_VULKANSC
2909 template <>
getCreateCount(void)2910 int getCreateCount<Instance>(void)
2911 {
2912     return 20;
2913 }
2914 template <>
getCreateCount(void)2915 int getCreateCount<Device>(void)
2916 {
2917     return 20;
2918 }
2919 template <>
getCreateCount(void)2920 int getCreateCount<DeviceGroup>(void)
2921 {
2922     return 20;
2923 }
2924 #else
2925 template <>
getCreateCount(void)2926 int getCreateCount<Instance>(void)
2927 {
2928     return 2;
2929 }
2930 template <>
getCreateCount(void)2931 int getCreateCount<Device>(void)
2932 {
2933     return 2;
2934 }
2935 template <>
getCreateCount(void)2936 int getCreateCount<DeviceGroup>(void)
2937 {
2938     return 2;
2939 }
2940 #endif // CTS_USES_VULKANSC
2941 
2942 template <typename Object>
2943 class CreateThread : public ThreadGroupThread
2944 {
2945 public:
CreateThread(const Environment & env,const typename Object::Resources & resources,const typename Object::Parameters & params)2946     CreateThread(const Environment &env, const typename Object::Resources &resources,
2947                  const typename Object::Parameters &params)
2948         : m_env(env)
2949         , m_resources(resources)
2950         , m_params(params)
2951     {
2952     }
2953 
runThread(void)2954     void runThread(void)
2955     {
2956         const int numIters = getCreateCount<Object>();
2957 #ifndef CTS_USES_VULKANSC
2958         const int itersBetweenSyncs = numIters / 5;
2959 #else
2960         const int itersBetweenSyncs = 1;
2961 #endif // CTS_USES_VULKANSC
2962 
2963         DE_ASSERT(itersBetweenSyncs > 0);
2964 
2965         for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
2966         {
2967             // Sync every Nth iteration to make entering driver at the same time more likely
2968             if ((iterNdx % itersBetweenSyncs) == 0)
2969                 barrier();
2970 
2971             {
2972                 Unique<typename Object::Type> obj(Object::create(m_env, m_resources, m_params));
2973 #ifdef CTS_USES_VULKANSC
2974                 if (iterNdx == 0)
2975                 {
2976                     barrier();
2977                 }
2978 #endif
2979             }
2980         }
2981     }
2982 
2983 private:
2984     const Environment &m_env;
2985     const typename Object::Resources &m_resources;
2986     const typename Object::Parameters &m_params;
2987 };
2988 
2989 template <typename Object>
multithreadedCreateSharedResourcesTest(Context & context,typename Object::Parameters params)2990 tcu::TestStatus multithreadedCreateSharedResourcesTest(Context &context, typename Object::Parameters params)
2991 {
2992 #ifdef CTS_USES_VULKANSC
2993     MultithreadedDestroyGuard mdGuard(context.getResourceInterface());
2994 #endif // CTS_USES_VULKANSC
2995     TestLog &log              = context.getTestContext().getLog();
2996     const uint32_t numThreads = getDefaultTestThreadCount();
2997     const Environment env(context, numThreads);
2998     const typename Object::Resources res(env, params);
2999     ThreadGroup threads;
3000 
3001     log << TestLog::Message << "numThreads = " << numThreads << TestLog::EndMessage;
3002 
3003     for (uint32_t ndx = 0; ndx < numThreads; ndx++)
3004         threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(env, res, params)));
3005 
3006     return threads.run();
3007 }
3008 
3009 template <typename Object>
multithreadedCreatePerThreadResourcesTest(Context & context,typename Object::Parameters params)3010 tcu::TestStatus multithreadedCreatePerThreadResourcesTest(Context &context, typename Object::Parameters params)
3011 {
3012     typedef SharedPtr<typename Object::Resources> ResPtr;
3013 #ifdef CTS_USES_VULKANSC
3014     MultithreadedDestroyGuard mdGuard(context.getResourceInterface());
3015 #endif // CTS_USES_VULKANSC
3016     TestLog &log              = context.getTestContext().getLog();
3017     const uint32_t numThreads = getDefaultTestThreadCount();
3018     const Environment env(context, 1u);
3019     vector<ResPtr> resources(numThreads);
3020     ThreadGroup threads;
3021 
3022     log << TestLog::Message << "numThreads = " << numThreads << TestLog::EndMessage;
3023 
3024     for (uint32_t ndx = 0; ndx < numThreads; ndx++)
3025     {
3026         resources[ndx] = ResPtr(new typename Object::Resources(env, params));
3027         threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(env, *resources[ndx], params)));
3028     }
3029 
3030     return threads.run();
3031 }
3032 
3033 struct EnvClone
3034 {
3035     Device::Resources deviceRes;
3036     Unique<VkDevice> device;
3037 #ifndef CTS_USES_VULKANSC
3038     de::MovePtr<vk::DeviceDriver> vkd;
3039 #else
3040     de::MovePtr<vk::DeviceDriverSC, vk::DeinitDeviceDeleter> vkd;
3041 #endif // CTS_USES_VULKANSC
3042     Environment env;
3043 
EnvClonevkt::api::__anonc97e7d540111::EnvClone3044     EnvClone(const Environment &parent, const Device::Parameters &deviceParams, uint32_t maxResourceConsumers)
3045         : deviceRes(parent, deviceParams)
3046         , device(Device::create(parent, deviceRes, deviceParams))
3047 #ifndef CTS_USES_VULKANSC
3048         , vkd(de::MovePtr<DeviceDriver>(
3049               new DeviceDriver(parent.vkp, parent.instance, *device, parent.apiVersion, parent.commandLine)))
3050         , env(parent.vkp, parent.apiVersion, parent.instanceInterface, parent.instance, *vkd, *device,
3051               deviceRes.queueFamilyIndex, parent.programBinaries, parent.allocationCallbacks, maxResourceConsumers,
3052               parent.commandLine)
3053 #else
3054         , vkd(de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(
3055               new DeviceDriverSC(parent.vkp, parent.instance, *device, parent.commandLine, parent.resourceInterface,
3056                                  parent.vulkanSC10Properties, parent.properties, parent.apiVersion),
3057               vk::DeinitDeviceDeleter(parent.resourceInterface.get(), *device)))
3058         , env(parent.vkp, parent.apiVersion, parent.instanceInterface, parent.instance, *vkd, *device,
3059               deviceRes.queueFamilyIndex, parent.programBinaries, parent.allocationCallbacks, maxResourceConsumers,
3060               parent.resourceInterface, parent.vulkanSC10Properties, parent.commandLine)
3061 #endif // CTS_USES_VULKANSC
3062     {
3063     }
3064 };
3065 
getDefaulDeviceParameters(Context & context)3066 Device::Parameters getDefaulDeviceParameters(Context &context)
3067 {
3068     return Device::Parameters(context.getTestContext().getCommandLine().getVKDeviceId() - 1u,
3069                               VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
3070 }
3071 
3072 template <typename Object>
multithreadedCreatePerThreadDeviceTest(Context & context,typename Object::Parameters params)3073 tcu::TestStatus multithreadedCreatePerThreadDeviceTest(Context &context, typename Object::Parameters params)
3074 {
3075 #ifdef CTS_USES_VULKANSC
3076     MultithreadedDestroyGuard mdGuard(context.getResourceInterface());
3077 #endif // CTS_USES_VULKANSC
3078     typedef SharedPtr<EnvClone> EnvPtr;
3079     typedef SharedPtr<typename Object::Resources> ResPtr;
3080 
3081     TestLog &log                          = context.getTestContext().getLog();
3082     const uint32_t numThreads             = getDefaultTestThreadCount();
3083     const Device::Parameters deviceParams = getDefaulDeviceParameters(context);
3084     const Environment sharedEnv(context, numThreads); // For creating Device's
3085     vector<EnvPtr> perThreadEnv(numThreads);
3086     vector<ResPtr> resources(numThreads);
3087     ThreadGroup threads;
3088 
3089     log << TestLog::Message << "numThreads = " << numThreads << TestLog::EndMessage;
3090 
3091     for (uint32_t ndx = 0; ndx < numThreads; ndx++)
3092     {
3093         perThreadEnv[ndx] = EnvPtr(new EnvClone(sharedEnv, deviceParams, 1u));
3094         resources[ndx]    = ResPtr(new typename Object::Resources(perThreadEnv[ndx]->env, params));
3095 
3096         threads.add(
3097             MovePtr<ThreadGroupThread>(new CreateThread<Object>(perThreadEnv[ndx]->env, *resources[ndx], params)));
3098     }
3099 
3100     return threads.run();
3101 }
3102 
3103 #ifndef CTS_USES_VULKANSC
3104 
3105 template <typename Object>
createSingleAllocCallbacksTest(Context & context,typename Object::Parameters params)3106 tcu::TestStatus createSingleAllocCallbacksTest(Context &context, typename Object::Parameters params)
3107 {
3108     const uint32_t noCmdScope = (1u << VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE) |
3109                                 (1u << VK_SYSTEM_ALLOCATION_SCOPE_DEVICE) | (1u << VK_SYSTEM_ALLOCATION_SCOPE_CACHE) |
3110                                 (1u << VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
3111 
3112     // Callbacks used by resources
3113     AllocationCallbackRecorder resCallbacks(getSystemAllocator(), 128);
3114 
3115     // Root environment still uses default instance and device, created without callbacks
3116     const Environment rootEnv(context.getPlatformInterface(), context.getUsedApiVersion(),
3117                               context.getInstanceInterface(), context.getInstance(), context.getDeviceInterface(),
3118                               context.getDevice(), context.getUniversalQueueFamilyIndex(),
3119                               context.getBinaryCollection(), resCallbacks.getCallbacks(), 1u,
3120 #ifdef CTS_USES_VULKANSC
3121                               context.getResourceInterface(), context.getDeviceVulkanSC10Properties(),
3122 #endif // CTS_USES_VULKANSC
3123                               context.getTestContext().getCommandLine());
3124 
3125     {
3126         // Test env has instance & device created with callbacks
3127         const EnvClone resEnv(rootEnv, getDefaulDeviceParameters(context), 1u);
3128         const typename Object::Resources res(resEnv.env, params);
3129 
3130         // Supply a separate callback recorder just for object construction
3131         AllocationCallbackRecorder objCallbacks(getSystemAllocator(), 128);
3132         const Environment objEnv(resEnv.env.vkp, resEnv.env.apiVersion, resEnv.env.instanceInterface,
3133                                  resEnv.env.instance, resEnv.env.vkd, resEnv.env.device, resEnv.env.queueFamilyIndex,
3134                                  resEnv.env.programBinaries, objCallbacks.getCallbacks(),
3135                                  resEnv.env.maxResourceConsumers,
3136 #ifdef CTS_USES_VULKANSC
3137                                  resEnv.env.resourceInterface, resEnv.env.vulkanSC10Properties,
3138 #endif // CTS_USES_VULKANSC
3139                                  resEnv.env.commandLine);
3140 
3141         {
3142             Unique<typename Object::Type> obj(Object::create(objEnv, res, params));
3143 
3144             // Validate that no command-level allocations are live
3145             if (!validateAndLog(context.getTestContext().getLog(), objCallbacks, noCmdScope))
3146                 return tcu::TestStatus::fail("Invalid allocation callback");
3147         }
3148 
3149         // At this point all allocations made against object callbacks must have been freed
3150         if (!validateAndLog(context.getTestContext().getLog(), objCallbacks, 0u))
3151             return tcu::TestStatus::fail("Invalid allocation callback");
3152     }
3153 
3154     if (!validateAndLog(context.getTestContext().getLog(), resCallbacks, 0u))
3155         return tcu::TestStatus::fail("Invalid allocation callback");
3156 
3157     return tcu::TestStatus::pass("Ok");
3158 }
3159 
3160 #endif // CTS_USES_VULKANSC
3161 
3162 template <typename Object>
getOomIterLimit(void)3163 uint32_t getOomIterLimit(void)
3164 {
3165     return 40;
3166 }
3167 #ifndef CTS_USES_VULKANSC
3168 template <>
getOomIterLimit(void)3169 uint32_t getOomIterLimit<Device>(void)
3170 {
3171     return 20;
3172 }
3173 template <>
getOomIterLimit(void)3174 uint32_t getOomIterLimit<DeviceGroup>(void)
3175 {
3176     return 20;
3177 }
3178 #endif // CTS_USES_VULKANSC
3179 
3180 #ifndef CTS_USES_VULKANSC
3181 
3182 template <typename Object>
allocCallbackFailTest(Context & context,typename Object::Parameters params)3183 tcu::TestStatus allocCallbackFailTest(Context &context, typename Object::Parameters params)
3184 {
3185     AllocationCallbackRecorder resCallbacks(getSystemAllocator(), 128);
3186     const Environment rootEnv(context.getPlatformInterface(), context.getUsedApiVersion(),
3187                               context.getInstanceInterface(), context.getInstance(), context.getDeviceInterface(),
3188                               context.getDevice(), context.getUniversalQueueFamilyIndex(),
3189                               context.getBinaryCollection(), resCallbacks.getCallbacks(), 1u,
3190 #ifdef CTS_USES_VULKANSC
3191                               context.getResourceInterface(), context.getDeviceVulkanSC10Properties(),
3192 #endif // CTS_USES_VULKANSC
3193                               context.getTestContext().getCommandLine());
3194     uint32_t numPassingAllocs       = 0;
3195     const uint32_t cmdLineIterCount = (uint32_t)context.getTestContext().getCommandLine().getTestIterationCount();
3196     const uint32_t maxTries         = cmdLineIterCount != 0 ? cmdLineIterCount : getOomIterLimit<Object>();
3197     const uint32_t finalLimit       = std::max(maxTries, 10000u);
3198     bool createOk                   = false;
3199 
3200     {
3201         const EnvClone resEnv(rootEnv, getDefaulDeviceParameters(context), 1u);
3202         const typename Object::Resources res(resEnv.env, params);
3203 
3204         // Iterate over test until object allocation succeeds
3205         while (true)
3206         {
3207             DeterministicFailAllocator objAllocator(getSystemAllocator(),
3208                                                     DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs);
3209             AllocationCallbackRecorder recorder(objAllocator.getCallbacks(), 128);
3210             const Environment objEnv(resEnv.env.vkp, resEnv.env.apiVersion, resEnv.env.instanceInterface,
3211                                      resEnv.env.instance, resEnv.env.vkd, resEnv.env.device,
3212                                      resEnv.env.queueFamilyIndex, resEnv.env.programBinaries, recorder.getCallbacks(),
3213                                      resEnv.env.maxResourceConsumers,
3214 #ifdef CTS_USES_VULKANSC
3215                                      resEnv.env.resourceInterface, resEnv.env.vulkanSC10Properties,
3216 #endif // CTS_USES_VULKANSC
3217                                      resEnv.env.commandLine);
3218 
3219             context.getTestContext().getLog()
3220                 << TestLog::Message << "Trying to create object with " << numPassingAllocs << " allocation"
3221                 << (numPassingAllocs != 1 ? "s" : "") << " passing" << TestLog::EndMessage;
3222 
3223             createOk = false;
3224             try
3225             {
3226                 Unique<typename Object::Type> obj(Object::create(objEnv, res, params));
3227                 createOk = true;
3228             }
3229             catch (const vk::OutOfMemoryError &e)
3230             {
3231                 if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY)
3232                 {
3233                     context.getTestContext().getLog() << e;
3234                     return tcu::TestStatus::fail("Got invalid error code");
3235                 }
3236             }
3237 
3238             if (!validateAndLog(context.getTestContext().getLog(), recorder, 0u))
3239                 return tcu::TestStatus::fail("Invalid allocation callback");
3240 
3241             if (createOk)
3242             {
3243                 context.getTestContext().getLog()
3244                     << TestLog::Message << "Object construction succeeded! " << TestLog::EndMessage;
3245                 break;
3246             }
3247 
3248             ++numPassingAllocs;
3249             // if allocation didn't succeed with huge limit then stop trying
3250             if (numPassingAllocs >= finalLimit)
3251                 break;
3252             // if we reached maxTries but didn't create object, try doing it with huge limit
3253             if (numPassingAllocs >= maxTries)
3254                 numPassingAllocs = finalLimit;
3255         }
3256     }
3257 
3258     if (!validateAndLog(context.getTestContext().getLog(), resCallbacks, 0u))
3259         return tcu::TestStatus::fail("Invalid allocation callback");
3260 
3261     if (numPassingAllocs == 0)
3262         return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks not called");
3263     else if (numPassingAllocs >= finalLimit)
3264     {
3265         if (createOk)
3266         {
3267             context.getTestContext().getLog() << TestLog::Message << "Maximum iteration count (" << maxTries
3268                                               << ") reached without object construction passing. "
3269                                               << "Object was succesfully constructed with " << numPassingAllocs
3270                                               << " iterations limit." << TestLog::EndMessage;
3271             return tcu::TestStatus(QP_TEST_RESULT_PASS, "Construction passed but not all iterations were checked");
3272         }
3273 
3274         context.getTestContext().getLog()
3275             << TestLog::Message << "WARNING: Maximum iteration count (" << finalLimit
3276             << ") reached without object construction passing. "
3277             << "OOM testing incomplete, use --deqp-test-iteration-count= to test with higher limit."
3278             << TestLog::EndMessage;
3279         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Max iter count reached");
3280     }
3281     else
3282         return tcu::TestStatus::pass("Ok");
3283 }
3284 
3285 #endif // CTS_USES_VULKANSC
3286 
3287 // Determine whether an API call sets the invalid handles to NULL (true) or leaves them undefined or not modified (false)
3288 template <typename T>
isNullHandleOnAllocationFailure(Context &)3289 inline bool isNullHandleOnAllocationFailure(Context &)
3290 {
3291     return false;
3292 }
3293 
3294 #ifndef CTS_USES_VULKANSC
3295 template <>
isNullHandleOnAllocationFailure(Context & context)3296 inline bool isNullHandleOnAllocationFailure<VkCommandBuffer>(Context &context)
3297 {
3298     return hasDeviceExtension(context, "VK_KHR_maintenance1");
3299 }
3300 template <>
isNullHandleOnAllocationFailure(Context & context)3301 inline bool isNullHandleOnAllocationFailure<VkDescriptorSet>(Context &context)
3302 {
3303     return hasDeviceExtension(context, "VK_KHR_maintenance1");
3304 }
3305 template <>
isNullHandleOnAllocationFailure(Context &)3306 inline bool isNullHandleOnAllocationFailure<VkPipeline>(Context &)
3307 {
3308     return true;
3309 }
3310 #endif // CTS_USES_VULKANSC
3311 
3312 template <typename T>
isPooledObject(void)3313 inline bool isPooledObject(void)
3314 {
3315     return false;
3316 };
3317 #ifndef CTS_USES_VULKANSC
3318 template <>
isPooledObject(void)3319 inline bool isPooledObject<VkCommandBuffer>(void)
3320 {
3321     return true;
3322 };
3323 template <>
isPooledObject(void)3324 inline bool isPooledObject<VkDescriptorSet>(void)
3325 {
3326     return true;
3327 };
3328 #endif // CTS_USES_VULKANSC
3329 
3330 template <typename Object>
allocCallbackFailMultipleObjectsTest(Context & context,typename Object::Parameters params)3331 tcu::TestStatus allocCallbackFailMultipleObjectsTest(Context &context, typename Object::Parameters params)
3332 {
3333     typedef SharedPtr<Move<typename Object::Type>> ObjectTypeSp;
3334 
3335     static const uint32_t numObjects = 4;
3336     const bool expectNullHandles     = isNullHandleOnAllocationFailure<typename Object::Type>(context);
3337     uint32_t numPassingAllocs        = 0;
3338 
3339     {
3340         vector<typename Object::Type> handles(numObjects);
3341         VkResult result = VK_NOT_READY;
3342 
3343         for (; numPassingAllocs <= numObjects; ++numPassingAllocs)
3344         {
3345             ValidateQueryBits::fillBits(handles.begin(), handles.end()); // fill with garbage
3346 
3347             // \note We have to use the same allocator for both resource dependencies and the object under test,
3348             //       because pooled objects take memory from the pool.
3349             DeterministicFailAllocator objAllocator(getSystemAllocator(), DeterministicFailAllocator::MODE_DO_NOT_COUNT,
3350                                                     0);
3351             AllocationCallbackRecorder recorder(objAllocator.getCallbacks(), 128);
3352             const Environment objEnv(context.getPlatformInterface(), context.getUsedApiVersion(),
3353                                      context.getInstanceInterface(), context.getInstance(),
3354                                      context.getDeviceInterface(), context.getDevice(),
3355                                      context.getUniversalQueueFamilyIndex(), context.getBinaryCollection(),
3356                                      recorder.getCallbacks(), numObjects,
3357 #ifdef CTS_USES_VULKANSC
3358                                      context.getResourceInterface(), context.getDeviceVulkanSC10Properties(),
3359 #endif // CTS_USES_VULKANSC
3360                                      context.getTestContext().getCommandLine());
3361 
3362             context.getTestContext().getLog()
3363                 << TestLog::Message << "Trying to create " << numObjects << " objects with " << numPassingAllocs
3364                 << " allocation" << (numPassingAllocs != 1 ? "s" : "") << " passing" << TestLog::EndMessage;
3365 
3366             {
3367                 const typename Object::Resources res(objEnv, params);
3368 
3369                 objAllocator.reset(DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs);
3370                 const vector<ObjectTypeSp> scopedHandles =
3371                     Object::createMultiple(objEnv, res, params, &handles, &result);
3372             }
3373 
3374             if (result == VK_SUCCESS)
3375             {
3376                 context.getTestContext().getLog()
3377                     << TestLog::Message << "Construction of all objects succeeded! " << TestLog::EndMessage;
3378                 break;
3379             }
3380             else
3381             {
3382                 if (expectNullHandles)
3383                 {
3384                     for (uint32_t nullNdx = numPassingAllocs; nullNdx < numObjects; ++nullNdx)
3385                     {
3386                         if (handles[nullNdx] != DE_NULL)
3387                             return tcu::TestStatus::fail("Some object handles weren't set to NULL");
3388                     }
3389                 }
3390 
3391                 if (result != VK_ERROR_OUT_OF_HOST_MEMORY)
3392                     return tcu::TestStatus::fail("Got invalid error code: " + de::toString(getResultName(result)));
3393 
3394                 if (!validateAndLog(context.getTestContext().getLog(), recorder, 0u))
3395                     return tcu::TestStatus::fail("Invalid allocation callback");
3396             }
3397         }
3398     }
3399 
3400     if (numPassingAllocs == 0)
3401     {
3402         if (isPooledObject<typename Object::Type>())
3403             return tcu::TestStatus::pass("Not validated: pooled objects didn't seem to use host memory");
3404         else
3405             return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks not called");
3406     }
3407     else
3408         return tcu::TestStatus::pass("Ok");
3409 }
3410 
3411 // Utilities for creating groups
3412 
3413 template <typename Object>
3414 struct NamedParameters
3415 {
3416     const char *name;
3417     typename Object::Parameters parameters;
3418 };
3419 
3420 template <typename Object>
3421 struct CaseDescription
3422 {
3423     typename FunctionInstance1<typename Object::Parameters>::Function function;
3424     const NamedParameters<Object> *paramsBegin;
3425     const NamedParameters<Object> *paramsEnd;
3426     typename FunctionSupport1<typename Object::Parameters>::Function supportFunction;
3427 };
3428 
3429 #define EMPTY_CASE_DESC(OBJECT)                                                              \
3430     {                                                                                        \
3431         (FunctionInstance1<OBJECT::Parameters>::Function) DE_NULL, DE_NULL, DE_NULL, DE_NULL \
3432     }
3433 
3434 #define CASE_DESC(FUNCTION, CASES, SUPPORT)                           \
3435     {                                                                 \
3436         FUNCTION, DE_ARRAY_BEGIN(CASES), DE_ARRAY_END(CASES), SUPPORT \
3437     }
3438 
3439 struct CaseDescriptions
3440 {
3441     CaseDescription<Instance> instance;
3442     CaseDescription<Device> device;
3443     CaseDescription<DeviceGroup> deviceGroup;
3444     CaseDescription<DeviceMemory> deviceMemory;
3445     CaseDescription<Buffer> buffer;
3446     CaseDescription<BufferView> bufferView;
3447     CaseDescription<Image> image;
3448     CaseDescription<ImageView> imageView;
3449     CaseDescription<Semaphore> semaphore;
3450     CaseDescription<Event> event;
3451     CaseDescription<Fence> fence;
3452     CaseDescription<QueryPool> queryPool;
3453     CaseDescription<ShaderModule> shaderModule;
3454     CaseDescription<PipelineCache> pipelineCache;
3455     CaseDescription<MergedPipelineCache> mergedPipelineCache;
3456     CaseDescription<PipelineLayout> pipelineLayout;
3457     CaseDescription<RenderPass> renderPass;
3458     CaseDescription<GraphicsPipeline> graphicsPipeline;
3459     CaseDescription<ComputePipeline> computePipeline;
3460     CaseDescription<DescriptorSetLayout> descriptorSetLayout;
3461     CaseDescription<Sampler> sampler;
3462     CaseDescription<DescriptorPool> descriptorPool;
3463     CaseDescription<DescriptorSet> descriptorSet;
3464     CaseDescription<Framebuffer> framebuffer;
3465     CaseDescription<CommandPool> commandPool;
3466     CaseDescription<CommandBuffer> commandBuffer;
3467 };
3468 
3469 template <typename Object>
addCases(tcu::TestCaseGroup * group,const CaseDescription<Object> & cases)3470 void addCases(tcu::TestCaseGroup *group, const CaseDescription<Object> &cases)
3471 {
3472     for (const NamedParameters<Object> *cur = cases.paramsBegin; cur != cases.paramsEnd; ++cur)
3473     {
3474         if (cases.supportFunction == DE_NULL)
3475             addFunctionCase(group, cur->name, cases.function, cur->parameters);
3476         else
3477             addFunctionCase(group, cur->name, cases.supportFunction, cases.function, cur->parameters);
3478     }
3479 }
3480 
checkImageCubeArraySupport(Context & context,const ImageView::Parameters params)3481 void checkImageCubeArraySupport(Context &context, const ImageView::Parameters params)
3482 {
3483     if (params.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY && !context.getDeviceFeatures().imageCubeArray)
3484         TCU_THROW(NotSupportedError, "imageCubeArray feature is not supported by this implementation");
3485 }
3486 
checkGetPhysicalDevicePropertiesExtension(Context & context,const Device::Parameters)3487 void checkGetPhysicalDevicePropertiesExtension(Context &context, const Device::Parameters)
3488 {
3489     context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
3490 }
3491 
checkEventSupport(Context & context,const Event::Parameters)3492 void checkEventSupport(Context &context, const Event::Parameters)
3493 {
3494 #ifndef CTS_USES_VULKANSC
3495     if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
3496         !context.getPortabilitySubsetFeatures().events)
3497         TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation");
3498 #else
3499     DE_UNREF(context);
3500 #endif // CTS_USES_VULKANSC
3501 }
3502 
checkPipelineCacheControlSupport(Context & context,const MergedPipelineCache::Parameters)3503 void checkPipelineCacheControlSupport(Context &context, const MergedPipelineCache::Parameters)
3504 {
3505     (void)context;
3506 #ifndef CTS_USES_VULKANSC
3507     if (!context.isDeviceFunctionalitySupported("VK_EXT_pipeline_creation_cache_control") ||
3508         !context.getPipelineCreationCacheControlFeatures().pipelineCreationCacheControl)
3509         TCU_THROW(NotSupportedError, "pipelineCreationCacheControl not supported by this implementation");
3510 #endif // CTS_USES_VULKANSC
3511 }
3512 
checkRecycleDescriptorSetMemorySupport(Context & context,const DescriptorSet::Parameters)3513 void checkRecycleDescriptorSetMemorySupport(Context &context, const DescriptorSet::Parameters)
3514 {
3515 #ifdef CTS_USES_VULKANSC
3516     if (!context.getDeviceVulkanSC10Properties().recycleDescriptorSetMemory)
3517         TCU_THROW(
3518             NotSupportedError,
3519             "VkPhysicalDeviceVulkanSC10Properties::recycleDescriptorSetMemory not supported by this implementation");
3520 #else
3521     DE_UNREF(context);
3522 #endif // CTS_USES_VULKANSC
3523 }
3524 
3525 template <typename Object>
addCasesWithProgs(tcu::TestCaseGroup * group,const CaseDescription<Object> & cases)3526 void addCasesWithProgs(tcu::TestCaseGroup *group, const CaseDescription<Object> &cases)
3527 {
3528     for (const NamedParameters<Object> *cur = cases.paramsBegin; cur != cases.paramsEnd; ++cur)
3529     {
3530         if (cases.supportFunction == DE_NULL)
3531             addFunctionCaseWithPrograms(group, cur->name, Object::initPrograms, cases.function, cur->parameters);
3532         else
3533             addFunctionCaseWithPrograms(group, cur->name, cases.supportFunction, Object::initPrograms, cases.function,
3534                                         cur->parameters);
3535     }
3536 }
3537 
createTests(tcu::TestCaseGroup * group,CaseDescriptions cases)3538 static void createTests(tcu::TestCaseGroup *group, CaseDescriptions cases)
3539 {
3540     addCases(group, cases.instance);
3541     addCases(group, cases.device);
3542     addCases(group, cases.deviceGroup);
3543     addCases(group, cases.deviceMemory);
3544     addCases(group, cases.buffer);
3545     addCases(group, cases.bufferView);
3546     addCases(group, cases.image);
3547     addCases(group, cases.imageView);
3548     addCases(group, cases.semaphore);
3549     addCases(group, cases.event);
3550     addCases(group, cases.fence);
3551     addCases(group, cases.queryPool);
3552     addCases(group, cases.sampler);
3553     addCasesWithProgs(group, cases.shaderModule);
3554 #ifndef CTS_USES_VULKANSC
3555     addCases(group, cases.pipelineCache);
3556     addCasesWithProgs(group, cases.mergedPipelineCache);
3557 #else
3558     addCasesWithProgs(group, cases.pipelineCache);
3559 #endif // CTS_USES_VULKANSC
3560     addCases(group, cases.pipelineLayout);
3561     addCases(group, cases.renderPass);
3562     addCasesWithProgs(group, cases.graphicsPipeline);
3563     addCasesWithProgs(group, cases.computePipeline);
3564     addCases(group, cases.descriptorSetLayout);
3565     addCases(group, cases.descriptorPool);
3566     addCases(group, cases.descriptorSet);
3567     addCases(group, cases.framebuffer);
3568     addCases(group, cases.commandPool);
3569     addCases(group, cases.commandBuffer);
3570 }
3571 
3572 #ifndef CTS_USES_VULKANSC
cleanupGroup(tcu::TestCaseGroup * group,CaseDescriptions cases)3573 static void cleanupGroup(tcu::TestCaseGroup *group, CaseDescriptions cases)
3574 {
3575     DE_UNREF(group);
3576     DE_UNREF(cases);
3577     // Destroy singleton object
3578 
3579     SingletonDevice::destroy();
3580 }
3581 #endif // CTS_USES_VULKANSC
3582 
createGroup(tcu::TestContext & testCtx,const char * name,const CaseDescriptions & cases)3583 tcu::TestCaseGroup *createGroup(tcu::TestContext &testCtx, const char *name, const CaseDescriptions &cases)
3584 {
3585     MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, name));
3586     createTests(group.get(), cases);
3587     return group.release();
3588 }
3589 
3590 } // namespace
3591 
createObjectManagementTests(tcu::TestContext & testCtx)3592 tcu::TestCaseGroup *createObjectManagementTests(tcu::TestContext &testCtx)
3593 {
3594     MovePtr<tcu::TestCaseGroup> objectMgmtTests(new tcu::TestCaseGroup(testCtx, "object_management"));
3595 
3596     const Image::Parameters img1D(0u, VK_IMAGE_TYPE_1D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(256, 1, 1), 1u, 4u,
3597                                   VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT,
3598                                   VK_IMAGE_LAYOUT_UNDEFINED);
3599     const Image::Parameters img2D(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(64, 64, 1), 1u, 12u,
3600                                   VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
3601                                   VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
3602                                   VK_IMAGE_LAYOUT_UNDEFINED);
3603     const Image::Parameters imgCube(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
3604                                     makeExtent3D(64, 64, 1), 1u, 12u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
3605                                     VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
3606                                     VK_IMAGE_LAYOUT_UNDEFINED);
3607     const Image::Parameters img3D(0u, VK_IMAGE_TYPE_3D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(64, 64, 4), 1u, 1u,
3608                                   VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT,
3609                                   VK_IMAGE_LAYOUT_UNDEFINED);
3610     const ImageView::Parameters imgView1D(img1D, VK_IMAGE_VIEW_TYPE_1D, img1D.format, makeComponentMappingRGBA(),
3611                                           makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
3612     const ImageView::Parameters imgView1DArr(img1D, VK_IMAGE_VIEW_TYPE_1D_ARRAY, img1D.format,
3613                                              makeComponentMappingRGBA(),
3614                                              makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 4u));
3615     const ImageView::Parameters imgView2D(img2D, VK_IMAGE_VIEW_TYPE_2D, img2D.format, makeComponentMappingRGBA(),
3616                                           makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
3617     const ImageView::Parameters imgView2DArr(img2D, VK_IMAGE_VIEW_TYPE_2D_ARRAY, img2D.format,
3618                                              makeComponentMappingRGBA(),
3619                                              makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 8u));
3620     const ImageView::Parameters imgViewCube(imgCube, VK_IMAGE_VIEW_TYPE_CUBE, img2D.format, makeComponentMappingRGBA(),
3621                                             makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 6u));
3622     const ImageView::Parameters imgViewCubeArr(imgCube, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, img2D.format,
3623                                                makeComponentMappingRGBA(),
3624                                                makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 12u));
3625     const ImageView::Parameters imgView3D(img3D, VK_IMAGE_VIEW_TYPE_3D, img3D.format, makeComponentMappingRGBA(),
3626                                           makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
3627 
3628     const DescriptorSetLayout::Parameters singleUboDescLayout =
3629         DescriptorSetLayout::Parameters::single(0u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, VK_SHADER_STAGE_VERTEX_BIT);
3630 
3631     static const NamedParameters<Instance> s_instanceCases[] = {
3632         {"instance", Instance::Parameters()},
3633     };
3634     // \note Device index may change - must not be static
3635 
3636     const NamedParameters<Device> s_deviceCases[] = {
3637         {"device", Device::Parameters(testCtx.getCommandLine().getVKDeviceId() - 1u, VK_QUEUE_GRAPHICS_BIT)},
3638     };
3639     const NamedParameters<DeviceGroup> s_deviceGroupCases[] = {
3640         {"device_group", DeviceGroup::Parameters(testCtx.getCommandLine().getVKDeviceGroupId() - 1u,
3641                                                  testCtx.getCommandLine().getVKDeviceId() - 1u, VK_QUEUE_GRAPHICS_BIT)},
3642     };
3643     static const NamedParameters<DeviceMemory> s_deviceMemCases[] = {
3644         {"device_memory_small", DeviceMemory::Parameters(1024, 0u)},
3645     };
3646     static const NamedParameters<Buffer> s_bufferCases[] = {
3647         {
3648             "buffer_uniform_small",
3649             Buffer::Parameters(1024u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
3650         },
3651         {
3652             "buffer_uniform_large",
3653             Buffer::Parameters(1024u * 1024u * 16u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
3654         },
3655         {
3656             "buffer_storage_small",
3657             Buffer::Parameters(1024u, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
3658         },
3659         {
3660             "buffer_storage_large",
3661             Buffer::Parameters(1024u * 1024u * 16u, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
3662         },
3663     };
3664     static const NamedParameters<BufferView> s_bufferViewCases[] = {
3665         {"buffer_view_uniform_r8g8b8a8_unorm",
3666          BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT),
3667                                 VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u)},
3668         {"buffer_view_storage_r8g8b8a8_unorm",
3669          BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT),
3670                                 VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u)},
3671     };
3672     static const NamedParameters<Image> s_imageCases[] = {
3673         {"image_1d", img1D},
3674         {"image_2d", img2D},
3675         {"image_3d", img3D},
3676     };
3677     static const NamedParameters<ImageView> s_imageViewCases[] = {
3678         {"image_view_1d", imgView1D},     {"image_view_1d_arr", imgView1DArr},
3679         {"image_view_2d", imgView2D},     {"image_view_2d_arr", imgView2DArr},
3680         {"image_view_cube", imgViewCube}, {"image_view_cube_arr", imgViewCubeArr},
3681         {"image_view_3d", imgView3D},
3682     };
3683     static const NamedParameters<Semaphore> s_semaphoreCases[] = {{
3684         "semaphore",
3685         Semaphore::Parameters(0u),
3686     }};
3687     static const NamedParameters<Event> s_eventCases[]         = {{"event", Event::Parameters(0u)}};
3688     static const NamedParameters<Fence> s_fenceCases[]         = {
3689         {"fence", Fence::Parameters(0u)}, {"fence_signaled", Fence::Parameters(VK_FENCE_CREATE_SIGNALED_BIT)}};
3690     static const NamedParameters<QueryPool> s_queryPoolCases[] = {
3691         {"query_pool", QueryPool::Parameters(VK_QUERY_TYPE_OCCLUSION, 1u, 0u)}};
3692     static const NamedParameters<ShaderModule> s_shaderModuleCases[] = {
3693         {"shader_module", ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "test")}};
3694     static const NamedParameters<PipelineCache> s_pipelineCacheCases[] = {
3695         {"pipeline_cache", PipelineCache::Parameters()}};
3696     static const NamedParameters<MergedPipelineCache> s_mergedPipelineCacheCases[] = {
3697         {"merged_pipeline_cache", MergedPipelineCache::Parameters(false, false)},
3698         {"merged_pipeline_cache_src_sync", MergedPipelineCache::Parameters(true, false)},
3699         {"merged_pipeline_cache_dst_sync", MergedPipelineCache::Parameters(false, true)},
3700         {"merged_pipeline_cache_src_dst_sync", MergedPipelineCache::Parameters(true, true)}};
3701     static const NamedParameters<PipelineLayout> s_pipelineLayoutCases[] = {
3702         {"pipeline_layout_empty", PipelineLayout::Parameters::empty()},
3703         {"pipeline_layout_single", PipelineLayout::Parameters::singleDescriptorSet(singleUboDescLayout)}};
3704     static const NamedParameters<RenderPass> s_renderPassCases[] = {{"render_pass", RenderPass::Parameters()}};
3705     static const NamedParameters<GraphicsPipeline> s_graphicsPipelineCases[] = {
3706         {"graphics_pipeline", GraphicsPipeline::Parameters()}};
3707     static const NamedParameters<ComputePipeline> s_computePipelineCases[] = {
3708         {"compute_pipeline", ComputePipeline::Parameters()}};
3709     static const NamedParameters<DescriptorSetLayout> s_descriptorSetLayoutCases[] = {
3710         {"descriptor_set_layout_empty", DescriptorSetLayout::Parameters::empty()},
3711         {"descriptor_set_layout_single", singleUboDescLayout}};
3712     static const NamedParameters<Sampler> s_samplerCases[]               = {{"sampler", Sampler::Parameters()}};
3713     static const NamedParameters<DescriptorPool> s_descriptorPoolCases[] = {
3714         {"descriptor_pool", DescriptorPool::Parameters::singleType((VkDescriptorPoolCreateFlags)0, 4u,
3715                                                                    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u)},
3716         {"descriptor_pool_free_descriptor_set",
3717          DescriptorPool::Parameters::singleType(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 4u,
3718                                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u)}};
3719     static const NamedParameters<DescriptorSet> s_descriptorSetCases[] = {
3720         {"descriptor_set", DescriptorSet::Parameters(singleUboDescLayout)}};
3721     static const NamedParameters<Framebuffer> s_framebufferCases[] = {{"framebuffer", Framebuffer::Parameters()}};
3722     static const NamedParameters<CommandPool> s_commandPoolCases[] = {
3723         {"command_pool", CommandPool::Parameters((VkCommandPoolCreateFlags)0)},
3724         {"command_pool_transient", CommandPool::Parameters(VK_COMMAND_POOL_CREATE_TRANSIENT_BIT)}};
3725     static const NamedParameters<CommandBuffer> s_commandBufferCases[] = {
3726         {"command_buffer_primary", CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u),
3727                                                              VK_COMMAND_BUFFER_LEVEL_PRIMARY)},
3728         {"command_buffer_secondary", CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u),
3729                                                                VK_COMMAND_BUFFER_LEVEL_SECONDARY)}};
3730 
3731     const CaseDescriptions s_createSingleGroup = {
3732         CASE_DESC(createSingleTest<Instance>, s_instanceCases, DE_NULL),
3733         CASE_DESC(createSingleTest<Device>, s_deviceCases, checkGetPhysicalDevicePropertiesExtension),
3734         CASE_DESC(createSingleTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
3735         CASE_DESC(createSingleTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3736         CASE_DESC(createSingleTest<Buffer>, s_bufferCases, DE_NULL),
3737         CASE_DESC(createSingleTest<BufferView>, s_bufferViewCases, DE_NULL),
3738         CASE_DESC(createSingleTest<Image>, s_imageCases, DE_NULL),
3739         CASE_DESC(createSingleTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3740         CASE_DESC(createSingleTest<Semaphore>, s_semaphoreCases, DE_NULL),
3741         CASE_DESC(createSingleTest<Event>, s_eventCases, checkEventSupport),
3742         CASE_DESC(createSingleTest<Fence>, s_fenceCases, DE_NULL),
3743         CASE_DESC(createSingleTest<QueryPool>, s_queryPoolCases, DE_NULL),
3744         CASE_DESC(createSingleTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3745         CASE_DESC(createSingleTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3746         CASE_DESC(createSingleTest<MergedPipelineCache>, s_mergedPipelineCacheCases, checkPipelineCacheControlSupport),
3747         CASE_DESC(createSingleTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3748         CASE_DESC(createSingleTest<RenderPass>, s_renderPassCases, DE_NULL),
3749         CASE_DESC(createSingleTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
3750         CASE_DESC(createSingleTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
3751         CASE_DESC(createSingleTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
3752         CASE_DESC(createSingleTest<Sampler>, s_samplerCases, DE_NULL),
3753         CASE_DESC(createSingleTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
3754         CASE_DESC(createSingleTest<DescriptorSet>, s_descriptorSetCases, DE_NULL),
3755         CASE_DESC(createSingleTest<Framebuffer>, s_framebufferCases, DE_NULL),
3756         CASE_DESC(createSingleTest<CommandPool>, s_commandPoolCases, DE_NULL),
3757         CASE_DESC(createSingleTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
3758     };
3759     // Create single object
3760     objectMgmtTests->addChild(createGroup(testCtx, "single", s_createSingleGroup));
3761 
3762     const CaseDescriptions s_createMultipleUniqueResourcesGroup = {
3763         CASE_DESC(createMultipleUniqueResourcesTest<Instance>, s_instanceCases, DE_NULL),
3764 #ifndef CTS_USES_VULKANSC
3765         CASE_DESC(createMultipleUniqueResourcesTest<Device>, s_deviceCases, DE_NULL),
3766         CASE_DESC(createMultipleUniqueResourcesTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
3767 #else
3768         EMPTY_CASE_DESC(Device),
3769         EMPTY_CASE_DESC(DeviceGroup),
3770 #endif
3771         CASE_DESC(createMultipleUniqueResourcesTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3772         CASE_DESC(createMultipleUniqueResourcesTest<Buffer>, s_bufferCases, DE_NULL),
3773         CASE_DESC(createMultipleUniqueResourcesTest<BufferView>, s_bufferViewCases, DE_NULL),
3774         CASE_DESC(createMultipleUniqueResourcesTest<Image>, s_imageCases, DE_NULL),
3775         CASE_DESC(createMultipleUniqueResourcesTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3776         CASE_DESC(createMultipleUniqueResourcesTest<Semaphore>, s_semaphoreCases, DE_NULL),
3777         CASE_DESC(createMultipleUniqueResourcesTest<Event>, s_eventCases, checkEventSupport),
3778         CASE_DESC(createMultipleUniqueResourcesTest<Fence>, s_fenceCases, DE_NULL),
3779         CASE_DESC(createMultipleUniqueResourcesTest<QueryPool>, s_queryPoolCases, DE_NULL),
3780         CASE_DESC(createMultipleUniqueResourcesTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3781         CASE_DESC(createMultipleUniqueResourcesTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3782         CASE_DESC(createMultipleUniqueResourcesTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
3783                   checkPipelineCacheControlSupport),
3784         CASE_DESC(createMultipleUniqueResourcesTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3785         CASE_DESC(createMultipleUniqueResourcesTest<RenderPass>, s_renderPassCases, DE_NULL),
3786         CASE_DESC(createMultipleUniqueResourcesTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
3787         CASE_DESC(createMultipleUniqueResourcesTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
3788         CASE_DESC(createMultipleUniqueResourcesTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
3789         CASE_DESC(createMultipleUniqueResourcesTest<Sampler>, s_samplerCases, DE_NULL),
3790         CASE_DESC(createMultipleUniqueResourcesTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
3791         CASE_DESC(createMultipleUniqueResourcesTest<DescriptorSet>, s_descriptorSetCases, DE_NULL),
3792         CASE_DESC(createMultipleUniqueResourcesTest<Framebuffer>, s_framebufferCases, DE_NULL),
3793         CASE_DESC(createMultipleUniqueResourcesTest<CommandPool>, s_commandPoolCases, DE_NULL),
3794         CASE_DESC(createMultipleUniqueResourcesTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
3795     };
3796     // Multiple objects with per-object unique resources
3797     objectMgmtTests->addChild(createGroup(testCtx, "multiple_unique_resources", s_createMultipleUniqueResourcesGroup));
3798 
3799     const CaseDescriptions s_createMultipleSharedResourcesGroup = {
3800         EMPTY_CASE_DESC(Instance), // No resources used
3801 #ifndef CTS_USES_VULKANSC
3802         CASE_DESC(createMultipleSharedResourcesTest<Device>, s_deviceCases, DE_NULL),
3803         CASE_DESC(createMultipleSharedResourcesTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
3804 #else
3805         EMPTY_CASE_DESC(Device),
3806         EMPTY_CASE_DESC(DeviceGroup),
3807 #endif
3808         CASE_DESC(createMultipleSharedResourcesTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3809         CASE_DESC(createMultipleSharedResourcesTest<Buffer>, s_bufferCases, DE_NULL),
3810         CASE_DESC(createMultipleSharedResourcesTest<BufferView>, s_bufferViewCases, DE_NULL),
3811         CASE_DESC(createMultipleSharedResourcesTest<Image>, s_imageCases, DE_NULL),
3812         CASE_DESC(createMultipleSharedResourcesTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3813         CASE_DESC(createMultipleSharedResourcesTest<Semaphore>, s_semaphoreCases, DE_NULL),
3814         CASE_DESC(createMultipleSharedResourcesTest<Event>, s_eventCases, checkEventSupport),
3815         CASE_DESC(createMultipleSharedResourcesTest<Fence>, s_fenceCases, DE_NULL),
3816         CASE_DESC(createMultipleSharedResourcesTest<QueryPool>, s_queryPoolCases, DE_NULL),
3817         CASE_DESC(createMultipleSharedResourcesTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3818         CASE_DESC(createMultipleSharedResourcesTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3819         CASE_DESC(createMultipleSharedResourcesTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
3820                   checkPipelineCacheControlSupport),
3821         CASE_DESC(createMultipleSharedResourcesTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3822         CASE_DESC(createMultipleSharedResourcesTest<RenderPass>, s_renderPassCases, DE_NULL),
3823         CASE_DESC(createMultipleSharedResourcesTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
3824         CASE_DESC(createMultipleSharedResourcesTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
3825         CASE_DESC(createMultipleSharedResourcesTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
3826         CASE_DESC(createMultipleSharedResourcesTest<Sampler>, s_samplerCases, DE_NULL),
3827         CASE_DESC(createMultipleSharedResourcesTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
3828         CASE_DESC(createMultipleSharedResourcesTest<DescriptorSet>, s_descriptorSetCases, DE_NULL),
3829         CASE_DESC(createMultipleSharedResourcesTest<Framebuffer>, s_framebufferCases, DE_NULL),
3830         CASE_DESC(createMultipleSharedResourcesTest<CommandPool>, s_commandPoolCases, DE_NULL),
3831         CASE_DESC(createMultipleSharedResourcesTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
3832     };
3833     // Multiple objects with shared resources
3834     objectMgmtTests->addChild(createGroup(testCtx, "multiple_shared_resources", s_createMultipleSharedResourcesGroup));
3835 
3836 #ifndef CTS_USES_VULKANSC
3837     // Removed from Vulkan SC test set: VkAllocationCallbacks is not supported and pointers to this type must be NULL
3838     const CaseDescriptions s_createMaxConcurrentGroup = {
3839         CASE_DESC(createMaxConcurrentTest<Instance>, s_instanceCases, DE_NULL),
3840         CASE_DESC(createMaxConcurrentTest<Device>, s_deviceCases, DE_NULL),
3841         CASE_DESC(createMaxConcurrentTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
3842         CASE_DESC(createMaxConcurrentTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3843         CASE_DESC(createMaxConcurrentTest<Buffer>, s_bufferCases, DE_NULL),
3844         CASE_DESC(createMaxConcurrentTest<BufferView>, s_bufferViewCases, DE_NULL),
3845         CASE_DESC(createMaxConcurrentTest<Image>, s_imageCases, DE_NULL),
3846         CASE_DESC(createMaxConcurrentTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3847         CASE_DESC(createMaxConcurrentTest<Semaphore>, s_semaphoreCases, DE_NULL),
3848         CASE_DESC(createMaxConcurrentTest<Event>, s_eventCases, checkEventSupport),
3849         CASE_DESC(createMaxConcurrentTest<Fence>, s_fenceCases, DE_NULL),
3850         CASE_DESC(createMaxConcurrentTest<QueryPool>, s_queryPoolCases, DE_NULL),
3851         CASE_DESC(createMaxConcurrentTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3852         CASE_DESC(createMaxConcurrentTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3853         CASE_DESC(createMaxConcurrentTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
3854                   checkPipelineCacheControlSupport),
3855         CASE_DESC(createMaxConcurrentTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3856         CASE_DESC(createMaxConcurrentTest<RenderPass>, s_renderPassCases, DE_NULL),
3857         CASE_DESC(createMaxConcurrentTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
3858         CASE_DESC(createMaxConcurrentTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
3859         CASE_DESC(createMaxConcurrentTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
3860         CASE_DESC(createMaxConcurrentTest<Sampler>, s_samplerCases, DE_NULL),
3861         CASE_DESC(createMaxConcurrentTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
3862         CASE_DESC(createMaxConcurrentTest<DescriptorSet>, s_descriptorSetCases, DE_NULL),
3863         CASE_DESC(createMaxConcurrentTest<Framebuffer>, s_framebufferCases, DE_NULL),
3864         CASE_DESC(createMaxConcurrentTest<CommandPool>, s_commandPoolCases, DE_NULL),
3865         CASE_DESC(createMaxConcurrentTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
3866     };
3867     // Maximum number of concurrently live objects
3868     objectMgmtTests->addChild(createGroup(testCtx, "max_concurrent", s_createMaxConcurrentGroup));
3869 #endif // CTS_USES_VULKANSC
3870 
3871     const CaseDescriptions s_multithreadedCreatePerThreadDeviceGroup = {
3872         EMPTY_CASE_DESC(Instance),    // Does not make sense
3873         EMPTY_CASE_DESC(Device),      // Does not make sense
3874         EMPTY_CASE_DESC(DeviceGroup), // Does not make sense
3875         CASE_DESC(multithreadedCreatePerThreadDeviceTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3876         CASE_DESC(multithreadedCreatePerThreadDeviceTest<Buffer>, s_bufferCases, DE_NULL),
3877         CASE_DESC(multithreadedCreatePerThreadDeviceTest<BufferView>, s_bufferViewCases, DE_NULL),
3878         CASE_DESC(multithreadedCreatePerThreadDeviceTest<Image>, s_imageCases, DE_NULL),
3879         CASE_DESC(multithreadedCreatePerThreadDeviceTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3880         CASE_DESC(multithreadedCreatePerThreadDeviceTest<Semaphore>, s_semaphoreCases, DE_NULL),
3881         CASE_DESC(multithreadedCreatePerThreadDeviceTest<Event>, s_eventCases, checkEventSupport),
3882         CASE_DESC(multithreadedCreatePerThreadDeviceTest<Fence>, s_fenceCases, DE_NULL),
3883         CASE_DESC(multithreadedCreatePerThreadDeviceTest<QueryPool>, s_queryPoolCases, DE_NULL),
3884         CASE_DESC(multithreadedCreatePerThreadDeviceTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3885         CASE_DESC(multithreadedCreatePerThreadDeviceTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3886         CASE_DESC(multithreadedCreatePerThreadDeviceTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
3887                   checkPipelineCacheControlSupport),
3888         CASE_DESC(multithreadedCreatePerThreadDeviceTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3889         CASE_DESC(multithreadedCreatePerThreadDeviceTest<RenderPass>, s_renderPassCases, DE_NULL),
3890         CASE_DESC(multithreadedCreatePerThreadDeviceTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
3891         CASE_DESC(multithreadedCreatePerThreadDeviceTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
3892         CASE_DESC(multithreadedCreatePerThreadDeviceTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
3893         CASE_DESC(multithreadedCreatePerThreadDeviceTest<Sampler>, s_samplerCases, DE_NULL),
3894         CASE_DESC(multithreadedCreatePerThreadDeviceTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
3895         CASE_DESC(multithreadedCreatePerThreadDeviceTest<DescriptorSet>, s_descriptorSetCases,
3896                   checkRecycleDescriptorSetMemorySupport),
3897         CASE_DESC(multithreadedCreatePerThreadDeviceTest<Framebuffer>, s_framebufferCases, DE_NULL),
3898         CASE_DESC(multithreadedCreatePerThreadDeviceTest<CommandPool>, s_commandPoolCases, DE_NULL),
3899         CASE_DESC(multithreadedCreatePerThreadDeviceTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
3900     };
3901     // Multithreaded object construction with per-thread device
3902     objectMgmtTests->addChild(
3903         createGroup(testCtx, "multithreaded_per_thread_device", s_multithreadedCreatePerThreadDeviceGroup));
3904 
3905     const CaseDescriptions s_multithreadedCreatePerThreadResourcesGroup = {
3906         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Instance>, s_instanceCases, DE_NULL),
3907         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Device>, s_deviceCases, DE_NULL),
3908         CASE_DESC(multithreadedCreatePerThreadResourcesTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
3909         CASE_DESC(multithreadedCreatePerThreadResourcesTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3910         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Buffer>, s_bufferCases, DE_NULL),
3911         CASE_DESC(multithreadedCreatePerThreadResourcesTest<BufferView>, s_bufferViewCases, DE_NULL),
3912         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Image>, s_imageCases, DE_NULL),
3913         CASE_DESC(multithreadedCreatePerThreadResourcesTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3914         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Semaphore>, s_semaphoreCases, DE_NULL),
3915         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Event>, s_eventCases, checkEventSupport),
3916         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Fence>, s_fenceCases, DE_NULL),
3917         CASE_DESC(multithreadedCreatePerThreadResourcesTest<QueryPool>, s_queryPoolCases, DE_NULL),
3918         CASE_DESC(multithreadedCreatePerThreadResourcesTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3919         CASE_DESC(multithreadedCreatePerThreadResourcesTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3920         CASE_DESC(multithreadedCreatePerThreadResourcesTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
3921                   checkPipelineCacheControlSupport),
3922         CASE_DESC(multithreadedCreatePerThreadResourcesTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3923         CASE_DESC(multithreadedCreatePerThreadResourcesTest<RenderPass>, s_renderPassCases, DE_NULL),
3924         CASE_DESC(multithreadedCreatePerThreadResourcesTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
3925         CASE_DESC(multithreadedCreatePerThreadResourcesTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
3926         CASE_DESC(multithreadedCreatePerThreadResourcesTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
3927         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Sampler>, s_samplerCases, DE_NULL),
3928         CASE_DESC(multithreadedCreatePerThreadResourcesTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
3929         CASE_DESC(multithreadedCreatePerThreadResourcesTest<DescriptorSet>, s_descriptorSetCases,
3930                   checkRecycleDescriptorSetMemorySupport),
3931         CASE_DESC(multithreadedCreatePerThreadResourcesTest<Framebuffer>, s_framebufferCases, DE_NULL),
3932         CASE_DESC(multithreadedCreatePerThreadResourcesTest<CommandPool>, s_commandPoolCases, DE_NULL),
3933         CASE_DESC(multithreadedCreatePerThreadResourcesTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
3934     };
3935     // Multithreaded object construction with per-thread resources
3936     objectMgmtTests->addChild(
3937         createGroup(testCtx, "multithreaded_per_thread_resources", s_multithreadedCreatePerThreadResourcesGroup));
3938 
3939     const CaseDescriptions s_multithreadedCreateSharedResourcesGroup = {
3940         EMPTY_CASE_DESC(Instance),
3941 #ifndef CTS_USES_VULKANSC
3942         CASE_DESC(multithreadedCreateSharedResourcesTest<Device>, s_deviceCases, DE_NULL),
3943         CASE_DESC(multithreadedCreateSharedResourcesTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
3944 #else
3945         EMPTY_CASE_DESC(Device),
3946         EMPTY_CASE_DESC(DeviceGroup),
3947 #endif
3948         CASE_DESC(multithreadedCreateSharedResourcesTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3949         CASE_DESC(multithreadedCreateSharedResourcesTest<Buffer>, s_bufferCases, DE_NULL),
3950         CASE_DESC(multithreadedCreateSharedResourcesTest<BufferView>, s_bufferViewCases, DE_NULL),
3951         CASE_DESC(multithreadedCreateSharedResourcesTest<Image>, s_imageCases, DE_NULL),
3952         CASE_DESC(multithreadedCreateSharedResourcesTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3953         CASE_DESC(multithreadedCreateSharedResourcesTest<Semaphore>, s_semaphoreCases, DE_NULL),
3954         CASE_DESC(multithreadedCreateSharedResourcesTest<Event>, s_eventCases, checkEventSupport),
3955         CASE_DESC(multithreadedCreateSharedResourcesTest<Fence>, s_fenceCases, DE_NULL),
3956         CASE_DESC(multithreadedCreateSharedResourcesTest<QueryPool>, s_queryPoolCases, DE_NULL),
3957         CASE_DESC(multithreadedCreateSharedResourcesTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3958         CASE_DESC(multithreadedCreateSharedResourcesTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3959         CASE_DESC(multithreadedCreateSharedResourcesTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
3960                   checkPipelineCacheControlSupport),
3961         CASE_DESC(multithreadedCreateSharedResourcesTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3962         CASE_DESC(multithreadedCreateSharedResourcesTest<RenderPass>, s_renderPassCases, DE_NULL),
3963         CASE_DESC(multithreadedCreateSharedResourcesTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
3964         CASE_DESC(multithreadedCreateSharedResourcesTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
3965         CASE_DESC(multithreadedCreateSharedResourcesTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
3966         CASE_DESC(multithreadedCreateSharedResourcesTest<Sampler>, s_samplerCases, DE_NULL),
3967         CASE_DESC(multithreadedCreateSharedResourcesTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
3968         EMPTY_CASE_DESC(DescriptorSet), // \note Needs per-thread DescriptorPool
3969         CASE_DESC(multithreadedCreateSharedResourcesTest<Framebuffer>, s_framebufferCases, DE_NULL),
3970         CASE_DESC(multithreadedCreateSharedResourcesTest<CommandPool>, s_commandPoolCases, DE_NULL),
3971         EMPTY_CASE_DESC(CommandBuffer), // \note Needs per-thread CommandPool
3972     };
3973     // Multithreaded object construction with shared resources
3974     objectMgmtTests->addChild(
3975         createGroup(testCtx, "multithreaded_shared_resources", s_multithreadedCreateSharedResourcesGroup));
3976 
3977 #ifndef CTS_USES_VULKANSC
3978 
3979     // Removed from Vulkan SC test set: VkAllocationCallbacks is not supported and pointers to this type must be NULL
3980     const CaseDescriptions s_createSingleAllocCallbacksGroup = {
3981         CASE_DESC(createSingleAllocCallbacksTest<Instance>, s_instanceCases, DE_NULL),
3982         CASE_DESC(createSingleAllocCallbacksTest<Device>, s_deviceCases, DE_NULL),
3983         CASE_DESC(createSingleAllocCallbacksTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
3984         CASE_DESC(createSingleAllocCallbacksTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
3985         CASE_DESC(createSingleAllocCallbacksTest<Buffer>, s_bufferCases, DE_NULL),
3986         CASE_DESC(createSingleAllocCallbacksTest<BufferView>, s_bufferViewCases, DE_NULL),
3987         CASE_DESC(createSingleAllocCallbacksTest<Image>, s_imageCases, DE_NULL),
3988         CASE_DESC(createSingleAllocCallbacksTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
3989         CASE_DESC(createSingleAllocCallbacksTest<Semaphore>, s_semaphoreCases, DE_NULL),
3990         CASE_DESC(createSingleAllocCallbacksTest<Event>, s_eventCases, checkEventSupport),
3991         CASE_DESC(createSingleAllocCallbacksTest<Fence>, s_fenceCases, DE_NULL),
3992         CASE_DESC(createSingleAllocCallbacksTest<QueryPool>, s_queryPoolCases, DE_NULL),
3993         CASE_DESC(createSingleAllocCallbacksTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
3994         CASE_DESC(createSingleAllocCallbacksTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
3995         CASE_DESC(createSingleAllocCallbacksTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
3996                   checkPipelineCacheControlSupport),
3997         CASE_DESC(createSingleAllocCallbacksTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
3998         CASE_DESC(createSingleAllocCallbacksTest<RenderPass>, s_renderPassCases, DE_NULL),
3999         CASE_DESC(createSingleAllocCallbacksTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
4000         CASE_DESC(createSingleAllocCallbacksTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
4001         CASE_DESC(createSingleAllocCallbacksTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
4002         CASE_DESC(createSingleAllocCallbacksTest<Sampler>, s_samplerCases, DE_NULL),
4003         CASE_DESC(createSingleAllocCallbacksTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
4004         CASE_DESC(createSingleAllocCallbacksTest<DescriptorSet>, s_descriptorSetCases, DE_NULL),
4005         CASE_DESC(createSingleAllocCallbacksTest<Framebuffer>, s_framebufferCases, DE_NULL),
4006         CASE_DESC(createSingleAllocCallbacksTest<CommandPool>, s_commandPoolCases, DE_NULL),
4007         CASE_DESC(createSingleAllocCallbacksTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
4008     };
4009     // Create single object
4010     objectMgmtTests->addChild(createGroup(testCtx, "single_alloc_callbacks", s_createSingleAllocCallbacksGroup));
4011 #endif // CTS_USES_VULKANSC
4012 
4013 #ifndef CTS_USES_VULKANSC
4014     // Removed from Vulkan SC test set: VkAllocationCallbacks is not supported and pointers to this type must be NULL
4015     // \note Skip pooled objects in this test group. They are properly handled by the "multiple" group farther down below.
4016     const CaseDescriptions s_allocCallbackFailGroup = {
4017         CASE_DESC(allocCallbackFailTest<Instance>, s_instanceCases, DE_NULL),
4018         CASE_DESC(allocCallbackFailTest<Device>, s_deviceCases, DE_NULL),
4019         CASE_DESC(allocCallbackFailTest<DeviceGroup>, s_deviceGroupCases, DE_NULL),
4020         CASE_DESC(allocCallbackFailTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
4021         CASE_DESC(allocCallbackFailTest<Buffer>, s_bufferCases, DE_NULL),
4022         CASE_DESC(allocCallbackFailTest<BufferView>, s_bufferViewCases, DE_NULL),
4023         CASE_DESC(allocCallbackFailTest<Image>, s_imageCases, DE_NULL),
4024         CASE_DESC(allocCallbackFailTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
4025         CASE_DESC(allocCallbackFailTest<Semaphore>, s_semaphoreCases, DE_NULL),
4026         CASE_DESC(allocCallbackFailTest<Event>, s_eventCases, checkEventSupport),
4027         CASE_DESC(allocCallbackFailTest<Fence>, s_fenceCases, DE_NULL),
4028         CASE_DESC(allocCallbackFailTest<QueryPool>, s_queryPoolCases, DE_NULL),
4029         CASE_DESC(allocCallbackFailTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
4030         CASE_DESC(allocCallbackFailTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
4031         CASE_DESC(allocCallbackFailTest<MergedPipelineCache>, s_mergedPipelineCacheCases,
4032                   checkPipelineCacheControlSupport),
4033         CASE_DESC(allocCallbackFailTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
4034         CASE_DESC(allocCallbackFailTest<RenderPass>, s_renderPassCases, DE_NULL),
4035         CASE_DESC(allocCallbackFailTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
4036         CASE_DESC(allocCallbackFailTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
4037         CASE_DESC(allocCallbackFailTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
4038         CASE_DESC(allocCallbackFailTest<Sampler>, s_samplerCases, DE_NULL),
4039         CASE_DESC(allocCallbackFailTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
4040         EMPTY_CASE_DESC(DescriptorSet),
4041         CASE_DESC(allocCallbackFailTest<Framebuffer>, s_framebufferCases, DE_NULL),
4042         CASE_DESC(allocCallbackFailTest<CommandPool>, s_commandPoolCases, DE_NULL),
4043         EMPTY_CASE_DESC(CommandBuffer),
4044     };
4045     // Allocation callback failure
4046     objectMgmtTests->addChild(createGroup(testCtx, "alloc_callback_fail", s_allocCallbackFailGroup));
4047 #endif // CTS_USES_VULKANSC
4048 
4049 #ifndef CTS_USES_VULKANSC
4050     // Removed from Vulkan SC test set: VkAllocationCallbacks is not supported and pointers to this type must be NULL
4051     // \note Test objects that can be created in bulk
4052     const CaseDescriptions s_allocCallbackFailMultipleObjectsGroup = {
4053         EMPTY_CASE_DESC(Instance), // most objects can be created one at a time only
4054         EMPTY_CASE_DESC(Device),
4055         EMPTY_CASE_DESC(DeviceGroup),
4056         EMPTY_CASE_DESC(DeviceMemory),
4057         EMPTY_CASE_DESC(Buffer),
4058         EMPTY_CASE_DESC(BufferView),
4059         EMPTY_CASE_DESC(Image),
4060         EMPTY_CASE_DESC(ImageView),
4061         EMPTY_CASE_DESC(Semaphore),
4062         EMPTY_CASE_DESC(Event),
4063         EMPTY_CASE_DESC(Fence),
4064         EMPTY_CASE_DESC(QueryPool),
4065         EMPTY_CASE_DESC(ShaderModule),
4066         EMPTY_CASE_DESC(PipelineCache),
4067         EMPTY_CASE_DESC(MergedPipelineCache),
4068         EMPTY_CASE_DESC(PipelineLayout),
4069         EMPTY_CASE_DESC(RenderPass),
4070         CASE_DESC(allocCallbackFailMultipleObjectsTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
4071         CASE_DESC(allocCallbackFailMultipleObjectsTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
4072         EMPTY_CASE_DESC(DescriptorSetLayout),
4073         EMPTY_CASE_DESC(Sampler),
4074         EMPTY_CASE_DESC(DescriptorPool),
4075         CASE_DESC(allocCallbackFailMultipleObjectsTest<DescriptorSet>, s_descriptorSetCases, DE_NULL),
4076         EMPTY_CASE_DESC(Framebuffer),
4077         EMPTY_CASE_DESC(CommandPool),
4078         CASE_DESC(allocCallbackFailMultipleObjectsTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
4079     };
4080     // Allocation callback failure creating multiple objects with one call
4081     objectMgmtTests->addChild(
4082         createGroup(testCtx, "alloc_callback_fail_multiple", s_allocCallbackFailMultipleObjectsGroup));
4083 #endif // CTS_USES_VULKANSC
4084 
4085 #ifndef CTS_USES_VULKANSC
4086     // Removed from Vulkan SC test set: VK_EXT_private_data extension does not exist in Vulkan SC
4087     const CaseDescriptions s_privateDataResourcesGroup = {
4088         EMPTY_CASE_DESC(Instance),    // Does not make sense
4089         EMPTY_CASE_DESC(Device),      // Device is tested in each object test
4090         EMPTY_CASE_DESC(DeviceGroup), // Device is tested in each object test
4091         CASE_DESC(createPrivateDataTest<DeviceMemory>, s_deviceMemCases, DE_NULL),
4092         CASE_DESC(createPrivateDataTest<Buffer>, s_bufferCases, DE_NULL),
4093         CASE_DESC(createPrivateDataTest<BufferView>, s_bufferViewCases, DE_NULL),
4094         CASE_DESC(createPrivateDataTest<Image>, s_imageCases, DE_NULL),
4095         CASE_DESC(createPrivateDataTest<ImageView>, s_imageViewCases, checkImageCubeArraySupport),
4096         CASE_DESC(createPrivateDataTest<Semaphore>, s_semaphoreCases, DE_NULL),
4097         CASE_DESC(createPrivateDataTest<Event>, s_eventCases, checkEventSupport),
4098         CASE_DESC(createPrivateDataTest<Fence>, s_fenceCases, DE_NULL),
4099         CASE_DESC(createPrivateDataTest<QueryPool>, s_queryPoolCases, DE_NULL),
4100         CASE_DESC(createPrivateDataTest<ShaderModule>, s_shaderModuleCases, DE_NULL),
4101         CASE_DESC(createPrivateDataTest<PipelineCache>, s_pipelineCacheCases, DE_NULL),
4102         EMPTY_CASE_DESC(MergedPipelineCache),
4103         CASE_DESC(createPrivateDataTest<PipelineLayout>, s_pipelineLayoutCases, DE_NULL),
4104         CASE_DESC(createPrivateDataTest<RenderPass>, s_renderPassCases, DE_NULL),
4105         CASE_DESC(createPrivateDataTest<GraphicsPipeline>, s_graphicsPipelineCases, DE_NULL),
4106         CASE_DESC(createPrivateDataTest<ComputePipeline>, s_computePipelineCases, DE_NULL),
4107         CASE_DESC(createPrivateDataTest<DescriptorSetLayout>, s_descriptorSetLayoutCases, DE_NULL),
4108         CASE_DESC(createPrivateDataTest<Sampler>, s_samplerCases, DE_NULL),
4109         CASE_DESC(createPrivateDataTest<DescriptorPool>, s_descriptorPoolCases, DE_NULL),
4110         CASE_DESC(createPrivateDataTest<DescriptorSet>, s_descriptorSetCases, DE_NULL),
4111         CASE_DESC(createPrivateDataTest<Framebuffer>, s_framebufferCases, DE_NULL),
4112         CASE_DESC(createPrivateDataTest<CommandPool>, s_commandPoolCases, DE_NULL),
4113         CASE_DESC(createPrivateDataTest<CommandBuffer>, s_commandBufferCases, DE_NULL),
4114     };
4115     // Multiple objects with private data
4116     objectMgmtTests->addChild(
4117         createTestGroup(testCtx, "private_data", createTests, s_privateDataResourcesGroup, cleanupGroup));
4118 #endif // CTS_USES_VULKANSC
4119 
4120     return objectMgmtTests.release();
4121 }
4122 
4123 } // namespace api
4124 } // namespace vkt
4125