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

#include "vktImageMismatchedWriteOpTests.hpp"

#include "vktImageTexture.hpp"
#include "vkImageUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkObjUtil.hpp"
#include "vktImageTestsUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkBarrierUtil.hpp"

#include "tcuStringTemplate.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"

#include <set>

#define EPSILON_COMPARE(a,b,e)	((de::max((a),(b))-de::min((a),(b)))<=(e))

using namespace vk;

namespace vkt
{
namespace image
{
namespace
{

using tcu::TextureFormat;
using tcu::StringTemplate;
using tcu::TextureChannelClass;
using strings = std::map<std::string, std::string>;

class MismatchedWriteOpTest : public TestCase
{
public:
	struct Params
	{
		VkFormat			vkFormat;
		int					textureWidth;
		int					textureHeight;
		VkFormat			spirvFormat;
	};
	typedef de::SharedPtr<Params> ParamsSp;

										MismatchedWriteOpTest		(tcu::TestContext&			testCtx,
																	 const std::string&			name,
																	 const std::string&			description,
																	 const ParamsSp				params)
	: TestCase	(testCtx, name, description)
	, m_params	(params)
	{
	}

	virtual void						checkSupport				(Context&					context)		const override;
	virtual TextureFormat				getBufferFormat				(void)										const;
	void								getProgramCodeAndVariables	(StringTemplate&			code,
																	 strings&					variables)		const;

	template<class TestParams> void getParams(TestParams&);

protected:
	const ParamsSp	m_params;
};

class MismatchedVectorSizesTest : public MismatchedWriteOpTest
{
public:
										MismatchedVectorSizesTest	(tcu::TestContext&			testCtx,
																	 const std::string&			name,
																	 const std::string&			description,
																	 const ParamsSp				params,
																	 const int					sourceWidth)
		: MismatchedWriteOpTest	(testCtx, name, description, params)
		, m_sourceWidth			(sourceWidth)
	{
		DE_ASSERT(getNumUsedChannels(params->vkFormat) <= sourceWidth);
	}

	virtual void						initPrograms				(SourceCollections&			programCollection)	const override;
	virtual TestInstance*				createInstance				(Context&					context)			const override;

private:
	const int	m_sourceWidth;
};

class MismatchedSignednessAndTypeTest : public MismatchedWriteOpTest
{
public:
									MismatchedSignednessAndTypeTest	(tcu::TestContext&			testCtx,
																	 const std::string&			name,
																	 const std::string&			description,
																	 const ParamsSp				params)
		: MismatchedWriteOpTest	(testCtx, name, description, params)
	{
	}

	virtual void						initPrograms				(SourceCollections&			programCollection)	const override;
	virtual TestInstance*				createInstance				(Context&					context)			const override;
};

class MismatchedWriteOpTestInstance : public TestInstance
{
public:
	using TestClass	= MismatchedWriteOpTest;
	using ParamsSp	= MismatchedWriteOpTest::ParamsSp;

							MismatchedWriteOpTestInstance			(Context&					context,
																	 const ParamsSp				params,
																	 const TestClass*			test)
		: TestInstance	(context)
		, m_params		(params)
		, m_test		(test)
	{
	}

	virtual tcu::TestStatus	iterate									(void)											override;
	virtual void			clear									(tcu::PixelBufferAccess&	data)				const;
	virtual void			populate								(tcu::PixelBufferAccess&	data)				const;
	virtual bool			compare									(tcu::PixelBufferAccess&	result,
																	 tcu::PixelBufferAccess&	reference)			const = 0;
protected:
	const ParamsSp		m_params;
	const TestClass*	m_test;
};

class MismatchedVectorSizesTestInstance : public MismatchedWriteOpTestInstance
{
public:
							MismatchedVectorSizesTestInstance		(Context&					context,
																	 const ParamsSp				params,
																	 const TestClass*			test)
		: MismatchedWriteOpTestInstance	(context, params, test)
	{
	}

	bool					compare									(tcu::PixelBufferAccess&	result,
																	 tcu::PixelBufferAccess&	reference)			const override;
};

class MismatchedSignednessAndTypeTestInstance : public MismatchedWriteOpTestInstance
{
public:
							MismatchedSignednessAndTypeTestInstance	(Context&					context,
																	 const ParamsSp				params,
																	 const TestClass*			test)
		: MismatchedWriteOpTestInstance	(context, params, test)
	{
	}

	bool					compare									(tcu::PixelBufferAccess&	result,
																	tcu::PixelBufferAccess&		reference)			const override;
};

namespace ut
{

class StorageBuffer2D
{
public:
									StorageBuffer2D		(Context&					context,
														 const tcu::TextureFormat&	format,
														 deUint32					width,
														 deUint32					height);

	VkBuffer						getBuffer			(void) const { return *m_buffer; }
	VkDeviceSize					getSize				(void) const { return m_bufferSize; }

	tcu::PixelBufferAccess&			getPixelAccess		(void) { return m_access[0]; }

	void							flush				(void) { flushAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory); }
	void							invalidate			(void) { invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory); }

protected:
	friend class StorageImage2D;
	Allocation&						getMemory			(void) const { return *m_bufferMemory; }

private:
	Context&							m_context;
	const tcu::TextureFormat			m_format;
	const deUint32						m_width;
	const deUint32						m_height;
	const VkDeviceSize					m_bufferSize;
	Move<VkBuffer>						m_buffer;
	de::MovePtr<Allocation>				m_bufferMemory;
	std::vector<tcu::PixelBufferAccess>	m_access;
};

class StorageImage2D
{
public:
									StorageImage2D	(Context&				context,
													 VkFormat				vkFormat,
													 const int				width,
													 const int				height,
													 bool					sparse = false);

