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