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