	VkImageView						getView			(void) const	{ return *m_view; }

	tcu::PixelBufferAccess&			getPixelAccess	(void)			{ return m_buffer.getPixelAccess(); }

	void							flush			(void) { m_buffer.flush(); }
	void							invalidate		(void) { m_buffer.invalidate(); }

	void							upload			(const VkCommandBuffer	cmdBuffer);
	void							download		(const VkCommandBuffer	cmdBuffer);

private:
	Context&								m_context;
	const bool								m_sparse;
	const int								m_width;
	const int								m_height;
	const vk::VkFormat						m_vkFormat;
	const tcu::TextureFormat				m_texFormat;
	StorageBuffer2D							m_buffer;

	VkImageLayout							m_layout;
	Move<VkImage>							m_image;
	Move<VkImageView>						m_view;
	Move<VkSemaphore>						m_semaphore;
	std::vector<de::SharedPtr<Allocation>>	m_allocations;
	de::MovePtr<Allocation>					m_imageMemory;
};

StorageImage2D::StorageImage2D (Context& context, VkFormat vkFormat, const int width, const int height, bool sparse)
	: m_context		(context)
	, m_sparse		(sparse)
	, m_width		(width)
	, m_height		(height)
	, m_vkFormat	(vkFormat)
	, m_texFormat	(mapVkFormat(m_vkFormat))
	, m_buffer		(m_context, m_texFormat, m_width, m_height)
{
	const DeviceInterface&			vki					= m_context.getDeviceInterface();
	const VkDevice					dev					= m_context.getDevice();
	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&						allocator			= m_context.getDefaultAllocator();

	// Create an image
	{
		VkImageCreateFlags				imageCreateFlags	= m_sparse? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
		VkImageUsageFlags				imageUsageFlags		= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

		const VkImageCreateInfo			imageCreateInfo		=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			imageCreateFlags,								// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
			m_vkFormat,										// VkFormat					format;
			{ deUint32(m_width), deUint32(m_height), 1u },	// VkExtent3D				extent;
			1u,												// deUint32					mipLevels;
			1u,												// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
			imageUsageFlags,								// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
			1u,												// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
			(m_layout = VK_IMAGE_LAYOUT_UNDEFINED)			// VkImageLayout			initialLayout;
		};

		m_image		= createImage(vki, dev, &imageCreateInfo);

		if (m_sparse)
		{
			m_semaphore = createSemaphore(vki, dev);

			allocateAndBindSparseImage(	vki, dev, m_context.getPhysicalDevice(), m_context.getInstanceInterface(),
										imageCreateInfo, *m_semaphore, m_context.getSparseQueue(),
										allocator, m_allocations, mapVkFormat(m_vkFormat), *m_image	);
		}
		else
		{
			m_imageMemory = allocator.allocate(getImageMemoryRequirements(vki, dev, *m_image), MemoryRequirement::Any);
			VK_CHECK(vki.bindImageMemory(dev, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
		}

		VkImageSubresourceRange			subresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
		m_view	= makeImageView(vki, dev, *m_image, VK_IMAGE_VIEW_TYPE_2D, m_vkFormat, subresourceRange);
	}
}

void StorageImage2D::upload (const VkCommandBuffer cmdBuffer)
{
	const DeviceInterface&			vki							= m_context.getDeviceInterface();
	const VkImageSubresourceRange	fullImageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const VkBufferImageCopy			copyRegion					= makeBufferImageCopy(makeExtent3D(tcu::IVec3(m_width, m_height, 1)), 1u);

	{
		const VkBufferMemoryBarrier bufferBarrier = makeBufferMemoryBarrier(
			VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
			m_buffer.getBuffer(), 0ull, m_buffer.getSize());

		const VkImageMemoryBarrier beforeCopyBarrier = makeImageMemoryBarrier(
			(VkAccessFlagBits)0, VK_ACCESS_TRANSFER_WRITE_BIT,
			m_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			*m_image, fullImageSubresourceRange);

		vki.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
							   0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &beforeCopyBarrier);
	}

	vki.cmdCopyBufferToImage(cmdBuffer, m_buffer.getBuffer(), *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);

	{
		const VkBufferMemoryBarrier bufferBarrier = makeBufferMemoryBarrier(
			VK_ACCESS_TRANSFER_READ_BIT, (VkAccessFlags)0,
			m_buffer.getBuffer(), 0ull, m_buffer.getSize());

		m_layout = VK_IMAGE_LAYOUT_GENERAL;
		const VkImageMemoryBarrier afterCopyBarrier = makeImageMemoryBarrier(
			VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, m_layout,
			*m_image, fullImageSubresourceRange);

		vki.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0,
							   0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &afterCopyBarrier);
	}
}

void StorageImage2D::download (const VkCommandBuffer cmdBuffer)
{
	const DeviceInterface&			vki							= m_context.getDeviceInterface();
	const VkImageSubresourceRange	fullImageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const VkBufferImageCopy			copyRegion					= makeBufferImageCopy(makeExtent3D(tcu::IVec3(m_width, m_height, 1)), 1u);

	{
		const VkBufferMemoryBarrier bufferBarrier = makeBufferMemoryBarrier(
			(VkAccessFlags)0, VK_ACCESS_TRANSFER_WRITE_BIT,
			m_buffer.getBuffer(), 0ull, m_buffer.getSize());

		const VkImageMemoryBarrier beforeCopyBarrier = makeImageMemoryBarrier(
			VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
			m_layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
			*m_image, fullImageSubresourceRange);

		vki.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
							   0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &beforeCopyBarrier);
	}

