1/*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group 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 Buffer and image memory requirements tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "vktMemoryRequirementsTests.hpp"
25#include "vktTestCaseUtil.hpp"
26#include "vktTestGroupUtil.hpp"
27
28#include "vkDefs.hpp"
29#include "vkRef.hpp"
30#include "vkRefUtil.hpp"
31#include "vkMemUtil.hpp"
32#include "vkQueryUtil.hpp"
33#include "vkStrUtil.hpp"
34#include "vkTypeUtil.hpp"
35#include "vkImageUtil.hpp"
36
37#include "deUniquePtr.hpp"
38#include "deStringUtil.hpp"
39#include "deSTLUtil.hpp"
40
41#include "tcuResultCollector.hpp"
42#include "tcuTestLog.hpp"
43
44namespace vkt
45{
46namespace memory
47{
48namespace
49{
50using namespace vk;
51using de::MovePtr;
52using tcu::TestLog;
53
54Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
55{
56	const VkBufferCreateInfo createInfo =
57	{
58		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType        sType;
59		DE_NULL,									// const void*            pNext;
60		flags,										// VkBufferCreateFlags    flags;
61		size,										// VkDeviceSize           size;
62		usage,										// VkBufferUsageFlags     usage;
63		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode          sharingMode;
64		0u,											// uint32_t               queueFamilyIndexCount;
65		DE_NULL,									// const uint32_t*        pQueueFamilyIndices;
66	};
67	return createBuffer(vk, device, &createInfo);
68}
69
70VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
71{
72	const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
73	return getBufferMemoryRequirements(vk, device, *buffer);
74}
75
76VkMemoryRequirements getBufferMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage, void* next = DE_NULL)
77{
78	const Unique<VkBuffer>				buffer		(makeBuffer(vk, device, size, flags, usage));
79	VkBufferMemoryRequirementsInfo2		info	=
80	{
81		VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,	// VkStructureType	sType
82		DE_NULL,													// const void*		pNext
83		*buffer														// VkBuffer			buffer
84	};
85	VkMemoryRequirements2				req2	=
86	{
87		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,				// VkStructureType		sType
88		next,														// void*				pNext
89		{0, 0, 0}													// VkMemoryRequirements	memoryRequirements
90	};
91
92	vk.getBufferMemoryRequirements2(device, &info, &req2);
93
94	return req2.memoryRequirements;
95}
96
97VkMemoryRequirements getImageMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo, void* next = DE_NULL)
98{
99	const Unique<VkImage> image(createImage(vk, device, &createInfo));
100
101	VkImageMemoryRequirementsInfo2		info	=
102	{
103		VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR,		// VkStructureType	sType
104		DE_NULL,													// const void*		pNext
105		*image														// VkImage			image
106	};
107	VkMemoryRequirements2				req2	=
108	{
109		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,				// VkStructureType		sType
110		next,														// void*				pNext
111		{0, 0, 0}													// VkMemoryRequirements	memoryRequirements
112	};
113
114	vk.getImageMemoryRequirements2(device, &info, &req2);
115
116	return req2.memoryRequirements;
117}
118
119//! Get an index of each set bit, starting from the least significant bit.
120std::vector<deUint32> bitsToIndices (deUint32 bits)
121{
122	std::vector<deUint32> indices;
123	for (deUint32 i = 0u; bits != 0u; ++i, bits >>= 1)
124	{
125		if (bits & 1u)
126			indices.push_back(i);
127	}
128	return indices;
129}
130
131template<typename T>
132T nextEnum (T value)
133{
134	return static_cast<T>(static_cast<deUint32>(value) + 1);
135}
136
137template<typename T>
138T nextFlag (T value)
139{
140	if (value)
141		return static_cast<T>(static_cast<deUint32>(value) << 1);
142	else
143		return static_cast<T>(1);
144}
145
146template<typename T>
147T nextFlagExcluding (T value, T excludedFlags)
148{
149	deUint32 tmp = static_cast<deUint32>(value);
150	while ((tmp = nextFlag(tmp)) & static_cast<deUint32>(excludedFlags));
151	return static_cast<T>(tmp);
152}
153
154bool validValueVkBool32 (const VkBool32 value)
155{
156	return (value == VK_FALSE || value == VK_TRUE);
157}
158
159class IBufferMemoryRequirements
160{
161public:
162	virtual void populateTestGroup			(tcu::TestCaseGroup*						group) = 0;
163
164protected:
165	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
166											 const std::string&							name,
167											 const std::string&							desc,
168											 VkBufferCreateFlags						arg0) = 0;
169
170	virtual tcu::TestStatus execTest		(Context&									context,
171											 const VkBufferCreateFlags					bufferFlags) = 0;
172
173	virtual void preTestChecks				(Context&									context,
174											 const InstanceInterface&					vki,
175											 const VkPhysicalDevice						physDevice,
176											 const VkBufferCreateFlags					flags) = 0;
177
178	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
179											 const VkDevice								device,
180											 const VkDeviceSize							size,
181											 const VkBufferCreateFlags					flags,
182											 const VkBufferUsageFlags					usage,
183											 const bool									all) = 0;
184
185	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
186											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
187											 const VkPhysicalDeviceLimits&				limits,
188											 const VkBufferCreateFlags					bufferFlags,
189											 const VkBufferUsageFlags					usage) = 0;
190};
191
192class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
193{
194	static tcu::TestStatus testEntryPoint	(Context&									context,
195											 const VkBufferCreateFlags					bufferFlags);
196
197public:
198	virtual void populateTestGroup			(tcu::TestCaseGroup*						group);
199
200protected:
201	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
202											 const std::string&							name,
203											 const std::string&							desc,
204											 VkBufferCreateFlags						arg0);
205
206	virtual tcu::TestStatus execTest		(Context&									context,
207											 const VkBufferCreateFlags					bufferFlags);
208
209	virtual void preTestChecks				(Context&									context,
210											 const InstanceInterface&					vki,
211											 const VkPhysicalDevice						physDevice,
212											 const VkBufferCreateFlags					flags);
213
214	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
215											 const VkDevice								device,
216											 const VkDeviceSize							size,
217											 const VkBufferCreateFlags					flags,
218											 const VkBufferUsageFlags					usage,
219											 const bool									all);
220
221	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
222											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
223											 const VkPhysicalDeviceLimits&				limits,
224											 const VkBufferCreateFlags					bufferFlags,
225											 const VkBufferUsageFlags					usage);
226
227protected:
228	VkMemoryRequirements	m_allUsageFlagsRequirements;
229	VkMemoryRequirements	m_currentTestRequirements;
230};
231
232
233tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
234{
235	BufferMemoryRequirementsOriginal test;
236
237	return test.execTest(context, bufferFlags);
238}
239
240void BufferMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
241{
242	const struct
243	{
244		VkBufferCreateFlags		flags;
245		const char* const		name;
246	} bufferCases[] =
247	{
248		{ (VkBufferCreateFlags)0,																								"regular"					},
249		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT,																					"sparse"					},
250		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,											"sparse_residency"			},
251		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT											| VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	"sparse_aliased"			},
252		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT	| VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	"sparse_residency_aliased"	},
253	};
254
255	de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer", ""));
256
257	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
258		addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, "", bufferCases[ndx].flags);
259
260	group->addChild(bufferGroup.release());
261}
262
263void BufferMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup*	group,
264															const std::string&	name,
265															const std::string&	desc,
266															VkBufferCreateFlags	arg0)
267{
268	addFunctionCase(group, name, desc, testEntryPoint, arg0);
269}
270
271tcu::TestStatus BufferMemoryRequirementsOriginal::execTest (Context& context, const VkBufferCreateFlags bufferFlags)
272{
273	const DeviceInterface&					vk			= context.getDeviceInterface();
274	const InstanceInterface&				vki			= context.getInstanceInterface();
275	const VkDevice							device		= context.getDevice();
276	const VkPhysicalDevice					physDevice	= context.getPhysicalDevice();
277
278	preTestChecks(context, vki, physDevice, bufferFlags);
279
280	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physDevice);
281	const VkPhysicalDeviceLimits			limits				= getPhysicalDeviceProperties(vki, physDevice).limits;
282	const VkBufferUsageFlags				allUsageFlags		= static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
283	tcu::TestLog&							log					= context.getTestContext().getLog();
284	bool									allPass				= true;
285
286	const VkDeviceSize sizeCases[] =
287	{
288		1    * 1024,
289		8    * 1024,
290		64   * 1024,
291		1024 * 1024,
292	};
293
294	// Updates m_allUsageFlags* fields
295	updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size
296
297	for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage))
298	{
299		deUint32		previousMemoryTypeBits	= 0u;
300		VkDeviceSize	previousAlignment		= 0u;
301
302		log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage;
303
304		for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
305		{
306			log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;
307
308			tcu::ResultCollector result(log, "ERROR: ");
309
310			// Updates m_allUsageFlags* fields
311			updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false);
312
313			// Check:
314			// - requirements for a particular buffer usage
315			// - memoryTypeBits are a subset of bits for requirements with all usage flags combined
316			verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage);
317
318			// Check that for the same usage and create flags:
319			// - memoryTypeBits are the same
320			// - alignment is the same
321			if (pSize > sizeCases)
322			{
323				result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits,
324					"memoryTypeBits differ from the ones in the previous buffer size");
325
326				result.check(m_currentTestRequirements.alignment == previousAlignment,
327					"alignment differs from the one in the previous buffer size");
328			}
329
330			if (result.getResult() != QP_TEST_RESULT_PASS)
331				allPass = false;
332
333			previousMemoryTypeBits	= m_currentTestRequirements.memoryTypeBits;
334			previousAlignment		= m_currentTestRequirements.alignment;
335		}
336
337		if (!allPass)
338			break;
339	}
340
341	return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
342}
343
344void BufferMemoryRequirementsOriginal::preTestChecks (Context&								,
345													  const InstanceInterface&				vki,
346													  const VkPhysicalDevice				physDevice,
347													  const VkBufferCreateFlags				flags)
348{
349	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
350
351	if ((flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
352		TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
353
354	if ((flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && !features.sparseResidencyBuffer)
355		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyBuffer");
356
357	if ((flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
358		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
359}
360
361void BufferMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface&		vk,
362																 const VkDevice				device,
363																 const VkDeviceSize			size,
364																 const VkBufferCreateFlags	flags,
365																 const VkBufferUsageFlags	usage,
366																 const bool					all)
367{
368	if (all)
369	{
370		m_allUsageFlagsRequirements	= getBufferMemoryRequirements(vk, device, size, flags, usage);
371	}
372	else
373	{
374		m_currentTestRequirements	= getBufferMemoryRequirements(vk, device, size, flags, usage);
375	}
376}
377
378void BufferMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&						result,
379																 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
380																 const VkPhysicalDeviceLimits&				limits,
381																 const VkBufferCreateFlags					bufferFlags,
382																 const VkBufferUsageFlags					usage)
383{
384	if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
385	{
386		typedef std::vector<deUint32>::const_iterator	IndexIterator;
387		const std::vector<deUint32>						usedMemoryTypeIndices			= bitsToIndices(m_currentTestRequirements.memoryTypeBits);
388		bool											deviceLocalMemoryFound			= false;
389		bool											hostVisibleCoherentMemoryFound	= false;
390
391		for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
392		{
393			if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
394			{
395				result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
396				continue;
397			}
398
399			const VkMemoryPropertyFlags	memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
400
401			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
402				deviceLocalMemoryFound = true;
403
404			if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
405				hostVisibleCoherentMemoryFound = true;
406
407			result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
408				"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
409		}
410
411		result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
412			"VkMemoryRequirements alignment isn't power of two");
413
414		if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
415		{
416			result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment,
417				"VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
418		}
419
420		if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
421		{
422			result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment,
423				"VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
424		}
425
426		if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
427		{
428			result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment,
429				"VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
430		}
431
432		result.check(deviceLocalMemoryFound,
433			"None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
434
435		result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
436			"Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
437
438		result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) == m_allUsageFlagsRequirements.memoryTypeBits,
439			"Memory type bits aren't a superset of memory type bits for all usage flags combined");
440	}
441}
442
443class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
444{
445	static tcu::TestStatus testEntryPoint	(Context&					context,
446											 const VkBufferCreateFlags	bufferFlags);
447
448protected:
449	virtual void addFunctionTestCase		(tcu::TestCaseGroup*		group,
450											 const std::string&			name,
451											 const std::string&			desc,
452											 VkBufferCreateFlags		arg0);
453
454	virtual void preTestChecks				(Context&					context,
455											 const InstanceInterface&	vki,
456											 const VkPhysicalDevice		physDevice,
457											 const VkBufferCreateFlags	flags);
458
459	virtual void updateMemoryRequirements	(const DeviceInterface&		vk,
460											 const VkDevice				device,
461											 const VkDeviceSize			size,
462											 const VkBufferCreateFlags	flags,
463											 const VkBufferUsageFlags	usage,
464											 const bool					all);
465};
466
467tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
468{
469	BufferMemoryRequirementsExtended test;
470
471	return test.execTest(context, bufferFlags);
472}
473
474void BufferMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup*	group,
475															const std::string&	name,
476															const std::string&	desc,
477															VkBufferCreateFlags	arg0)
478{
479	addFunctionCase(group, name, desc, testEntryPoint, arg0);
480}
481
482void BufferMemoryRequirementsExtended::preTestChecks (Context&					context,
483													  const InstanceInterface&	vki,
484													  const VkPhysicalDevice	physDevice,
485													  const VkBufferCreateFlags	flags)
486{
487	const std::string extensionName("VK_KHR_get_memory_requirements2");
488
489	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName))
490		TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
491
492	BufferMemoryRequirementsOriginal::preTestChecks(context, vki, physDevice, flags);
493}
494
495void BufferMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&		vk,
496																 const VkDevice				device,
497																 const VkDeviceSize			size,
498																 const VkBufferCreateFlags	flags,
499																 const VkBufferUsageFlags	usage,
500																 const bool					all)
501{
502	if (all)
503	{
504		m_allUsageFlagsRequirements	= getBufferMemoryRequirements2(vk, device, size, flags, usage);
505	}
506	else
507	{
508		m_currentTestRequirements	= getBufferMemoryRequirements2(vk, device, size, flags, usage);
509	}
510}
511
512
513class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended
514{
515	static tcu::TestStatus testEntryPoint	(Context&									context,
516											 const VkBufferCreateFlags					bufferFlags);
517
518protected:
519	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
520											 const std::string&							name,
521											 const std::string&							desc,
522											 VkBufferCreateFlags						arg0);
523
524	virtual void preTestChecks				(Context&									context,
525											 const InstanceInterface&					vki,
526											 const VkPhysicalDevice						physDevice,
527											 const VkBufferCreateFlags					flags);
528
529	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
530											 const VkDevice								device,
531											 const VkDeviceSize							size,
532											 const VkBufferCreateFlags					flags,
533											 const VkBufferUsageFlags					usage,
534											 const bool									all);
535
536	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
537											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
538											 const VkPhysicalDeviceLimits&				limits,
539											 const VkBufferCreateFlags					bufferFlags,
540											 const VkBufferUsageFlags					usage);
541
542protected:
543	VkBool32	m_allUsageFlagsPrefersDedicatedAllocation;
544	VkBool32	m_allUsageFlagsRequiresDedicatedAllocation;
545
546	VkBool32	m_currentTestPrefersDedicatedAllocation;
547	VkBool32	m_currentTestRequiresDedicatedAllocation;
548};
549
550
551tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags)
552{
553	BufferMemoryRequirementsDedicatedAllocation test;
554
555	return test.execTest(context, bufferFlags);
556}
557
558void BufferMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*	group,
559																	   const std::string&	name,
560																	   const std::string&	desc,
561																	   VkBufferCreateFlags	arg0)
562{
563	addFunctionCase(group, name, desc, testEntryPoint, arg0);
564}
565
566void BufferMemoryRequirementsDedicatedAllocation::preTestChecks (Context&					context,
567																 const InstanceInterface&	vki,
568																 const VkPhysicalDevice		physDevice,
569																 const VkBufferCreateFlags	flags)
570{
571	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation"))
572		TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
573
574	BufferMemoryRequirementsExtended::preTestChecks(context, vki, physDevice, flags);
575}
576
577void BufferMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&		vk,
578																			const VkDevice				device,
579																			const VkDeviceSize			size,
580																			const VkBufferCreateFlags	flags,
581																			const VkBufferUsageFlags	usage,
582																			const bool					all)
583{
584	const deUint32						invalidVkBool32			= static_cast<deUint32>(~0);
585
586	VkMemoryDedicatedRequirements	dedicatedRequirements	=
587	{
588		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,	// VkStructureType	sType
589		DE_NULL,												// void*			pNext
590		invalidVkBool32,										// VkBool32			prefersDedicatedAllocation
591		invalidVkBool32											// VkBool32			requiresDedicatedAllocation
592	};
593
594	if (all)
595	{
596		m_allUsageFlagsRequirements					= getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
597		m_allUsageFlagsPrefersDedicatedAllocation	= dedicatedRequirements.prefersDedicatedAllocation;
598		m_allUsageFlagsRequiresDedicatedAllocation	= dedicatedRequirements.requiresDedicatedAllocation;
599
600		TCU_CHECK(validValueVkBool32(m_allUsageFlagsPrefersDedicatedAllocation));
601		// Test design expects m_allUsageFlagsRequiresDedicatedAllocation to be false
602		TCU_CHECK(m_allUsageFlagsRequiresDedicatedAllocation == VK_FALSE);
603	}
604	else
605	{
606		m_currentTestRequirements					= getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
607		m_currentTestPrefersDedicatedAllocation		= dedicatedRequirements.prefersDedicatedAllocation;
608		m_currentTestRequiresDedicatedAllocation	= dedicatedRequirements.requiresDedicatedAllocation;
609	}
610}
611
612void BufferMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&					result,
613																			const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
614																			const VkPhysicalDeviceLimits&			limits,
615																			const VkBufferCreateFlags				bufferFlags,
616																			const VkBufferUsageFlags				usage)
617{
618	BufferMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags, usage);
619
620	result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
621		"Invalid VkBool32 value in m_currentTestPrefersDedicatedAllocation");
622
623	result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
624		"Regular (non-shared) objects must not require dedicated allocations");
625
626	result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
627		"Preferred and required flags for dedicated memory cannot be set to true at the same time");
628}
629
630
631struct ImageTestParams
632{
633	ImageTestParams (VkImageCreateFlags		flags_,
634					 VkImageTiling			tiling_,
635					 bool					transient_)
636	: flags		(flags_)
637	, tiling	(tiling_)
638	, transient	(transient_)
639	{
640	}
641
642	ImageTestParams (void)
643	{
644	}
645
646	VkImageCreateFlags		flags;
647	VkImageTiling			tiling;
648	bool					transient;
649};
650
651class IImageMemoryRequirements
652{
653public:
654	virtual void populateTestGroup			(tcu::TestCaseGroup*						group) = 0;
655
656protected:
657	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
658											 const std::string&							name,
659											 const std::string&							desc,
660											 const ImageTestParams						arg0) = 0;
661
662	virtual tcu::TestStatus execTest		(Context&									context,
663											 const ImageTestParams						bufferFlags) = 0;
664
665	virtual void preTestChecks				(Context&									context,
666											 const InstanceInterface&					vki,
667											 const VkPhysicalDevice						physDevice,
668											 const VkImageCreateFlags					flags) = 0;
669
670	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
671											 const VkDevice								device) = 0;
672
673	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
674											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties) = 0;
675};
676
677class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
678{
679	static tcu::TestStatus testEntryPoint	(Context&									context,
680											 const ImageTestParams						params);
681
682public:
683	virtual void populateTestGroup			(tcu::TestCaseGroup*						group);
684
685protected:
686	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
687											 const std::string&							name,
688											 const std::string&							desc,
689											 const ImageTestParams						arg0);
690
691	virtual tcu::TestStatus execTest		(Context&									context,
692											 const ImageTestParams						params);
693
694	virtual void preTestChecks				(Context&									context,
695											 const InstanceInterface&					vki,
696											 const VkPhysicalDevice						physDevice,
697											 const VkImageCreateFlags					flags);
698
699	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
700											 const VkDevice								device);
701
702	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
703											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties);
704
705private:
706	virtual bool isImageSupported			(const deUint32								apiVersion,
707											 const InstanceInterface&					vki,
708											 const VkPhysicalDevice						physDevice,
709											 const std::vector<std::string>&			deviceExtensions,
710											 const VkImageCreateInfo&					info);
711
712	virtual bool isFormatMatchingAspect		(const VkFormat								format,
713											 const VkImageAspectFlags					aspect);
714
715protected:
716	VkImageCreateInfo		m_currentTestImageInfo;
717	VkMemoryRequirements	m_currentTestRequirements;
718};
719
720
721tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params)
722{
723	ImageMemoryRequirementsOriginal test;
724
725	return test.execTest(context, params);
726}
727
728void ImageMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
729{
730	const struct
731	{
732		VkImageCreateFlags		flags;
733		bool					transient;
734		const char* const		name;
735	} imageFlagsCases[] =
736	{
737		{ (VkImageCreateFlags)0,																								false,	"regular"					},
738		{ (VkImageCreateFlags)0,																								true,	"transient"					},
739		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT,																					false,	"sparse"					},
740		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,											false,	"sparse_residency"			},
741		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT											| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_aliased"			},
742		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT		| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_residency_aliased"	},
743	};
744
745	de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image", ""));
746
747	for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
748	for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
749	{
750		ImageTestParams		params;
751		std::ostringstream	caseName;
752
753		params.flags		=  imageFlagsCases[flagsNdx].flags;
754		params.transient	=  imageFlagsCases[flagsNdx].transient;
755		caseName			<< imageFlagsCases[flagsNdx].name;
756
757		if (tilingNdx != 0)
758		{
759			params.tiling =  VK_IMAGE_TILING_OPTIMAL;
760			caseName      << "_tiling_optimal";
761		}
762		else
763		{
764			params.tiling =  VK_IMAGE_TILING_LINEAR;
765			caseName      << "_tiling_linear";
766		}
767
768		if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
769			continue;
770
771		addFunctionTestCase(imageGroup.get(), caseName.str(), "", params);
772	}
773
774	group->addChild(imageGroup.release());
775}
776
777void ImageMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup*		group,
778														   const std::string&		name,
779														   const std::string&		desc,
780														   const ImageTestParams	arg0)
781{
782	addFunctionCase(group, name, desc, testEntryPoint, arg0);
783}
784
785void ImageMemoryRequirementsOriginal::preTestChecks (Context&					,
786													 const InstanceInterface&	vki,
787													 const VkPhysicalDevice		physDevice,
788													 const VkImageCreateFlags	createFlags)
789{
790	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
791
792	if ((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
793		TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
794
795	if ((createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
796		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");
797
798	if ((createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
799		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
800}
801
802void ImageMemoryRequirementsOriginal::updateMemoryRequirements	(const DeviceInterface&		vk,
803																 const VkDevice				device)
804{
805	const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
806
807	m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image);
808}
809
810void ImageMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&					result,
811																const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties)
812{
813	if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
814	{
815		typedef std::vector<deUint32>::const_iterator	IndexIterator;
816		const std::vector<deUint32>						usedMemoryTypeIndices			= bitsToIndices(m_currentTestRequirements.memoryTypeBits);
817		bool											deviceLocalMemoryFound			= false;
818		bool											hostVisibleCoherentMemoryFound	= false;
819
820		for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
821		{
822			if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
823			{
824				result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
825				continue;
826			}
827
828			const VkMemoryPropertyFlags	memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
829
830			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
831				deviceLocalMemoryFound = true;
832
833			if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
834				hostVisibleCoherentMemoryFound = true;
835
836			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
837			{
838				result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
839					"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
840			}
841		}
842
843		result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
844			"VkMemoryRequirements alignment isn't power of two");
845
846		result.check(deviceLocalMemoryFound,
847			"None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
848
849		result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
850			"Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
851	}
852}
853
854bool isUsageMatchesFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
855{
856	if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
857		return true;
858	if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
859		return true;
860	if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
861		return true;
862	if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
863		return true;
864
865	return false;
866}
867
868//! This catches both invalid as well as legal but unsupported combinations of image parameters
869bool ImageMemoryRequirementsOriginal::isImageSupported (const deUint32 apiVersion, const InstanceInterface& vki, const VkPhysicalDevice physDevice, const std::vector<std::string>& deviceExtensions, const VkImageCreateInfo& info)
870{
871	DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);
872
873	if ((isYCbCrFormat(info.format)
874		&& (info.imageType != VK_IMAGE_TYPE_2D
875			|| info.mipLevels != 1
876			|| info.arrayLayers != 1
877			|| info.samples != VK_SAMPLE_COUNT_1_BIT))
878			|| !isDeviceExtensionSupported(apiVersion, deviceExtensions, "VK_KHR_sampler_ycbcr_conversion"))
879	{
880		return false;
881	}
882
883	if (info.imageType == VK_IMAGE_TYPE_1D)
884	{
885		DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
886	}
887	else if (info.imageType == VK_IMAGE_TYPE_2D)
888	{
889		DE_ASSERT(info.extent.depth == 1u);
890
891		if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
892		{
893			DE_ASSERT(info.extent.width == info.extent.height);
894			DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
895		}
896	}
897
898	if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
899		return false;
900
901	if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
902		(info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
903		return false;
904
905	if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
906		(info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
907		return false;
908
909	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
910
911	if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
912	{
913		DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
914
915		if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
916			return false;
917		if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
918			return false;
919		if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
920			return false;
921		if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
922			return false;
923		if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
924			return false;
925		if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
926			return false;
927		if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
928			return false;
929	}
930
931	if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample)
932		return false;
933
934	switch (info.format)
935	{
936		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
937		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
938		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
939		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
940		case VK_FORMAT_BC2_UNORM_BLOCK:
941		case VK_FORMAT_BC2_SRGB_BLOCK:
942		case VK_FORMAT_BC3_UNORM_BLOCK:
943		case VK_FORMAT_BC3_SRGB_BLOCK:
944		case VK_FORMAT_BC4_UNORM_BLOCK:
945		case VK_FORMAT_BC4_SNORM_BLOCK:
946		case VK_FORMAT_BC5_UNORM_BLOCK:
947		case VK_FORMAT_BC5_SNORM_BLOCK:
948		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
949		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
950		case VK_FORMAT_BC7_UNORM_BLOCK:
951		case VK_FORMAT_BC7_SRGB_BLOCK:
952			if (!features.textureCompressionBC)
953				return false;
954			break;
955
956		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
957		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
958		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
959		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
960		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
961		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
962		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
963		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
964		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
965		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
966			if (!features.textureCompressionETC2)
967				return false;
968			break;
969
970		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
971		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
972		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
973		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
974		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
975		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
976		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
977		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
978		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
979		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
980		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
981		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
982		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
983		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
984		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
985		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
986		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
987		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
988		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
989		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
990		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
991		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
992		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
993		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
994		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
995		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
996		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
997		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
998			if (!features.textureCompressionASTC_LDR)
999				return false;
1000			break;
1001
1002		default:
1003			break;
1004	}
1005
1006	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
1007	const VkFormatFeatureFlags	formatFeatures		= (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
1008																							 : formatProperties.optimalTilingFeatures);
1009
1010	if (!isUsageMatchesFeatures(info.usage, formatFeatures))
1011		return false;
1012
1013	VkImageFormatProperties		imageFormatProperties;
1014	const VkResult				result				= vki.getPhysicalDeviceImageFormatProperties(
1015														physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1016
1017	if (result == VK_SUCCESS)
1018	{
1019		if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1020			return false;
1021		if (info.mipLevels > imageFormatProperties.maxMipLevels)
1022			return false;
1023		if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1024			return false;
1025	}
1026
1027	return result == VK_SUCCESS;
1028}
1029
1030VkExtent3D makeExtentForImage (const VkImageType imageType)
1031{
1032	VkExtent3D extent = { 64u, 64u, 4u };
1033
1034	if (imageType == VK_IMAGE_TYPE_1D)
1035		extent.height = extent.depth = 1u;
1036	else if (imageType == VK_IMAGE_TYPE_2D)
1037		extent.depth = 1u;
1038
1039	return extent;
1040}
1041
1042bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect)
1043{
1044	DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1045
1046	// D/S formats are laid out next to each other in the enum
1047	const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);
1048
1049	return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
1050}
1051
1052std::string getImageInfoString (const VkImageCreateInfo& imageInfo)
1053{
1054	std::ostringstream str;
1055
1056	switch (imageInfo.imageType)
1057	{
1058		case VK_IMAGE_TYPE_1D:			str << "1D "; break;
1059		case VK_IMAGE_TYPE_2D:			str << "2D "; break;
1060		case VK_IMAGE_TYPE_3D:			str << "3D "; break;
1061		default:						break;
1062	}
1063
1064	switch (imageInfo.tiling)
1065	{
1066		case VK_IMAGE_TILING_OPTIMAL:	str << "(optimal) "; break;
1067		case VK_IMAGE_TILING_LINEAR:	str << "(linear) "; break;
1068		default:						break;
1069	}
1070
1071	str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] ";
1072	str << imageInfo.format << " ";
1073	str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " ";
1074	str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " ";
1075	str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " ";
1076
1077	return str.str();
1078}
1079
1080tcu::TestStatus ImageMemoryRequirementsOriginal::execTest (Context& context, const ImageTestParams params)
1081{
1082	const VkFormat				formats[]		=
1083	{
1084		VK_FORMAT_R4G4_UNORM_PACK8,
1085		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1086		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1087		VK_FORMAT_R5G6B5_UNORM_PACK16,
1088		VK_FORMAT_B5G6R5_UNORM_PACK16,
1089		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1090		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1091		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1092		VK_FORMAT_R8_UNORM,
1093		VK_FORMAT_R8_SNORM,
1094		VK_FORMAT_R8_USCALED,
1095		VK_FORMAT_R8_SSCALED,
1096		VK_FORMAT_R8_UINT,
1097		VK_FORMAT_R8_SINT,
1098		VK_FORMAT_R8_SRGB,
1099		VK_FORMAT_R8G8_UNORM,
1100		VK_FORMAT_R8G8_SNORM,
1101		VK_FORMAT_R8G8_USCALED,
1102		VK_FORMAT_R8G8_SSCALED,
1103		VK_FORMAT_R8G8_UINT,
1104		VK_FORMAT_R8G8_SINT,
1105		VK_FORMAT_R8G8_SRGB,
1106		VK_FORMAT_R8G8B8_UNORM,
1107		VK_FORMAT_R8G8B8_SNORM,
1108		VK_FORMAT_R8G8B8_USCALED,
1109		VK_FORMAT_R8G8B8_SSCALED,
1110		VK_FORMAT_R8G8B8_UINT,
1111		VK_FORMAT_R8G8B8_SINT,
1112		VK_FORMAT_R8G8B8_SRGB,
1113		VK_FORMAT_B8G8R8_UNORM,
1114		VK_FORMAT_B8G8R8_SNORM,
1115		VK_FORMAT_B8G8R8_USCALED,
1116		VK_FORMAT_B8G8R8_SSCALED,
1117		VK_FORMAT_B8G8R8_UINT,
1118		VK_FORMAT_B8G8R8_SINT,
1119		VK_FORMAT_B8G8R8_SRGB,
1120		VK_FORMAT_R8G8B8A8_UNORM,
1121		VK_FORMAT_R8G8B8A8_SNORM,
1122		VK_FORMAT_R8G8B8A8_USCALED,
1123		VK_FORMAT_R8G8B8A8_SSCALED,
1124		VK_FORMAT_R8G8B8A8_UINT,
1125		VK_FORMAT_R8G8B8A8_SINT,
1126		VK_FORMAT_R8G8B8A8_SRGB,
1127		VK_FORMAT_B8G8R8A8_UNORM,
1128		VK_FORMAT_B8G8R8A8_SNORM,
1129		VK_FORMAT_B8G8R8A8_USCALED,
1130		VK_FORMAT_B8G8R8A8_SSCALED,
1131		VK_FORMAT_B8G8R8A8_UINT,
1132		VK_FORMAT_B8G8R8A8_SINT,
1133		VK_FORMAT_B8G8R8A8_SRGB,
1134		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1135		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1136		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1137		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1138		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1139		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1140		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1141		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1142		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1143		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1144		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1145		VK_FORMAT_A2R10G10B10_UINT_PACK32,
1146		VK_FORMAT_A2R10G10B10_SINT_PACK32,
1147		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1148		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1149		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1150		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1151		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1152		VK_FORMAT_A2B10G10R10_SINT_PACK32,
1153		VK_FORMAT_R16_UNORM,
1154		VK_FORMAT_R16_SNORM,
1155		VK_FORMAT_R16_USCALED,
1156		VK_FORMAT_R16_SSCALED,
1157		VK_FORMAT_R16_UINT,
1158		VK_FORMAT_R16_SINT,
1159		VK_FORMAT_R16_SFLOAT,
1160		VK_FORMAT_R16G16_UNORM,
1161		VK_FORMAT_R16G16_SNORM,
1162		VK_FORMAT_R16G16_USCALED,
1163		VK_FORMAT_R16G16_SSCALED,
1164		VK_FORMAT_R16G16_UINT,
1165		VK_FORMAT_R16G16_SINT,
1166		VK_FORMAT_R16G16_SFLOAT,
1167		VK_FORMAT_R16G16B16_UNORM,
1168		VK_FORMAT_R16G16B16_SNORM,
1169		VK_FORMAT_R16G16B16_USCALED,
1170		VK_FORMAT_R16G16B16_SSCALED,
1171		VK_FORMAT_R16G16B16_UINT,
1172		VK_FORMAT_R16G16B16_SINT,
1173		VK_FORMAT_R16G16B16_SFLOAT,
1174		VK_FORMAT_R16G16B16A16_UNORM,
1175		VK_FORMAT_R16G16B16A16_SNORM,
1176		VK_FORMAT_R16G16B16A16_USCALED,
1177		VK_FORMAT_R16G16B16A16_SSCALED,
1178		VK_FORMAT_R16G16B16A16_UINT,
1179		VK_FORMAT_R16G16B16A16_SINT,
1180		VK_FORMAT_R16G16B16A16_SFLOAT,
1181		VK_FORMAT_R32_UINT,
1182		VK_FORMAT_R32_SINT,
1183		VK_FORMAT_R32_SFLOAT,
1184		VK_FORMAT_R32G32_UINT,
1185		VK_FORMAT_R32G32_SINT,
1186		VK_FORMAT_R32G32_SFLOAT,
1187		VK_FORMAT_R32G32B32_UINT,
1188		VK_FORMAT_R32G32B32_SINT,
1189		VK_FORMAT_R32G32B32_SFLOAT,
1190		VK_FORMAT_R32G32B32A32_UINT,
1191		VK_FORMAT_R32G32B32A32_SINT,
1192		VK_FORMAT_R32G32B32A32_SFLOAT,
1193		VK_FORMAT_R64_UINT,
1194		VK_FORMAT_R64_SINT,
1195		VK_FORMAT_R64_SFLOAT,
1196		VK_FORMAT_R64G64_UINT,
1197		VK_FORMAT_R64G64_SINT,
1198		VK_FORMAT_R64G64_SFLOAT,
1199		VK_FORMAT_R64G64B64_UINT,
1200		VK_FORMAT_R64G64B64_SINT,
1201		VK_FORMAT_R64G64B64_SFLOAT,
1202		VK_FORMAT_R64G64B64A64_UINT,
1203		VK_FORMAT_R64G64B64A64_SINT,
1204		VK_FORMAT_R64G64B64A64_SFLOAT,
1205		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1206		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1207		VK_FORMAT_D16_UNORM,
1208		VK_FORMAT_X8_D24_UNORM_PACK32,
1209		VK_FORMAT_D32_SFLOAT,
1210		VK_FORMAT_S8_UINT,
1211		VK_FORMAT_D16_UNORM_S8_UINT,
1212		VK_FORMAT_D24_UNORM_S8_UINT,
1213		VK_FORMAT_D32_SFLOAT_S8_UINT,
1214		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
1215		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
1216		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
1217		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
1218		VK_FORMAT_BC2_UNORM_BLOCK,
1219		VK_FORMAT_BC2_SRGB_BLOCK,
1220		VK_FORMAT_BC3_UNORM_BLOCK,
1221		VK_FORMAT_BC3_SRGB_BLOCK,
1222		VK_FORMAT_BC4_UNORM_BLOCK,
1223		VK_FORMAT_BC4_SNORM_BLOCK,
1224		VK_FORMAT_BC5_UNORM_BLOCK,
1225		VK_FORMAT_BC5_SNORM_BLOCK,
1226		VK_FORMAT_BC6H_UFLOAT_BLOCK,
1227		VK_FORMAT_BC6H_SFLOAT_BLOCK,
1228		VK_FORMAT_BC7_UNORM_BLOCK,
1229		VK_FORMAT_BC7_SRGB_BLOCK,
1230		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1231		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1232		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1233		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1234		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1235		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1236		VK_FORMAT_EAC_R11_UNORM_BLOCK,
1237		VK_FORMAT_EAC_R11_SNORM_BLOCK,
1238		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1239		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1240		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1241		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
1242		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
1243		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1244		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
1245		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
1246		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1247		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
1248		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
1249		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1250		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
1251		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
1252		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1253		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
1254		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
1255		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1256		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
1257		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
1258		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1259		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
1260		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
1261		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1262		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
1263		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
1264		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1265		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
1266		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
1267		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1268		VK_FORMAT_G8B8G8R8_422_UNORM_KHR,
1269		VK_FORMAT_B8G8R8G8_422_UNORM_KHR,
1270		VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR,
1271		VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
1272		VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR,
1273		VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR,
1274		VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR,
1275		VK_FORMAT_R10X6_UNORM_PACK16_KHR,
1276		VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR,
1277		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR,
1278		VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR,
1279		VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR,
1280		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR,
1281		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR,
1282		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR,
1283		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR,
1284		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR,
1285		VK_FORMAT_R12X4_UNORM_PACK16_KHR,
1286		VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR,
1287		VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR,
1288		VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR,
1289		VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR,
1290		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR,
1291		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR,
1292		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR,
1293		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR,
1294		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR,
1295		VK_FORMAT_G16B16G16R16_422_UNORM_KHR,
1296		VK_FORMAT_B16G16R16G16_422_UNORM_KHR,
1297		VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR,
1298		VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR,
1299		VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR,
1300		VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR,
1301		VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR
1302	};
1303	const DeviceInterface&		vk				= context.getDeviceInterface();
1304	const InstanceInterface&	vki				= context.getInstanceInterface();
1305	const VkDevice				device			= context.getDevice();
1306	const VkPhysicalDevice		physDevice		= context.getPhysicalDevice();
1307	const VkImageCreateFlags	sparseFlags		= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1308	const VkImageUsageFlags		transientFlags	= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1309
1310	preTestChecks(context, vki, physDevice, params.flags);
1311
1312	const VkPhysicalDeviceMemoryProperties	memoryProperties		= getPhysicalDeviceMemoryProperties(vki, physDevice);
1313	const deUint32							notInitializedBits		= ~0u;
1314	const VkImageAspectFlags				colorAspect				= VK_IMAGE_ASPECT_COLOR_BIT;
1315	const VkImageAspectFlags				depthStencilAspect		= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1316	const VkImageAspectFlags				allAspects[2]			= { colorAspect, depthStencilAspect };
1317	tcu::TestLog&							log						= context.getTestContext().getLog();
1318	bool									allPass					= true;
1319	deUint32								numCheckedImages		= 0u;
1320
1321	log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;
1322
1323	for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
1324	{
1325		const VkImageAspectFlags	aspect					= allAspects[loopAspectNdx];
1326		deUint32					previousMemoryTypeBits	= notInitializedBits;
1327
1328		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1329		{
1330			const VkFormat format = formats[formatNdx];
1331
1332			if  (isFormatMatchingAspect(format, aspect))
1333			{
1334				// memoryTypeBits may differ between depth/stencil formats
1335				if (aspect == depthStencilAspect)
1336					previousMemoryTypeBits = notInitializedBits;
1337
1338				for (VkImageType			loopImageType	= VK_IMAGE_TYPE_1D;					loopImageType	!= VK_IMAGE_TYPE_LAST;					loopImageType	= nextEnum(loopImageType))
1339				for (VkImageCreateFlags		loopCreateFlags	= (VkImageCreateFlags)0;			loopCreateFlags	<= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;	loopCreateFlags	= nextFlagExcluding(loopCreateFlags, sparseFlags))
1340				for (VkImageUsageFlags		loopUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;	loopUsageFlags	<= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;	loopUsageFlags	= nextFlagExcluding(loopUsageFlags, transientFlags))
1341				for (VkSampleCountFlagBits	loopSampleCount	= VK_SAMPLE_COUNT_1_BIT;			loopSampleCount	<= VK_SAMPLE_COUNT_16_BIT;				loopSampleCount	= nextFlag(loopSampleCount))
1342				{
1343					const VkImageCreateFlags	actualCreateFlags	= loopCreateFlags | params.flags;
1344					const VkImageUsageFlags		actualUsageFlags	= loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1345					const bool					isCube				= (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
1346					const VkImageCreateInfo		imageInfo			=
1347					{
1348						VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
1349						DE_NULL,									// const void*              pNext;
1350						actualCreateFlags,							// VkImageCreateFlags       flags;
1351						loopImageType,								// VkImageType              imageType;
1352						format,									// VkFormat                 format;
1353						makeExtentForImage(loopImageType),			// VkExtent3D               extent;
1354						1u,											// uint32_t                 mipLevels;
1355						(isCube ? 6u : 1u),							// uint32_t                 arrayLayers;
1356						loopSampleCount,							// VkSampleCountFlagBits    samples;
1357						params.tiling,								// VkImageTiling            tiling;
1358						actualUsageFlags,							// VkImageUsageFlags        usage;
1359						VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
1360						0u,											// uint32_t                 queueFamilyIndexCount;
1361						DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
1362						VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
1363					};
1364
1365					m_currentTestImageInfo = imageInfo;
1366
1367					if (!isImageSupported(context.getUsedApiVersion(), vki, physDevice, context.getDeviceExtensions(), m_currentTestImageInfo))
1368						continue;
1369
1370					log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo) << tcu::TestLog::EndMessage;
1371					++numCheckedImages;
1372
1373					tcu::ResultCollector result(log, "ERROR: ");
1374
1375					updateMemoryRequirements(vk, device);
1376
1377					verifyMemoryRequirements(result, memoryProperties);
1378
1379					// For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
1380					result.check((previousMemoryTypeBits == notInitializedBits) || (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits),
1381									"memoryTypeBits differ from the ones in the previous image configuration");
1382
1383					if (result.getResult() != QP_TEST_RESULT_PASS)
1384						allPass = false;
1385
1386					previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
1387				}
1388			}
1389		}
1390	}
1391
1392	if (numCheckedImages == 0u)
1393		log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage;
1394
1395	return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
1396}
1397
1398
1399class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
1400{
1401public:
1402	static tcu::TestStatus testEntryPoint	(Context&									context,
1403											 const ImageTestParams						params);
1404
1405protected:
1406	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
1407											 const std::string&							name,
1408											 const std::string&							desc,
1409											 const ImageTestParams						arg0);
1410
1411	virtual void preTestChecks				(Context&									context,
1412											 const InstanceInterface&					vki,
1413											 const VkPhysicalDevice						physDevice,
1414											 const VkImageCreateFlags					flags);
1415
1416	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
1417											 const VkDevice								device);
1418};
1419
1420
1421tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params)
1422{
1423	ImageMemoryRequirementsExtended test;
1424
1425	return test.execTest(context, params);
1426}
1427
1428void ImageMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup*		group,
1429														   const std::string&		name,
1430														   const std::string&		desc,
1431														   const ImageTestParams	arg0)
1432{
1433	addFunctionCase(group, name, desc, testEntryPoint, arg0);
1434}
1435
1436void ImageMemoryRequirementsExtended::preTestChecks (Context&					context,
1437													 const InstanceInterface&	vki,
1438													 const VkPhysicalDevice		physDevice,
1439													 const VkImageCreateFlags	createFlags)
1440{
1441	const std::string extensionName("VK_KHR_get_memory_requirements2");
1442
1443	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName))
1444		TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1445
1446	ImageMemoryRequirementsOriginal::preTestChecks (context, vki, physDevice, createFlags);
1447}
1448
1449void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&		vk,
1450															    const VkDevice				device)
1451{
1452	m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
1453}
1454
1455
1456class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended
1457{
1458public:
1459	static tcu::TestStatus testEntryPoint	(Context&									context,
1460											 const ImageTestParams						params);
1461
1462protected:
1463	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
1464											 const std::string&							name,
1465											 const std::string&							desc,
1466											 const ImageTestParams						arg0);
1467
1468	virtual void preTestChecks				(Context&									context,
1469											 const InstanceInterface&					vki,
1470											 const VkPhysicalDevice						physDevice,
1471											 const VkImageCreateFlags					flags);
1472
1473	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
1474											 const VkDevice								device);
1475
1476	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
1477											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties);
1478
1479protected:
1480	VkBool32	m_currentTestPrefersDedicatedAllocation;
1481	VkBool32	m_currentTestRequiresDedicatedAllocation;
1482};
1483
1484
1485tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint (Context& context, const ImageTestParams params)
1486{
1487	ImageMemoryRequirementsDedicatedAllocation test;
1488
1489	return test.execTest(context, params);
1490}
1491
1492void ImageMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*		group,
1493																	  const std::string&		name,
1494																	  const std::string&		desc,
1495																	  const ImageTestParams		arg0)
1496{
1497	addFunctionCase(group, name, desc, testEntryPoint, arg0);
1498}
1499
1500void ImageMemoryRequirementsDedicatedAllocation::preTestChecks (Context&					context,
1501																const InstanceInterface&	vki,
1502																const VkPhysicalDevice		physDevice,
1503																const VkImageCreateFlags	createFlags)
1504{
1505	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation"))
1506		TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1507
1508	ImageMemoryRequirementsExtended::preTestChecks (context, vki, physDevice, createFlags);
1509}
1510
1511
1512void ImageMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&	vk,
1513																		   const VkDevice			device)
1514{
1515	const deUint32						invalidVkBool32			= static_cast<deUint32>(~0);
1516
1517	VkMemoryDedicatedRequirements	dedicatedRequirements	=
1518	{
1519		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,	// VkStructureType	sType
1520		DE_NULL,												// void*			pNext
1521		invalidVkBool32,										// VkBool32			prefersDedicatedAllocation
1522		invalidVkBool32											// VkBool32			requiresDedicatedAllocation
1523	};
1524
1525	m_currentTestRequirements					= getImageMemoryRequirements2(vk, device, m_currentTestImageInfo, &dedicatedRequirements);
1526	m_currentTestPrefersDedicatedAllocation		= dedicatedRequirements.prefersDedicatedAllocation;
1527	m_currentTestRequiresDedicatedAllocation	= dedicatedRequirements.requiresDedicatedAllocation;
1528}
1529
1530void ImageMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&						result,
1531																		   const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties)
1532{
1533	ImageMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties);
1534
1535	result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
1536		"Non-bool value in m_currentTestPrefersDedicatedAllocation");
1537
1538	result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
1539		"Test design expects m_currentTestRequiresDedicatedAllocation to be false");
1540
1541	result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
1542		"Preferred and required flags for dedicated memory cannot be set to true at the same time");
1543}
1544
1545void populateCoreTestGroup (tcu::TestCaseGroup* group)
1546{
1547	BufferMemoryRequirementsOriginal	bufferTest;
1548	ImageMemoryRequirementsOriginal		imageTest;
1549
1550	bufferTest.populateTestGroup(group);
1551	imageTest.populateTestGroup(group);
1552}
1553
1554void populateExtendedTestGroup (tcu::TestCaseGroup* group)
1555{
1556	BufferMemoryRequirementsExtended	bufferTest;
1557	ImageMemoryRequirementsExtended		imageTest;
1558
1559	bufferTest.populateTestGroup(group);
1560	imageTest.populateTestGroup(group);
1561}
1562
1563void populateDedicatedAllocationTestGroup (tcu::TestCaseGroup* group)
1564{
1565	BufferMemoryRequirementsDedicatedAllocation	bufferTest;
1566	ImageMemoryRequirementsDedicatedAllocation	imageTest;
1567
1568	bufferTest.populateTestGroup(group);
1569	imageTest.populateTestGroup(group);
1570}
1571
1572bool isMultiplaneImageSupported (const InstanceInterface&	vki,
1573								 const VkPhysicalDevice		physicalDevice,
1574								 const VkImageCreateInfo&	info)
1575{
1576	if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
1577		return false;
1578
1579	if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
1580		(info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
1581		return false;
1582
1583	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physicalDevice);
1584
1585	if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
1586	{
1587		DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
1588
1589		if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
1590			return false;
1591	}
1592
1593	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physicalDevice, info.format);
1594	const VkFormatFeatureFlags	formatFeatures		= (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
1595																							 : formatProperties.optimalTilingFeatures);
1596
1597	if (!isUsageMatchesFeatures(info.usage, formatFeatures))
1598		return false;
1599
1600	VkImageFormatProperties		imageFormatProperties;
1601	const VkResult				result				= vki.getPhysicalDeviceImageFormatProperties(
1602														physicalDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1603
1604	if (result == VK_SUCCESS)
1605	{
1606		if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1607			return false;
1608		if (info.mipLevels > imageFormatProperties.maxMipLevels)
1609			return false;
1610		if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1611			return false;
1612	}
1613
1614	return result == VK_SUCCESS;
1615}
1616
1617tcu::TestStatus testMultiplaneImages (Context& context, ImageTestParams params)
1618{
1619	const VkFormat multiplaneFormats[] =
1620	{
1621		VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR,
1622		VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
1623		VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR,
1624		VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR,
1625		VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR,
1626		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR,
1627		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR,
1628		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR,
1629		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR,
1630		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR,
1631		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR,
1632		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR,
1633		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR,
1634		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR,
1635		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR,
1636		VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR,
1637		VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR,
1638		VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR,
1639		VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR
1640	};
1641	{
1642		const std::string extensionName("VK_KHR_get_memory_requirements2");
1643
1644		if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName))
1645			TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1646	}
1647	{
1648		const std::string extensionName("VK_KHR_sampler_ycbcr_conversion");
1649
1650		if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), extensionName))
1651			TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1652	}
1653
1654	const DeviceInterface&					vk					= context.getDeviceInterface();
1655	const InstanceInterface&				vki					= context.getInstanceInterface();
1656	const VkDevice							device				= context.getDevice();
1657	const VkPhysicalDevice					physicalDevice		= context.getPhysicalDevice();
1658	const VkImageCreateFlags				sparseFlags			= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1659	const VkImageUsageFlags					transientFlags		= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1660	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physicalDevice);
1661	tcu::TestLog&							log					= context.getTestContext().getLog();
1662	tcu::ResultCollector					result				(log, "ERROR: ");
1663	deUint32								errorCount			= 0;
1664
1665	log << TestLog::Message << "Memory properties: " << memoryProperties << TestLog::EndMessage;
1666
1667	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(multiplaneFormats); formatNdx++)
1668	{
1669		for (VkImageCreateFlags		loopCreateFlags	= (VkImageCreateFlags)0;			loopCreateFlags	<= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;	loopCreateFlags	= nextFlagExcluding(loopCreateFlags, sparseFlags))
1670		for (VkImageUsageFlags		loopUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;	loopUsageFlags	<= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;	loopUsageFlags	= nextFlagExcluding(loopUsageFlags, transientFlags))
1671		{
1672			const VkFormat				format				= multiplaneFormats[formatNdx];
1673			const VkImageCreateFlags	actualCreateFlags	= loopCreateFlags | params.flags;
1674			const VkImageUsageFlags		actualUsageFlags	= loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1675			const VkImageCreateInfo		imageInfo			=
1676			{
1677				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType          sType;
1678				DE_NULL,								// const void*              pNext;
1679				actualCreateFlags,						// VkImageCreateFlags       flags;
1680				VK_IMAGE_TYPE_2D,						// VkImageType              imageType;
1681				format,									// VkFormat                 format;
1682				{ 64u, 64u, 1u, },						// VkExtent3D               extent;
1683				1u,										// uint32_t                 mipLevels;
1684				1u,										// uint32_t                 arrayLayers;
1685				VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits    samples;
1686				params.tiling,							// VkImageTiling            tiling;
1687				actualUsageFlags,						// VkImageUsageFlags        usage;
1688				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode            sharingMode;
1689				0u,										// uint32_t                 queueFamilyIndexCount;
1690				DE_NULL,								// const uint32_t*          pQueueFamilyIndices;
1691				VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout            initialLayout;
1692			};
1693
1694			if (isMultiplaneImageSupported(vki, physicalDevice, imageInfo))
1695			{
1696				const Unique<VkImage>			image			(createImage(vk, device, &imageInfo));
1697
1698				log << tcu::TestLog::Message << "- " << getImageInfoString(imageInfo) << tcu::TestLog::EndMessage;
1699
1700				for (deUint32 planeNdx = 0; planeNdx < (deUint32)getPlaneCount(format); planeNdx++)
1701				{
1702					const VkImageAspectFlagBits					aspect		= getPlaneAspect(planeNdx);
1703					const VkImagePlaneMemoryRequirementsInfo	aspectInfo	=
1704					{
1705						VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR,
1706						DE_NULL,
1707						aspect
1708					};
1709					const VkImageMemoryRequirementsInfo2		info		=
1710					{
1711						VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR,
1712						(actualCreateFlags & VK_IMAGE_CREATE_DISJOINT_BIT_KHR) == 0 ? DE_NULL : &aspectInfo,
1713						*image
1714					};
1715					VkMemoryRequirements2						requirements	=
1716					{
1717						VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
1718						DE_NULL,
1719						{ 0u, 0u, 0u }
1720					};
1721
1722					vk.getImageMemoryRequirements2(device, &info, &requirements);
1723
1724					log << TestLog::Message << "Aspect: " << getImageAspectFlagsStr(aspect) << ", Requirements: " << requirements << TestLog::EndMessage;
1725
1726					result.check(deIsPowerOfTwo64(static_cast<deUint64>(requirements.memoryRequirements.alignment)), "VkMemoryRequirements alignment isn't power of two");
1727
1728					if (result.check(requirements.memoryRequirements.memoryTypeBits != 0, "No supported memory types"))
1729					{
1730						bool	hasHostVisibleType	= false;
1731
1732						for (deUint32 memoryTypeIndex = 0; (0x1u << memoryTypeIndex) <= requirements.memoryRequirements.memoryTypeBits; memoryTypeIndex++)
1733						{
1734							if (result.check(memoryTypeIndex < memoryProperties.memoryTypeCount, "Unknown memory type bits set in memory requirements"))
1735							{
1736								const VkMemoryPropertyFlags	propertyFlags	(memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags);
1737
1738								if (propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
1739									hasHostVisibleType = true;
1740
1741								if (propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
1742								{
1743									result.check((imageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
1744										"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
1745								}
1746							}
1747							else
1748								break;
1749						}
1750
1751						result.check(params.tiling != VK_IMAGE_TILING_LINEAR || hasHostVisibleType, "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
1752					}
1753				}
1754			}
1755		}
1756	}
1757
1758	if (errorCount > 1)
1759		return tcu::TestStatus(result.getResult(), "Failed " + de::toString(errorCount) + " cases.");
1760	else
1761		return tcu::TestStatus(result.getResult(), result.getMessage());
1762}
1763
1764void populateMultiplaneTestGroup (tcu::TestCaseGroup* group)
1765{
1766	const struct
1767	{
1768		VkImageCreateFlags		flags;
1769		bool					transient;
1770		const char* const		name;
1771	} imageFlagsCases[] =
1772	{
1773		{ (VkImageCreateFlags)0,																								false,	"regular"					},
1774		{ (VkImageCreateFlags)0,																								true,	"transient"					},
1775		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT,																					false,	"sparse"					},
1776		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,											false,	"sparse_residency"			},
1777		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT											| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_aliased"			},
1778		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT		| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_residency_aliased"	},
1779	};
1780	const struct
1781	{
1782		VkImageTiling	value;
1783		const char*		name;
1784	} tilings[] =
1785	{
1786		{ VK_IMAGE_TILING_OPTIMAL,	"optimal"	},
1787		{ VK_IMAGE_TILING_LINEAR,	"linear"	}
1788	};
1789
1790	for (size_t flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
1791	for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tilings); ++tilingNdx)
1792	{
1793		const VkImageCreateFlags	flags		= imageFlagsCases[flagsNdx].flags;
1794		const bool					transient	= imageFlagsCases[flagsNdx].transient;
1795		const VkImageTiling			tiling		= tilings[tilingNdx].value;
1796		const ImageTestParams		params		(flags, tiling, transient);
1797		const std::string			name		= std::string(imageFlagsCases[flagsNdx].name) + "_" + tilings[tilingNdx].name;
1798
1799		if (tiling == VK_IMAGE_TILING_LINEAR && (flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0)
1800			continue;
1801
1802		addFunctionCase(group, name, name, testMultiplaneImages, params);
1803	}
1804}
1805
1806} // anonymous
1807
1808
1809tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx)
1810{
1811	de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements", "Buffer and image memory requirements"));
1812
1813	requirementsGroup->addChild(createTestGroup(testCtx, "core",					"Memory requirements tests with core functionality",						populateCoreTestGroup));
1814	requirementsGroup->addChild(createTestGroup(testCtx, "extended",				"Memory requirements tests with extension VK_KHR_get_memory_requirements2",	populateExtendedTestGroup));
1815	requirementsGroup->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Memory requirements tests with extension VK_KHR_dedicated_allocation",		populateDedicatedAllocationTestGroup));
1816	requirementsGroup->addChild(createTestGroup(testCtx, "multiplane_image",		"Memory requirements tests with vkGetImagePlaneMemoryRequirements",			populateMultiplaneTestGroup));
1817
1818	return requirementsGroup.release();
1819}
1820
1821} // memory
1822} // vkt
1823