/*------------------------------------------------------------------------
 * 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);

	invalidateAlloc(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
