/*------------------------------------------------------------------------
 * 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 "tcuTextureUtil.hpp"
#include "tcuFloat.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 || 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);

	// 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
