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