/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Buffer and image memory requirements tests.
 *//*--------------------------------------------------------------------*/

#include "vktMemoryRequirementsTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"

#include "vkDefs.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkStrUtil.hpp"
#include "vkTypeUtil.hpp"

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"

#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"

namespace vkt
{
namespace memory
{
namespace
{
using namespace vk;
using de::MovePtr;

Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
{
	const VkBufferCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType        sType;
		DE_NULL,									// const void*            pNext;
		flags,										// VkBufferCreateFlags    flags;
		size,										// VkDeviceSize           size;
		usage,										// VkBufferUsageFlags     usage;
		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode          sharingMode;
		0u,											// uint32_t               queueFamilyIndexCount;
		DE_NULL,									// const uint32_t*        pQueueFamilyIndices;
	};
	return createBuffer(vk, device, &createInfo);
}

//! Get an index of each set bit, starting from the least significant bit.
std::vector<deUint32> bitsToIndices (deUint32 bits)
{
	std::vector<deUint32> indices;
	for (deUint32 i = 0u; bits != 0u; ++i, bits >>= 1)
	{
		if (bits & 1u)
			indices.push_back(i);
	}
	return indices;
}

VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
{
	const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
	return getBufferMemoryRequirements(vk, device, *buffer);
}

template<typename T>
T nextEnum (T value)
{
	return static_cast<T>(static_cast<deUint32>(value) + 1);
}

template<typename T>
T nextFlag (T value)
{
	if (value)
		return static_cast<T>(static_cast<deUint32>(value) << 1);
	else
		return static_cast<T>(1);
}

template<typename T>
T nextFlagExcluding (T value, T excludedFlags)
{
	deUint32 tmp = static_cast<deUint32>(value);
	while ((tmp = nextFlag(tmp)) & static_cast<deUint32>(excludedFlags));
	return static_cast<T>(tmp);
}

void requireBufferSparseFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkBufferCreateFlags flags)
{
	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);