	vki.cmdCopyImageToBuffer(cmdBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_buffer.getBuffer(), 1, &copyRegion);

	{
		const VkBufferMemoryBarrier bufferBarrier = makeBufferMemoryBarrier(
			VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
			m_buffer.getBuffer(), 0ull, m_buffer.getSize());

		const VkImageMemoryBarrier afterCopyBarrier = makeImageMemoryBarrier(
			VK_ACCESS_TRANSFER_READ_BIT, (VkAccessFlags)0,
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_layout,
			*m_image, fullImageSubresourceRange);

		vki.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
							   0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &afterCopyBarrier);
	}

}

StorageBuffer2D::StorageBuffer2D (Context& context, const tcu::TextureFormat& format, deUint32 width, deUint32 height)
	: m_context		(context)
	, m_format		(format)
	, m_width		(width)
	, m_height		(height)
	, m_bufferSize	(m_width * m_height * m_format.getPixelSize())
{
	const DeviceInterface&			vki					= m_context.getDeviceInterface();
	const VkDevice					dev					= m_context.getDevice();
	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&						allocator			= m_context.getDefaultAllocator();

	const VkBufferUsageFlags		bufferUsageFlags	= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;

	const VkBufferCreateInfo		bufferCreateInfo	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		0u,											// VkBufferCreateFlags		flags;
		m_bufferSize,								// VkDeviceSize				size;
		bufferUsageFlags,							// VkBufferUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
		1u,											// deUint32					queueFamilyIndexCount;
		&queueFamilyIndex							// const deUint32*			pQueueFamilyIndices;
	};

	m_buffer		= createBuffer(vki, dev, &bufferCreateInfo);

	m_bufferMemory	= allocator.allocate(getBufferMemoryRequirements(vki, dev, *m_buffer), MemoryRequirement::HostVisible);
	VK_CHECK(vki.bindBufferMemory(dev, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset()));

	m_access.emplace_back(m_format, tcu::IVec3(m_width, m_height, 1), m_bufferMemory->getHostPtr());
}

tcu::Vec4 gluePixels (const tcu::Vec4& a, const tcu::Vec4& b, const int pivot)
{
	tcu::Vec4 result;
	for (int i = 0; i < pivot; ++i) result[i] = a[i];
	for (int i = pivot; i < 4; ++i) result[i] = b[i];
	return result;
}

template<class T, int N>
bool comparePixels (const tcu::Vector<T,N>& res, const tcu::Vector<T,N>& ref, const int targetWidth, const T eps = {})
{
	bool		ok		= true;

	for (int i = 0; ok && i < targetWidth; ++i)
	{
		ok &= EPSILON_COMPARE(res[i], ref[i], eps);
	}

	return ok;
}

} // ut

TestInstance* MismatchedVectorSizesTest::createInstance (Context& context) const
{
	return (new MismatchedVectorSizesTestInstance(context, m_params, this));
}

TestInstance* MismatchedSignednessAndTypeTest::createInstance (Context& context) const
{
	return (new MismatchedSignednessAndTypeTestInstance(context, m_params, this));
}

enum class OpCapability
{
	Shader,
	StorageImageExtendedFormats,
	Int64ImageEXT
};

const char* OpCapabilityToStr (const OpCapability& cap)
{
	switch (cap)
	{
		case OpCapability::Shader:						return "Shader";
		case OpCapability::StorageImageExtendedFormats:	return "StorageImageExtendedFormats";
		case OpCapability::Int64ImageEXT:				return "Int64ImageEXT";
	}
	DE_ASSERT(DE_FALSE);
	return nullptr;
}

