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