	if ((flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
		TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");

	if ((flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && !features.sparseResidencyBuffer)
		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyBuffer");

	if ((flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
}

void verifyBufferRequirements (tcu::ResultCollector&					result,
							   const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
							   const VkMemoryRequirements&				requirements,
							   const VkMemoryRequirements&				allUsageFlagsRequirements,
							   const VkPhysicalDeviceLimits&			limits,
							   const VkBufferCreateFlags				bufferFlags,
							   const VkBufferUsageFlags					usage)
{
	if (result.check(requirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
	{
		typedef std::vector<deUint32>::const_iterator	IndexIterator;
		const std::vector<deUint32>						usedMemoryTypeIndices			= bitsToIndices(requirements.memoryTypeBits);
		bool											deviceLocalMemoryFound			= false;
		bool											hostVisibleCoherentMemoryFound	= false;

		for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
		{
			if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
			{
				result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
				continue;
			}

			const VkMemoryPropertyFlags	memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;

			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
				deviceLocalMemoryFound = true;

			if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
				hostVisibleCoherentMemoryFound = true;

			result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
				"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
		}

		result.check(deIsPowerOfTwo64(static_cast<deUint64>(requirements.alignment)) == DE_TRUE,
			"VkMemoryRequirements alignment isn't power of two");

		if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
		{
			result.check(requirements.alignment >= limits.minTexelBufferOffsetAlignment,
				"VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
		}

		if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
		{
			result.check(requirements.alignment >= limits.minUniformBufferOffsetAlignment,
				"VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
		}

		if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
		{
			result.check(requirements.alignment >= limits.minStorageBufferOffsetAlignment,
				"VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
		}

		result.check(deviceLocalMemoryFound,
			"None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");

		result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
			"Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");

		result.check((requirements.memoryTypeBits & allUsageFlagsRequirements.memoryTypeBits) == allUsageFlagsRequirements.memoryTypeBits,
			"Memory type bits aren't a superset of memory type bits for all usage flags combined");
	}
}

tcu::TestStatus testBuffer (Context& context, const VkBufferCreateFlags bufferFlags)
{
	const DeviceInterface&					vk							= context.getDeviceInterface();
	const InstanceInterface&				vki							= context.getInstanceInterface();
	const VkDevice							device						= context.getDevice();
	const VkPhysicalDevice					physDevice					= context.getPhysicalDevice();

	requireBufferSparseFeatures(vki, physDevice, bufferFlags);

	const VkPhysicalDeviceMemoryProperties	memoryProperties			= getPhysicalDeviceMemoryProperties(vki, physDevice);
	const VkPhysicalDeviceLimits			limits						= getPhysicalDeviceProperties(vki, physDevice).limits;
	const VkBufferUsageFlags				allUsageFlags				= static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
	const VkMemoryRequirements				allUsageFlagsRequirements	= getBufferMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags); // doesn't depend on size
	tcu::TestLog&							log							= context.getTestContext().getLog();
	bool									allPass						= true;

	const VkDeviceSize sizeCases[] =
	{
		1	 * 1024,
		8    * 1024,
		64   * 1024,
		1024 * 1024,
	};

	for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage))
	{
		deUint32		previousMemoryTypeBits	= 0u;
		VkDeviceSize	previousAlignment		= 0u;

		log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage;

		for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
		{
			log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;

			const VkMemoryRequirements	requirements	= getBufferMemoryRequirements(vk, device, *pSize, bufferFlags, usage);
			tcu::ResultCollector		result			(log, "ERROR: ");

			// Check:
			// - requirements for a particular buffer usage
			// - memoryTypeBits are a subset of bits for requirements with all usage flags combined
			verifyBufferRequirements(result, memoryProperties, requirements, allUsageFlagsRequirements, limits, bufferFlags, usage);

			// Check that for the same usage and create flags:
			// - memoryTypeBits are the same
			// - alignment is the same
			if (pSize > sizeCases)
			{
				result.check(requirements.memoryTypeBits == previousMemoryTypeBits,
					"memoryTypeBits differ from the ones in the previous buffer size");

				result.check(requirements.alignment == previousAlignment,
					"alignment differs from the one in the previous buffer size");
			}

			if (result.getResult() != QP_TEST_RESULT_PASS)
				allPass = false;

			previousMemoryTypeBits	= requirements.memoryTypeBits;
			previousAlignment		= requirements.alignment;
		}

		if (!allPass)
			break;
	}

	return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
}

void requireImageSparseFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkImageCreateFlags createFlags)
{
	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);

	if ((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
		TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");

	if ((createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");

	if ((createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
}

bool imageUsageMatchesFormatFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
{
	if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
		return true;
	if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
		return true;
	if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
		return true;
	if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
		return true;

	return false;
}

//! This catches both invalid as well as legal but unsupported combinations of image parameters
bool isImageSupported (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkImageCreateInfo& info)
{
	DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);

	if (info.imageType == VK_IMAGE_TYPE_1D)
	{
		DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
	}
	else if (info.imageType == VK_IMAGE_TYPE_2D)
	{
		DE_ASSERT(info.extent.depth == 1u);

		if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
		{
			DE_ASSERT(info.extent.width == info.extent.height);
			DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
		}
	}

	if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
		return false;

	if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
		(info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
		return false;

	if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
		(info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
		return false;

	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);

	if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
	{
		DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);

		if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
			return false;
		if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
			return false;
		if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
			return false;
		if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
			return false;
		if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
			return false;
		if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
			return false;
		if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
			return false;
	}

	if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample)
		return false;

	switch (info.format)
	{
		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
		case VK_FORMAT_BC2_UNORM_BLOCK:
		case VK_FORMAT_BC2_SRGB_BLOCK:
		case VK_FORMAT_BC3_UNORM_BLOCK:
		case VK_FORMAT_BC3_SRGB_BLOCK:
		case VK_FORMAT_BC4_UNORM_BLOCK:
		case VK_FORMAT_BC4_SNORM_BLOCK:
		case VK_FORMAT_BC5_UNORM_BLOCK:
		case VK_FORMAT_BC5_SNORM_BLOCK:
		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
		case VK_FORMAT_BC7_UNORM_BLOCK:
		case VK_FORMAT_BC7_SRGB_BLOCK:
			if (!features.textureCompressionBC)
				return false;
			break;

		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
			if (!features.textureCompressionETC2)
				return false;
			break;

		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
			if (!features.textureCompressionASTC_LDR)
				return false;
			break;

		default:
			break;
	}

	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
	const VkFormatFeatureFlags	formatFeatures		= (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
																							 : formatProperties.optimalTilingFeatures);

	if (!imageUsageMatchesFormatFeatures(info.usage, formatFeatures))
		return false;

	VkImageFormatProperties		imageFormatProperties;
	const VkResult				result				= vki.getPhysicalDeviceImageFormatProperties(
														physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);

	if (result == VK_SUCCESS)
	{
		if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
			return false;
		if (info.mipLevels > imageFormatProperties.maxMipLevels)
			return false;
		if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
			return false;
	}

	return result == VK_SUCCESS;
}

VkExtent3D makeExtentForImage (const VkImageType imageType)
{
	VkExtent3D extent = { 64u, 64u, 4u };

	if (imageType == VK_IMAGE_TYPE_1D)
		extent.height = extent.depth = 1u;
	else if (imageType == VK_IMAGE_TYPE_2D)
		extent.depth = 1u;

	return extent;
}

bool isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect)
{
	DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));

	// D/S formats are laid out next to each other in the enum
	const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);

	return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
}

void verifyImageRequirements (tcu::ResultCollector&						result,
							  const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
							  const VkMemoryRequirements&				requirements,
							  const VkImageCreateInfo&					imageInfo)
{
	if (result.check(requirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
	{
		typedef std::vector<deUint32>::const_iterator	IndexIterator;
		const std::vector<deUint32>						usedMemoryTypeIndices			= bitsToIndices(requirements.memoryTypeBits);
		bool											deviceLocalMemoryFound			= false;
		bool											hostVisibleCoherentMemoryFound	= false;

		for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
		{
			if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
			{
				result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
				continue;
			}

			const VkMemoryPropertyFlags	memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;

			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
				deviceLocalMemoryFound = true;

			if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
				hostVisibleCoherentMemoryFound = true;

			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
			{
				result.check((imageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
					"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
			}
		}

		result.check(deIsPowerOfTwo64(static_cast<deUint64>(requirements.alignment)) == DE_TRUE,
			"VkMemoryRequirements alignment isn't power of two");

		result.check(deviceLocalMemoryFound,
			"None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");

		result.check(imageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
			"Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
	}
}

std::string getImageInfoString (const VkImageCreateInfo& imageInfo)
{
	std::ostringstream str;

	switch (imageInfo.imageType)
	{
		case VK_IMAGE_TYPE_1D:			str << "1D "; break;
		case VK_IMAGE_TYPE_2D:			str << "2D "; break;
		case VK_IMAGE_TYPE_3D:			str << "3D "; break;
		default:						break;
	}

	switch (imageInfo.tiling)
	{
		case VK_IMAGE_TILING_OPTIMAL:	str << "(optimal) "; break;
		case VK_IMAGE_TILING_LINEAR:	str << "(linear) "; break;
		default:						break;
	}

	str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] ";
	str << imageInfo.format << " ";
	str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " ";
	str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " ";
	str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " ";

	return str.str();
}

struct ImageParams
{
	VkImageCreateFlags		flags;
	VkImageTiling			tiling;
	bool					transient;
};

tcu::TestStatus testImage (Context& context, const ImageParams params)
{
	const DeviceInterface&		vk				= context.getDeviceInterface();
	const InstanceInterface&	vki				= context.getInstanceInterface();
	const VkDevice				device			= context.getDevice();
	const VkPhysicalDevice		physDevice		= context.getPhysicalDevice();
	const VkImageCreateFlags	sparseFlags		= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
	const VkImageUsageFlags		transientFlags	= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;

	requireImageSparseFeatures(vki, physDevice, params.flags);

	const VkPhysicalDeviceMemoryProperties	memoryProperties		= getPhysicalDeviceMemoryProperties(vki, physDevice);
	const deUint32							notInitializedBits		= ~0u;
	const VkImageAspectFlags				colorAspect				= VK_IMAGE_ASPECT_COLOR_BIT;
	const VkImageAspectFlags				depthStencilAspect		= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
	const VkImageAspectFlags				allAspects[2]			= { colorAspect, depthStencilAspect };
	tcu::TestLog&							log						= context.getTestContext().getLog();
	bool									allPass					= true;
	deUint32								numCheckedImages		= 0u;

	log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;

	for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
	{
		const VkImageAspectFlags	aspect					= allAspects[loopAspectNdx];
		deUint32					previousMemoryTypeBits	= notInitializedBits;

		for (VkFormat loopFormat = VK_FORMAT_R4G4_UNORM_PACK8; loopFormat <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; loopFormat = nextEnum(loopFormat))
		if  (isFormatMatchingAspect(loopFormat, aspect))
		{
			// memoryTypeBits may differ between depth/stencil formats
			if (aspect == depthStencilAspect)
				previousMemoryTypeBits = notInitializedBits;

			for (VkImageType			loopImageType	= VK_IMAGE_TYPE_1D;					loopImageType	!= VK_IMAGE_TYPE_LAST;					loopImageType	= nextEnum(loopImageType))
			for (VkImageCreateFlags		loopCreateFlags	= (VkImageCreateFlags)0;			loopCreateFlags	<= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;	loopCreateFlags	= nextFlagExcluding(loopCreateFlags, sparseFlags))
			for (VkImageUsageFlags		loopUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;	loopUsageFlags	<= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;	loopUsageFlags	= nextFlagExcluding(loopUsageFlags, transientFlags))
			for (VkSampleCountFlagBits	loopSampleCount	= VK_SAMPLE_COUNT_1_BIT;			loopSampleCount	<= VK_SAMPLE_COUNT_16_BIT;				loopSampleCount	= nextFlag(loopSampleCount))
			{
				const VkImageCreateFlags	actualCreateFlags	= loopCreateFlags | params.flags;
				const VkImageUsageFlags		actualUsageFlags	= loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
				const bool					isCube				= (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
				const VkImageCreateInfo		imageInfo			=
				{
					VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
					DE_NULL,									// const void*              pNext;
					actualCreateFlags,							// VkImageCreateFlags       flags;
					loopImageType,								// VkImageType              imageType;
					loopFormat,									// VkFormat                 format;
					makeExtentForImage(loopImageType),			// VkExtent3D               extent;
					1u,											// uint32_t                 mipLevels;
					(isCube ? 6u : 1u),							// uint32_t                 arrayLayers;
					loopSampleCount,							// VkSampleCountFlagBits    samples;
					params.tiling,								// VkImageTiling            tiling;
					actualUsageFlags,							// VkImageUsageFlags        usage;
					VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
					0u,											// uint32_t                 queueFamilyIndexCount;
					DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
					VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
				};

				if (!isImageSupported(vki, physDevice, imageInfo))
					continue;

				log << tcu::TestLog::Message << "- " << getImageInfoString(imageInfo) << tcu::TestLog::EndMessage;
				++numCheckedImages;

				const Unique<VkImage>		image			(createImage(vk, device, &imageInfo));
				const VkMemoryRequirements	requirements	= getImageMemoryRequirements(vk, device, *image);
				tcu::ResultCollector		result			(log, "ERROR: ");

				verifyImageRequirements(result, memoryProperties, requirements, imageInfo);

				// For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
				result.check((previousMemoryTypeBits == notInitializedBits) || (requirements.memoryTypeBits == previousMemoryTypeBits),
								"memoryTypeBits differ from the ones in the previous image configuration");

				if (result.getResult() != QP_TEST_RESULT_PASS)
					allPass = false;

				previousMemoryTypeBits = requirements.memoryTypeBits;
			}
		}
	}

	if (numCheckedImages == 0u)
		log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage;

	return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
}

void populateTestGroup (tcu::TestCaseGroup* group)
{
	// Buffers
	{
		const struct
		{
			VkBufferCreateFlags		flags;
			const char* const		name;
		} bufferCases[] =
		{
			{ (VkBufferCreateFlags)0,																								"regular"					},
			{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT,																					"sparse"					},
			{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,											"sparse_residency"			},
			{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT											| VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	"sparse_aliased"			},
			{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT	| VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	"sparse_residency_aliased"	},
		};

		de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer", ""));

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
			addFunctionCase(bufferGroup.get(), bufferCases[ndx].name, "", testBuffer, bufferCases[ndx].flags);

		group->addChild(bufferGroup.release());
	}

	// Images
	{
		const struct
		{
			VkImageCreateFlags		flags;
			bool					transient;
			const char* const		name;
		} imageFlagsCases[] =
		{
			{ (VkImageCreateFlags)0,																								false,	"regular"					},
			{ (VkImageCreateFlags)0,																								true,	"transient"					},
			{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT,																					false,	"sparse"					},
			{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,											false,	"sparse_residency"			},
			{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT											| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_aliased"			},
			{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT		| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_residency_aliased"	},
		};

		de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image", ""));

		for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
		for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
		{
			ImageParams			params;
			std::ostringstream	caseName;

			params.flags		=  imageFlagsCases[flagsNdx].flags;
			params.transient	=  imageFlagsCases[flagsNdx].transient;
			caseName			<< imageFlagsCases[flagsNdx].name;

			if (tilingNdx != 0)
			{
				params.tiling =  VK_IMAGE_TILING_OPTIMAL;
				caseName      << "_tiling_optimal";
			}
			else
			{
				params.tiling =  VK_IMAGE_TILING_LINEAR;
				caseName      << "_tiling_linear";
			}

			if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
				continue;

			addFunctionCase(imageGroup.get(), caseName.str(), "", testImage, params);
		}

		group->addChild(imageGroup.release());
	}
}

} // anonymous

tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "requirements", "Buffer and image memory requirements", populateTestGroup);
}

} // memory
} // vkt
