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

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