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