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