struct FormatInfo {
	VkFormat		vkFormat;
	const char*		spirvName;
	OpCapability	capability;
	bool operator==(const FormatInfo& other) const {
		return ((vkFormat == other.vkFormat) && (spirvName == other.spirvName) && (capability == other.capability));
	}
}
const formatsInfos[] =
{
	// ----- FLOATS -----

	{ VK_FORMAT_R32G32B32A32_SFLOAT,		"Rgba32f",		OpCapability::Shader						},
	{ VK_FORMAT_R32G32_SFLOAT,				"Rg32f",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R32_SFLOAT,					"R32f",			OpCapability::Shader						},

	{ VK_FORMAT_R16G16B16A16_SFLOAT,		"Rgba16f",		OpCapability::Shader						},
	{ VK_FORMAT_R16G16_SFLOAT,				"Rg16f",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R16_SFLOAT,					"R16f",			OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_R16G16B16A16_UNORM,			"Rgba16",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R16G16_UNORM,				"Rg16",			OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R16_UNORM,					"R16",			OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_R16G16B16A16_SNORM,			"Rgba16Snorm",	OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R16G16_SNORM,				"Rg16Snorm",	OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R16_SNORM,					"R16Snorm",		OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_A2B10G10R10_UNORM_PACK32,	"Rgb10A2",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_B10G11R11_UFLOAT_PACK32,	"R11fG11fB10f",	OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_R8G8B8A8_UNORM,				"Rgba8",		OpCapability::Shader						},
	{ VK_FORMAT_R8G8_UNORM,					"Rg8",			OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R8_UNORM,					"R8",			OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_R8G8B8A8_SNORM,				"Rgba8Snorm",	OpCapability::Shader						},
	{ VK_FORMAT_R8G8_SNORM,					"Rg8Snorm",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R8_SNORM,					"R8Snorm",		OpCapability::StorageImageExtendedFormats	},

	// ----- SIGNED INTEGERS -----

	{ VK_FORMAT_R32G32B32A32_SINT,			"Rgba32i",		OpCapability::Shader						},
	{ VK_FORMAT_R32G32_SINT,				"Rg32i",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R32_SINT,					"R32i",			OpCapability::Shader						},

	{ VK_FORMAT_R16G16B16A16_SINT,			"Rgba16i",		OpCapability::Shader						},
	{ VK_FORMAT_R16G16_SINT,				"Rg16i",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R16_SINT,					"R16i",			OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_R8G8B8A8_SINT,				"Rgba8i",		OpCapability::Shader						},
	{ VK_FORMAT_R8G8_SINT,					"Rg8i",			OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R8_SINT,					"R8i",			OpCapability::StorageImageExtendedFormats	},

	// ----- UNSIGNED INTEGERS ------

	{ VK_FORMAT_R32G32B32A32_UINT,			"Rgba32ui",		OpCapability::Shader						},
	{ VK_FORMAT_R32G32_UINT,				"Rg32ui",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R32_UINT,					"R32ui",		OpCapability::Shader						},

	{ VK_FORMAT_R16G16B16A16_UINT,			"Rgba16ui",		OpCapability::Shader						},
	{ VK_FORMAT_R16G16_UINT,				"Rg16ui",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R16_UINT,					"R16ui",		OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_A2B10G10R10_UINT_PACK32,	"Rgb10a2ui",	OpCapability::StorageImageExtendedFormats	},

	{ VK_FORMAT_R8G8B8A8_UINT,				"Rgba8ui",		OpCapability::Shader						},
	{ VK_FORMAT_R8G8_UINT,					"Rg8ui",		OpCapability::StorageImageExtendedFormats	},
	{ VK_FORMAT_R8_UINT,					"R8ui",			OpCapability::StorageImageExtendedFormats	},

	// ----- EXTENDED INTEGERS -----

	{ VK_FORMAT_R64_SINT,					"R64i",			OpCapability::Int64ImageEXT					},
	{ VK_FORMAT_R64_UINT,					"R64ui",		OpCapability::Int64ImageEXT					},
};

const FormatInfo* findFormatInfo (VkFormat vkFormat)
{
	for (const auto& formatInfo : formatsInfos)
	{
		if (formatInfo.vkFormat == vkFormat)
			return &formatInfo;
	}
	DE_ASSERT(DE_FALSE);
	return nullptr;
}

std::vector<FormatInfo> findFormatsByChannelClass(TextureChannelClass channelClass)
{
	std::vector<FormatInfo> result;
	for (const FormatInfo& fi : formatsInfos)
	{
		if (getTextureChannelClass(mapVkFormat(fi.vkFormat).type) == channelClass)
			result.emplace_back(fi);
	}
	DE_ASSERT(!result.empty());
	return result;
}

const char* getChannelStr (const TextureFormat::ChannelType& type)
{
	switch (type)
	{
		case TextureFormat::FLOAT:				return "float";
		case TextureFormat::SIGNED_INT32:		return "sint";
		case TextureFormat::UNSIGNED_INT32:		return "uint";
		case TextureFormat::FLOAT64:			return "double";
		case TextureFormat::SIGNED_INT64:		return "slong";
		case TextureFormat::UNSIGNED_INT64:		return "ulong";
		default:								DE_ASSERT(DE_FALSE);
	}

	return nullptr;
}

TextureFormat::ChannelType makeChannelType (tcu::TextureChannelClass channelClass, bool doubled)
{
	auto	channelType	= TextureFormat::ChannelType::CHANNELTYPE_LAST;
	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			channelType	= doubled ? TextureFormat::ChannelType::SIGNED_INT64 : TextureFormat::ChannelType::SIGNED_INT32;
			break;
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			channelType	= doubled ? TextureFormat::ChannelType::UNSIGNED_INT64 : TextureFormat::ChannelType::UNSIGNED_INT32;
			break;
		default:
			channelType	= doubled ? TextureFormat::ChannelType::FLOAT64 : TextureFormat::ChannelType::FLOAT;
	}
	return channelType;
}

TextureFormat makeBufferFormat (tcu::TextureChannelClass channelClass, bool doubled)
{
	return TextureFormat(TextureFormat::ChannelOrder::RGBA, makeChannelType(channelClass, doubled));
}

void MismatchedWriteOpTest::checkSupport (Context& context) const
{
	const FormatInfo* info = findFormatInfo(m_params->vkFormat);

	// capabilities that may be used in the shader
	if (info->capability == OpCapability::Int64ImageEXT)
	{
		const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
		if(!deviceFeatures.shaderInt64)
		{
			TCU_THROW(NotSupportedError, "Device feature shaderInt64 is not supported");
		}
		context.requireDeviceFunctionality("VK_EXT_shader_image_atomic_int64");
	}

	// extensions used statically in the shader
	context.requireDeviceFunctionality("VK_KHR_variable_pointers");
	context.requireDeviceFunctionality("VK_KHR_storage_buffer_storage_class");

	VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), m_params->vkFormat);

	if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
	{
		TCU_THROW(NotSupportedError, "Creating storage image with this format is not supported");
	}
}

