/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2020 The Khronos Group Inc.
 * Copyright (c) 2020 Valve Corporation.
 *
 * 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  vktImageSubresourceLayoutTests.cpp
 * \brief Tests for vkGetImageSubresourceLayout
 *//*--------------------------------------------------------------------*/

#include "vktTestCase.hpp"

#include "vkDefs.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkStrUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkImageWithMemory.hpp"

#include "tcuTestLog.hpp"
#include "vktTestCase.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuFloat.hpp"
#include "tcuCommandLine.hpp"

#include "deRandom.hpp"

#include <vector>
#include <sstream>
#include <limits>
#include <string>

using namespace vk;

namespace vkt
{
namespace image
{
namespace
{

// Helper class to calculate buffer sizes and offsets for image mipmap levels.
class BufferLevels
{
public:
	struct Level
	{
		VkDeviceSize	offset;		// In bytes.
		VkDeviceSize	size;		// In bytes.
		VkExtent3D		dimensions;	// .depth will be the number of layers for 2D images and the depth for 3D images.
	};

					BufferLevels	(VkImageType type, VkFormat format, VkExtent3D levelZero, deUint32 maxLevels, VkImageAspectFlags aspects = 0u);
	VkDeviceSize	totalSize		() const;
	VkDeviceSize	pixelSize		() const;
	deUint32		numLevels		() const;
	const Level&	getLevel		(deUint32 level) const;

private:
	VkDeviceSize		m_pixelSize; // In bytes.
	std::vector<Level>	m_levels;
};

BufferLevels::BufferLevels (VkImageType type, VkFormat format, VkExtent3D levelZero, deUint32 maxLevels, VkImageAspectFlags aspects)
{
	DE_ASSERT(type == VK_IMAGE_TYPE_2D || type == VK_IMAGE_TYPE_3D);
	DE_ASSERT(maxLevels >= 1u);

	const auto		tcuFormat		= vk::mapVkFormat(format);
	const auto		maxLevelsSz		= static_cast<size_t>(maxLevels);

	VkDeviceSize	currentOffset	= 0ull;
	VkExtent3D		nextExtent		= levelZero;
	deUint32		levelCount		= 0;

	if (!aspects || (aspects & VK_IMAGE_ASPECT_COLOR_BIT))
	{
		m_pixelSize = static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat));
	}
	else if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
	{
		const auto copyFormat = getDepthCopyFormat(format);
		m_pixelSize = static_cast<VkDeviceSize>(tcu::getPixelSize(copyFormat));
	}
	else if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
	{
		const auto copyFormat = getStencilCopyFormat(format);
		m_pixelSize = static_cast<VkDeviceSize>(tcu::getPixelSize(copyFormat));
	}
	else
		DE_ASSERT(false);

	while (m_levels.size() < maxLevelsSz)
	{
		Level level;

		level.offset		= currentOffset;
		level.size			= m_pixelSize * nextExtent.width * nextExtent.height * nextExtent.depth;
		level.dimensions	= nextExtent;

		m_levels.push_back(level);

		// This was the last available level.
		if (nextExtent.width == 1u && nextExtent.height == 1u && (type == VK_IMAGE_TYPE_2D || nextExtent.depth == 1u))
			break;

		nextExtent.width = std::max(1u, (nextExtent.width / 2u));
		nextExtent.height = std::max(1u, (nextExtent.height / 2u));

		// 2D arrays all have the same array size.
		if (type == VK_IMAGE_TYPE_3D)
			nextExtent.depth = std::max(1u, (nextExtent.depth / 2u));

		currentOffset += level.size;
		++levelCount;
	}
}

VkDeviceSize BufferLevels::totalSize () const
{
	VkDeviceSize total = 0ull;
	std::for_each(begin(m_levels), end(m_levels), [&total] (const Level& l) { total += l.size; });
	return total;
}

VkDeviceSize BufferLevels::pixelSize () const
{
	return m_pixelSize;
}

deUint32 BufferLevels::numLevels () const
{
	return static_cast<deUint32>(m_levels.size());
}

const BufferLevels::Level& BufferLevels::getLevel (deUint32 level) const
{
	return m_levels.at(level);
}

// Default image dimensions. For 2D images, .depth indicates the number of layers.
VkExtent3D getDefaultDimensions (VkImageType type, bool array)
{
	DE_ASSERT(type == VK_IMAGE_TYPE_2D || type == VK_IMAGE_TYPE_3D);
	DE_ASSERT(!array || type == VK_IMAGE_TYPE_2D);

	constexpr VkExtent3D kDefault3D			= { 32u, 48u, 56u };
	constexpr VkExtent3D kDefault2DArray	= kDefault3D;
	constexpr VkExtent3D kDefault2D			= { 240u, 320u, 1u };

	if (type == VK_IMAGE_TYPE_3D)
		return kDefault3D;
	if (array)
		return kDefault2DArray;
	return kDefault2D;
}

class ImageSubresourceLayoutCase : public vkt::TestCase
{
public:
	struct TestParams
	{
		VkImageType	imageType;
		VkFormat	imageFormat;
		VkExtent3D	dimensions;		// .depth will be the number of layers for 2D images and the depth for 3D images.
		deUint32	mipLevels;
	};

							ImageSubresourceLayoutCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params);
	virtual					~ImageSubresourceLayoutCase		(void) {}

	virtual void			initPrograms					(vk::SourceCollections&) const {}
	virtual TestInstance*	createInstance					(Context& context) const;
	virtual void			checkSupport					(Context& context) const;

	static constexpr VkFormatFeatureFlags	kRequiredFeatures	= (VK_FORMAT_FEATURE_TRANSFER_DST_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
	static constexpr VkImageUsageFlags		kImageUsageFlags	= (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
	static constexpr VkImageTiling			kImageTiling		= VK_IMAGE_TILING_LINEAR;
private:
	TestParams m_params;
};

class ImageSubresourceLayoutInstance : public vkt::TestInstance
{
public:
								ImageSubresourceLayoutInstance	(Context& context, const ImageSubresourceLayoutCase::TestParams& params);
	virtual						~ImageSubresourceLayoutInstance	(void) {}

	virtual tcu::TestStatus		iterate							(void);
	tcu::TestStatus				iterateAspect					(VkImageAspectFlagBits aspect);
private:
	ImageSubresourceLayoutCase::TestParams m_params;
};

ImageSubresourceLayoutCase::ImageSubresourceLayoutCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
	: vkt::TestCase	(testCtx, name, description)
	, m_params		(params)
{
}

TestInstance* ImageSubresourceLayoutCase::createInstance (Context& context) const
{
	return new ImageSubresourceLayoutInstance (context, m_params);
}

void ImageSubresourceLayoutCase::checkSupport (Context& context) const
{
	const auto&	vki				= context.getInstanceInterface();
	const auto	physicalDevice	= context.getPhysicalDevice();

	const auto formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, m_params.imageFormat);
	if ((formatProperties.linearTilingFeatures & kRequiredFeatures) != kRequiredFeatures)
		TCU_THROW(NotSupportedError, "Required format features not supported");

	VkImageFormatProperties imgFormatProperties;
	const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_params.imageFormat, m_params.imageType, kImageTiling, kImageUsageFlags, 0u, &imgFormatProperties);
	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
		TCU_THROW(NotSupportedError, "Linear tiling not supported for format");
	VK_CHECK(result);

	{
		BufferLevels levels (m_params.imageType, m_params.imageFormat, m_params.dimensions, m_params.mipLevels);
		if (imgFormatProperties.maxMipLevels < levels.numLevels())
			TCU_THROW(NotSupportedError, "Required number of mip levels not supported for format");
	}

	if (m_params.imageType == VK_IMAGE_TYPE_2D && imgFormatProperties.maxArrayLayers < m_params.dimensions.depth)
		TCU_THROW(NotSupportedError, "Required number of layers not supported for format");
}

ImageSubresourceLayoutInstance::ImageSubresourceLayoutInstance (Context& context, const ImageSubresourceLayoutCase::TestParams& params)
	: vkt::TestInstance	(context)
	, m_params			(params)
{
}

