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