TextureFormat MismatchedWriteOpTest::getBufferFormat (void) const
{
	const FormatInfo*	info		= findFormatInfo(m_params->vkFormat);
	const TextureFormat texFormat	= mapVkFormat(m_params->vkFormat);
	return makeBufferFormat(getTextureChannelClass(texFormat.type), info->capability == OpCapability::Int64ImageEXT);
}


void MismatchedWriteOpTest::getProgramCodeAndVariables (StringTemplate& code, strings& variables) const
{
	std::string shaderTemplate(R"(

							  ${ENABLING_CAPABILITIES}
							  ${CAPABILITY_INT64}
							  OpExtension      "SPV_KHR_variable_pointers"
							  OpExtension      "SPV_KHR_storage_buffer_storage_class"
							  ${EXTENSIONS}

					%std450 = OpExtInstImport  "GLSL.std.450"
							  OpMemoryModel    Logical GLSL450

							  OpEntryPoint     GLCompute %main "main" %gid %image %buffer
							  OpExecutionMode  %main LocalSize 1 1 1

							  OpDecorate       %gid BuiltIn GlobalInvocationId

							  OpDecorate       %image DescriptorSet 0
							  OpDecorate       %image Binding 0

							  OpDecorate       %rta    ArrayStride ${ARRAY_STRIDE}
							  OpMemberDecorate %struct 0 Offset 0
							  OpDecorate       %struct Block
							  OpDecorate       %buffer DescriptorSet 0
							  OpDecorate       %buffer Binding 1

					  %void = OpTypeVoid
				   %fn_void = OpTypeFunction %void

					${TYPES_INT64}

					 %float = OpTypeFloat 32
					  %sint = OpTypeInt 32 1
					  %uint = OpTypeInt 32 0

				   %v4float = OpTypeVector %float 4
				   %v3float = OpTypeVector %float 3
				   %v2float = OpTypeVector %float 2

					%v4sint = OpTypeVector %sint 4
					%v3sint = OpTypeVector %sint 3
					%v2sint = OpTypeVector %sint 2

					%v4uint = OpTypeVector %uint 4
					%v3uint = OpTypeVector %uint 3
					%v2uint = OpTypeVector %uint 2

			 %v3uint_in_ptr = OpTypePointer Input %v3uint
					   %gid = OpVariable %v3uint_in_ptr Input

				%image_type = OpTypeImage %${SAMPLED_TYPE} 2D 0 0 0 2 ${SPIRV_IMAGE_FORMAT}
				 %image_ptr = OpTypePointer UniformConstant %image_type
					 %image = OpVariable %image_ptr UniformConstant

			   %image_width = OpConstant %sint ${IMAGE_WIDTH}
			  %image_height = OpConstant %sint ${IMAGE_HEIGHT}

				%rta_offset = OpConstant %uint 0
					   %rta = OpTypeRuntimeArray %v4${SAMPLED_TYPE}
					%struct = OpTypeStruct %rta
				  %ssbo_ptr = OpTypePointer StorageBuffer %struct
					%buffer = OpVariable %ssbo_ptr StorageBuffer

				%red_offset = OpConstant %uint 0
			  %green_offset = OpConstant %uint 1
			   %blue_offset = OpConstant %uint 2
			  %alpha_offset = OpConstant %uint 3

	   %${SAMPLED_TYPE}_PTR = OpTypePointer StorageBuffer %${SAMPLED_TYPE}
			  %var_sint_ptr = OpTypePointer Function %sint

				; Entry main procedure
					  %main = OpFunction %void None %fn_void
					 %entry = OpLabel

					 %index = OpVariable %var_sint_ptr Function

				; Transform gl_GlobalInvocationID.xyz to ivec2(gl_GlobalInvocationID.xy)
						%id = OpLoad %v3uint %gid

					%u_id_x = OpCompositeExtract %uint %id 0
					%s_id_x = OpBitcast %sint %u_id_x

					%u_id_y = OpCompositeExtract %uint %id 1
					%s_id_y = OpBitcast %sint %u_id_y

					 %id_xy = OpCompositeConstruct %v2sint %s_id_x %s_id_y

				; Calculate index in buffer
					   %mul = OpIMul %sint %s_id_y %image_width
					   %add = OpIAdd %sint %mul %s_id_x
							  OpStore %index %add

				; Final image variable used to read from or write to
					   %img = OpLoad %image_type %image

				; Accessors to buffer components
					   %idx = OpLoad %sint %index
			  %alpha_access = OpAccessChain %${SAMPLED_TYPE}_PTR %buffer %rta_offset %idx %alpha_offset
			   %blue_access = OpAccessChain %${SAMPLED_TYPE}_PTR %buffer %rta_offset %idx %blue_offset
			  %green_access = OpAccessChain %${SAMPLED_TYPE}_PTR %buffer %rta_offset %idx %green_offset
				%red_access = OpAccessChain %${SAMPLED_TYPE}_PTR %buffer %rta_offset %idx %red_offset

					   %red = OpLoad %${SAMPLED_TYPE} %red_access
					 %green = OpLoad %${SAMPLED_TYPE} %green_access
					  %blue = OpLoad %${SAMPLED_TYPE} %blue_access
					 %alpha = OpLoad %${SAMPLED_TYPE} %alpha_access

							  ${WRITE_TO_IMAGE}

							  OpReturn
							  OpFunctionEnd
	)");

	const std::string typesInt64(R"(
					 %slong = OpTypeInt 64 1
					 %ulong = OpTypeInt 64 0

				   %v4slong = OpTypeVector %slong 4
				   %v3slong = OpTypeVector %slong 3
				   %v2slong = OpTypeVector %slong 2

				   %v4ulong = OpTypeVector %ulong 4
				   %v3ulong = OpTypeVector %ulong 3
				   %v2ulong = OpTypeVector %ulong 2
	)");

	const tcu::TextureFormat			buffFormat	= getBufferFormat();

	const FormatInfo*					info		= findFormatInfo(m_params->spirvFormat);

	variables["SPIRV_IMAGE_FORMAT"]					= info->spirvName;
	variables["ENABLING_CAPABILITIES"]				= std::string("OpCapability ") + OpCapabilityToStr(info->capability);
	variables["CAPABILITY_INT64"]					= "";
	variables["EXTENSIONS"]							= "";
	variables["TYPES_INT64"]						= "";

	if (info->capability == OpCapability::Int64ImageEXT)
	{
		variables["EXTENSIONS"]						= "OpExtension	   \"SPV_EXT_shader_image_int64\"";
		variables["CAPABILITY_INT64"]				= std::string("OpCapability Int64");
		variables["TYPES_INT64"]					= typesInt64;
	}

	variables["SAMPLED_TYPE"]						= getChannelStr(buffFormat.type);
	variables["IMAGE_WIDTH"]						= std::to_string(m_params->textureWidth);
	variables["IMAGE_HEIGHT"]						= std::to_string(m_params->textureHeight);
	variables["ARRAY_STRIDE"]						= std::to_string(tcu::getChannelSize(buffFormat.type) * tcu::getNumUsedChannels(buffFormat.order));

	code.setString(shaderTemplate);
}