// Fills length bytes starting at location with pseudorandom data.
void fillWithRandomData (de::Random& rnd, void* location, VkDeviceSize length)
{
	auto		bytePtr	= reinterpret_cast<unsigned char*>(location);
	const auto	endPtr	= bytePtr + length;

	while (bytePtr != endPtr)
	{
		const auto remaining = (endPtr - bytePtr);

		if (remaining >= 8)			{ const auto data = rnd.getUint64();	deMemcpy(bytePtr, &data, sizeof(data)); bytePtr += sizeof(data); }
		else if (remaining >= 4)	{ const auto data = rnd.getUint32();	deMemcpy(bytePtr, &data, sizeof(data)); bytePtr += sizeof(data); }
		else if (remaining >= 2)	{ const auto data = rnd.getUint16();	deMemcpy(bytePtr, &data, sizeof(data)); bytePtr += sizeof(data); }
		else						{ const auto data = rnd.getUint8();		deMemcpy(bytePtr, &data, sizeof(data)); bytePtr += sizeof(data); }
	}
}

// Fills data in blocks of 32 bits, discarding the higher 8 bits of each block.
void fillWithRandomData24In32 (de::Random& rnd, void* location, VkDeviceSize length)
{
	static const auto blockSize = sizeof(deUint32);
	DE_ASSERT(length % blockSize == 0);

	auto		dataPtr		= reinterpret_cast<unsigned char*>(location);
	const auto	numBlocks	= length / blockSize;

	for (VkDeviceSize i = 0; i < numBlocks; ++i)
	{
		auto data = rnd.getUint32();
		data &= 0xFFFFFFu; // Remove the higher 8 bits.
		deMemcpy(dataPtr, &data, blockSize);
		dataPtr += blockSize;
	}
}

// Helpers to make fillWithRandomFloatingPoint a template. Returns normal numbers in the range [0, 1).
template <class T>
T getNormalFPValue (de::Random& rnd);

template<>
float getNormalFPValue<float> (de::Random& rnd)
{
	float value;
	do {
		value = rnd.getFloat();
	} while (tcu::Float32(value).isDenorm());
	return value;
}

template<>
double getNormalFPValue<double> (de::Random& rnd)
{
	double value;
	do {
		value = rnd.getDouble();
	} while (tcu::Float64(value).isDenorm());
	return value;
}

template<>
tcu::Float16 getNormalFPValue<tcu::Float16> (de::Random& rnd)
{
	tcu::Float16 value;
	do {
		value = tcu::Float16(rnd.getFloat());
	} while (value.isDenorm());
	return value;
}

template <class T>
void fillWithRandomFloatingPoint (de::Random& rnd, void* location, VkDeviceSize length)
{
	static const auto typeSize = sizeof(T);

	DE_ASSERT(length % typeSize == 0);

	const auto	numElements	= length / typeSize;
	auto		elemPtr		= reinterpret_cast<unsigned char*>(location);
	T			elem;

	for (VkDeviceSize i = 0; i < numElements; ++i)
	{
		elem = getNormalFPValue<T>(rnd);
		deMemcpy(elemPtr, &elem, typeSize);
		elemPtr += typeSize;
	}
}

tcu::TestStatus ImageSubresourceLayoutInstance::iterate (void)
{
	// Test every aspect supported by the image format.
	const auto tcuFormat	= mapVkFormat(m_params.imageFormat);
	const auto aspectFlags	= getImageAspectFlags(tcuFormat);

	static const VkImageAspectFlagBits aspectBits[] =
	{
		VK_IMAGE_ASPECT_COLOR_BIT,
		VK_IMAGE_ASPECT_DEPTH_BIT,
		VK_IMAGE_ASPECT_STENCIL_BIT,
	};

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(aspectBits); ++i)
	{
		const auto bit = aspectBits[i];
		if (aspectFlags & bit)
		{
			const auto aspectResult = iterateAspect(bit);
			if (aspectResult.getCode() != QP_TEST_RESULT_PASS)
				return aspectResult; // Early return for failures.
		}
	}

	return tcu::TestStatus::pass("Pass");
}

