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