void MismatchedVectorSizesTest::initPrograms (SourceCollections& programCollection) const
{
	strings				variables		{};
	StringTemplate		shaderTemplate	{};

	const StringTemplate writeFromSingleComponent	(R"(
					 OpImageWrite %img %id_xy %red
	)");
	const StringTemplate writeFromTwoComponents		(R"(
			   %rg = OpCompositeConstruct %v2${SAMPLED_TYPE} %red %green
					 OpImageWrite %img %id_xy %rg
	)");

	const StringTemplate writeFromThreeComponents	(R"(
			  %rgb = OpCompositeConstruct %v3${SAMPLED_TYPE} %red %green %blue
					 OpImageWrite %img %id_xy %rgb
	)");
	const StringTemplate writeFromFourComponents	(R"(
			 %rgba = OpCompositeConstruct %v4${SAMPLED_TYPE} %red %green %blue %alpha
					 OpImageWrite %img %id_xy %rgba
	)");

	getProgramCodeAndVariables(shaderTemplate, variables);

	variables["WRITE_TO_IMAGE"]						= (m_sourceWidth == 1
													   ? writeFromSingleComponent
													   : m_sourceWidth == 2
														 ? writeFromTwoComponents
														 : m_sourceWidth == 3
														   ? writeFromThreeComponents
														   : writeFromFourComponents).specialize(variables);
	programCollection.spirvAsmSources.add("comp")
			<< shaderTemplate.specialize(variables)
			<< vk::SpirVAsmBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
}

void MismatchedSignednessAndTypeTest::initPrograms (SourceCollections& programCollection) const
{
	strings				variables		{};
	StringTemplate		shaderTemplate	{};

	const StringTemplate writeToImage	(R"(
			%color = OpCompositeConstruct %v4${SAMPLED_TYPE} %red %green %blue %alpha
					 OpImageWrite %img %id_xy %color
	)");

	getProgramCodeAndVariables(shaderTemplate, variables);

	variables["WRITE_TO_IMAGE"]			= writeToImage.specialize(variables);

	programCollection.spirvAsmSources.add("comp")
			<< shaderTemplate.specialize(variables)
			<< vk::SpirVAsmBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
}

void MismatchedWriteOpTestInstance::clear (tcu::PixelBufferAccess& pixels) const
{
	const auto channelClass = tcu::getTextureChannelClass(mapVkFormat(m_params->vkFormat).type);
	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			tcu::clear(pixels, tcu::IVec4(-1, -2, -3, -4));
			break;

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			tcu::clear(pixels, tcu::UVec4(1, 2, 3, 4));
			break;

		default:
			tcu::clear(pixels, tcu::Vec4(0.2f, 0.3f, 0.4f, 0.5f));
	}
}