tcu::TestStatus ImageSubresourceLayoutInstance::iterateAspect (VkImageAspectFlagBits imageAspect)
{
	// * Create linear image with several mipmaps
	// * Fill its levels with unique appropriate data (avoiding invalid sfloat values, for example).
	// * Ask for the subresource layout parameters.
	// * Verify they make sense.
	// * Check accessing data with the given parameters gives back the original data.

	const auto&	vkd					= m_context.getDeviceInterface();
	const auto	device				= m_context.getDevice();
	auto&		alloc				= m_context.getDefaultAllocator();
	const auto	queue				= m_context.getUniversalQueue();
	const auto	queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	auto&		log					= m_context.getTestContext().getLog();

	log << tcu::TestLog::Message << "Testing aspect " << imageAspect << tcu::TestLog::EndMessage;

	// Get an idea of the buffer size and parameters to prepare image data.
	const BufferLevels	bufferLevels	(m_params.imageType, m_params.imageFormat, m_params.dimensions, m_params.mipLevels, imageAspect);
	const auto			pixelSize		= bufferLevels.pixelSize();
	const auto			pixelSizeSz		= static_cast<size_t>(pixelSize);
	const auto			numLevels		= bufferLevels.numLevels();

	// Create source buffer.
	const auto			bufferSize	= bufferLevels.totalSize();
	const auto			bufferInfo	= makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
	BufferWithMemory	buffer		(vkd, device, alloc, bufferInfo, MemoryRequirement::HostVisible);
	auto&				bufferAlloc	= buffer.getAllocation();
	auto*				bufferPtr	= reinterpret_cast<unsigned char*>(bufferAlloc.getHostPtr());

	// Fill buffer with random appropriate data.
	const deUint32	randomSeed	= 1594055758u + static_cast<deUint32>(m_params.imageFormat) + static_cast<deUint32>(imageAspect);
	de::Random		rnd			(randomSeed);
	const auto		tcuFormat	= mapVkFormat(m_params.imageFormat);
	// For some formats, the copy block is 32 bits wide but the 8 MSB need to be ignored, so we zero them out.
	const bool		use24LSB	= ((m_params.imageFormat == VK_FORMAT_X8_D24_UNORM_PACK32 || m_params.imageFormat == VK_FORMAT_D24_UNORM_S8_UINT) && imageAspect == VK_IMAGE_ASPECT_DEPTH_BIT);

	if (tcuFormat.type == tcu::TextureFormat::FLOAT || (m_params.imageFormat == VK_FORMAT_D32_SFLOAT_S8_UINT && imageAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
		fillWithRandomFloatingPoint<float>(rnd, bufferPtr, bufferSize);
	else if (tcuFormat.type == tcu::TextureFormat::FLOAT64)
		fillWithRandomFloatingPoint<double>(rnd, bufferPtr, bufferSize);
	else if (tcuFormat.type == tcu::TextureFormat::HALF_FLOAT)
		fillWithRandomFloatingPoint<tcu::Float16>(rnd, bufferPtr, bufferSize);
	else if (use24LSB)
		fillWithRandomData24In32(rnd, bufferPtr, bufferSize);
	else
		fillWithRandomData(rnd, bufferPtr, bufferSize);

	flushAlloc(vkd, device, bufferAlloc);

	// Reinterpret the depth dimension parameter as the number of layers if needed.
	const auto	numLayers	= ((m_params.imageType == VK_IMAGE_TYPE_3D) ? 1u : m_params.dimensions.depth);
	VkExtent3D	imageExtent	= m_params.dimensions;
	if (m_params.imageType == VK_IMAGE_TYPE_2D)
		imageExtent.depth = 1u;

	// Create image.
	const VkImageCreateInfo imageInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			//	VkStructureType			sType;
		nullptr,										//	const void*				pNext;
		0u,												//	VkImageCreateFlags		flags;
		m_params.imageType,								//	VkImageType				imageType;
		m_params.imageFormat,							//	VkFormat				format;
		imageExtent,									//	VkExtent3D				extent;
		numLevels,										//	deUint32				mipLevels;
		numLayers,										//	deUint32				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,							//	VkSampleCountFlagBits	samples;
		ImageSubresourceLayoutCase::kImageTiling,		//	VkImageTiling			tiling;
		ImageSubresourceLayoutCase::kImageUsageFlags,	//	VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,						//	VkSharingMode			sharingMode;
		0u,												//	deUint32				queueFamilyIndexCount;
		nullptr,										//	const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,						//	VkImageLayout			initialLayout;
	};
	ImageWithMemory image		(vkd, device, alloc, imageInfo, MemoryRequirement::HostVisible);
	auto&			imageAlloc	= image.getAllocation();
	auto*			imagePtr	= reinterpret_cast<unsigned char*>(imageAlloc.getHostPtr());

	// Copy regions.
	std::vector<VkBufferImageCopy> copyRegions;
	copyRegions.reserve(numLevels);

	for (deUint32 levelNdx = 0u; levelNdx < numLevels; ++levelNdx)
	{
		const auto&	level		= bufferLevels.getLevel(levelNdx);
		auto		levelExtent	= level.dimensions;

		if (m_params.imageType == VK_IMAGE_TYPE_2D)
			levelExtent.depth = 1u;	// For 2D images, .depth indicates the number of layers.

		VkBufferImageCopy region;
		region.bufferOffset						= level.offset;
		region.bufferRowLength					= 0u;	// Tightly packed data.
		region.bufferImageHeight				= 0u;	// Ditto.
		region.imageSubresource.aspectMask		= imageAspect;
		region.imageSubresource.baseArrayLayer	= 0u;
		region.imageSubresource.layerCount		= numLayers;
		region.imageSubresource.mipLevel		= levelNdx;
		region.imageOffset						= { 0, 0, 0 };
		region.imageExtent						= levelExtent;

		copyRegions.push_back(region);
	}

	// Image layout transitions.
	const auto imageSubresourceRange	= makeImageSubresourceRange(imageAspect, 0u, numLevels, 0u, numLayers);
	const auto initialLayoutBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.get(), imageSubresourceRange);
	const auto finalLayoutBarrier		= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, image.get(), imageSubresourceRange);

	// Command buffer.
	const auto cmdPool		= makeCommandPool(vkd, device, queueFamilyIndex);
	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto cmdBuffer	= cmdBufferPtr.get();

	// Transition layout, copy, transition layout.
	beginCommandBuffer(vkd, cmdBuffer);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &initialLayoutBarrier);
	vkd.cmdCopyBufferToImage(cmdBuffer, buffer.get(), image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(copyRegions.size()), copyRegions.data());
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &finalLayoutBarrier);
	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

