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