Home | History | Annotate | Download | only in memory
      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 
     44 namespace vkt
     45 {
     46 namespace memory
     47 {
     48 namespace
     49 {
     50 using namespace vk;
     51 using de::MovePtr;
     52 using tcu::TestLog;
     53 
     54 Move<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 
     70 VkMemoryRequirements 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 
     76 VkMemoryRequirements 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 
     97 VkMemoryRequirements 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.
    120 std::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 
    131 template<typename T>
    132 T nextEnum (T value)
    133 {
    134 	return static_cast<T>(static_cast<deUint32>(value) + 1);
    135 }
    136 
    137 template<typename T>
    138 T 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 
    146 template<typename T>
    147 T 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 
    154 bool validValueVkBool32 (const VkBool32 value)
    155 {
    156 	return (value == VK_FALSE || value == VK_TRUE);
    157 }
    158 
    159 class IBufferMemoryRequirements
    160 {
    161 public:
    162 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group) = 0;
    163 
    164 protected:
    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 
    192 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
    193 {
    194 	static tcu::TestStatus testEntryPoint	(Context&									context,
    195 											 const VkBufferCreateFlags					bufferFlags);
    196 
    197 public:
    198 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group);
    199 
    200 protected:
    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 
    227 protected:
    228 	VkMemoryRequirements	m_allUsageFlagsRequirements;
    229 	VkMemoryRequirements	m_currentTestRequirements;
    230 };
    231 
    232 
    233 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
    234 {
    235 	BufferMemoryRequirementsOriginal test;
    236 
    237 	return test.execTest(context, bufferFlags);
    238 }
    239 
    240 void 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 
    263 void 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 
    271 tcu::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 
    344 void 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 
    361 void 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 
    378 void 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 
    443 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
    444 {
    445 	static tcu::TestStatus testEntryPoint	(Context&					context,
    446 											 const VkBufferCreateFlags	bufferFlags);
    447 
    448 protected:
    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 
    467 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
    468 {
    469 	BufferMemoryRequirementsExtended test;
    470 
    471 	return test.execTest(context, bufferFlags);
    472 }
    473 
    474 void 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 
    482 void 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 
    495 void 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 
    513 class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended
    514 {
    515 	static tcu::TestStatus testEntryPoint	(Context&									context,
    516 											 const VkBufferCreateFlags					bufferFlags);
    517 
    518 protected:
    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 
    542 protected:
    543 	VkBool32	m_allUsageFlagsPrefersDedicatedAllocation;
    544 	VkBool32	m_allUsageFlagsRequiresDedicatedAllocation;
    545 
    546 	VkBool32	m_currentTestPrefersDedicatedAllocation;
    547 	VkBool32	m_currentTestRequiresDedicatedAllocation;
    548 };
    549 
    550 
    551 tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags)
    552 {
    553 	BufferMemoryRequirementsDedicatedAllocation test;
    554 
    555 	return test.execTest(context, bufferFlags);
    556 }
    557 
    558 void 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 
    566 void 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 
    577 void 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 
    612 void 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 
    631 struct 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 
    651 class IImageMemoryRequirements
    652 {
    653 public:
    654 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group) = 0;
    655 
    656 protected:
    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 
    677 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
    678 {
    679 	static tcu::TestStatus testEntryPoint	(Context&									context,
    680 											 const ImageTestParams						params);
    681 
    682 public:
    683 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group);
    684 
    685 protected:
    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 
    705 private:
    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 
    715 protected:
    716 	VkImageCreateInfo		m_currentTestImageInfo;
    717 	VkMemoryRequirements	m_currentTestRequirements;
    718 };
    719 
    720 
    721 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params)
    722 {
    723 	ImageMemoryRequirementsOriginal test;
    724 
    725 	return test.execTest(context, params);
    726 }
    727 
    728 void 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 
    777 void 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 
    785 void 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 
    802 void 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 
    810 void 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 
    854 bool 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
    869 bool 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 
   1030 VkExtent3D 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 
   1042 bool 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 
   1052 std::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 
   1080 tcu::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 
   1399 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
   1400 {
   1401 public:
   1402 	static tcu::TestStatus testEntryPoint	(Context&									context,
   1403 											 const ImageTestParams						params);
   1404 
   1405 protected:
   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 
   1421 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params)
   1422 {
   1423 	ImageMemoryRequirementsExtended test;
   1424 
   1425 	return test.execTest(context, params);
   1426 }
   1427 
   1428 void 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 
   1436 void 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 
   1449 void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&		vk,
   1450 															    const VkDevice				device)
   1451 {
   1452 	m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
   1453 }
   1454 
   1455 
   1456 class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended
   1457 {
   1458 public:
   1459 	static tcu::TestStatus testEntryPoint	(Context&									context,
   1460 											 const ImageTestParams						params);
   1461 
   1462 protected:
   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 
   1479 protected:
   1480 	VkBool32	m_currentTestPrefersDedicatedAllocation;
   1481 	VkBool32	m_currentTestRequiresDedicatedAllocation;
   1482 };
   1483 
   1484 
   1485 tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint (Context& context, const ImageTestParams params)
   1486 {
   1487 	ImageMemoryRequirementsDedicatedAllocation test;
   1488 
   1489 	return test.execTest(context, params);
   1490 }
   1491 
   1492 void 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 
   1500 void 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 
   1512 void 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 
   1530 void 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 
   1545 void populateCoreTestGroup (tcu::TestCaseGroup* group)
   1546 {
   1547 	BufferMemoryRequirementsOriginal	bufferTest;
   1548 	ImageMemoryRequirementsOriginal		imageTest;
   1549 
   1550 	bufferTest.populateTestGroup(group);
   1551 	imageTest.populateTestGroup(group);
   1552 }
   1553 
   1554 void populateExtendedTestGroup (tcu::TestCaseGroup* group)
   1555 {
   1556 	BufferMemoryRequirementsExtended	bufferTest;
   1557 	ImageMemoryRequirementsExtended		imageTest;
   1558 
   1559 	bufferTest.populateTestGroup(group);
   1560 	imageTest.populateTestGroup(group);
   1561 }
   1562 
   1563 void populateDedicatedAllocationTestGroup (tcu::TestCaseGroup* group)
   1564 {
   1565 	BufferMemoryRequirementsDedicatedAllocation	bufferTest;
   1566 	ImageMemoryRequirementsDedicatedAllocation	imageTest;
   1567 
   1568 	bufferTest.populateTestGroup(group);
   1569 	imageTest.populateTestGroup(group);
   1570 }
   1571 
   1572 bool 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 
   1617 tcu::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 
   1764 void 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 
   1809 tcu::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