#ifdef CTS_USES_VULKANSC
	if (!m_context.getTestContext().getCommandLine().isSubProcess())
		return tcu::TestStatus::pass("Pass");
#endif

	// Sync image memory for host access.
	invalidateAlloc(vkd, device, imageAlloc);

	VkSubresourceLayout levelSubresourceLayout;
	VkSubresourceLayout subresourceLayout;
	for (deUint32 levelNdx = 0u; levelNdx < numLevels; ++levelNdx)
	{
		// Get base level subresource.
		const auto levelSubresource = makeImageSubresource(imageAspect, levelNdx, 0u);
		vkd.getImageSubresourceLayout(device, image.get(), &levelSubresource, &levelSubresourceLayout);

		const auto& level = bufferLevels.getLevel(levelNdx);
		for (deUint32 layerNdx = 0; layerNdx < numLayers; ++layerNdx)
		{
			const auto imageSubresource = makeImageSubresource(imageAspect, levelNdx, layerNdx);
			vkd.getImageSubresourceLayout(device, image.get(), &imageSubresource, &subresourceLayout);

			// Verify returned values.
			const auto subresourceWidth		= level.dimensions.width;
			const auto subresourceHeight	= level.dimensions.height;
			const auto subresourceDepth		= ((m_params.imageType == VK_IMAGE_TYPE_2D) ? 1u : level.dimensions.depth);
			const auto numPixels			= subresourceWidth * subresourceHeight * subresourceDepth;

			if (numLayers > 1u && levelSubresourceLayout.arrayPitch != subresourceLayout.arrayPitch)
			{
				// Inconsistent arrayPitch.
				std::ostringstream msg;
				msg << "Image level " << levelNdx
					<< " layer " << layerNdx
					<< " reports array pitch of " << subresourceLayout.arrayPitch << " bytes in size"
					<< " with base layer reporting array pitch of " << levelSubresourceLayout.arrayPitch << " bytes in size";
				return tcu::TestStatus::fail(msg.str());
			}

			if ((subresourceLayout.offset - levelSubresourceLayout.offset) != (layerNdx * subresourceLayout.arrayPitch))
			{
				// Inconsistent offset.
				std::ostringstream msg;
				msg << "Image level " << levelNdx
					<< " layer " << layerNdx
					<< " has offset inconsistent with array pitch: base offset " << levelSubresourceLayout.offset
					<< ", layer offset " << subresourceLayout.offset
					<< ", array pitch " << subresourceLayout.arrayPitch;
				return tcu::TestStatus::fail(msg.str());
			}

			if (subresourceLayout.size < pixelSize * numPixels)
			{
				// Subresource size too small.
				std::ostringstream msg;
				msg << "Image level " << levelNdx
					<< " layer " << layerNdx
					<< " reports " << subresourceLayout.size << " bytes in size"
					<< " with pixel size " << pixelSize
					<< " and dimensions " << subresourceWidth << "x" << subresourceHeight << "x" << subresourceDepth;
				return tcu::TestStatus::fail(msg.str());
			}

			// Note: if subresourceHeight is <= 1u, rowPitch can be zero.
			if (subresourceHeight > 1u && subresourceLayout.rowPitch < pixelSize * subresourceWidth)
			{
				// Row pitch too small.
				std::ostringstream msg;
				msg << "Image level " << levelNdx
					<< " layer " << layerNdx
					<< " reports row pitch of " << subresourceLayout.rowPitch
					<< " bytes with " << pixelSize
					<< " bytes in pixel size and width " << subresourceWidth;
				return tcu::TestStatus::fail(msg.str());
			}

			if (numLayers > 1u && subresourceLayout.arrayPitch < pixelSize * numPixels)
			{
				// Array pitch too small.
				std::ostringstream msg;
				msg << "Image level " << levelNdx
					<< " layer " << layerNdx
					<< " reports array pitch of " << subresourceLayout.arrayPitch
					<< " bytes with " << pixelSize
					<< " bytes in pixel size and layer dimensions " << subresourceWidth << "x" << subresourceHeight;
				return tcu::TestStatus::fail(msg.str());
			}

			// If subresourceDepth is <= 1u, depthPitch can be zero.
			if (subresourceDepth > 1u && m_params.imageType == VK_IMAGE_TYPE_3D && subresourceLayout.depthPitch < pixelSize * subresourceWidth * subresourceHeight)
			{
				// Depth pitch too small.
				std::ostringstream msg;
				msg << "Image level " << levelNdx
					<< " layer " << layerNdx
					<< " reports depth pitch of " << subresourceLayout.depthPitch << " bytes"
					<< " with pixel size " << pixelSize
					<< " and dimensions " << subresourceWidth << "x" << subresourceHeight << "x" << subresourceDepth;
				return tcu::TestStatus::fail(msg.str());
			}

			// Verify image data.
			const auto	layerBufferOffset	= level.offset + layerNdx * numPixels * pixelSize;
			const auto	layerImageOffset	= subresourceLayout.offset;
			const auto	layerBufferPtr		= bufferPtr + layerBufferOffset;
			const auto	layerImagePtr		= imagePtr + layerImageOffset;
			bool		pixelMatch;

			// We could do this row by row to be faster, but in the use24LSB case we need to manipulate pixels independently.
			for (deUint32 x = 0u; x < subresourceWidth; ++x)
			for (deUint32 y = 0u; y < subresourceHeight; ++y)
			for (deUint32 z = 0u; z < subresourceDepth; ++z)
			{
				const auto bufferPixelOffset	= (z * subresourceWidth * subresourceHeight + y * subresourceWidth + x) * pixelSize;
				const auto imagePixelOffset		= z * subresourceLayout.depthPitch + y * subresourceLayout.rowPitch + x * pixelSize;
				const auto bufferPixelPtr		= layerBufferPtr + bufferPixelOffset;
				const auto imagePixelPtr		= layerImagePtr + imagePixelOffset;

				if (use24LSB)
				{
					DE_ASSERT(pixelSize == sizeof(deUint32));
					deUint32 pixelValue;
					deMemcpy(&pixelValue, imagePixelPtr, pixelSizeSz);
					pixelValue &= 0xFFFFFFu; // Discard the 8 MSB.
					pixelMatch = (deMemCmp(bufferPixelPtr, &pixelValue, pixelSizeSz) == 0);
				}
				else
					pixelMatch = (deMemCmp(bufferPixelPtr, imagePixelPtr, pixelSizeSz) == 0);

				if (!pixelMatch)
				{
					std::ostringstream msg;
					msg << "Found difference from image pixel to buffer pixel at coordinates"
						<< " level=" << levelNdx
						<< " layer=" << layerNdx
						<< " x=" << x
						<< " y=" << y
						<< " z=" << z
						;
					return tcu::TestStatus::fail(msg.str());
				}
			}
		}
	}

	return tcu::TestStatus::pass("Pass");
}

} // anonymous namespace