void MismatchedWriteOpTestInstance::populate (tcu::PixelBufferAccess& pixels) const
{
	const auto				texFormat			= mapVkFormat(m_params->vkFormat);
	const auto				bitDepth			= tcu::getTextureFormatBitDepth(texFormat);
	const auto				channelClass		= tcu::getTextureChannelClass(texFormat.type);

	const tcu::IVec4		signedMinValues		(bitDepth[0] ? deIntMinValue32(deMin32(bitDepth[0], 32)) : (-1),
												 bitDepth[1] ? deIntMinValue32(deMin32(bitDepth[1], 32)) : (-1),
												 bitDepth[2] ? deIntMinValue32(deMin32(bitDepth[2], 32)) : (-1),
												 bitDepth[3] ? deIntMinValue32(deMin32(bitDepth[3], 32)) : (-1));

	const tcu::IVec4		signedMaxValues		(bitDepth[0] ? deIntMaxValue32(deMin32(bitDepth[0], 32)) : 1,
												 bitDepth[1] ? deIntMaxValue32(deMin32(bitDepth[1], 32)) : 1,
												 bitDepth[2] ? deIntMaxValue32(deMin32(bitDepth[2], 32)) : 1,
												 bitDepth[3] ? deIntMaxValue32(deMin32(bitDepth[3], 32)) : 1);

	const tcu::UVec4		unsignedMinValues	(0u);

	const tcu::UVec4		unsignedMaxValues	(bitDepth[0] ? deUintMaxValue32(deMin32(bitDepth[0], 32)) : 1u,
												 bitDepth[1] ? deUintMaxValue32(deMin32(bitDepth[1], 32)) : 1u,
												 bitDepth[2] ? deUintMaxValue32(deMin32(bitDepth[2], 32)) : 1u,
												 bitDepth[3] ? deUintMaxValue32(deMin32(bitDepth[3], 32)) : 1u);

	auto					nextSigned			= [&](tcu::IVec4& color)
	{
		color[0] = (static_cast<deInt64>(color[0] + 2) < signedMaxValues[0]) ? (color[0] + 2) : signedMinValues[0];
		color[1] = (static_cast<deInt64>(color[1] + 3) < signedMaxValues[1]) ? (color[1] + 3) : signedMinValues[1];
		color[2] = (static_cast<deInt64>(color[2] + 5) < signedMaxValues[2]) ? (color[2] + 5) : signedMinValues[2];
		color[3] = (static_cast<deInt64>(color[3] + 7) < signedMaxValues[3]) ? (color[3] + 7) : signedMinValues[3];
	};

	auto					nextUnsigned		= [&](tcu::UVec4& color)
	{
		color[0] = (static_cast<deUint64>(color[0] + 2) < unsignedMaxValues[0]) ? (color[0] + 2) : unsignedMinValues[0];
		color[1] = (static_cast<deUint64>(color[1] + 3) < unsignedMaxValues[1]) ? (color[1] + 3) : unsignedMinValues[1];
		color[2] = (static_cast<deUint64>(color[2] + 5) < unsignedMaxValues[2]) ? (color[2] + 5) : unsignedMinValues[2];
		color[3] = (static_cast<deUint64>(color[3] + 7) < unsignedMaxValues[3]) ? (color[3] + 7) : unsignedMinValues[3];
	};

	deUint64				floatsData			[4];
	tcu::PixelBufferAccess	floatsAccess		(texFormat, 1, 1, 1, floatsData);
	tcu::Vec4				tmpFloats			(0.0f);

	const float				divider				(static_cast<float>(m_params->textureHeight));
	const tcu::Vec4			ufloatStep			(1.0f/(divider*1.0f), 1.0f/(divider*2.0f), 1.0f/(divider*3.0f), 1.0f/(divider*5.0f));
	const tcu::Vec4			sfloatStep			(2.0f/(divider*1.0f), 2.0f/(divider*2.0f), 2.0f/(divider*3.0f), 2.0f/(divider*5.0f));

	tcu::IVec4				signedColor			(0);
	tcu::UVec4				unsignedColor		(0u);
	tcu::Vec4				ufloatColor			(0.0f);
	tcu::Vec4				sfloatColor			(-1.0f);

	for (int y = 0; y < m_params->textureHeight; ++y)
	{
		for (int x = 0; x < m_params->textureWidth; ++x)
		{
			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
					pixels.setPixel(signedColor, x, y);
					break;

				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
					pixels.setPixel(unsignedColor, x, y);
					break;

				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
					floatsAccess.setPixel(sfloatColor, 0, 0);
					tmpFloats = ut::gluePixels(floatsAccess.getPixel(0, 0), sfloatColor, tcu::getNumUsedChannels(texFormat.order));
					pixels.setPixel(tmpFloats, x, y);
					break;

				// TEXTURECHANNELCLASS_FLOATING_POINT or
				// TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT
				default:
					floatsAccess.setPixel(ufloatColor, 0, 0);
					tmpFloats = ut::gluePixels(floatsAccess.getPixel(0, 0), ufloatColor, tcu::getNumUsedChannels(texFormat.order));
					pixels.setPixel(tmpFloats, x, y);
					break;
			}
		}

		nextSigned		(signedColor);
		nextUnsigned	(unsignedColor);
		sfloatColor +=	sfloatStep;
		ufloatColor +=	ufloatStep;
	}
}

