Revert "Touch watchdog during object cleanup in max_concurrent tests"
[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
27 #include "vkDefs.hpp"
28 #include "vkRef.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkStrUtil.hpp"
36 #include "vkAllocationCallbackUtil.hpp"
37
38 #include "tcuVector.hpp"
39 #include "tcuResultCollector.hpp"
40 #include "tcuCommandLine.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuPlatform.hpp"
43
44 #include "deUniquePtr.hpp"
45 #include "deSharedPtr.hpp"
46 #include "deArrayUtil.hpp"
47 #include "deSpinBarrier.hpp"
48 #include "deThread.hpp"
49 #include "deInt32.h"
50
51 #include <limits>
52
53 namespace vkt
54 {
55 namespace api
56 {
57
58 namespace
59 {
60
61 using namespace vk;
62
63 using de::UniquePtr;
64 using de::MovePtr;
65 using de::SharedPtr;
66
67 using tcu::IVec3;
68 using tcu::UVec3;
69 using tcu::ResultCollector;
70 using tcu::TestStatus;
71 using tcu::TestLog;
72
73 using std::string;
74 using std::vector;
75
76 class ThreadGroupThread;
77
78 /*--------------------------------------------------------------------*//*!
79  * \brief Thread group
80  *
81  * Thread group manages collection of threads that are expected to be
82  * launched simultaneously as a group.
83  *
84  * Shared barrier is provided for synchronizing execution. Terminating thread
85  * early either by returning from ThreadGroupThread::runThread() or throwing
86  * an exception is safe, and other threads will continue execution. The
87  * thread that has been terminated is simply removed from the synchronization
88  * group.
89  *
90  * TestException-based exceptions are collected and translated into a
91  * tcu::TestStatus by using tcu::ResultCollector.
92  *
93  * Use cases for ThreadGroup include for example testing thread-safety of
94  * certain API operations by poking API simultaneously from multiple
95  * threads.
96  *//*--------------------------------------------------------------------*/
97 class ThreadGroup
98 {
99 public:
100                                                         ThreadGroup                     (void);
101                                                         ~ThreadGroup            (void);
102
103         void                                    add                                     (de::MovePtr<ThreadGroupThread> thread);
104         TestStatus                              run                                     (void);
105
106 private:
107         typedef std::vector<de::SharedPtr<ThreadGroupThread> >  ThreadVector;
108
109         ThreadVector                    m_threads;
110         de::SpinBarrier                 m_barrier;
111 } DE_WARN_UNUSED_TYPE;
112
113 class ThreadGroupThread : private de::Thread
114 {
115 public:
116                                                         ThreadGroupThread       (void);
117         virtual                                 ~ThreadGroupThread      (void);
118
119         void                                    start                           (de::SpinBarrier* groupBarrier);
120
121         ResultCollector&                getResultCollector      (void) { return m_resultCollector; }
122
123         using de::Thread::join;
124
125 protected:
126         virtual void                    runThread                       (void) = 0;
127
128         void                                    barrier                         (void);
129
130 private:
131                                                         ThreadGroupThread       (const ThreadGroupThread&);
132         ThreadGroupThread&              operator=                       (const ThreadGroupThread&);
133
134         void                                    run                                     (void);
135
136         ResultCollector                 m_resultCollector;
137         de::SpinBarrier*                m_barrier;
138 };
139
140 // ThreadGroup
141
142 ThreadGroup::ThreadGroup (void)
143         : m_barrier(1)
144 {
145 }
146
147 ThreadGroup::~ThreadGroup (void)
148 {
149 }
150
151 void ThreadGroup::add (de::MovePtr<ThreadGroupThread> thread)
152 {
153         m_threads.push_back(de::SharedPtr<ThreadGroupThread>(thread.release()));
154 }
155
156 tcu::TestStatus ThreadGroup::run (void)
157 {
158         tcu::ResultCollector    resultCollector;
159
160         m_barrier.reset((int)m_threads.size());
161
162         for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
163                 (*threadIter)->start(&m_barrier);
164
165         for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
166         {
167                 tcu::ResultCollector&   threadResult    = (*threadIter)->getResultCollector();
168                 (*threadIter)->join();
169                 resultCollector.addResult(threadResult.getResult(), threadResult.getMessage());
170         }
171
172         return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
173 }
174
175 // ThreadGroupThread
176
177 ThreadGroupThread::ThreadGroupThread (void)
178         : m_barrier(DE_NULL)
179 {
180 }
181
182 ThreadGroupThread::~ThreadGroupThread (void)
183 {
184 }
185
186 void ThreadGroupThread::start (de::SpinBarrier* groupBarrier)
187 {
188         m_barrier = groupBarrier;
189         de::Thread::start();
190 }
191
192 void ThreadGroupThread::run (void)
193 {
194         try
195         {
196                 runThread();
197         }
198         catch (const tcu::TestException& e)
199         {
200                 getResultCollector().addResult(e.getTestResult(), e.getMessage());
201         }
202         catch (const std::exception& e)
203         {
204                 getResultCollector().addResult(QP_TEST_RESULT_FAIL, e.what());
205         }
206         catch (...)
207         {
208                 getResultCollector().addResult(QP_TEST_RESULT_FAIL, "Exception");
209         }
210
211         m_barrier->removeThread(de::SpinBarrier::WAIT_MODE_AUTO);
212 }
213
214 inline void ThreadGroupThread::barrier (void)
215 {
216         m_barrier->sync(de::SpinBarrier::WAIT_MODE_AUTO);
217 }
218
219 deUint32 getDefaultTestThreadCount (void)
220 {
221         return de::clamp(deGetNumAvailableLogicalCores(), 2u, 8u);
222 }
223
224 // Utilities
225
226 struct Environment
227 {
228         const PlatformInterface&                vkp;
229         const DeviceInterface&                  vkd;
230         VkDevice                                                device;
231         deUint32                                                queueFamilyIndex;
232         const BinaryCollection&                 programBinaries;
233         const VkAllocationCallbacks*    allocationCallbacks;
234         deUint32                                                maxResourceConsumers;           // Maximum number of objects using same Object::Resources concurrently
235
236         Environment (Context& context, deUint32 maxResourceConsumers_)
237                 : vkp                                   (context.getPlatformInterface())
238                 , vkd                                   (context.getDeviceInterface())
239                 , device                                (context.getDevice())
240                 , queueFamilyIndex              (context.getUniversalQueueFamilyIndex())
241                 , programBinaries               (context.getBinaryCollection())
242                 , allocationCallbacks   (DE_NULL)
243                 , maxResourceConsumers  (maxResourceConsumers_)
244         {
245         }
246
247         Environment (const PlatformInterface&           vkp_,
248                                  const DeviceInterface&                 vkd_,
249                                  VkDevice                                               device_,
250                                  deUint32                                               queueFamilyIndex_,
251                                  const BinaryCollection&                programBinaries_,
252                                  const VkAllocationCallbacks*   allocationCallbacks_,
253                                  deUint32                                               maxResourceConsumers_)
254                 : vkp                                   (vkp_)
255                 , vkd                                   (vkd_)
256                 , device                                (device_)
257                 , queueFamilyIndex              (queueFamilyIndex_)
258                 , programBinaries               (programBinaries_)
259                 , allocationCallbacks   (allocationCallbacks_)
260                 , maxResourceConsumers  (maxResourceConsumers_)
261         {
262         }
263 };
264
265 template<typename Case>
266 struct Dependency
267 {
268         typename Case::Resources                resources;
269         Unique<typename Case::Type>             object;
270
271         Dependency (const Environment& env, const typename Case::Parameters& params)
272                 : resources     (env, params)
273                 , object        (Case::create(env, resources, params))
274         {}
275 };
276
277 template<typename T>
278 T roundUpToNextMultiple (T value, T multiple)
279 {
280         if (value % multiple == 0)
281                 return value;
282         else
283                 return value + multiple - (value % multiple);
284 }
285
286 #if defined(DE_DEBUG)
287 template<typename T>
288 bool isPowerOfTwo (T value)
289 {
290         return ((value & (value - T(1))) == 0);
291 }
292 #endif
293
294 template<typename T>
295 T alignToPowerOfTwo (T value, T align)
296 {
297         DE_ASSERT(isPowerOfTwo(align));
298         return (value + align - T(1)) & ~(align - T(1));
299 }
300
301 VkDeviceSize getPageTableSize (const PlatformMemoryLimits& limits, VkDeviceSize allocationSize)
302 {
303         VkDeviceSize    totalSize       = 0;
304
305         for (size_t levelNdx = 0; levelNdx < limits.devicePageTableHierarchyLevels; ++levelNdx)
306         {
307                 const VkDeviceSize      coveredAddressSpaceSize = limits.devicePageSize<<levelNdx;
308                 const VkDeviceSize      numPagesNeeded                  = alignToPowerOfTwo(allocationSize, coveredAddressSpaceSize) / coveredAddressSpaceSize;
309
310                 totalSize += numPagesNeeded*limits.devicePageTableEntrySize;
311         }
312
313         return totalSize;
314 }
315
316
317
318 size_t getCurrentSystemMemoryUsage (const AllocationCallbackRecorder& allocRecoder)
319 {
320         const size_t                                            systemAllocationOverhead        = sizeof(void*)*2;
321         AllocationCallbackValidationResults     validationResults;
322
323         validateAllocationCallbacks(allocRecoder, &validationResults);
324         TCU_CHECK(validationResults.violations.empty());
325
326         return getLiveSystemAllocationTotal(validationResults) + systemAllocationOverhead*validationResults.liveAllocations.size();
327 }
328
329 template<typename Object>
330 size_t computeSystemMemoryUsage (Context& context, const typename Object::Parameters& params)
331 {
332         AllocationCallbackRecorder                      allocRecorder           (getSystemAllocator());
333         const Environment                                       env                                     (context.getPlatformInterface(),
334                                                                                                                          context.getDeviceInterface(),
335                                                                                                                          context.getDevice(),
336                                                                                                                          context.getUniversalQueueFamilyIndex(),
337                                                                                                                          context.getBinaryCollection(),
338                                                                                                                          allocRecorder.getCallbacks(),
339                                                                                                                          1u);
340         const typename Object::Resources        res                                     (env, params);
341         const size_t                                            resourceMemoryUsage     = getCurrentSystemMemoryUsage(allocRecorder);
342
343         {
344                 Unique<typename Object::Type>   obj                                     (Object::create(env, res, params));
345                 const size_t                                    totalMemoryUsage        = getCurrentSystemMemoryUsage(allocRecorder);
346
347                 return totalMemoryUsage - resourceMemoryUsage;
348         }
349 }
350
351 size_t getSafeObjectCount (const PlatformMemoryLimits&  memoryLimits,
352                                                    size_t                                               objectSystemMemoryUsage,
353                                                    VkDeviceSize                                 objectDeviceMemoryUsage = 0)
354 {
355         const VkDeviceSize      roundedUpDeviceMemory   = roundUpToNextMultiple(objectDeviceMemoryUsage, memoryLimits.deviceMemoryAllocationGranularity);
356
357         if (memoryLimits.totalDeviceLocalMemory > 0 && roundedUpDeviceMemory > 0)
358         {
359                 if (objectSystemMemoryUsage > 0)
360                         return de::min(memoryLimits.totalSystemMemory / objectSystemMemoryUsage,
361                                                    (size_t)(memoryLimits.totalDeviceLocalMemory / roundedUpDeviceMemory));
362                 else
363                         return (size_t)(memoryLimits.totalDeviceLocalMemory / roundedUpDeviceMemory);
364         }
365         else if (objectSystemMemoryUsage + roundedUpDeviceMemory > 0)
366         {
367                 DE_ASSERT(roundedUpDeviceMemory <= std::numeric_limits<size_t>::max() - objectSystemMemoryUsage);
368                 return memoryLimits.totalSystemMemory / (objectSystemMemoryUsage + (size_t)roundedUpDeviceMemory);
369         }
370         else
371         {
372                 // Warning: at this point driver has probably not implemented allocation callbacks correctly
373                 return std::numeric_limits<size_t>::max();
374         }
375 }
376
377 PlatformMemoryLimits getPlatformMemoryLimits (Context& context)
378 {
379         PlatformMemoryLimits    memoryLimits;
380
381         context.getTestContext().getPlatform().getVulkanPlatform().getMemoryLimits(memoryLimits);
382
383         return memoryLimits;
384 }
385
386 size_t getSafeObjectCount (Context& context, size_t objectSystemMemoryUsage, VkDeviceSize objectDeviceMemorySize = 0)
387 {
388         return getSafeObjectCount(getPlatformMemoryLimits(context), objectSystemMemoryUsage, objectDeviceMemorySize);
389 }
390
391 VkDeviceSize getPageTableSize (Context& context, VkDeviceSize allocationSize)
392 {
393         return getPageTableSize(getPlatformMemoryLimits(context), allocationSize);
394 }
395
396 template<typename Object>
397 deUint32 getSafeObjectCount (Context&                                                   context,
398                                                          const typename Object::Parameters&     params,
399                                                          deUint32                                                       hardCountLimit,
400                                                          VkDeviceSize                                           deviceMemoryUsage = 0)
401 {
402         return (deUint32)de::min((size_t)hardCountLimit,
403                                                          getSafeObjectCount(context,
404                                                                                                 computeSystemMemoryUsage<Object>(context, params),
405                                                                                                 deviceMemoryUsage));
406 }
407
408 // Object definitions
409
410 enum
411 {
412         MAX_CONCURRENT_INSTANCES                = 32,
413         MAX_CONCURRENT_DEVICES                  = 32,
414         MAX_CONCURRENT_SYNC_PRIMITIVES  = 100,
415         DEFAULT_MAX_CONCURRENT_OBJECTS  = 16*1024,
416 };
417
418 struct Instance
419 {
420         typedef VkInstance Type;
421
422         struct Parameters
423         {
424                 Parameters (void) {}
425         };
426
427         struct Resources
428         {
429                 Resources (const Environment&, const Parameters&) {}
430         };
431
432         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
433         {
434                 return getSafeObjectCount<Instance>(context, params, MAX_CONCURRENT_INSTANCES);
435         }
436
437         static Move<VkInstance> create (const Environment& env, const Resources&, const Parameters&)
438         {
439                 const VkApplicationInfo         appInfo                 =
440                 {
441                         VK_STRUCTURE_TYPE_APPLICATION_INFO,
442                         DE_NULL,
443                         DE_NULL,                                                        // pApplicationName
444                         0u,                                                                     // applicationVersion
445                         DE_NULL,                                                        // pEngineName
446                         0u,                                                                     // engineVersion
447                         VK_MAKE_VERSION(1,0,0)
448                 };
449                 const VkInstanceCreateInfo      instanceInfo    =
450                 {
451                         VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
452                         DE_NULL,
453                         (VkInstanceCreateFlags)0,
454                         &appInfo,
455                         0u,                                                                     // enabledLayerNameCount
456                         DE_NULL,                                                        // ppEnabledLayerNames
457                         0u,                                                                     // enabledExtensionNameCount
458                         DE_NULL,                                                        // ppEnabledExtensionNames
459                 };
460
461                 return createInstance(env.vkp, &instanceInfo, env.allocationCallbacks);
462         }
463 };
464
465 struct Device
466 {
467         typedef VkDevice Type;
468
469         struct Parameters
470         {
471                 deUint32                deviceIndex;
472                 VkQueueFlags    queueFlags;
473
474                 Parameters (deUint32 deviceIndex_, VkQueueFlags queueFlags_)
475                         : deviceIndex   (deviceIndex_)
476                         , queueFlags    (queueFlags_)
477                 {}
478         };
479
480         struct Resources
481         {
482                 Dependency<Instance>    instance;
483                 InstanceDriver                  vki;
484                 VkPhysicalDevice                physicalDevice;
485                 deUint32                                queueFamilyIndex;
486
487                 Resources (const Environment& env, const Parameters& params)
488                         : instance                      (env, Instance::Parameters())
489                         , vki                           (env.vkp, *instance.object)
490                         , physicalDevice        (0)
491                         , queueFamilyIndex      (~0u)
492                 {
493                         {
494                                 const vector<VkPhysicalDevice>  physicalDevices = enumeratePhysicalDevices(vki, *instance.object);
495
496                                 if (physicalDevices.size() <= (size_t)params.deviceIndex)
497                                         TCU_THROW(NotSupportedError, "Device not found");
498
499                                 physicalDevice = physicalDevices[params.deviceIndex];
500                         }
501
502                         {
503                                 const vector<VkQueueFamilyProperties>   queueProps              = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
504                                 bool                                                                    foundMatching   = false;
505
506                                 for (size_t curQueueNdx = 0; curQueueNdx < queueProps.size(); curQueueNdx++)
507                                 {
508                                         if ((queueProps[curQueueNdx].queueFlags & params.queueFlags) == params.queueFlags)
509                                         {
510                                                 queueFamilyIndex        = (deUint32)curQueueNdx;
511                                                 foundMatching           = true;
512                                         }
513                                 }
514
515                                 if (!foundMatching)
516                                         TCU_THROW(NotSupportedError, "Matching queue not found");
517                         }
518                 }
519         };
520
521         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
522         {
523                 return getSafeObjectCount<Device>(context, params, MAX_CONCURRENT_DEVICES);
524         }
525
526         static Move<VkDevice> create (const Environment& env, const Resources& res, const Parameters&)
527         {
528                 const float     queuePriority   = 1.0;
529
530                 const VkDeviceQueueCreateInfo   queues[]        =
531                 {
532                         {
533                                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
534                                 DE_NULL,
535                                 (VkDeviceQueueCreateFlags)0,
536                                 res.queueFamilyIndex,
537                                 1u,                                                                     // queueCount
538                                 &queuePriority,                                         // pQueuePriorities
539                         }
540                 };
541                 const VkDeviceCreateInfo                deviceInfo      =
542                 {
543                         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
544                         DE_NULL,
545                         (VkDeviceCreateFlags)0,
546                         DE_LENGTH_OF_ARRAY(queues),
547                         queues,
548                         0u,                                                                             // enabledLayerNameCount
549                         DE_NULL,                                                                // ppEnabledLayerNames
550                         0u,                                                                             // enabledExtensionNameCount
551                         DE_NULL,                                                                // ppEnabledExtensionNames
552                         DE_NULL,                                                                // pEnabledFeatures
553                 };
554
555                 return createDevice(res.vki, res.physicalDevice, &deviceInfo, env.allocationCallbacks);
556         }
557 };
558
559 struct DeviceMemory
560 {
561         typedef VkDeviceMemory Type;
562
563         struct Parameters
564         {
565                 VkDeviceSize    size;
566                 deUint32                memoryTypeIndex;
567
568                 Parameters (VkDeviceSize size_, deUint32 memoryTypeIndex_)
569                         : size                          (size_)
570                         , memoryTypeIndex       (memoryTypeIndex_)
571                 {
572                         DE_ASSERT(memoryTypeIndex < VK_MAX_MEMORY_TYPES);
573                 }
574         };
575
576         struct Resources
577         {
578                 Resources (const Environment&, const Parameters&) {}
579         };
580
581         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
582         {
583                 const VkDeviceSize      deviceMemoryUsage       = params.size + getPageTableSize(context, params.size);
584
585                 return getSafeObjectCount<DeviceMemory>(context,
586                                                                                                 params,
587                                                                                                 de::min(context.getDeviceProperties().limits.maxMemoryAllocationCount,
588                                                                                                                 (deUint32)DEFAULT_MAX_CONCURRENT_OBJECTS),
589                                                                                                 deviceMemoryUsage);
590         }
591
592         static Move<VkDeviceMemory> create (const Environment& env, const Resources&, const Parameters& params)
593         {
594                 const VkMemoryAllocateInfo      allocInfo       =
595                 {
596                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
597                         DE_NULL,
598                         params.size,
599                         params.memoryTypeIndex
600                 };
601
602                 return allocateMemory(env.vkd, env.device, &allocInfo, env.allocationCallbacks);
603         }
604 };
605
606 DeviceMemory::Parameters getDeviceMemoryParameters (const VkMemoryRequirements& memReqs)
607 {
608         return DeviceMemory::Parameters(memReqs.size, deCtz32(memReqs.memoryTypeBits));
609 }
610
611 DeviceMemory::Parameters getDeviceMemoryParameters (const Environment& env, VkImage image)
612 {
613         return getDeviceMemoryParameters(getImageMemoryRequirements(env.vkd, env.device, image));
614 }
615
616 DeviceMemory::Parameters getDeviceMemoryParameters (const Environment& env, VkBuffer image)
617 {
618         return getDeviceMemoryParameters(getBufferMemoryRequirements(env.vkd, env.device, image));
619 }
620
621 struct Buffer
622 {
623         typedef VkBuffer Type;
624
625         struct Parameters
626         {
627                 VkDeviceSize            size;
628                 VkBufferUsageFlags      usage;
629
630                 Parameters (VkDeviceSize                size_,
631                                         VkBufferUsageFlags      usage_)
632                         : size  (size_)
633                         , usage (usage_)
634                 {}
635         };
636
637         struct Resources
638         {
639                 Resources (const Environment&, const Parameters&) {}
640         };
641
642         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
643         {
644                 const Environment                       env             (context, 1u);
645                 const Resources                         res             (env, params);
646                 const Unique<VkBuffer>          buffer  (create(env, res, params));
647                 const VkMemoryRequirements      memReqs = getBufferMemoryRequirements(env.vkd, env.device, *buffer);
648
649                 return getSafeObjectCount<Buffer>(context,
650                                                                                   params,
651                                                                                   DEFAULT_MAX_CONCURRENT_OBJECTS,
652                                                                                   getPageTableSize(context, memReqs.size));
653         }
654
655         static Move<VkBuffer> create (const Environment& env, const Resources&, const Parameters& params)
656         {
657                 const VkBufferCreateInfo        bufferInfo      =
658                 {
659                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
660                         DE_NULL,
661                         (VkBufferCreateFlags)0,
662                         params.size,
663                         params.usage,
664                         VK_SHARING_MODE_EXCLUSIVE,
665                         1u,
666                         &env.queueFamilyIndex
667                 };
668
669                 return createBuffer(env.vkd, env.device, &bufferInfo, env.allocationCallbacks);
670         }
671 };
672
673 struct BufferView
674 {
675         typedef VkBufferView Type;
676
677         struct Parameters
678         {
679                 Buffer::Parameters      buffer;
680                 VkFormat                        format;
681                 VkDeviceSize            offset;
682                 VkDeviceSize            range;
683
684                 Parameters (const Buffer::Parameters&   buffer_,
685                                         VkFormat                                        format_,
686                                         VkDeviceSize                            offset_,
687                                         VkDeviceSize                            range_)
688                         : buffer        (buffer_)
689                         , format        (format_)
690                         , offset        (offset_)
691                         , range         (range_)
692                 {}
693         };
694
695         struct Resources
696         {
697                 Dependency<Buffer>                      buffer;
698                 Dependency<DeviceMemory>        memory;
699
700                 Resources (const Environment& env, const Parameters& params)
701                         : buffer(env, params.buffer)
702                         , memory(env, getDeviceMemoryParameters(env, *buffer.object))
703                 {
704                         VK_CHECK(env.vkd.bindBufferMemory(env.device, *buffer.object, *memory.object, 0));
705                 }
706         };
707
708         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
709         {
710                 return getSafeObjectCount<BufferView>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
711         }
712
713         static Move<VkBufferView> create (const Environment& env, const Resources& res, const Parameters& params)
714         {
715                 const VkBufferViewCreateInfo    bufferViewInfo  =
716                 {
717                         VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
718                         DE_NULL,
719                         (VkBufferViewCreateFlags)0,
720                         *res.buffer.object,
721                         params.format,
722                         params.offset,
723                         params.range
724                 };
725
726                 return createBufferView(env.vkd, env.device, &bufferViewInfo, env.allocationCallbacks);
727         }
728 };
729
730 struct Image
731 {
732         typedef VkImage Type;
733
734         struct Parameters
735         {
736                 VkImageCreateFlags              flags;
737                 VkImageType                             imageType;
738                 VkFormat                                format;
739                 VkExtent3D                              extent;
740                 deUint32                                mipLevels;
741                 deUint32                                arraySize;
742                 VkSampleCountFlagBits   samples;
743                 VkImageTiling                   tiling;
744                 VkImageUsageFlags               usage;
745                 VkImageLayout                   initialLayout;
746
747                 Parameters (VkImageCreateFlags          flags_,
748                                         VkImageType                             imageType_,
749                                         VkFormat                                format_,
750                                         VkExtent3D                              extent_,
751                                         deUint32                                mipLevels_,
752                                         deUint32                                arraySize_,
753                                         VkSampleCountFlagBits   samples_,
754                                         VkImageTiling                   tiling_,
755                                         VkImageUsageFlags               usage_,
756                                         VkImageLayout                   initialLayout_)
757                         : flags                 (flags_)
758                         , imageType             (imageType_)
759                         , format                (format_)
760                         , extent                (extent_)
761                         , mipLevels             (mipLevels_)
762                         , arraySize             (arraySize_)
763                         , samples               (samples_)
764                         , tiling                (tiling_)
765                         , usage                 (usage_)
766                         , initialLayout (initialLayout_)
767                 {}
768         };
769
770         struct Resources
771         {
772                 Resources (const Environment&, const Parameters&) {}
773         };
774
775         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
776         {
777                 const Environment                       env             (context, 1u);
778                 const Resources                         res             (env, params);
779                 const Unique<VkImage>           image   (create(env, res, params));
780                 const VkMemoryRequirements      memReqs = getImageMemoryRequirements(env.vkd, env.device, *image);
781
782                 return getSafeObjectCount<Image>(context,
783                                                                                  params,
784                                                                                  DEFAULT_MAX_CONCURRENT_OBJECTS,
785                                                                                  getPageTableSize(context, memReqs.size));
786         }
787
788         static Move<VkImage> create (const Environment& env, const Resources&, const Parameters& params)
789         {
790                 const VkImageCreateInfo         imageInfo       =
791                 {
792                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
793                         DE_NULL,
794                         params.flags,
795                         params.imageType,
796                         params.format,
797                         params.extent,
798                         params.mipLevels,
799                         params.arraySize,
800                         params.samples,
801                         params.tiling,
802                         params.usage,
803                         VK_SHARING_MODE_EXCLUSIVE,              // sharingMode
804                         1u,                                                             // queueFamilyIndexCount
805                         &env.queueFamilyIndex,                  // pQueueFamilyIndices
806                         params.initialLayout
807                 };
808
809                 return createImage(env.vkd, env.device, &imageInfo, env.allocationCallbacks);
810         }
811 };
812
813 struct ImageView
814 {
815         typedef VkImageView Type;
816
817         struct Parameters
818         {
819                 Image::Parameters               image;
820                 VkImageViewType                 viewType;
821                 VkFormat                                format;
822                 VkComponentMapping              components;
823                 VkImageSubresourceRange subresourceRange;
824
825                 Parameters (const Image::Parameters&    image_,
826                                         VkImageViewType                         viewType_,
827                                         VkFormat                                        format_,
828                                         VkComponentMapping                      components_,
829                                         VkImageSubresourceRange         subresourceRange_)
830                         : image                         (image_)
831                         , viewType                      (viewType_)
832                         , format                        (format_)
833                         , components            (components_)
834                         , subresourceRange      (subresourceRange_)
835                 {}
836         };
837
838         struct Resources
839         {
840                 Dependency<Image>                       image;
841                 Dependency<DeviceMemory>        memory;
842
843                 Resources (const Environment& env, const Parameters& params)
844                         : image (env, params.image)
845                         , memory(env, getDeviceMemoryParameters(env, *image.object))
846                 {
847                         VK_CHECK(env.vkd.bindImageMemory(env.device, *image.object, *memory.object, 0));
848                 }
849         };
850
851         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
852         {
853                 return getSafeObjectCount<ImageView>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
854         }
855
856         static Move<VkImageView> create (const Environment& env, const Resources& res, const Parameters& params)
857         {
858                 const VkImageViewCreateInfo     imageViewInfo   =
859                 {
860                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
861                         DE_NULL,
862                         (VkImageViewCreateFlags)0,
863                         *res.image.object,
864                         params.viewType,
865                         params.format,
866                         params.components,
867                         params.subresourceRange,
868                 };
869
870                 return createImageView(env.vkd, env.device, &imageViewInfo, env.allocationCallbacks);
871         }
872 };
873
874 struct Semaphore
875 {
876         typedef VkSemaphore Type;
877
878         struct Parameters
879         {
880                 VkSemaphoreCreateFlags  flags;
881
882                 Parameters (VkSemaphoreCreateFlags flags_)
883                         : flags(flags_)
884                 {}
885         };
886
887         struct Resources
888         {
889                 Resources (const Environment&, const Parameters&) {}
890         };
891
892         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
893         {
894                 return getSafeObjectCount<Semaphore>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES);
895         }
896
897         static Move<VkSemaphore> create (const Environment& env, const Resources&, const Parameters& params)
898         {
899                 const VkSemaphoreCreateInfo     semaphoreInfo   =
900                 {
901                         VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
902                         DE_NULL,
903                         params.flags
904                 };
905
906                 return createSemaphore(env.vkd, env.device, &semaphoreInfo, env.allocationCallbacks);
907         }
908 };
909
910 struct Fence
911 {
912         typedef VkFence Type;
913
914         struct Parameters
915         {
916                 VkFenceCreateFlags      flags;
917
918                 Parameters (VkFenceCreateFlags flags_)
919                         : flags(flags_)
920                 {}
921         };
922
923         struct Resources
924         {
925                 Resources (const Environment&, const Parameters&) {}
926         };
927
928         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
929         {
930                 return getSafeObjectCount<Fence>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES);
931         }
932
933         static Move<VkFence> create (const Environment& env, const Resources&, const Parameters& params)
934         {
935                 const VkFenceCreateInfo fenceInfo       =
936                 {
937                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
938                         DE_NULL,
939                         params.flags
940                 };
941
942                 return createFence(env.vkd, env.device, &fenceInfo, env.allocationCallbacks);
943         }
944 };
945
946 struct Event
947 {
948         typedef VkEvent Type;
949
950         struct Parameters
951         {
952                 VkEventCreateFlags      flags;
953
954                 Parameters (VkEventCreateFlags flags_)
955                         : flags(flags_)
956                 {}
957         };
958
959         struct Resources
960         {
961                 Resources (const Environment&, const Parameters&) {}
962         };
963
964         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
965         {
966                 return getSafeObjectCount<Event>(context, params, MAX_CONCURRENT_SYNC_PRIMITIVES);
967         }
968
969         static Move<VkEvent> create (const Environment& env, const Resources&, const Parameters& params)
970         {
971                 const VkEventCreateInfo eventInfo       =
972                 {
973                         VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
974                         DE_NULL,
975                         params.flags
976                 };
977
978                 return createEvent(env.vkd, env.device, &eventInfo, env.allocationCallbacks);
979         }
980 };
981
982 struct QueryPool
983 {
984         typedef VkQueryPool Type;
985
986         struct Parameters
987         {
988                 VkQueryType                                             queryType;
989                 deUint32                                                entryCount;
990                 VkQueryPipelineStatisticFlags   pipelineStatistics;
991
992                 Parameters (VkQueryType                                         queryType_,
993                                         deUint32                                                entryCount_,
994                                         VkQueryPipelineStatisticFlags   pipelineStatistics_)
995                         : queryType                             (queryType_)
996                         , entryCount                    (entryCount_)
997                         , pipelineStatistics    (pipelineStatistics_)
998                 {}
999         };
1000
1001         struct Resources
1002         {
1003                 Resources (const Environment&, const Parameters&) {}
1004         };
1005
1006         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1007         {
1008                 return getSafeObjectCount<QueryPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1009         }
1010
1011         static Move<VkQueryPool> create (const Environment& env, const Resources&, const Parameters& params)
1012         {
1013                 const VkQueryPoolCreateInfo     queryPoolInfo   =
1014                 {
1015                         VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
1016                         DE_NULL,
1017                         (VkQueryPoolCreateFlags)0,
1018                         params.queryType,
1019                         params.entryCount,
1020                         params.pipelineStatistics
1021                 };
1022
1023                 return createQueryPool(env.vkd, env.device, &queryPoolInfo, env.allocationCallbacks);
1024         }
1025 };
1026
1027 struct ShaderModule
1028 {
1029         typedef VkShaderModule Type;
1030
1031         struct Parameters
1032         {
1033                 VkShaderStageFlagBits   shaderStage;
1034                 string                                  binaryName;
1035
1036                 Parameters (VkShaderStageFlagBits       shaderStage_,
1037                                         const std::string&              binaryName_)
1038                         : shaderStage   (shaderStage_)
1039                         , binaryName    (binaryName_)
1040                 {}
1041         };
1042
1043         struct Resources
1044         {
1045                 const ProgramBinary&    binary;
1046
1047                 Resources (const Environment& env, const Parameters& params)
1048                         : binary(env.programBinaries.get(params.binaryName))
1049                 {}
1050         };
1051
1052         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1053         {
1054                 return getSafeObjectCount<ShaderModule>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1055         }
1056
1057         static const char* getSource (VkShaderStageFlagBits stage)
1058         {
1059                 switch (stage)
1060                 {
1061                         case VK_SHADER_STAGE_VERTEX_BIT:
1062                                 return "#version 310 es\n"
1063                                            "layout(location = 0) in highp vec4 a_position;\n"
1064                                            "void main () { gl_Position = a_position; }\n";
1065
1066                         case VK_SHADER_STAGE_FRAGMENT_BIT:
1067                                 return "#version 310 es\n"
1068                                            "layout(location = 0) out mediump vec4 o_color;\n"
1069                                            "void main () { o_color = vec4(1.0, 0.5, 0.25, 1.0); }";
1070
1071                         case VK_SHADER_STAGE_COMPUTE_BIT:
1072                                 return "#version 310 es\n"
1073                                            "layout(binding = 0) buffer Input { highp uint dataIn[]; };\n"
1074                                            "layout(binding = 1) buffer Output { highp uint dataOut[]; };\n"
1075                                            "void main (void)\n"
1076                                            "{\n"
1077                                            "    dataOut[gl_GlobalInvocationID.x] = ~dataIn[gl_GlobalInvocationID.x];\n"
1078                                            "}\n";
1079
1080                         default:
1081                                 DE_FATAL("Not implemented");
1082                                 return DE_NULL;
1083                 }
1084         }
1085
1086         static void initPrograms (SourceCollections& dst, Parameters params)
1087         {
1088                 const char* const       source  = getSource(params.shaderStage);
1089
1090                 DE_ASSERT(source);
1091
1092                 dst.glslSources.add(params.binaryName)
1093                         << glu::ShaderSource(getGluShaderType(params.shaderStage), source);
1094         }
1095
1096         static Move<VkShaderModule> create (const Environment& env, const Resources& res, const Parameters&)
1097         {
1098                 const VkShaderModuleCreateInfo  shaderModuleInfo        =
1099                 {
1100                         VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
1101                         DE_NULL,
1102                         (VkShaderModuleCreateFlags)0,
1103                         res.binary.getSize(),
1104                         (const deUint32*)res.binary.getBinary(),
1105                 };
1106
1107                 return createShaderModule(env.vkd, env.device, &shaderModuleInfo, env.allocationCallbacks);
1108         }
1109 };
1110
1111 struct PipelineCache
1112 {
1113         typedef VkPipelineCache Type;
1114
1115         struct Parameters
1116         {
1117                 Parameters (void) {}
1118         };
1119
1120         struct Resources
1121         {
1122                 Resources (const Environment&, const Parameters&) {}
1123         };
1124
1125         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1126         {
1127                 return getSafeObjectCount<PipelineCache>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1128         }
1129
1130         static Move<VkPipelineCache> create (const Environment& env, const Resources&, const Parameters&)
1131         {
1132                 const VkPipelineCacheCreateInfo pipelineCacheInfo       =
1133                 {
1134                         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
1135                         DE_NULL,
1136                         (VkPipelineCacheCreateFlags)0u,
1137                         0u,                                                             // initialDataSize
1138                         DE_NULL,                                                // pInitialData
1139                 };
1140
1141                 return createPipelineCache(env.vkd, env.device, &pipelineCacheInfo, env.allocationCallbacks);
1142         }
1143 };
1144
1145 struct Sampler
1146 {
1147         typedef VkSampler Type;
1148
1149         struct Parameters
1150         {
1151                 VkFilter                                magFilter;
1152                 VkFilter                                minFilter;
1153                 VkSamplerMipmapMode             mipmapMode;
1154                 VkSamplerAddressMode    addressModeU;
1155                 VkSamplerAddressMode    addressModeV;
1156                 VkSamplerAddressMode    addressModeW;
1157                 float                                   mipLodBias;
1158                 VkBool32                                anisotropyEnable;
1159                 float                                   maxAnisotropy;
1160                 VkBool32                                compareEnable;
1161                 VkCompareOp                             compareOp;
1162                 float                                   minLod;
1163                 float                                   maxLod;
1164                 VkBorderColor                   borderColor;
1165                 VkBool32                                unnormalizedCoordinates;
1166
1167                 // \todo [2015-09-17 pyry] Other configurations
1168                 Parameters (void)
1169                         : magFilter                                     (VK_FILTER_NEAREST)
1170                         , minFilter                                     (VK_FILTER_NEAREST)
1171                         , mipmapMode                            (VK_SAMPLER_MIPMAP_MODE_NEAREST)
1172                         , addressModeU                          (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1173                         , addressModeV                          (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1174                         , addressModeW                          (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1175                         , mipLodBias                            (0.0f)
1176                         , anisotropyEnable                      (VK_FALSE)
1177                         , maxAnisotropy                         (1.0f)
1178                         , compareEnable                         (VK_FALSE)
1179                         , compareOp                                     (VK_COMPARE_OP_ALWAYS)
1180                         , minLod                                        (-1000.f)
1181                         , maxLod                                        (+1000.f)
1182                         , borderColor                           (VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK)
1183                         , unnormalizedCoordinates       (VK_FALSE)
1184                 {}
1185         };
1186
1187         struct Resources
1188         {
1189                 Resources (const Environment&, const Parameters&) {}
1190         };
1191
1192         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1193         {
1194                 return getSafeObjectCount<Sampler>(context,
1195                                                                                    params,
1196                                                                                    de::min(context.getDeviceProperties().limits.maxSamplerAllocationCount,
1197                                                                                                    (deUint32)DEFAULT_MAX_CONCURRENT_OBJECTS));
1198         }
1199
1200         static Move<VkSampler> create (const Environment& env, const Resources&, const Parameters& params)
1201         {
1202                 const VkSamplerCreateInfo       samplerInfo     =
1203                 {
1204                         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1205                         DE_NULL,
1206                         (VkSamplerCreateFlags)0,
1207                         params.magFilter,
1208                         params.minFilter,
1209                         params.mipmapMode,
1210                         params.addressModeU,
1211                         params.addressModeV,
1212                         params.addressModeW,
1213                         params.mipLodBias,
1214                         params.anisotropyEnable,
1215                         params.maxAnisotropy,
1216                         params.compareEnable,
1217                         params.compareOp,
1218                         params.minLod,
1219                         params.maxLod,
1220                         params.borderColor,
1221                         params.unnormalizedCoordinates
1222                 };
1223
1224                 return createSampler(env.vkd, env.device, &samplerInfo, env.allocationCallbacks);
1225         }
1226 };
1227
1228 struct DescriptorSetLayout
1229 {
1230         typedef VkDescriptorSetLayout Type;
1231
1232         struct Parameters
1233         {
1234                 struct Binding
1235                 {
1236                         deUint32                        binding;
1237                         VkDescriptorType        descriptorType;
1238                         deUint32                        descriptorCount;
1239                         VkShaderStageFlags      stageFlags;
1240                         bool                            useImmutableSampler;
1241
1242                         Binding (deUint32                       binding_,
1243                                          VkDescriptorType       descriptorType_,
1244                                          deUint32                       descriptorCount_,
1245                                          VkShaderStageFlags     stageFlags_,
1246                                          bool                           useImmutableSampler_)
1247                                 : binding                               (binding_)
1248                                 , descriptorType                (descriptorType_)
1249                                 , descriptorCount               (descriptorCount_)
1250                                 , stageFlags                    (stageFlags_)
1251                                 , useImmutableSampler   (useImmutableSampler_)
1252                         {}
1253
1254                         Binding (void) {}
1255                 };
1256
1257                 vector<Binding> bindings;
1258
1259                 Parameters (const vector<Binding>& bindings_)
1260                         : bindings(bindings_)
1261                 {}
1262
1263                 static Parameters empty (void)
1264                 {
1265                         return Parameters(vector<Binding>());
1266                 }
1267
1268                 static Parameters single (deUint32                              binding,
1269                                                                   VkDescriptorType              descriptorType,
1270                                                                   deUint32                              descriptorCount,
1271                                                                   VkShaderStageFlags    stageFlags,
1272                                                                   bool                                  useImmutableSampler = false)
1273                 {
1274                         vector<Binding> bindings;
1275                         bindings.push_back(Binding(binding, descriptorType, descriptorCount, stageFlags, useImmutableSampler));
1276                         return Parameters(bindings);
1277                 }
1278         };
1279
1280         struct Resources
1281         {
1282                 vector<VkDescriptorSetLayoutBinding>    bindings;
1283                 MovePtr<Dependency<Sampler> >                   immutableSampler;
1284                 vector<VkSampler>                                               immutableSamplersPtr;
1285
1286                 Resources (const Environment& env, const Parameters& params)
1287                 {
1288                         // Create immutable sampler if needed
1289                         for (vector<Parameters::Binding>::const_iterator cur = params.bindings.begin(); cur != params.bindings.end(); cur++)
1290                         {
1291                                 if (cur->useImmutableSampler && !immutableSampler)
1292                                 {
1293                                         immutableSampler = de::newMovePtr<Dependency<Sampler> >(env, Sampler::Parameters());
1294
1295                                         if (cur->useImmutableSampler && immutableSamplersPtr.size() < (size_t)cur->descriptorCount)
1296                                                 immutableSamplersPtr.resize(cur->descriptorCount, *immutableSampler->object);
1297                                 }
1298                         }
1299
1300                         for (vector<Parameters::Binding>::const_iterator cur = params.bindings.begin(); cur != params.bindings.end(); cur++)
1301                         {
1302                                 const VkDescriptorSetLayoutBinding      binding =
1303                                 {
1304                                         cur->binding,
1305                                         cur->descriptorType,
1306                                         cur->descriptorCount,
1307                                         cur->stageFlags,
1308                                         (cur->useImmutableSampler ? &immutableSamplersPtr[0] : DE_NULL)
1309                                 };
1310
1311                                 bindings.push_back(binding);
1312                         }
1313                 }
1314         };
1315
1316         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1317         {
1318                 return getSafeObjectCount<DescriptorSetLayout>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1319         }
1320
1321         static Move<VkDescriptorSetLayout> create (const Environment& env, const Resources& res, const Parameters&)
1322         {
1323                 const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutInfo =
1324                 {
1325                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1326                         DE_NULL,
1327                         (VkDescriptorSetLayoutCreateFlags)0,
1328                         (deUint32)res.bindings.size(),
1329                         (res.bindings.empty() ? DE_NULL : &res.bindings[0])
1330                 };
1331
1332                 return createDescriptorSetLayout(env.vkd, env.device, &descriptorSetLayoutInfo, env.allocationCallbacks);
1333         }
1334 };
1335
1336 struct PipelineLayout
1337 {
1338         typedef VkPipelineLayout Type;
1339
1340         struct Parameters
1341         {
1342                 vector<DescriptorSetLayout::Parameters> descriptorSetLayouts;
1343                 vector<VkPushConstantRange>                             pushConstantRanges;
1344
1345                 Parameters (void) {}
1346
1347                 static Parameters empty (void)
1348                 {
1349                         return Parameters();
1350                 }
1351
1352                 static Parameters singleDescriptorSet (const DescriptorSetLayout::Parameters& descriptorSetLayout)
1353                 {
1354                         Parameters params;
1355                         params.descriptorSetLayouts.push_back(descriptorSetLayout);
1356                         return params;
1357                 }
1358         };
1359
1360         struct Resources
1361         {
1362                 typedef SharedPtr<Dependency<DescriptorSetLayout> >     DescriptorSetLayoutDepSp;
1363                 typedef vector<DescriptorSetLayoutDepSp>                        DescriptorSetLayouts;
1364
1365                 DescriptorSetLayouts                    descriptorSetLayouts;
1366                 vector<VkDescriptorSetLayout>   pSetLayouts;
1367
1368                 Resources (const Environment& env, const Parameters& params)
1369                 {
1370                         for (vector<DescriptorSetLayout::Parameters>::const_iterator dsParams = params.descriptorSetLayouts.begin();
1371                                  dsParams != params.descriptorSetLayouts.end();
1372                                  ++dsParams)
1373                         {
1374                                 descriptorSetLayouts.push_back(DescriptorSetLayoutDepSp(new Dependency<DescriptorSetLayout>(env, *dsParams)));
1375                                 pSetLayouts.push_back(*descriptorSetLayouts.back()->object);
1376                         }
1377                 }
1378         };
1379
1380         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1381         {
1382                 return getSafeObjectCount<PipelineLayout>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1383         }
1384
1385         static Move<VkPipelineLayout> create (const Environment& env, const Resources& res, const Parameters& params)
1386         {
1387                 const VkPipelineLayoutCreateInfo        pipelineLayoutInfo      =
1388                 {
1389                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1390                         DE_NULL,
1391                         (VkPipelineLayoutCreateFlags)0,
1392                         (deUint32)res.pSetLayouts.size(),
1393                         (res.pSetLayouts.empty() ? DE_NULL : &res.pSetLayouts[0]),
1394                         (deUint32)params.pushConstantRanges.size(),
1395                         (params.pushConstantRanges.empty() ? DE_NULL : &params.pushConstantRanges[0]),
1396                 };
1397
1398                 return createPipelineLayout(env.vkd, env.device, &pipelineLayoutInfo, env.allocationCallbacks);
1399         }
1400 };
1401
1402 struct RenderPass
1403 {
1404         typedef VkRenderPass Type;
1405
1406         // \todo [2015-09-17 pyry] More interesting configurations
1407         struct Parameters
1408         {
1409                 Parameters (void) {}
1410         };
1411
1412         struct Resources
1413         {
1414                 Resources (const Environment&, const Parameters&) {}
1415         };
1416
1417         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1418         {
1419                 return getSafeObjectCount<RenderPass>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1420         }
1421
1422         static Move<VkRenderPass> create (const Environment& env, const Resources&, const Parameters&)
1423         {
1424                 const VkAttachmentDescription   attachments[]           =
1425                 {
1426                         {
1427                                 (VkAttachmentDescriptionFlags)0,
1428                                 VK_FORMAT_R8G8B8A8_UNORM,
1429                                 VK_SAMPLE_COUNT_1_BIT,
1430                                 VK_ATTACHMENT_LOAD_OP_CLEAR,
1431                                 VK_ATTACHMENT_STORE_OP_STORE,
1432                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1433                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1434                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1435                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1436                         },
1437                         {
1438                                 (VkAttachmentDescriptionFlags)0,
1439                                 VK_FORMAT_D16_UNORM,
1440                                 VK_SAMPLE_COUNT_1_BIT,
1441                                 VK_ATTACHMENT_LOAD_OP_CLEAR,
1442                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1443                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1444                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1445                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1446                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1447                         }
1448                 };
1449                 const VkAttachmentReference             colorAttachments[]      =
1450                 {
1451                         {
1452                                 0u,                                                                                     // attachment
1453                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1454                         }
1455                 };
1456                 const VkAttachmentReference             dsAttachment            =
1457                 {
1458                         1u,                                                                                     // attachment
1459                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
1460                 };
1461                 const VkSubpassDescription              subpasses[]                     =
1462                 {
1463                         {
1464                                 (VkSubpassDescriptionFlags)0,
1465                                 VK_PIPELINE_BIND_POINT_GRAPHICS,
1466                                 0u,                                                                                     // inputAttachmentCount
1467                                 DE_NULL,                                                                        // pInputAttachments
1468                                 DE_LENGTH_OF_ARRAY(colorAttachments),
1469                                 colorAttachments,
1470                                 DE_NULL,                                                                        // pResolveAttachments
1471                                 &dsAttachment,
1472                                 0u,                                                                                     // preserveAttachmentCount
1473                                 DE_NULL,                                                                        // pPreserveAttachments
1474                         }
1475                 };
1476                 const VkRenderPassCreateInfo    renderPassInfo          =
1477                 {
1478                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1479                         DE_NULL,
1480                         (VkRenderPassCreateFlags)0,
1481                         DE_LENGTH_OF_ARRAY(attachments),
1482                         attachments,
1483                         DE_LENGTH_OF_ARRAY(subpasses),
1484                         subpasses,
1485                         0u,                                                                                             // dependencyCount
1486                         DE_NULL                                                                                 // pDependencies
1487                 };
1488
1489                 return createRenderPass(env.vkd, env.device, &renderPassInfo, env.allocationCallbacks);
1490         }
1491 };
1492
1493 struct GraphicsPipeline
1494 {
1495         typedef VkPipeline Type;
1496
1497         // \todo [2015-09-17 pyry] More interesting configurations
1498         struct Parameters
1499         {
1500                 Parameters (void) {}
1501         };
1502
1503         struct Resources
1504         {
1505                 Dependency<ShaderModule>        vertexShader;
1506                 Dependency<ShaderModule>        fragmentShader;
1507                 Dependency<PipelineLayout>      layout;
1508                 Dependency<RenderPass>          renderPass;
1509                 Dependency<PipelineCache>       pipelineCache;
1510
1511                 Resources (const Environment& env, const Parameters&)
1512                         : vertexShader          (env, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert"))
1513                         , fragmentShader        (env, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag"))
1514                         , layout                        (env, PipelineLayout::Parameters::singleDescriptorSet(
1515                                                                                 DescriptorSetLayout::Parameters::single(0u, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u, VK_SHADER_STAGE_FRAGMENT_BIT, true)))
1516                         , renderPass            (env, RenderPass::Parameters())
1517                         , pipelineCache         (env, PipelineCache::Parameters())
1518                 {}
1519         };
1520
1521         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1522         {
1523                 return getSafeObjectCount<GraphicsPipeline>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1524         }
1525
1526         static void initPrograms (SourceCollections& dst, Parameters)
1527         {
1528                 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert"));
1529                 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag"));
1530         }
1531
1532         static Move<VkPipeline> create (const Environment& env, const Resources& res, const Parameters&)
1533         {
1534                 const VkPipelineShaderStageCreateInfo                   stages[]                        =
1535                 {
1536                         {
1537                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1538                                 DE_NULL,
1539                                 (VkPipelineShaderStageCreateFlags)0,
1540                                 VK_SHADER_STAGE_VERTEX_BIT,
1541                                 *res.vertexShader.object,
1542                                 "main",
1543                                 DE_NULL,                                                        // pSpecializationInfo
1544                         },
1545                         {
1546                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1547                                 DE_NULL,
1548                                 (VkPipelineShaderStageCreateFlags)0,
1549                                 VK_SHADER_STAGE_FRAGMENT_BIT,
1550                                 *res.fragmentShader.object,
1551                                 "main",
1552                                 DE_NULL,                                                        // pSpecializationInfo
1553                         }
1554                 };
1555                 const VkVertexInputBindingDescription                   vertexBindings[]        =
1556                 {
1557                         {
1558                                 0u,                                                                     // binding
1559                                 16u,                                                            // stride
1560                                 VK_VERTEX_INPUT_RATE_VERTEX
1561                         }
1562                 };
1563                 const VkVertexInputAttributeDescription                 vertexAttribs[]         =
1564                 {
1565                         {
1566                                 0u,                                                                     // location
1567                                 0u,                                                                     // binding
1568                                 VK_FORMAT_R32G32B32A32_SFLOAT,
1569                                 0u,                                                                     // offset
1570                         }
1571                 };
1572                 const VkPipelineVertexInputStateCreateInfo              vertexInputState        =
1573                 {
1574                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1575                         DE_NULL,
1576                         (VkPipelineVertexInputStateCreateFlags)0,
1577                         DE_LENGTH_OF_ARRAY(vertexBindings),
1578                         vertexBindings,
1579                         DE_LENGTH_OF_ARRAY(vertexAttribs),
1580                         vertexAttribs
1581                 };
1582                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyState      =
1583                 {
1584                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1585                         DE_NULL,
1586                         (VkPipelineInputAssemblyStateCreateFlags)0,
1587                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1588                         VK_FALSE                                                                // primitiveRestartEnable
1589                 };
1590                 const VkViewport                                                                viewports[]                     =
1591                 {
1592                         { 0.0f, 0.0f, 64.f, 64.f, 0.0f, 1.0f }
1593                 };
1594                 const VkRect2D                                                                  scissors[]                      =
1595                 {
1596                         { { 0, 0 }, { 64, 64 } }
1597                 };
1598                 const VkPipelineViewportStateCreateInfo                 viewportState           =
1599                 {
1600                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1601                         DE_NULL,
1602                         (VkPipelineViewportStateCreateFlags)0,
1603                         DE_LENGTH_OF_ARRAY(viewports),
1604                         viewports,
1605                         DE_LENGTH_OF_ARRAY(scissors),
1606                         scissors,
1607                 };
1608                 const VkPipelineRasterizationStateCreateInfo    rasterState                     =
1609                 {
1610                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1611                         DE_NULL,
1612                         (VkPipelineRasterizationStateCreateFlags)0,
1613                         VK_TRUE,                                                                // depthClampEnable
1614                         VK_FALSE,                                                               // rasterizerDiscardEnable
1615                         VK_POLYGON_MODE_FILL,
1616                         VK_CULL_MODE_BACK_BIT,
1617                         VK_FRONT_FACE_COUNTER_CLOCKWISE,
1618                         VK_FALSE,                                                               // depthBiasEnable
1619                         0.0f,                                                                   // depthBiasConstantFactor
1620                         0.0f,                                                                   // depthBiasClamp
1621                         0.0f,                                                                   // depthBiasSlopeFactor
1622                         1.0f,                                                                   // lineWidth
1623                 };
1624                 const VkPipelineMultisampleStateCreateInfo              multisampleState        =
1625                 {
1626                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1627                         DE_NULL,
1628                         (VkPipelineMultisampleStateCreateFlags)0,
1629                         VK_SAMPLE_COUNT_1_BIT,
1630                         VK_FALSE,                                                               // sampleShadingEnable
1631                         1.0f,                                                                   // minSampleShading
1632                         DE_NULL,                                                                // pSampleMask
1633                         VK_FALSE,                                                               // alphaToCoverageEnable
1634                         VK_FALSE,                                                               // alphaToOneEnable
1635                 };
1636                 const VkPipelineDepthStencilStateCreateInfo             depthStencilState       =
1637                 {
1638                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1639                         DE_NULL,
1640                         (VkPipelineDepthStencilStateCreateFlags)0,
1641                         VK_TRUE,                                                                // depthTestEnable
1642                         VK_TRUE,                                                                // depthWriteEnable
1643                         VK_COMPARE_OP_LESS,                                             // depthCompareOp
1644                         VK_FALSE,                                                               // depthBoundsTestEnable
1645                         VK_FALSE,                                                               // stencilTestEnable
1646                         { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u },
1647                         { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u },
1648                         -1.0f,                                                                  // minDepthBounds
1649                         +1.0f,                                                                  // maxDepthBounds
1650                 };
1651                 const VkPipelineColorBlendAttachmentState               colorBlendAttState[]=
1652                 {
1653                         {
1654                                 VK_FALSE,                                                       // blendEnable
1655                                 VK_BLEND_FACTOR_ONE,
1656                                 VK_BLEND_FACTOR_ZERO,
1657                                 VK_BLEND_OP_ADD,
1658                                 VK_BLEND_FACTOR_ONE,
1659                                 VK_BLEND_FACTOR_ZERO,
1660                                 VK_BLEND_OP_ADD,
1661                                 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
1662                         }
1663                 };
1664                 const VkPipelineColorBlendStateCreateInfo               colorBlendState         =
1665                 {
1666                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1667                         DE_NULL,
1668                         (VkPipelineColorBlendStateCreateFlags)0,
1669                         VK_FALSE,                                                               // logicOpEnable
1670                         VK_LOGIC_OP_COPY,
1671                         DE_LENGTH_OF_ARRAY(colorBlendAttState),
1672                         colorBlendAttState,
1673                         { 0.0f, 0.0f, 0.0f, 0.0f }                              // blendConstants
1674                 };
1675                 const VkGraphicsPipelineCreateInfo                              pipelineInfo            =
1676                 {
1677                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1678                         DE_NULL,
1679                         (VkPipelineCreateFlags)0,
1680                         DE_LENGTH_OF_ARRAY(stages),
1681                         stages,
1682                         &vertexInputState,
1683                         &inputAssemblyState,
1684                         DE_NULL,                                                                // pTessellationState
1685                         &viewportState,
1686                         &rasterState,
1687                         &multisampleState,
1688                         &depthStencilState,
1689                         &colorBlendState,
1690                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,
1691                         *res.layout.object,
1692                         *res.renderPass.object,
1693                         0u,                                                                             // subpass
1694                         (VkPipeline)0,                                                  // basePipelineHandle
1695                         0,                                                                              // basePipelineIndex
1696                 };
1697
1698                 return createGraphicsPipeline(env.vkd, env.device, *res.pipelineCache.object, &pipelineInfo, env.allocationCallbacks);
1699         }
1700 };
1701
1702 struct ComputePipeline
1703 {
1704         typedef VkPipeline Type;
1705
1706         // \todo [2015-09-17 pyry] More interesting configurations
1707         struct Parameters
1708         {
1709                 Parameters (void) {}
1710         };
1711
1712         struct Resources
1713         {
1714                 Dependency<ShaderModule>        shaderModule;
1715                 Dependency<PipelineLayout>      layout;
1716                 Dependency<PipelineCache>       pipelineCache;
1717
1718                 static DescriptorSetLayout::Parameters getDescriptorSetLayout (void)
1719                 {
1720                         typedef DescriptorSetLayout::Parameters::Binding Binding;
1721
1722                         vector<Binding> bindings;
1723
1724                         bindings.push_back(Binding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false));
1725                         bindings.push_back(Binding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false));
1726
1727                         return DescriptorSetLayout::Parameters(bindings);
1728                 }
1729
1730                 Resources (const Environment& env, const Parameters&)
1731                         : shaderModule          (env, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"))
1732                         , layout                        (env, PipelineLayout::Parameters::singleDescriptorSet(getDescriptorSetLayout()))
1733                         , pipelineCache         (env, PipelineCache::Parameters())
1734                 {}
1735         };
1736
1737         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1738         {
1739                 return getSafeObjectCount<ComputePipeline>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1740         }
1741
1742         static void initPrograms (SourceCollections& dst, Parameters)
1743         {
1744                 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"));
1745         }
1746
1747         static Move<VkPipeline> create (const Environment& env, const Resources& res, const Parameters&)
1748         {
1749                 const VkComputePipelineCreateInfo       pipelineInfo    =
1750                 {
1751                         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1752                         DE_NULL,
1753                         (VkPipelineCreateFlags)0,
1754                         {
1755                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1756                                 DE_NULL,
1757                                 (VkPipelineShaderStageCreateFlags)0,
1758                                 VK_SHADER_STAGE_COMPUTE_BIT,
1759                                 *res.shaderModule.object,
1760                                 "main",
1761                                 DE_NULL                                 // pSpecializationInfo
1762                         },
1763                         *res.layout.object,
1764                         (VkPipeline)0,                          // basePipelineHandle
1765                         0u,                                                     // basePipelineIndex
1766                 };
1767
1768                 return createComputePipeline(env.vkd, env.device, *res.pipelineCache.object, &pipelineInfo, env.allocationCallbacks);
1769         }
1770 };
1771
1772 struct DescriptorPool
1773 {
1774         typedef VkDescriptorPool Type;
1775
1776         struct Parameters
1777         {
1778                 VkDescriptorPoolCreateFlags             flags;
1779                 deUint32                                                maxSets;
1780                 vector<VkDescriptorPoolSize>    poolSizes;
1781
1782                 Parameters (VkDescriptorPoolCreateFlags                         flags_,
1783                                         deUint32                                                                maxSets_,
1784                                         const vector<VkDescriptorPoolSize>&             poolSizes_)
1785                         : flags         (flags_)
1786                         , maxSets       (maxSets_)
1787                         , poolSizes     (poolSizes_)
1788                 {}
1789
1790                 static Parameters singleType (VkDescriptorPoolCreateFlags       flags,
1791                                                                           deUint32                                              maxSets,
1792                                                                           VkDescriptorType                              type,
1793                                                                           deUint32                                              count)
1794                 {
1795                         vector<VkDescriptorPoolSize> poolSizes;
1796                         poolSizes.push_back(makeDescriptorPoolSize(type, count));
1797                         return Parameters(flags, maxSets, poolSizes);
1798                 }
1799         };
1800
1801         struct Resources
1802         {
1803                 Resources (const Environment&, const Parameters&) {}
1804         };
1805
1806         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1807         {
1808                 return getSafeObjectCount<DescriptorPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1809         }
1810
1811         static Move<VkDescriptorPool> create (const Environment& env, const Resources&, const Parameters& params)
1812         {
1813                 const VkDescriptorPoolCreateInfo        descriptorPoolInfo      =
1814                 {
1815                         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1816                         DE_NULL,
1817                         params.flags,
1818                         params.maxSets,
1819                         (deUint32)params.poolSizes.size(),
1820                         (params.poolSizes.empty() ? DE_NULL : &params.poolSizes[0])
1821                 };
1822
1823                 return createDescriptorPool(env.vkd, env.device, &descriptorPoolInfo, env.allocationCallbacks);
1824         }
1825 };
1826
1827 struct DescriptorSet
1828 {
1829         typedef VkDescriptorSet Type;
1830
1831         struct Parameters
1832         {
1833                 DescriptorSetLayout::Parameters descriptorSetLayout;
1834
1835                 Parameters (const DescriptorSetLayout::Parameters& descriptorSetLayout_)
1836                         : descriptorSetLayout(descriptorSetLayout_)
1837                 {}
1838         };
1839
1840         struct Resources
1841         {
1842                 Dependency<DescriptorPool>              descriptorPool;
1843                 Dependency<DescriptorSetLayout> descriptorSetLayout;
1844
1845                 static vector<VkDescriptorPoolSize> computePoolSizes (const DescriptorSetLayout::Parameters& layout, int maxSets)
1846                 {
1847                         deUint32                                                countByType[VK_DESCRIPTOR_TYPE_LAST];
1848                         vector<VkDescriptorPoolSize>    typeCounts;
1849
1850                         std::fill(DE_ARRAY_BEGIN(countByType), DE_ARRAY_END(countByType), 0u);
1851
1852                         for (vector<DescriptorSetLayout::Parameters::Binding>::const_iterator cur = layout.bindings.begin();
1853                                  cur != layout.bindings.end();
1854                                  ++cur)
1855                         {
1856                                 DE_ASSERT((deUint32)cur->descriptorType < VK_DESCRIPTOR_TYPE_LAST);
1857                                 countByType[cur->descriptorType] += cur->descriptorCount * maxSets;
1858                         }
1859
1860                         for (deUint32 type = 0; type < VK_DESCRIPTOR_TYPE_LAST; ++type)
1861                         {
1862                                 if (countByType[type] > 0)
1863                                         typeCounts.push_back(makeDescriptorPoolSize((VkDescriptorType)type, countByType[type]));
1864                         }
1865
1866                         return typeCounts;
1867                 }
1868
1869                 Resources (const Environment& env, const Parameters& params)
1870                         : descriptorPool                (env, DescriptorPool::Parameters(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, env.maxResourceConsumers, computePoolSizes(params.descriptorSetLayout, env.maxResourceConsumers)))
1871                         , descriptorSetLayout   (env, params.descriptorSetLayout)
1872                 {
1873                 }
1874         };
1875
1876         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1877         {
1878                 return getSafeObjectCount<DescriptorSet>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1879         }
1880
1881         static Move<VkDescriptorSet> create (const Environment& env, const Resources& res, const Parameters&)
1882         {
1883                 const VkDescriptorSetAllocateInfo       allocateInfo    =
1884                 {
1885                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1886                         DE_NULL,
1887                         *res.descriptorPool.object,
1888                         1u,
1889                         &res.descriptorSetLayout.object.get(),
1890                 };
1891
1892                 return allocateDescriptorSet(env.vkd, env.device, &allocateInfo);
1893         }
1894 };
1895
1896 struct Framebuffer
1897 {
1898         typedef VkFramebuffer Type;
1899
1900         struct Parameters
1901         {
1902                 Parameters (void)
1903                 {}
1904         };
1905
1906         struct Resources
1907         {
1908                 Dependency<ImageView>   colorAttachment;
1909                 Dependency<ImageView>   depthStencilAttachment;
1910                 Dependency<RenderPass>  renderPass;
1911
1912                 Resources (const Environment& env, const Parameters&)
1913                         : colorAttachment                       (env, ImageView::Parameters(Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
1914                                                                                                                                                                           makeExtent3D(256, 256, 1),
1915                                                                                                                                                                           1u, 1u,
1916                                                                                                                                                                           VK_SAMPLE_COUNT_1_BIT,
1917                                                                                                                                                                           VK_IMAGE_TILING_OPTIMAL,
1918                                                                                                                                                                           VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1919                                                                                                                                                                           VK_IMAGE_LAYOUT_UNDEFINED),
1920                                                                                                                                                  VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
1921                                                                                                                                                  makeComponentMappingRGBA(),
1922                                                                                                                                                  makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)))
1923                         , depthStencilAttachment        (env, ImageView::Parameters(Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM,
1924                                                                                                                                                                           makeExtent3D(256, 256, 1),
1925                                                                                                                                                                           1u, 1u,
1926                                                                                                                                                                           VK_SAMPLE_COUNT_1_BIT,
1927                                                                                                                                                                           VK_IMAGE_TILING_OPTIMAL,
1928                                                                                                                                                                           VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1929                                                                                                                                                                           VK_IMAGE_LAYOUT_UNDEFINED),
1930                                                                                                                                                  VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM,
1931                                                                                                                                                  makeComponentMappingRGBA(),
1932                                                                                                                                                  makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u)))
1933                         , renderPass                            (env, RenderPass::Parameters())
1934                 {}
1935         };
1936
1937         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1938         {
1939                 // \todo [2016-03-23 pyry] Take into account attachment sizes
1940                 return getSafeObjectCount<Framebuffer>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1941         }
1942
1943         static Move<VkFramebuffer> create (const Environment& env, const Resources& res, const Parameters&)
1944         {
1945                 const VkImageView                               attachments[]   =
1946                 {
1947                         *res.colorAttachment.object,
1948                         *res.depthStencilAttachment.object,
1949                 };
1950                 const VkFramebufferCreateInfo   framebufferInfo =
1951                 {
1952                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1953                         DE_NULL,
1954                         (VkFramebufferCreateFlags)0,
1955                         *res.renderPass.object,
1956                         (deUint32)DE_LENGTH_OF_ARRAY(attachments),
1957                         attachments,
1958                         256u,                                                                           // width
1959                         256u,                                                                           // height
1960                         1u                                                                                      // layers
1961                 };
1962
1963                 return createFramebuffer(env.vkd, env.device, &framebufferInfo, env.allocationCallbacks);
1964         }
1965 };
1966
1967 struct CommandPool
1968 {
1969         typedef VkCommandPool Type;
1970
1971         struct Parameters
1972         {
1973                 VkCommandPoolCreateFlags        flags;
1974
1975                 Parameters (VkCommandPoolCreateFlags flags_)
1976                         : flags(flags_)
1977                 {}
1978         };
1979
1980         struct Resources
1981         {
1982                 Resources (const Environment&, const Parameters&) {}
1983         };
1984
1985         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
1986         {
1987                 return getSafeObjectCount<CommandPool>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
1988         }
1989
1990         static Move<VkCommandPool> create (const Environment& env, const Resources&, const Parameters& params)
1991         {
1992                 const VkCommandPoolCreateInfo   cmdPoolInfo     =
1993                 {
1994                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1995                         DE_NULL,
1996                         params.flags,
1997                         env.queueFamilyIndex,
1998                 };
1999
2000                 return createCommandPool(env.vkd, env.device, &cmdPoolInfo, env.allocationCallbacks);
2001         }
2002 };
2003
2004 struct CommandBuffer
2005 {
2006         typedef VkCommandBuffer Type;
2007
2008         struct Parameters
2009         {
2010                 CommandPool::Parameters         commandPool;
2011                 VkCommandBufferLevel            level;
2012
2013                 Parameters (const CommandPool::Parameters&      commandPool_,
2014                                         VkCommandBufferLevel                    level_)
2015                         : commandPool   (commandPool_)
2016                         , level                 (level_)
2017                 {}
2018         };
2019
2020         struct Resources
2021         {
2022                 Dependency<CommandPool> commandPool;
2023
2024                 Resources (const Environment& env, const Parameters& params)
2025                         : commandPool(env, params.commandPool)
2026                 {}
2027         };
2028
2029         static deUint32 getMaxConcurrent (Context& context, const Parameters& params)
2030         {
2031                 return getSafeObjectCount<CommandBuffer>(context, params, DEFAULT_MAX_CONCURRENT_OBJECTS);
2032         }
2033
2034         static Move<VkCommandBuffer> create (const Environment& env, const Resources& res, const Parameters& params)
2035         {
2036                 const VkCommandBufferAllocateInfo       cmdBufferInfo   =
2037                 {
2038                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2039                         DE_NULL,
2040                         *res.commandPool.object,
2041                         params.level,
2042                         1,                                                      // bufferCount
2043                 };
2044
2045                 return allocateCommandBuffer(env.vkd, env.device, &cmdBufferInfo);
2046         }
2047 };
2048
2049 // Test cases
2050
2051 template<typename Object>
2052 tcu::TestStatus createSingleTest (Context& context, typename Object::Parameters params)
2053 {
2054         const Environment                                       env     (context, 1u);
2055         const typename Object::Resources        res     (env, params);
2056
2057         {
2058                 Unique<typename Object::Type>   obj     (Object::create(env, res, params));
2059         }
2060
2061         return tcu::TestStatus::pass("Ok");
2062 }
2063
2064 template<typename Object>
2065 tcu::TestStatus createMultipleUniqueResourcesTest (Context& context, typename Object::Parameters params)
2066 {
2067         const Environment                                       env             (context, 1u);
2068         const typename Object::Resources        res0    (env, params);
2069         const typename Object::Resources        res1    (env, params);
2070         const typename Object::Resources        res2    (env, params);
2071         const typename Object::Resources        res3    (env, params);
2072
2073         {
2074                 Unique<typename Object::Type>   obj0    (Object::create(env, res0, params));
2075                 Unique<typename Object::Type>   obj1    (Object::create(env, res1, params));
2076                 Unique<typename Object::Type>   obj2    (Object::create(env, res2, params));
2077                 Unique<typename Object::Type>   obj3    (Object::create(env, res3, params));
2078         }
2079
2080         return tcu::TestStatus::pass("Ok");
2081 }
2082
2083 template<typename Object>
2084 tcu::TestStatus createMultipleSharedResourcesTest (Context& context, typename Object::Parameters params)
2085 {
2086         const Environment                                       env     (context, 4u);
2087         const typename Object::Resources        res     (env, params);
2088
2089         {
2090                 Unique<typename Object::Type>   obj0    (Object::create(env, res, params));
2091                 Unique<typename Object::Type>   obj1    (Object::create(env, res, params));
2092                 Unique<typename Object::Type>   obj2    (Object::create(env, res, params));
2093                 Unique<typename Object::Type>   obj3    (Object::create(env, res, params));
2094         }
2095
2096         return tcu::TestStatus::pass("Ok");
2097 }
2098
2099 template<typename Object>
2100 tcu::TestStatus createMaxConcurrentTest (Context& context, typename Object::Parameters params)
2101 {
2102         typedef Unique<typename Object::Type>   UniqueObject;
2103         typedef SharedPtr<UniqueObject>                 ObjectPtr;
2104
2105         const deUint32                                          numObjects                      = Object::getMaxConcurrent(context, params);
2106         const Environment                                       env                                     (context, numObjects);
2107         const typename Object::Resources        res                                     (env, params);
2108         vector<ObjectPtr>                                       objects                         (numObjects);
2109         const deUint32                                          watchdogInterval        = 1024;
2110
2111         context.getTestContext().getLog()
2112                 << TestLog::Message << "Creating " << numObjects << " " << getTypeName<typename Object::Type>() << " objects" << TestLog::EndMessage;
2113
2114         for (deUint32 ndx = 0; ndx < numObjects; ndx++)
2115         {
2116                 objects[ndx] = ObjectPtr(new UniqueObject(Object::create(env, res, params)));
2117
2118                 if ((ndx > 0) && ((ndx % watchdogInterval) == 0))
2119                         context.getTestContext().touchWatchdog();
2120         }
2121
2122         objects.clear();
2123
2124         return tcu::TestStatus::pass("Ok");
2125 }
2126
2127 template<typename Object>
2128 int getCreateCount (void)
2129 {
2130         return 100;
2131 }
2132
2133 template<>
2134 int getCreateCount<Device> (void)
2135 {
2136         // Creating VkDevice can take significantly longer than other object types
2137         return 20;
2138 }
2139
2140 template<typename Object>
2141 class CreateThread : public ThreadGroupThread
2142 {
2143 public:
2144         CreateThread (const Environment& env, const typename Object::Resources& resources, const typename Object::Parameters& params)
2145                 : m_env                 (env)
2146                 , m_resources   (resources)
2147                 , m_params              (params)
2148         {}
2149
2150         void runThread (void)
2151         {
2152                 const int       numIters                        = getCreateCount<Object>();
2153                 const int       itersBetweenSyncs       = numIters / 5;
2154
2155                 DE_ASSERT(itersBetweenSyncs > 0);
2156
2157                 for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
2158                 {
2159                         // Sync every Nth iteration to make entering driver at the same time more likely
2160                         if ((iterNdx % itersBetweenSyncs) == 0)
2161                                 barrier();
2162
2163                         {
2164                                 Unique<typename Object::Type>   obj     (Object::create(m_env, m_resources, m_params));
2165                         }
2166                 }
2167         }
2168
2169 private:
2170         const Environment&                                      m_env;
2171         const typename Object::Resources&       m_resources;
2172         const typename Object::Parameters&      m_params;
2173 };
2174
2175 template<typename Object>
2176 tcu::TestStatus multithreadedCreateSharedResourcesTest (Context& context, typename Object::Parameters params)
2177 {
2178         const deUint32                                          numThreads      = getDefaultTestThreadCount();
2179         const Environment                                       env                     (context, numThreads);
2180         const typename Object::Resources        res                     (env, params);
2181         ThreadGroup                                                     threads;
2182
2183         for (deUint32 ndx = 0; ndx < numThreads; ndx++)
2184                 threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(env, res, params)));
2185
2186         return threads.run();
2187 }
2188
2189 template<typename Object>
2190 tcu::TestStatus multithreadedCreatePerThreadResourcesTest (Context& context, typename Object::Parameters params)
2191 {
2192         typedef SharedPtr<typename Object::Resources>   ResPtr;
2193
2194         const deUint32          numThreads      = getDefaultTestThreadCount();
2195         const Environment       env                     (context, 1u);
2196         vector<ResPtr>          resources       (numThreads);
2197         ThreadGroup                     threads;
2198
2199         for (deUint32 ndx = 0; ndx < numThreads; ndx++)
2200         {
2201                 resources[ndx] = ResPtr(new typename Object::Resources(env, params));
2202                 threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(env, *resources[ndx], params)));
2203         }
2204
2205         return threads.run();
2206 }
2207
2208 struct EnvClone
2209 {
2210         Device::Resources       deviceRes;
2211         Unique<VkDevice>        device;
2212         DeviceDriver            vkd;
2213         Environment                     env;
2214
2215         EnvClone (const Environment& parent, const Device::Parameters& deviceParams, deUint32 maxResourceConsumers)
2216                 : deviceRes     (parent, deviceParams)
2217                 , device        (Device::create(parent, deviceRes, deviceParams))
2218                 , vkd           (deviceRes.vki, *device)
2219                 , env           (parent.vkp, vkd, *device, deviceRes.queueFamilyIndex, parent.programBinaries, parent.allocationCallbacks, maxResourceConsumers)
2220         {
2221         }
2222 };
2223
2224 Device::Parameters getDefaulDeviceParameters (Context& context)
2225 {
2226         return Device::Parameters(context.getTestContext().getCommandLine().getVKDeviceId()-1u,
2227                                                           VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT);
2228 }
2229
2230 template<typename Object>
2231 tcu::TestStatus multithreadedCreatePerThreadDeviceTest (Context& context, typename Object::Parameters params)
2232 {
2233         typedef SharedPtr<EnvClone>                                             EnvPtr;
2234         typedef SharedPtr<typename Object::Resources>   ResPtr;
2235
2236         const deUint32                          numThreads              = getDefaultTestThreadCount();
2237         const Device::Parameters        deviceParams    = getDefaulDeviceParameters(context);
2238         const Environment                       sharedEnv               (context, numThreads);                  // For creating Device's
2239         vector<EnvPtr>                          perThreadEnv    (numThreads);
2240         vector<ResPtr>                          resources               (numThreads);
2241         ThreadGroup                                     threads;
2242
2243         for (deUint32 ndx = 0; ndx < numThreads; ndx++)
2244         {
2245                 perThreadEnv[ndx]       = EnvPtr(new EnvClone(sharedEnv, deviceParams, 1u));
2246                 resources[ndx]          = ResPtr(new typename Object::Resources(perThreadEnv[ndx]->env, params));
2247
2248                 threads.add(MovePtr<ThreadGroupThread>(new CreateThread<Object>(perThreadEnv[ndx]->env, *resources[ndx], params)));
2249         }
2250
2251         return threads.run();
2252 }
2253
2254 template<typename Object>
2255 tcu::TestStatus createSingleAllocCallbacksTest (Context& context, typename Object::Parameters params)
2256 {
2257         const deUint32                                          noCmdScope              = (1u << VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)
2258                                                                                                                 | (1u << VK_SYSTEM_ALLOCATION_SCOPE_DEVICE)
2259                                                                                                                 | (1u << VK_SYSTEM_ALLOCATION_SCOPE_CACHE)
2260                                                                                                                 | (1u << VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2261
2262         // Callbacks used by resources
2263         AllocationCallbackRecorder                      resCallbacks    (getSystemAllocator(), 128);
2264
2265         // Root environment still uses default instance and device, created without callbacks
2266         const Environment                                       rootEnv                 (context.getPlatformInterface(),
2267                                                                                                                  context.getDeviceInterface(),
2268                                                                                                                  context.getDevice(),
2269                                                                                                                  context.getUniversalQueueFamilyIndex(),
2270                                                                                                                  context.getBinaryCollection(),
2271                                                                                                                  resCallbacks.getCallbacks(),
2272                                                                                                                  1u);
2273
2274         {
2275                 // Test env has instance & device created with callbacks
2276                 const EnvClone                                          resEnv          (rootEnv, getDefaulDeviceParameters(context), 1u);
2277                 const typename Object::Resources        res                     (resEnv.env, params);
2278
2279                 // Supply a separate callback recorder just for object construction
2280                 AllocationCallbackRecorder                      objCallbacks(getSystemAllocator(), 128);
2281                 const Environment                                       objEnv          (resEnv.env.vkp,
2282                                                                                                                  resEnv.env.vkd,
2283                                                                                                                  resEnv.env.device,
2284                                                                                                                  resEnv.env.queueFamilyIndex,
2285                                                                                                                  resEnv.env.programBinaries,
2286                                                                                                                  objCallbacks.getCallbacks(),
2287                                                                                                                  resEnv.env.maxResourceConsumers);
2288
2289                 {
2290                         Unique<typename Object::Type>   obj     (Object::create(objEnv, res, params));
2291
2292                         // Validate that no command-level allocations are live
2293                         if (!validateAndLog(context.getTestContext().getLog(), objCallbacks, noCmdScope))
2294                                 return tcu::TestStatus::fail("Invalid allocation callback");
2295                 }
2296
2297                 // At this point all allocations made against object callbacks must have been freed
2298                 if (!validateAndLog(context.getTestContext().getLog(), objCallbacks, 0u))
2299                         return tcu::TestStatus::fail("Invalid allocation callback");
2300         }
2301
2302         if (!validateAndLog(context.getTestContext().getLog(), resCallbacks, 0u))
2303                 return tcu::TestStatus::fail("Invalid allocation callback");
2304
2305         return tcu::TestStatus::pass("Ok");
2306 }
2307
2308 template<typename Object>
2309 tcu::TestStatus allocCallbackFailTest (Context& context, typename Object::Parameters params)
2310 {
2311         AllocationCallbackRecorder                      resCallbacks    (getSystemAllocator(), 128);
2312         const Environment                                       rootEnv                 (context.getPlatformInterface(),
2313                                                                                                                  context.getDeviceInterface(),
2314                                                                                                                  context.getDevice(),
2315                                                                                                                  context.getUniversalQueueFamilyIndex(),
2316                                                                                                                  context.getBinaryCollection(),
2317                                                                                                                  resCallbacks.getCallbacks(),
2318                                                                                                                  1u);
2319
2320         {
2321                 const EnvClone                                          resEnv                          (rootEnv, getDefaulDeviceParameters(context), 1u);
2322                 const typename Object::Resources        res                                     (resEnv.env, params);
2323                 deUint32                                                        numPassingAllocs        = 0;
2324                 const deUint32                                          maxTries                        = 1u<<10;
2325
2326                 // Iterate over test until object allocation succeeds
2327                 for (; numPassingAllocs < maxTries; ++numPassingAllocs)
2328                 {
2329                         DeterministicFailAllocator                      objAllocator(getSystemAllocator(), numPassingAllocs);
2330                         AllocationCallbackRecorder                      recorder        (objAllocator.getCallbacks(), 128);
2331                         const Environment                                       objEnv          (resEnv.env.vkp,
2332                                                                                                                          resEnv.env.vkd,
2333                                                                                                                          resEnv.env.device,
2334                                                                                                                          resEnv.env.queueFamilyIndex,
2335                                                                                                                          resEnv.env.programBinaries,
2336                                                                                                                          recorder.getCallbacks(),
2337                                                                                                                          resEnv.env.maxResourceConsumers);
2338                         bool                                                            createOk        = false;
2339
2340                         context.getTestContext().getLog()
2341                                 << TestLog::Message
2342                                 << "Trying to create object with " << numPassingAllocs << " allocation" << (numPassingAllocs != 1 ? "s" : "") << " passing"
2343                                 << TestLog::EndMessage;
2344
2345                         try
2346                         {
2347                                 Unique<typename Object::Type>   obj     (Object::create(objEnv, res, params));
2348                                 createOk = true;
2349                         }
2350                         catch (const vk::OutOfMemoryError& e)
2351                         {
2352                                 if (e.getError() != VK_ERROR_OUT_OF_HOST_MEMORY)
2353                                 {
2354                                         context.getTestContext().getLog() << e;
2355                                         return tcu::TestStatus::fail("Got invalid error code");
2356                                 }
2357                         }
2358
2359                         if (!validateAndLog(context.getTestContext().getLog(), recorder, 0u))
2360                                 return tcu::TestStatus::fail("Invalid allocation callback");
2361
2362                         if (createOk)
2363                         {
2364                                 context.getTestContext().getLog()
2365                                         << TestLog::Message << "Object construction succeeded! " << TestLog::EndMessage;
2366                                 break;
2367                         }
2368                 }
2369         }
2370
2371         if (!validateAndLog(context.getTestContext().getLog(), resCallbacks, 0u))
2372                 return tcu::TestStatus::fail("Invalid allocation callback");
2373
2374         return tcu::TestStatus::pass("Ok");
2375 }
2376
2377 // Utilities for creating groups
2378
2379 template<typename Object>
2380 struct NamedParameters
2381 {
2382         const char*                                             name;
2383         typename Object::Parameters             parameters;
2384 };
2385
2386 template<typename Object>
2387 struct CaseDescription
2388 {
2389         typename FunctionInstance1<typename Object::Parameters>::Function       function;
2390         const NamedParameters<Object>*                                                                          paramsBegin;
2391         const NamedParameters<Object>*                                                                          paramsEnd;
2392 };
2393
2394 #define EMPTY_CASE_DESC(OBJECT) \
2395         { (FunctionInstance1<OBJECT::Parameters>::Function)DE_NULL, DE_NULL, DE_NULL }
2396
2397 #define CASE_DESC(FUNCTION, CASES)      \
2398         { FUNCTION, DE_ARRAY_BEGIN(CASES), DE_ARRAY_END(CASES)  }
2399
2400 struct CaseDescriptions
2401 {
2402         CaseDescription<Instance>                               instance;
2403         CaseDescription<Device>                                 device;
2404         CaseDescription<DeviceMemory>                   deviceMemory;
2405         CaseDescription<Buffer>                                 buffer;
2406         CaseDescription<BufferView>                             bufferView;
2407         CaseDescription<Image>                                  image;
2408         CaseDescription<ImageView>                              imageView;
2409         CaseDescription<Semaphore>                              semaphore;
2410         CaseDescription<Event>                                  event;
2411         CaseDescription<Fence>                                  fence;
2412         CaseDescription<QueryPool>                              queryPool;
2413         CaseDescription<ShaderModule>                   shaderModule;
2414         CaseDescription<PipelineCache>                  pipelineCache;
2415         CaseDescription<PipelineLayout>                 pipelineLayout;
2416         CaseDescription<RenderPass>                             renderPass;
2417         CaseDescription<GraphicsPipeline>               graphicsPipeline;
2418         CaseDescription<ComputePipeline>                computePipeline;
2419         CaseDescription<DescriptorSetLayout>    descriptorSetLayout;
2420         CaseDescription<Sampler>                                sampler;
2421         CaseDescription<DescriptorPool>                 descriptorPool;
2422         CaseDescription<DescriptorSet>                  descriptorSet;
2423         CaseDescription<Framebuffer>                    framebuffer;
2424         CaseDescription<CommandPool>                    commandPool;
2425         CaseDescription<CommandBuffer>                  commandBuffer;
2426 };
2427
2428 template<typename Object>
2429 void addCases (const MovePtr<tcu::TestCaseGroup>& group, const CaseDescription<Object>& cases)
2430 {
2431         for (const NamedParameters<Object>* cur = cases.paramsBegin; cur != cases.paramsEnd; ++cur)
2432                 addFunctionCase(group.get(), cur->name, "", cases.function, cur->parameters);
2433 }
2434
2435 template<typename Object>
2436 void addCasesWithProgs (const MovePtr<tcu::TestCaseGroup>& group, const CaseDescription<Object>& cases)
2437 {
2438         for (const NamedParameters<Object>* cur = cases.paramsBegin; cur != cases.paramsEnd; ++cur)
2439                 addFunctionCaseWithPrograms(group.get(), cur->name, "", Object::initPrograms, cases.function, cur->parameters);
2440 }
2441
2442 tcu::TestCaseGroup* createGroup (tcu::TestContext& testCtx, const char* name, const char* desc, const CaseDescriptions& cases)
2443 {
2444         MovePtr<tcu::TestCaseGroup>     group   (new tcu::TestCaseGroup(testCtx, name, desc));
2445
2446         addCases                        (group, cases.instance);
2447         addCases                        (group, cases.device);
2448         addCases                        (group, cases.deviceMemory);
2449         addCases                        (group, cases.buffer);
2450         addCases                        (group, cases.bufferView);
2451         addCases                        (group, cases.image);
2452         addCases                        (group, cases.imageView);
2453         addCases                        (group, cases.semaphore);
2454         addCases                        (group, cases.event);
2455         addCases                        (group, cases.fence);
2456         addCases                        (group, cases.queryPool);
2457         addCases                        (group, cases.sampler);
2458         addCasesWithProgs       (group, cases.shaderModule);
2459         addCases                        (group, cases.pipelineCache);
2460         addCases                        (group, cases.pipelineLayout);
2461         addCases                        (group, cases.renderPass);
2462         addCasesWithProgs       (group, cases.graphicsPipeline);
2463         addCasesWithProgs       (group, cases.computePipeline);
2464         addCases                        (group, cases.descriptorSetLayout);
2465         addCases                        (group, cases.descriptorPool);
2466         addCases                        (group, cases.descriptorSet);
2467         addCases                        (group, cases.framebuffer);
2468         addCases                        (group, cases.commandPool);
2469         addCases                        (group, cases.commandBuffer);
2470
2471         return group.release();
2472 }
2473
2474 } // anonymous
2475
2476 tcu::TestCaseGroup* createObjectManagementTests (tcu::TestContext& testCtx)
2477 {
2478         MovePtr<tcu::TestCaseGroup>     objectMgmtTests (new tcu::TestCaseGroup(testCtx, "object_management", "Object management tests"));
2479
2480         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);
2481         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);
2482         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);
2483         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);
2484         const ImageView::Parameters     imgView1D               (img1D, VK_IMAGE_VIEW_TYPE_1D,                  img1D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
2485         const ImageView::Parameters     imgView1DArr    (img1D, VK_IMAGE_VIEW_TYPE_1D_ARRAY,    img1D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 4u));
2486         const ImageView::Parameters     imgView2D               (img2D, VK_IMAGE_VIEW_TYPE_2D,                  img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
2487         const ImageView::Parameters     imgView2DArr    (img2D, VK_IMAGE_VIEW_TYPE_2D_ARRAY,    img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 8u));
2488         const ImageView::Parameters     imgViewCube             (imgCube, VK_IMAGE_VIEW_TYPE_CUBE,              img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 6u));
2489         const ImageView::Parameters     imgViewCubeArr  (imgCube, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,        img2D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 12u));
2490         const ImageView::Parameters     imgView3D               (img3D, VK_IMAGE_VIEW_TYPE_3D,                  img3D.format, makeComponentMappingRGBA(), makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
2491
2492         const DescriptorSetLayout::Parameters   singleUboDescLayout     = DescriptorSetLayout::Parameters::single(0u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, VK_SHADER_STAGE_VERTEX_BIT);
2493
2494         static NamedParameters<Instance>                                s_instanceCases[]                       =
2495         {
2496                 { "instance",                                   Instance::Parameters() },
2497         };
2498         // \note Device index may change - must not be static
2499         const NamedParameters<Device>                                   s_deviceCases[]                         =
2500         {
2501                 { "device",                                             Device::Parameters(testCtx.getCommandLine().getVKDeviceId()-1u, VK_QUEUE_GRAPHICS_BIT)  },
2502         };
2503         static const NamedParameters<DeviceMemory>                      s_deviceMemCases[]                              =
2504         {
2505                 { "device_memory_small",                DeviceMemory::Parameters(1024, 0u)      },
2506         };
2507         static const NamedParameters<Buffer>                            s_bufferCases[]                                 =
2508         {
2509                 { "buffer_uniform_small",               Buffer::Parameters(1024u,                       VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),    },
2510                 { "buffer_uniform_large",               Buffer::Parameters(1024u*1024u*16u,     VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),    },
2511                 { "buffer_storage_small",               Buffer::Parameters(1024u,                       VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),    },
2512                 { "buffer_storage_large",               Buffer::Parameters(1024u*1024u*16u,     VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),    },
2513         };
2514         static const NamedParameters<BufferView>                        s_bufferViewCases[]                             =
2515         {
2516                 { "buffer_view_uniform_r8g8b8a8_unorm", BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT), VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u)        },
2517                 { "buffer_view_storage_r8g8b8a8_unorm", BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u)        },
2518         };
2519         static const NamedParameters<Image>                                     s_imageCases[]                                  =
2520         {
2521                 { "image_1d",                                   img1D           },
2522                 { "image_2d",                                   img2D           },
2523                 { "image_3d",                                   img3D           },
2524         };
2525         static const NamedParameters<ImageView>                         s_imageViewCases[]                              =
2526         {
2527                 { "image_view_1d",                              imgView1D               },
2528                 { "image_view_1d_arr",                  imgView1DArr    },
2529                 { "image_view_2d",                              imgView2D               },
2530                 { "image_view_2d_arr",                  imgView2DArr    },
2531                 { "image_view_cube",                    imgViewCube             },
2532                 { "image_view_cube_arr",                imgViewCubeArr  },
2533                 { "image_view_3d",                              imgView3D               },
2534         };
2535         static const NamedParameters<Semaphore>                         s_semaphoreCases[]                              =
2536         {
2537                 { "semaphore",                                  Semaphore::Parameters(0u),      }
2538         };
2539         static const NamedParameters<Event>                                     s_eventCases[]                                  =
2540         {
2541                 { "event",                                              Event::Parameters(0u)           }
2542         };
2543         static const NamedParameters<Fence>                                     s_fenceCases[]                                  =
2544         {
2545                 { "fence",                                              Fence::Parameters(0u)                                                           },
2546                 { "fence_signaled",                             Fence::Parameters(VK_FENCE_CREATE_SIGNALED_BIT)         }
2547         };
2548         static const NamedParameters<QueryPool>                         s_queryPoolCases[]                              =
2549         {
2550                 { "query_pool",                                 QueryPool::Parameters(VK_QUERY_TYPE_OCCLUSION, 1u, 0u)  }
2551         };
2552         static const NamedParameters<ShaderModule>                      s_shaderModuleCases[]                   =
2553         {
2554                 { "shader_module",                              ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "test")   }
2555         };
2556         static const NamedParameters<PipelineCache>                     s_pipelineCacheCases[]                  =
2557         {
2558                 { "pipeline_cache",                             PipelineCache::Parameters()             }
2559         };
2560         static const NamedParameters<PipelineLayout>            s_pipelineLayoutCases[]                 =
2561         {
2562                 { "pipeline_layout_empty",              PipelineLayout::Parameters::empty()                                                                             },
2563                 { "pipeline_layout_single",             PipelineLayout::Parameters::singleDescriptorSet(singleUboDescLayout)    }
2564         };
2565         static const NamedParameters<RenderPass>                        s_renderPassCases[]                             =
2566         {
2567                 { "render_pass",                                RenderPass::Parameters()                }
2568         };
2569         static const NamedParameters<GraphicsPipeline>          s_graphicsPipelineCases[]               =
2570         {
2571                 { "graphics_pipeline",                  GraphicsPipeline::Parameters()  }
2572         };
2573         static const NamedParameters<ComputePipeline>           s_computePipelineCases[]                =
2574         {
2575                 { "compute_pipeline",                   ComputePipeline::Parameters()   }
2576         };
2577         static const NamedParameters<DescriptorSetLayout>       s_descriptorSetLayoutCases[]    =
2578         {
2579                 { "descriptor_set_layout_empty",        DescriptorSetLayout::Parameters::empty()        },
2580                 { "descriptor_set_layout_single",       singleUboDescLayout                                                     }
2581         };
2582         static const NamedParameters<Sampler>                           s_samplerCases[]                                =
2583         {
2584                 { "sampler",                                    Sampler::Parameters()   }
2585         };
2586         static const NamedParameters<DescriptorPool>            s_descriptorPoolCases[]                 =
2587         {
2588                 { "descriptor_pool",                                            DescriptorPool::Parameters::singleType((VkDescriptorPoolCreateFlags)0,                                          4u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u)      },
2589                 { "descriptor_pool_free_descriptor_set",        DescriptorPool::Parameters::singleType(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,       4u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u)      }
2590         };
2591         static const NamedParameters<DescriptorSet>                     s_descriptorSetCases[]                  =
2592         {
2593                 { "descriptor_set",                             DescriptorSet::Parameters(singleUboDescLayout)  }
2594         };
2595         static const NamedParameters<Framebuffer>                       s_framebufferCases[]                    =
2596         {
2597                 { "framebuffer",                                Framebuffer::Parameters()       }
2598         };
2599         static const NamedParameters<CommandPool>                       s_commandPoolCases[]                    =
2600         {
2601                 { "command_pool",                               CommandPool::Parameters((VkCommandPoolCreateFlags)0)                    },
2602                 { "command_pool_transient",             CommandPool::Parameters(VK_COMMAND_POOL_CREATE_TRANSIENT_BIT)   }
2603         };
2604         static const NamedParameters<CommandBuffer>                     s_commandBufferCases[]                  =
2605         {
2606                 { "command_buffer_primary",             CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u), VK_COMMAND_BUFFER_LEVEL_PRIMARY)       },
2607                 { "command_buffer_secondary",   CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u), VK_COMMAND_BUFFER_LEVEL_SECONDARY)     }
2608         };
2609
2610         static const CaseDescriptions   s_createSingleGroup     =
2611         {
2612                 CASE_DESC(createSingleTest      <Instance>,                                     s_instanceCases),
2613                 CASE_DESC(createSingleTest      <Device>,                                       s_deviceCases),
2614                 CASE_DESC(createSingleTest      <DeviceMemory>,                         s_deviceMemCases),
2615                 CASE_DESC(createSingleTest      <Buffer>,                                       s_bufferCases),
2616                 CASE_DESC(createSingleTest      <BufferView>,                           s_bufferViewCases),
2617                 CASE_DESC(createSingleTest      <Image>,                                        s_imageCases),
2618                 CASE_DESC(createSingleTest      <ImageView>,                            s_imageViewCases),
2619                 CASE_DESC(createSingleTest      <Semaphore>,                            s_semaphoreCases),
2620                 CASE_DESC(createSingleTest      <Event>,                                        s_eventCases),
2621                 CASE_DESC(createSingleTest      <Fence>,                                        s_fenceCases),
2622                 CASE_DESC(createSingleTest      <QueryPool>,                            s_queryPoolCases),
2623                 CASE_DESC(createSingleTest      <ShaderModule>,                         s_shaderModuleCases),
2624                 CASE_DESC(createSingleTest      <PipelineCache>,                        s_pipelineCacheCases),
2625                 CASE_DESC(createSingleTest      <PipelineLayout>,                       s_pipelineLayoutCases),
2626                 CASE_DESC(createSingleTest      <RenderPass>,                           s_renderPassCases),
2627                 CASE_DESC(createSingleTest      <GraphicsPipeline>,                     s_graphicsPipelineCases),
2628                 CASE_DESC(createSingleTest      <ComputePipeline>,                      s_computePipelineCases),
2629                 CASE_DESC(createSingleTest      <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2630                 CASE_DESC(createSingleTest      <Sampler>,                                      s_samplerCases),
2631                 CASE_DESC(createSingleTest      <DescriptorPool>,                       s_descriptorPoolCases),
2632                 CASE_DESC(createSingleTest      <DescriptorSet>,                        s_descriptorSetCases),
2633                 CASE_DESC(createSingleTest      <Framebuffer>,                          s_framebufferCases),
2634                 CASE_DESC(createSingleTest      <CommandPool>,                          s_commandPoolCases),
2635                 CASE_DESC(createSingleTest      <CommandBuffer>,                        s_commandBufferCases),
2636         };
2637         objectMgmtTests->addChild(createGroup(testCtx, "single", "Create single object", s_createSingleGroup));
2638
2639         static const CaseDescriptions   s_createMultipleUniqueResourcesGroup    =
2640         {
2641                 CASE_DESC(createMultipleUniqueResourcesTest     <Instance>,                                     s_instanceCases),
2642                 CASE_DESC(createMultipleUniqueResourcesTest     <Device>,                                       s_deviceCases),
2643                 CASE_DESC(createMultipleUniqueResourcesTest     <DeviceMemory>,                         s_deviceMemCases),
2644                 CASE_DESC(createMultipleUniqueResourcesTest     <Buffer>,                                       s_bufferCases),
2645                 CASE_DESC(createMultipleUniqueResourcesTest     <BufferView>,                           s_bufferViewCases),
2646                 CASE_DESC(createMultipleUniqueResourcesTest     <Image>,                                        s_imageCases),
2647                 CASE_DESC(createMultipleUniqueResourcesTest     <ImageView>,                            s_imageViewCases),
2648                 CASE_DESC(createMultipleUniqueResourcesTest     <Semaphore>,                            s_semaphoreCases),
2649                 CASE_DESC(createMultipleUniqueResourcesTest     <Event>,                                        s_eventCases),
2650                 CASE_DESC(createMultipleUniqueResourcesTest     <Fence>,                                        s_fenceCases),
2651                 CASE_DESC(createMultipleUniqueResourcesTest     <QueryPool>,                            s_queryPoolCases),
2652                 CASE_DESC(createMultipleUniqueResourcesTest     <ShaderModule>,                         s_shaderModuleCases),
2653                 CASE_DESC(createMultipleUniqueResourcesTest     <PipelineCache>,                        s_pipelineCacheCases),
2654                 CASE_DESC(createMultipleUniqueResourcesTest     <PipelineLayout>,                       s_pipelineLayoutCases),
2655                 CASE_DESC(createMultipleUniqueResourcesTest     <RenderPass>,                           s_renderPassCases),
2656                 CASE_DESC(createMultipleUniqueResourcesTest     <GraphicsPipeline>,                     s_graphicsPipelineCases),
2657                 CASE_DESC(createMultipleUniqueResourcesTest     <ComputePipeline>,                      s_computePipelineCases),
2658                 CASE_DESC(createMultipleUniqueResourcesTest     <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2659                 CASE_DESC(createMultipleUniqueResourcesTest     <Sampler>,                                      s_samplerCases),
2660                 CASE_DESC(createMultipleUniqueResourcesTest     <DescriptorPool>,                       s_descriptorPoolCases),
2661                 CASE_DESC(createMultipleUniqueResourcesTest     <DescriptorSet>,                        s_descriptorSetCases),
2662                 CASE_DESC(createMultipleUniqueResourcesTest     <Framebuffer>,                          s_framebufferCases),
2663                 CASE_DESC(createMultipleUniqueResourcesTest     <CommandPool>,                          s_commandPoolCases),
2664                 CASE_DESC(createMultipleUniqueResourcesTest     <CommandBuffer>,                        s_commandBufferCases),
2665         };
2666         objectMgmtTests->addChild(createGroup(testCtx, "multiple_unique_resources", "Multiple objects with per-object unique resources", s_createMultipleUniqueResourcesGroup));
2667
2668         static const CaseDescriptions   s_createMultipleSharedResourcesGroup    =
2669         {
2670                 EMPTY_CASE_DESC(Instance), // No resources used
2671                 CASE_DESC(createMultipleSharedResourcesTest     <Device>,                                       s_deviceCases),
2672                 CASE_DESC(createMultipleSharedResourcesTest     <DeviceMemory>,                         s_deviceMemCases),
2673                 CASE_DESC(createMultipleSharedResourcesTest     <Buffer>,                                       s_bufferCases),
2674                 CASE_DESC(createMultipleSharedResourcesTest     <BufferView>,                           s_bufferViewCases),
2675                 CASE_DESC(createMultipleSharedResourcesTest     <Image>,                                        s_imageCases),
2676                 CASE_DESC(createMultipleSharedResourcesTest     <ImageView>,                            s_imageViewCases),
2677                 CASE_DESC(createMultipleSharedResourcesTest     <Semaphore>,                            s_semaphoreCases),
2678                 CASE_DESC(createMultipleSharedResourcesTest     <Event>,                                        s_eventCases),
2679                 CASE_DESC(createMultipleSharedResourcesTest     <Fence>,                                        s_fenceCases),
2680                 CASE_DESC(createMultipleSharedResourcesTest     <QueryPool>,                            s_queryPoolCases),
2681                 CASE_DESC(createMultipleSharedResourcesTest     <ShaderModule>,                         s_shaderModuleCases),
2682                 CASE_DESC(createMultipleSharedResourcesTest     <PipelineCache>,                        s_pipelineCacheCases),
2683                 CASE_DESC(createMultipleSharedResourcesTest     <PipelineLayout>,                       s_pipelineLayoutCases),
2684                 CASE_DESC(createMultipleSharedResourcesTest     <RenderPass>,                           s_renderPassCases),
2685                 CASE_DESC(createMultipleSharedResourcesTest     <GraphicsPipeline>,                     s_graphicsPipelineCases),
2686                 CASE_DESC(createMultipleSharedResourcesTest     <ComputePipeline>,                      s_computePipelineCases),
2687                 CASE_DESC(createMultipleSharedResourcesTest     <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2688                 CASE_DESC(createMultipleSharedResourcesTest     <Sampler>,                                      s_samplerCases),
2689                 CASE_DESC(createMultipleSharedResourcesTest     <DescriptorPool>,                       s_descriptorPoolCases),
2690                 CASE_DESC(createMultipleSharedResourcesTest     <DescriptorSet>,                        s_descriptorSetCases),
2691                 CASE_DESC(createMultipleSharedResourcesTest     <Framebuffer>,                          s_framebufferCases),
2692                 CASE_DESC(createMultipleSharedResourcesTest     <CommandPool>,                          s_commandPoolCases),
2693                 CASE_DESC(createMultipleSharedResourcesTest     <CommandBuffer>,                        s_commandBufferCases),
2694         };
2695         objectMgmtTests->addChild(createGroup(testCtx, "multiple_shared_resources", "Multiple objects with shared resources", s_createMultipleSharedResourcesGroup));
2696
2697         static const CaseDescriptions   s_createMaxConcurrentGroup      =
2698         {
2699                 CASE_DESC(createMaxConcurrentTest       <Instance>,                                     s_instanceCases),
2700                 CASE_DESC(createMaxConcurrentTest       <Device>,                                       s_deviceCases),
2701                 CASE_DESC(createMaxConcurrentTest       <DeviceMemory>,                         s_deviceMemCases),
2702                 CASE_DESC(createMaxConcurrentTest       <Buffer>,                                       s_bufferCases),
2703                 CASE_DESC(createMaxConcurrentTest       <BufferView>,                           s_bufferViewCases),
2704                 CASE_DESC(createMaxConcurrentTest       <Image>,                                        s_imageCases),
2705                 CASE_DESC(createMaxConcurrentTest       <ImageView>,                            s_imageViewCases),
2706                 CASE_DESC(createMaxConcurrentTest       <Semaphore>,                            s_semaphoreCases),
2707                 CASE_DESC(createMaxConcurrentTest       <Event>,                                        s_eventCases),
2708                 CASE_DESC(createMaxConcurrentTest       <Fence>,                                        s_fenceCases),
2709                 CASE_DESC(createMaxConcurrentTest       <QueryPool>,                            s_queryPoolCases),
2710                 CASE_DESC(createMaxConcurrentTest       <ShaderModule>,                         s_shaderModuleCases),
2711                 CASE_DESC(createMaxConcurrentTest       <PipelineCache>,                        s_pipelineCacheCases),
2712                 CASE_DESC(createMaxConcurrentTest       <PipelineLayout>,                       s_pipelineLayoutCases),
2713                 CASE_DESC(createMaxConcurrentTest       <RenderPass>,                           s_renderPassCases),
2714                 CASE_DESC(createMaxConcurrentTest       <GraphicsPipeline>,                     s_graphicsPipelineCases),
2715                 CASE_DESC(createMaxConcurrentTest       <ComputePipeline>,                      s_computePipelineCases),
2716                 CASE_DESC(createMaxConcurrentTest       <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2717                 CASE_DESC(createMaxConcurrentTest       <Sampler>,                                      s_samplerCases),
2718                 CASE_DESC(createMaxConcurrentTest       <DescriptorPool>,                       s_descriptorPoolCases),
2719                 CASE_DESC(createMaxConcurrentTest       <DescriptorSet>,                        s_descriptorSetCases),
2720                 CASE_DESC(createMaxConcurrentTest       <Framebuffer>,                          s_framebufferCases),
2721                 CASE_DESC(createMaxConcurrentTest       <CommandPool>,                          s_commandPoolCases),
2722                 CASE_DESC(createMaxConcurrentTest       <CommandBuffer>,                        s_commandBufferCases),
2723         };
2724         objectMgmtTests->addChild(createGroup(testCtx, "max_concurrent", "Maximum number of concurrently live objects", s_createMaxConcurrentGroup));
2725
2726         static const CaseDescriptions   s_multithreadedCreatePerThreadDeviceGroup       =
2727         {
2728                 EMPTY_CASE_DESC(Instance),      // Does not make sense
2729                 EMPTY_CASE_DESC(Device),        // Does not make sense
2730                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <DeviceMemory>,                         s_deviceMemCases),
2731                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <Buffer>,                                       s_bufferCases),
2732                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <BufferView>,                           s_bufferViewCases),
2733                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <Image>,                                        s_imageCases),
2734                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <ImageView>,                            s_imageViewCases),
2735                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <Semaphore>,                            s_semaphoreCases),
2736                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <Event>,                                        s_eventCases),
2737                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <Fence>,                                        s_fenceCases),
2738                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <QueryPool>,                            s_queryPoolCases),
2739                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <ShaderModule>,                         s_shaderModuleCases),
2740                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <PipelineCache>,                        s_pipelineCacheCases),
2741                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <PipelineLayout>,                       s_pipelineLayoutCases),
2742                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <RenderPass>,                           s_renderPassCases),
2743                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <GraphicsPipeline>,                     s_graphicsPipelineCases),
2744                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <ComputePipeline>,                      s_computePipelineCases),
2745                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2746                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <Sampler>,                                      s_samplerCases),
2747                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <DescriptorPool>,                       s_descriptorPoolCases),
2748                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <DescriptorSet>,                        s_descriptorSetCases),
2749                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <Framebuffer>,                          s_framebufferCases),
2750                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <CommandPool>,                          s_commandPoolCases),
2751                 CASE_DESC(multithreadedCreatePerThreadDeviceTest        <CommandBuffer>,                        s_commandBufferCases),
2752         };
2753         objectMgmtTests->addChild(createGroup(testCtx, "multithreaded_per_thread_device", "Multithreaded object construction with per-thread device ", s_multithreadedCreatePerThreadDeviceGroup));
2754
2755         static const CaseDescriptions   s_multithreadedCreatePerThreadResourcesGroup    =
2756         {
2757                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Instance>,                                     s_instanceCases),
2758                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Device>,                                       s_deviceCases),
2759                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <DeviceMemory>,                         s_deviceMemCases),
2760                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Buffer>,                                       s_bufferCases),
2761                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <BufferView>,                           s_bufferViewCases),
2762                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Image>,                                        s_imageCases),
2763                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <ImageView>,                            s_imageViewCases),
2764                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Semaphore>,                            s_semaphoreCases),
2765                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Event>,                                        s_eventCases),
2766                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Fence>,                                        s_fenceCases),
2767                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <QueryPool>,                            s_queryPoolCases),
2768                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <ShaderModule>,                         s_shaderModuleCases),
2769                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <PipelineCache>,                        s_pipelineCacheCases),
2770                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <PipelineLayout>,                       s_pipelineLayoutCases),
2771                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <RenderPass>,                           s_renderPassCases),
2772                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <GraphicsPipeline>,                     s_graphicsPipelineCases),
2773                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <ComputePipeline>,                      s_computePipelineCases),
2774                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2775                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Sampler>,                                      s_samplerCases),
2776                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <DescriptorPool>,                       s_descriptorPoolCases),
2777                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <DescriptorSet>,                        s_descriptorSetCases),
2778                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <Framebuffer>,                          s_framebufferCases),
2779                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <CommandPool>,                          s_commandPoolCases),
2780                 CASE_DESC(multithreadedCreatePerThreadResourcesTest     <CommandBuffer>,                        s_commandBufferCases),
2781         };
2782         objectMgmtTests->addChild(createGroup(testCtx, "multithreaded_per_thread_resources", "Multithreaded object construction with per-thread resources", s_multithreadedCreatePerThreadResourcesGroup));
2783
2784         static const CaseDescriptions   s_multithreadedCreateSharedResourcesGroup       =
2785         {
2786                 EMPTY_CASE_DESC(Instance),
2787                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Device>,                                       s_deviceCases),
2788                 CASE_DESC(multithreadedCreateSharedResourcesTest        <DeviceMemory>,                         s_deviceMemCases),
2789                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Buffer>,                                       s_bufferCases),
2790                 CASE_DESC(multithreadedCreateSharedResourcesTest        <BufferView>,                           s_bufferViewCases),
2791                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Image>,                                        s_imageCases),
2792                 CASE_DESC(multithreadedCreateSharedResourcesTest        <ImageView>,                            s_imageViewCases),
2793                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Semaphore>,                            s_semaphoreCases),
2794                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Event>,                                        s_eventCases),
2795                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Fence>,                                        s_fenceCases),
2796                 CASE_DESC(multithreadedCreateSharedResourcesTest        <QueryPool>,                            s_queryPoolCases),
2797                 CASE_DESC(multithreadedCreateSharedResourcesTest        <ShaderModule>,                         s_shaderModuleCases),
2798                 CASE_DESC(multithreadedCreateSharedResourcesTest        <PipelineCache>,                        s_pipelineCacheCases),
2799                 CASE_DESC(multithreadedCreateSharedResourcesTest        <PipelineLayout>,                       s_pipelineLayoutCases),
2800                 CASE_DESC(multithreadedCreateSharedResourcesTest        <RenderPass>,                           s_renderPassCases),
2801                 CASE_DESC(multithreadedCreateSharedResourcesTest        <GraphicsPipeline>,                     s_graphicsPipelineCases),
2802                 CASE_DESC(multithreadedCreateSharedResourcesTest        <ComputePipeline>,                      s_computePipelineCases),
2803                 CASE_DESC(multithreadedCreateSharedResourcesTest        <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2804                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Sampler>,                                      s_samplerCases),
2805                 CASE_DESC(multithreadedCreateSharedResourcesTest        <DescriptorPool>,                       s_descriptorPoolCases),
2806                 EMPTY_CASE_DESC(DescriptorSet),         // \note Needs per-thread DescriptorPool
2807                 CASE_DESC(multithreadedCreateSharedResourcesTest        <Framebuffer>,                          s_framebufferCases),
2808                 CASE_DESC(multithreadedCreateSharedResourcesTest        <CommandPool>,                          s_commandPoolCases),
2809                 EMPTY_CASE_DESC(CommandBuffer),                 // \note Needs per-thread CommandPool
2810         };
2811         objectMgmtTests->addChild(createGroup(testCtx, "multithreaded_shared_resources", "Multithreaded object construction with shared resources", s_multithreadedCreateSharedResourcesGroup));
2812
2813         static const CaseDescriptions   s_createSingleAllocCallbacksGroup       =
2814         {
2815                 CASE_DESC(createSingleAllocCallbacksTest        <Instance>,                                     s_instanceCases),
2816                 CASE_DESC(createSingleAllocCallbacksTest        <Device>,                                       s_deviceCases),
2817                 CASE_DESC(createSingleAllocCallbacksTest        <DeviceMemory>,                         s_deviceMemCases),
2818                 CASE_DESC(createSingleAllocCallbacksTest        <Buffer>,                                       s_bufferCases),
2819                 CASE_DESC(createSingleAllocCallbacksTest        <BufferView>,                           s_bufferViewCases),
2820                 CASE_DESC(createSingleAllocCallbacksTest        <Image>,                                        s_imageCases),
2821                 CASE_DESC(createSingleAllocCallbacksTest        <ImageView>,                            s_imageViewCases),
2822                 CASE_DESC(createSingleAllocCallbacksTest        <Semaphore>,                            s_semaphoreCases),
2823                 CASE_DESC(createSingleAllocCallbacksTest        <Event>,                                        s_eventCases),
2824                 CASE_DESC(createSingleAllocCallbacksTest        <Fence>,                                        s_fenceCases),
2825                 CASE_DESC(createSingleAllocCallbacksTest        <QueryPool>,                            s_queryPoolCases),
2826                 CASE_DESC(createSingleAllocCallbacksTest        <ShaderModule>,                         s_shaderModuleCases),
2827                 CASE_DESC(createSingleAllocCallbacksTest        <PipelineCache>,                        s_pipelineCacheCases),
2828                 CASE_DESC(createSingleAllocCallbacksTest        <PipelineLayout>,                       s_pipelineLayoutCases),
2829                 CASE_DESC(createSingleAllocCallbacksTest        <RenderPass>,                           s_renderPassCases),
2830                 CASE_DESC(createSingleAllocCallbacksTest        <GraphicsPipeline>,                     s_graphicsPipelineCases),
2831                 CASE_DESC(createSingleAllocCallbacksTest        <ComputePipeline>,                      s_computePipelineCases),
2832                 CASE_DESC(createSingleAllocCallbacksTest        <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2833                 CASE_DESC(createSingleAllocCallbacksTest        <Sampler>,                                      s_samplerCases),
2834                 CASE_DESC(createSingleAllocCallbacksTest        <DescriptorPool>,                       s_descriptorPoolCases),
2835                 CASE_DESC(createSingleAllocCallbacksTest        <DescriptorSet>,                        s_descriptorSetCases),
2836                 CASE_DESC(createSingleAllocCallbacksTest        <Framebuffer>,                          s_framebufferCases),
2837                 CASE_DESC(createSingleAllocCallbacksTest        <CommandPool>,                          s_commandPoolCases),
2838                 CASE_DESC(createSingleAllocCallbacksTest        <CommandBuffer>,                        s_commandBufferCases),
2839         };
2840         objectMgmtTests->addChild(createGroup(testCtx, "single_alloc_callbacks", "Create single object", s_createSingleAllocCallbacksGroup));
2841
2842         static const CaseDescriptions   s_allocCallbackFailGroup        =
2843         {
2844                 CASE_DESC(allocCallbackFailTest <Instance>,                                     s_instanceCases),
2845                 CASE_DESC(allocCallbackFailTest <Device>,                                       s_deviceCases),
2846                 CASE_DESC(allocCallbackFailTest <DeviceMemory>,                         s_deviceMemCases),
2847                 CASE_DESC(allocCallbackFailTest <Buffer>,                                       s_bufferCases),
2848                 CASE_DESC(allocCallbackFailTest <BufferView>,                           s_bufferViewCases),
2849                 CASE_DESC(allocCallbackFailTest <Image>,                                        s_imageCases),
2850                 CASE_DESC(allocCallbackFailTest <ImageView>,                            s_imageViewCases),
2851                 CASE_DESC(allocCallbackFailTest <Semaphore>,                            s_semaphoreCases),
2852                 CASE_DESC(allocCallbackFailTest <Event>,                                        s_eventCases),
2853                 CASE_DESC(allocCallbackFailTest <Fence>,                                        s_fenceCases),
2854                 CASE_DESC(allocCallbackFailTest <QueryPool>,                            s_queryPoolCases),
2855                 CASE_DESC(allocCallbackFailTest <ShaderModule>,                         s_shaderModuleCases),
2856                 CASE_DESC(allocCallbackFailTest <PipelineCache>,                        s_pipelineCacheCases),
2857                 CASE_DESC(allocCallbackFailTest <PipelineLayout>,                       s_pipelineLayoutCases),
2858                 CASE_DESC(allocCallbackFailTest <RenderPass>,                           s_renderPassCases),
2859                 CASE_DESC(allocCallbackFailTest <GraphicsPipeline>,                     s_graphicsPipelineCases),
2860                 CASE_DESC(allocCallbackFailTest <ComputePipeline>,                      s_computePipelineCases),
2861                 CASE_DESC(allocCallbackFailTest <DescriptorSetLayout>,          s_descriptorSetLayoutCases),
2862                 CASE_DESC(allocCallbackFailTest <Sampler>,                                      s_samplerCases),
2863                 CASE_DESC(allocCallbackFailTest <DescriptorPool>,                       s_descriptorPoolCases),
2864                 CASE_DESC(allocCallbackFailTest <DescriptorSet>,                        s_descriptorSetCases),
2865                 CASE_DESC(allocCallbackFailTest <Framebuffer>,                          s_framebufferCases),
2866                 CASE_DESC(allocCallbackFailTest <CommandPool>,                          s_commandPoolCases),
2867                 CASE_DESC(allocCallbackFailTest <CommandBuffer>,                        s_commandBufferCases),
2868         };
2869         objectMgmtTests->addChild(createGroup(testCtx, "alloc_callback_fail", "Allocation callback failure", s_allocCallbackFailGroup));
2870
2871         return objectMgmtTests.release();
2872 }
2873
2874 } // api
2875 } // vkt