tcu::TestCaseGroup* createImageSubresourceLayoutTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> layoutTestGroup (new tcu::TestCaseGroup(testCtx, "subresource_layout", "Tests for vkGetImageSubresourceLayout"));

	struct
	{
		VkImageType	type;
		bool		array;
		const char*	name;
		const char*	desc;
	} imageClass[] =
	{
		{ VK_IMAGE_TYPE_2D,	false,	"2d",		"2D images"							},
		{ VK_IMAGE_TYPE_2D,	true,	"2d_array",	"2D images with multiple layers"	},
		{ VK_IMAGE_TYPE_3D,	false,	"3d",		"3D images"							},
	};

	struct
	{
		deUint32	maxLevels;
		const char*	name;
		const char*	desc;
	} mipLevels[] =
	{
		{ 1u,									"1_level",		"Single mip level"		},
		{ 2u,									"2_levels",		"Two mip levels"		},
		{ 4u,									"4_levels",		"Four mip levels"		},
		{ std::numeric_limits<deUint32>::max(),	"all_levels",	"All possible levels"	},
	};

	VkFormat testFormats[] =
	{
		VK_FORMAT_R4G4_UNORM_PACK8,
		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_B5G6R5_UNORM_PACK16,
		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8_USCALED,
		VK_FORMAT_R8_SSCALED,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8_SRGB,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8_USCALED,
		VK_FORMAT_R8G8_SSCALED,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8G8_SRGB,
		VK_FORMAT_R8G8B8_UNORM,
		VK_FORMAT_R8G8B8_SNORM,
		VK_FORMAT_R8G8B8_USCALED,
		VK_FORMAT_R8G8B8_SSCALED,
		VK_FORMAT_R8G8B8_UINT,
		VK_FORMAT_R8G8B8_SINT,
		VK_FORMAT_R8G8B8_SRGB,
		VK_FORMAT_B8G8R8_UNORM,
		VK_FORMAT_B8G8R8_SNORM,
		VK_FORMAT_B8G8R8_USCALED,
		VK_FORMAT_B8G8R8_SSCALED,
		VK_FORMAT_B8G8R8_UINT,
		VK_FORMAT_B8G8R8_SINT,
		VK_FORMAT_B8G8R8_SRGB,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_USCALED,
		VK_FORMAT_R8G8B8A8_SSCALED,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8A8_SNORM,
		VK_FORMAT_B8G8R8A8_USCALED,
		VK_FORMAT_B8G8R8A8_SSCALED,
		VK_FORMAT_B8G8R8A8_UINT,
		VK_FORMAT_B8G8R8A8_SINT,
		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
		VK_FORMAT_A2R10G10B10_UINT_PACK32,
		VK_FORMAT_A2R10G10B10_SINT_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_A2B10G10R10_SINT_PACK32,
		VK_FORMAT_R16_UNORM,
		VK_FORMAT_R16_SNORM,
		VK_FORMAT_R16_USCALED,
		VK_FORMAT_R16_SSCALED,
		VK_FORMAT_R16_UINT,
		VK_FORMAT_R16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UNORM,
		VK_FORMAT_R16G16_SNORM,
		VK_FORMAT_R16G16_USCALED,
		VK_FORMAT_R16G16_SSCALED,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16_UNORM,
		VK_FORMAT_R16G16B16_SNORM,
		VK_FORMAT_R16G16B16_USCALED,
		VK_FORMAT_R16G16B16_SSCALED,
		VK_FORMAT_R16G16B16_UINT,
		VK_FORMAT_R16G16B16_SINT,
		VK_FORMAT_R16G16B16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UNORM,
		VK_FORMAT_R16G16B16A16_SNORM,
		VK_FORMAT_R16G16B16A16_USCALED,
		VK_FORMAT_R16G16B16A16_SSCALED,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32_UINT,
		VK_FORMAT_R32G32B32_SINT,
		VK_FORMAT_R32G32B32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
		VK_FORMAT_R64_UINT,
		VK_FORMAT_R64_SINT,
		VK_FORMAT_R64_SFLOAT,
		VK_FORMAT_R64G64_UINT,
		VK_FORMAT_R64G64_SINT,
		VK_FORMAT_R64G64_SFLOAT,
		VK_FORMAT_R64G64B64_UINT,
		VK_FORMAT_R64G64B64_SINT,
		VK_FORMAT_R64G64B64_SFLOAT,
		VK_FORMAT_R64G64B64A64_UINT,
		VK_FORMAT_R64G64B64A64_SINT,
		VK_FORMAT_R64G64B64A64_SFLOAT,
		// Leaving out depth/stencil formats due to this part of the spec:
		//
		// "Depth/stencil formats are considered opaque and need not be stored in the exact number of bits per texel or component
		// ordering indicated by the format enum. However, implementations must not substitute a different depth or stencil
		// precision than that described in the format (e.g. D16 must not be implemented as D24 or D32)."
		//
		// Which means the size of the texel is not known for depth/stencil formats and we cannot iterate over them to check their
		// values.
#if 0
		VK_FORMAT_D16_UNORM,
		VK_FORMAT_X8_D24_UNORM_PACK32,
		VK_FORMAT_D32_SFLOAT,
		VK_FORMAT_S8_UINT,
		VK_FORMAT_D16_UNORM_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,
		VK_FORMAT_D32_SFLOAT_S8_UINT,
#endif
	};

	for (int classIdx = 0; classIdx < DE_LENGTH_OF_ARRAY(imageClass); ++classIdx)
	{
		const auto& imgClass = imageClass[classIdx];
		de::MovePtr<tcu::TestCaseGroup> classGroup (new tcu::TestCaseGroup(testCtx, imgClass.name, imgClass.desc));

		for (int mipIdx = 0; mipIdx < DE_LENGTH_OF_ARRAY(mipLevels); ++mipIdx)
		{
			const auto &mipLevel = mipLevels[mipIdx];
			de::MovePtr<tcu::TestCaseGroup> mipGroup (new tcu::TestCaseGroup(testCtx, mipLevel.name, mipLevel.desc));

			for (int formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); ++formatIdx)
			{
				static const auto	prefixLen	= std::string("VK_FORMAT_").size();
				const auto			format		= testFormats[formatIdx];
				const auto			fmtName		= std::string(getFormatName(format));
				const auto			name		= de::toLower(fmtName.substr(prefixLen)); // Remove VK_FORMAT_ prefix.
				const auto			desc		= "Using format " + fmtName;

				ImageSubresourceLayoutCase::TestParams params;
				params.imageFormat	= format;
				params.imageType	= imgClass.type;
				params.mipLevels	= mipLevel.maxLevels;
				params.dimensions	= getDefaultDimensions(imgClass.type, imgClass.array);

				mipGroup->addChild(new ImageSubresourceLayoutCase(testCtx, name, desc, params));
			}

			classGroup->addChild(mipGroup.release());
		}

		layoutTestGroup->addChild(classGroup.release());
	}

	return layoutTestGroup.release();
}

} // namespace image
} // namespace vkt