tcu::TestStatus MismatchedWriteOpTestInstance::iterate (void)
{
	const DeviceInterface&			vki					= m_context.getDeviceInterface();
	const VkDevice					dev					= m_context.getDevice();
	const VkQueue					queue				= m_context.getUniversalQueue();
	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();

	Move<VkCommandPool>				cmdPool				= createCommandPool(vki, dev, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
	Move<VkCommandBuffer>			cmdBuffer			= allocateCommandBuffer(vki, dev, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	Move<VkShaderModule>			shaderModule		= createShaderModule(vki, dev, m_context.getBinaryCollection().get("comp"), 0);

	Move<VkDescriptorSetLayout>		descriptorSetLayout	= DescriptorSetLayoutBuilder()
															.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
															.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
															.build(vki, dev);
	Move<VkDescriptorPool>			descriptorPool		= DescriptorPoolBuilder()
															.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
															.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
															.build(vki, dev, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
	Move<VkDescriptorSet>			descriptorSet		= makeDescriptorSet(vki, dev, *descriptorPool, *descriptorSetLayout);
	Move<VkPipelineLayout>			pipelineLayout		= makePipelineLayout(vki, dev, *descriptorSetLayout);
	Move<VkPipeline>				pipeline			= makeComputePipeline(vki, dev, *pipelineLayout, *shaderModule);


	ut::StorageImage2D				image				(m_context, m_params->vkFormat, m_params->textureWidth, m_params->textureHeight);

	ut::StorageBuffer2D				buffer				(m_context, m_test->getBufferFormat(), m_params->textureWidth, m_params->textureHeight);

	VkDescriptorImageInfo			inputImageInfo		= makeDescriptorImageInfo(DE_NULL, image.getView(), VK_IMAGE_LAYOUT_GENERAL);
	VkDescriptorBufferInfo			outputBufferInfo	= makeDescriptorBufferInfo(buffer.getBuffer(), 0u, buffer.getSize());

	DescriptorSetUpdateBuilder		builder;
	builder
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &inputImageInfo)
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferInfo)
		.update(vki, dev);

	populate	(buffer.getPixelAccess());
	clear		(image.getPixelAccess());

	beginCommandBuffer(vki, *cmdBuffer);
		image.upload(*cmdBuffer);
		vki.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
		vki.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
		vki.cmdDispatch(*cmdBuffer, m_params->textureWidth, m_params->textureHeight, 1);
		image.download(*cmdBuffer);
	endCommandBuffer(vki, *cmdBuffer);

	image.flush();
	buffer.flush();

	submitCommandsAndWait(vki, dev, queue, *cmdBuffer);

	image.invalidate();
	buffer.invalidate();

	return compare(image.getPixelAccess(), buffer.getPixelAccess())
			? tcu::TestStatus::pass("")
			: tcu::TestStatus::fail("Pixel comparison failed");
}

bool MismatchedVectorSizesTestInstance::compare (tcu::PixelBufferAccess& result, tcu::PixelBufferAccess& reference) const
{
	const tcu::TextureFormat			texFormat		= mapVkFormat(m_params->vkFormat);
	const tcu::TextureChannelClass		channelClass	= tcu::getTextureChannelClass(texFormat.type);
	const int							targetWidth		= getNumUsedChannels(texFormat.order);

	bool								doContinue		= true;

	for (int y = 0; doContinue && y < m_params->textureHeight; ++y)
	{
		for (int x = 0; doContinue && x < m_params->textureWidth; ++x)
		{
			switch (channelClass)
			{
				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
					doContinue	= ut::comparePixels(result.getPixelInt(x,y),  reference.getPixelInt(x,y), targetWidth );
					break;
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
					doContinue	= ut::comparePixels(result.getPixelUint(x,y), reference.getPixelUint(x,y), targetWidth );
					break;
				default:
					doContinue	= ut::comparePixels(result.getPixel(x,y),     reference.getPixel(x,y),	   targetWidth, 0.0005f);
					break;
			}
		}
	}

	return doContinue;
}

bool MismatchedSignednessAndTypeTestInstance::compare (tcu::PixelBufferAccess& result, tcu::PixelBufferAccess& reference) const
{
	DE_UNREF(result);
	DE_UNREF(reference);
	return true;
}

} // anonymous

tcu::TestCaseGroup* createImageWriteOpTests (tcu::TestContext& testCtx)
{
	std::stringstream ss;

	auto genVectorSizesTestName			= [&](const FormatInfo& info, const int sourceWidth) -> std::string
	{
		ss.str(std::string());
		ss << de::toLower(info.spirvName) << "_from";
		if (sourceWidth > 1)
			ss << "_vec" << sourceWidth;
		else ss << "_scalar";

		return ss.str();
	};

	auto testGroup						= new tcu::TestCaseGroup(testCtx, "mismatched_write_op",			"Test image OpImageWrite operation in various aspects.");
	auto testGroupMismatchedVectorSizes	= new tcu::TestCaseGroup(testCtx, "mismatched_vector_sizes",		"Case OpImageWrite operation on mismatched vector sizes.");
	auto testGroupMismatchedSignedness	= new tcu::TestCaseGroup(testCtx, "mismatched_signedness_and_type",	"Case OpImageWrite operation on mismatched signedness and values.");

	for (const auto& info : formatsInfos)
	{
		{
			const auto switchClass = getTextureChannelClass(mapVkFormat(info.vkFormat).type);
			auto compatibleFormats = findFormatsByChannelClass(switchClass);

			auto end	= compatibleFormats.cend();
			auto begin	= compatibleFormats.cbegin();
			for (auto i = begin; i != end; ++i)
			{
				if (i->capability == OpCapability::Int64ImageEXT || info.capability == OpCapability::Int64ImageEXT) continue;

				const std::string testName = de::toLower(i->spirvName) + "_from_" + de::toLower(info.spirvName);
				auto params	= new MismatchedWriteOpTest::Params { info.vkFormat, 12, 8*static_cast<int>(std::distance(begin,i)+1), i->vkFormat };
				testGroupMismatchedSignedness->addChild(new MismatchedSignednessAndTypeTest(testCtx, testName, {}, MismatchedVectorSizesTest::ParamsSp(params)));
			}
		}

		for (int sourceWidth = 4; sourceWidth > 0; --sourceWidth)
		{
			if (sourceWidth >= getNumUsedChannels(info.vkFormat))
			{
				auto params = new MismatchedWriteOpTest::Params { info.vkFormat, 12*sourceWidth, 8*(4-sourceWidth+1), info.vkFormat };
				testGroupMismatchedVectorSizes->addChild(
					new MismatchedVectorSizesTest(testCtx, genVectorSizesTestName(info, sourceWidth), {}, MismatchedVectorSizesTest::ParamsSp(params), sourceWidth));
			}
		}
	}

	testGroup->addChild(testGroupMismatchedVectorSizes);
	testGroup->addChild(testGroupMismatchedSignedness);

	return testGroup;
}

} // image
} // vkt
