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