/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 The Khronos Group Inc.
 *
 * 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  vktImageAstcDecodeModeTests.cpp
 * \brief Astc decode mode tests
 *//*--------------------------------------------------------------------*/

#include "vktImageAstcDecodeModeTests.hpp"
#include "vktImageLoadStoreUtil.hpp"

#include "vktTestCaseUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "tcuAstcUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTexture.hpp"
#include "tcuCompressedTexture.hpp"
#include "tcuImageCompare.hpp"

#include "deRandom.hpp"
#include <vector>

using namespace vk;
namespace vkt
{
namespace image
{
namespace
{
using std::string;
using std::vector;
using tcu::TestContext;
using tcu::TestStatus;
using tcu::UVec3;
using tcu::IVec3;
using tcu::CompressedTexFormat;
using tcu::CompressedTexture;
using de::MovePtr;
using de::SharedPtr;
using de::Random;

struct TestParameters
{
	ImageType			imageType;
	UVec3				imageSize;

	VkFormat			testedFormat;
	deBool				testedIsUnorm;
	VkFormat			testedDecodeMode;
	VkImageUsageFlags	testedImageUsage;

	VkFormat			resultFormat;
	VkImageUsageFlags	resultImageUsage;
};

class BasicComputeTestInstance : public TestInstance
{
public:
					BasicComputeTestInstance	(Context&					context,
												 const TestParameters&		parameters);

	TestStatus		iterate						(void);

protected:

	const TestParameters	m_parameters;
};

BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters)
	: TestInstance	(context)
	, m_parameters	(parameters)
{
}

TestStatus BasicComputeTestInstance::iterate (void)
{
	Allocator&						allocator			= m_context.getDefaultAllocator();
	const DeviceInterface&			vk					= m_context.getDeviceInterface();
	const VkDevice					device				= m_context.getDevice();
	const VkQueue					queue				= m_context.getUniversalQueue();
	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkImageType				imageType			= mapImageType(m_parameters.imageType);
	const VkExtent3D				extentCompressed	= makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.testedFormat, m_parameters.imageSize));
	const VkExtent3D				extentUnCompressed	= makeExtent3D(m_parameters.imageSize);
	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const Unique<VkShaderModule>	shaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));

	const VkImageCreateInfo compressedImageInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
		DE_NULL,												// const void*				pNext;
		VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
		VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT,		// VkImageCreateFlags		flags;
		imageType,												// VkImageType				imageType;
		m_parameters.testedFormat,								// VkFormat					format;
		extentCompressed,										// VkExtent3D				extent;
		1u,														// deUint32					mipLevels;
		1u,														// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
		VK_IMAGE_USAGE_SAMPLED_BIT |
		VK_IMAGE_USAGE_TRANSFER_DST_BIT,						// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
		0u,														// deUint32					queueFamilyIndexCount;
		DE_NULL,												// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
	};

	const VkImageCreateInfo resultImageInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
		DE_NULL,												// const void*				pNext;
		0u,														// VkImageCreateFlags		flags;
		imageType,												// VkImageType				imageType;
		m_parameters.resultFormat,								// VkFormat					format;
		extentUnCompressed,										// VkExtent3D				extent;
		1u,														// deUint32					mipLevels;
		1u,														// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
		VK_IMAGE_USAGE_SAMPLED_BIT |
		VK_IMAGE_USAGE_STORAGE_BIT |
		VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
		VK_IMAGE_USAGE_TRANSFER_DST_BIT,						// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
		0u,														// deUint32					queueFamilyIndexCount;
		DE_NULL,												// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
	};

	// create images
	Image							testedImage				(vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
	Image							referenceImage			(vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
	Image							resultImage				(vk, device, allocator, resultImageInfo, MemoryRequirement::Any);

	// create image views
	const VkImageViewType			imageViewType			(mapImageViewType(m_parameters.imageType));
	VkImageSubresourceRange			subresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);

	VkImageViewASTCDecodeModeEXT decodeMode =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT,
		DE_NULL,
		m_parameters.testedDecodeMode
	};

	const VkImageViewCreateInfo imageViewParams =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
		&decodeMode,									// const void*				pNext;
		0u,												// VkImageViewCreateFlags	flags;
		testedImage.get(),								// VkImage					image;
		imageViewType,									// VkImageViewType			viewType;
		m_parameters.testedFormat,						// VkFormat					format;
		makeComponentMappingRGBA(),						// VkComponentMapping		components;
		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
	};

	Move<VkImageView>				testedView				= createImageView(vk, device, &imageViewParams);
	Move<VkImageView>				referenceView			= makeImageView(vk, device, referenceImage.get(), imageViewType, m_parameters.testedFormat, subresourceRange);
	Move<VkImageView>				resultView				= makeImageView(vk, device, resultImage.get(), imageViewType, m_parameters.resultFormat,
																makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, resultImageInfo.extent.depth, 0u, resultImageInfo.arrayLayers));

	Move<VkDescriptorSetLayout>		descriptorSetLayout		= DescriptorSetLayoutBuilder()
																.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
																.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
																.build(vk, device);
	Move<VkDescriptorPool>			descriptorPool			= DescriptorPoolBuilder()
																.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
																.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
																.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, resultImageInfo.arrayLayers)
																.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, resultImageInfo.arrayLayers);

	Move<VkDescriptorSet>			descriptorSet			= makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
	const Unique<VkPipelineLayout>	pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline>		pipeline				(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));

	const VkDeviceSize				bufferSizeCompresed		= getCompressedImageSizeInBytes(m_parameters.testedFormat, m_parameters.imageSize);
	const VkDeviceSize				bufferSizeUncompressed	= getImageSizeBytes(IVec3((int)extentUnCompressed.width, (int)extentUnCompressed.height, (int)extentUnCompressed.depth), m_parameters.resultFormat);
	VkBufferCreateInfo				compressedBufferCI		= makeBufferCreateInfo(bufferSizeCompresed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
	VkBufferCreateInfo				uncompressedBufferCI	= makeBufferCreateInfo(bufferSizeUncompressed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	Buffer							inBuffer				(vk, device, allocator, compressedBufferCI, MemoryRequirement::HostVisible);
	Buffer							resultBuffer			(vk, device, allocator, uncompressedBufferCI, MemoryRequirement::HostVisible);
	Move<VkSampler>					sampler;

	// generate data for compressed image and copy it to in buffer
	{
		vector<deUint8> generatedData;
		generatedData.resize(static_cast<size_t>(bufferSizeCompresed));

		auto blocks = getCompressedImageResolutionInBlocks(m_parameters.testedFormat, m_parameters.imageSize);
		tcu::astc::generateRandomValidBlocks(generatedData.data(),
										blocks.x() * blocks.y() * blocks.z(),
										mapVkCompressedFormat(m_parameters.testedFormat),
										tcu::TexDecompressionParams::ASTCMODE_LDR,
										1);

		const Allocation& alloc = inBuffer.getAllocation();
		deMemcpy(alloc.getHostPtr(), generatedData.data(), generatedData.size());
		flushAlloc(vk, device, alloc);
	}

	{
		const VkSamplerCreateInfo createInfo	=
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,			//VkStructureType		sType;
			DE_NULL,										//const void*			pNext;
			0u,												//VkSamplerCreateFlags	flags;
			VK_FILTER_NEAREST,								//VkFilter				magFilter;
			VK_FILTER_NEAREST,								//VkFilter				minFilter;
			VK_SAMPLER_MIPMAP_MODE_NEAREST,					//VkSamplerMipmapMode	mipmapMode;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			//VkSamplerAddressMode	addressModeU;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			//VkSamplerAddressMode	addressModeV;
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			//VkSamplerAddressMode	addressModeW;
			0.0f,											//float					mipLodBias;
			VK_FALSE,										//VkBool32				anisotropyEnable;
			1.0f,											//float					maxAnisotropy;
			VK_FALSE,										//VkBool32				compareEnable;
			VK_COMPARE_OP_EQUAL,							//VkCompareOp			compareOp;
			0.0f,											//float					minLod;
			1.0f,											//float					maxLod;
			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,		//VkBorderColor			borderColor;
			VK_FALSE,										//VkBool32				unnormalizedCoordinates;
		};
		sampler = createSampler(vk, device, &createInfo);
	}

	VkDescriptorImageInfo descriptorImageInfos[] =
	{
		makeDescriptorImageInfo(*sampler,	*testedView,	VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
		makeDescriptorImageInfo(*sampler,	*referenceView,	VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
		makeDescriptorImageInfo(DE_NULL,	*resultView,	VK_IMAGE_LAYOUT_GENERAL),
	};
	DescriptorSetUpdateBuilder()
		.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[0])
		.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[1])
		.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[2])
		.update(vk, device);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		// copy input buffer to tested and reference images
		{
			Image* inImages[] = { &testedImage, &referenceImage };
			for (Image* image : inImages)
			{
				const VkImageMemoryBarrier preCopyImageBarrier = makeImageMemoryBarrier(
					0u, VK_ACCESS_TRANSFER_WRITE_BIT,
					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
					image->get(), subresourceRange);

				const VkBufferMemoryBarrier flushHostCopyBarrier = makeBufferMemoryBarrier(
					VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
					inBuffer.get(), 0ull, bufferSizeCompresed);

				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
					(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &flushHostCopyBarrier, 1u, &preCopyImageBarrier);

				const VkBufferImageCopy copyRegion =
				{
					0ull,																			//VkDeviceSize				bufferOffset;
					0u,																				//deUint32					bufferRowLength;
					0u,																				//deUint32					bufferImageHeight;
					makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),				//VkImageSubresourceLayers	imageSubresource;
					makeOffset3D(0, 0, 0),															//VkOffset3D				imageOffset;
					extentCompressed,																//VkExtent3D				imageExtent;
				};

				vk.cmdCopyBufferToImage(*cmdBuffer, inBuffer.get(), image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
			}
		}

		// bind pipeline and descriptors
		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);

		{
			const VkImageMemoryBarrier preShaderImageBarriers[] =
			{
				makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
					testedImage.get(), subresourceRange),

				makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
					referenceImage.get(), subresourceRange),

				makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT,
					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
					resultImage.get(), subresourceRange)
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
				(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
				DE_LENGTH_OF_ARRAY(preShaderImageBarriers), preShaderImageBarriers);
		}

		vk.cmdDispatch(*cmdBuffer, extentUnCompressed.width, extentUnCompressed.height, extentUnCompressed.depth);

		{
			const VkImageMemoryBarrier postShaderImageBarriers[] =
			{
				makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
					VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
					resultImage.get(), subresourceRange)
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
				(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
				DE_LENGTH_OF_ARRAY(postShaderImageBarriers), postShaderImageBarriers);
		}

		const VkBufferImageCopy copyRegion =
		{
			0ull,																//	VkDeviceSize				bufferOffset;
			0u,																	//	deUint32					bufferRowLength;
			0u,																	//	deUint32					bufferImageHeight;
			makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),	//	VkImageSubresourceLayers	imageSubresource;
			makeOffset3D(0, 0, 0),												//	VkOffset3D					imageOffset;
			resultImageInfo.extent,												//	VkExtent3D					imageExtent;
		};
		vk.cmdCopyImageToBuffer(*cmdBuffer, resultImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, resultBuffer.get(), 1u, &copyRegion);

		{
			const VkBufferMemoryBarrier postCopyBufferBarrier[] =
			{
				makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
					resultBuffer.get(), 0ull, bufferSizeUncompressed),
			};

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
				(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBufferBarrier), postCopyBufferBarrier,
				0u, (const VkImageMemoryBarrier*)DE_NULL);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	const Allocation& resultAlloc = resultBuffer.getAllocation();
	invalidateAlloc(vk, device, resultAlloc);

	// verification is done in shader - here we just check if one of pixels has wrong value
	const size_t	numBytes		= static_cast<size_t>(bufferSizeUncompressed);
	deUint8*		result		= static_cast<deUint8*>(resultAlloc.getHostPtr());
	for (size_t i = 0 ; i < numBytes ; i += 4)
	{
		// expected result should be around 128 (if reference is same as tested mode then we return 0.5)
		if ((result[i] < 100) || (result[i] > 150))
			return TestStatus::fail("Fail");
	}

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

class AstcDecodeModeCase : public TestCase
{
public:
					AstcDecodeModeCase	(TestContext&			testCtx,
										 const std::string&		name,
										 const std::string&		desc,
										 const TestParameters&	parameters);
	virtual void	checkSupport		(Context&				context) const;
	void			initPrograms		(SourceCollections&		programCollection) const;
	TestInstance*	createInstance		(Context&				context) const;

protected:

	const TestParameters m_parameters;
};

AstcDecodeModeCase::AstcDecodeModeCase (TestContext&			testCtx,
										const std::string&		name,
										const std::string&		desc,
										const TestParameters&	parameters)
	: TestCase		(testCtx, name, desc)
	, m_parameters	(parameters)
{
}

void AstcDecodeModeCase::checkSupport (Context& context) const
{
	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
	const InstanceInterface&	vk				= context.getInstanceInterface();

	context.requireDeviceFunctionality("VK_EXT_astc_decode_mode");
	if (!getPhysicalDeviceFeatures(vk, physicalDevice).textureCompressionASTC_LDR)
		TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");

	VkImageFormatProperties imageFormatProperties;
	if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.testedFormat,
												  mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
												  m_parameters.testedImageUsage, 0u, &imageFormatProperties))
		TCU_THROW(NotSupportedError, "Operation not supported with this image format");

	if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.resultFormat,
												  mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
												  m_parameters.resultImageUsage, 0u, &imageFormatProperties))
		TCU_THROW(NotSupportedError, "Operation not supported with this image format");

	if ((m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
		!context.getASTCDecodeFeaturesEXT().decodeModeSharedExponent)
		TCU_THROW(NotSupportedError, "decodeModeSharedExponent not supported");

	VkFormatProperties properties;
	context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_parameters.resultFormat, &properties);
	if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
		TCU_THROW(NotSupportedError, "Format storage feature not supported");
}

void AstcDecodeModeCase::initPrograms (vk::SourceCollections& programCollection) const
{
	DE_ASSERT(m_parameters.imageSize.x() > 0);
	DE_ASSERT(m_parameters.imageSize.y() > 0);

	const string				formatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.resultFormat));
	const string				imageTypeStr		= getShaderImageType(mapVkFormat(m_parameters.resultFormat), m_parameters.imageType);

	std::ostringstream	src;
	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
		<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\n"
		<< "layout (binding = 0) uniform sampler2D compressed_tested;\n"
		<< "layout (binding = 1) uniform sampler2D compressed_reference;\n"
		<< "layout (binding = 2, " << formatQualifierStr << ") writeonly uniform " << imageTypeStr << " result;\n"
		<< "void main (void)\n"
		<< "{\n"
		<< "    const vec2 pixels_resolution = vec2(gl_NumWorkGroups.xy);\n"
		<< "    const vec2 cord = vec2(gl_GlobalInvocationID.xy) / vec2(pixels_resolution);\n"
		<< "    const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); \n"
		<< "    vec4 tested = texture(compressed_tested, cord);\n"
		<< "    vec4 reference = texture(compressed_reference, cord);\n";

	// special case for e5b9g9r9 decode mode that was set on unorm astc formats
	// here negative values are clamped to zero and alpha is set to 1
	if (m_parameters.testedIsUnorm && (m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32))
		src << "    reference = max(vec4(0,0,0,1), reference);\n"
			   "    float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
	else
		src << "    float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";

	src << "    imageStore(result, pos, vec4(result_color));\n"
		<< "}\n";

	programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
}

TestInstance* AstcDecodeModeCase::createInstance (Context& context) const
{
	return new BasicComputeTestInstance(context, m_parameters);
}

} // anonymous ns

tcu::TestCaseGroup* createImageAstcDecodeModeTests (tcu::TestContext& testCtx)
{
	struct FormatData
	{
		VkFormat		format;
		std::string		name;
		deBool			isUnorm;
	};
	const FormatData astcFormats[] =
	{
		{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK,		"4x4_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK,		"4x4_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK,		"5x4_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK,		"5x4_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK,		"5x5_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK,		"5x5_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK,		"6x5_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,		"6x5_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK,		"6x6_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK,		"6x6_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK,		"8x5_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK,		"8x5_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK,		"8x6_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK,		"8x6_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK,		"8x8_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK,		"8x8_srgb",		DE_FALSE },
		{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK,		"10x5_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK,		"10x5_srgb",	DE_FALSE },
		{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK,		"10x6_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK,		"10x6_srgb",	DE_FALSE },
		{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK,		"10x8_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK,		"10x8_srgb",	DE_FALSE },
		{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK,		"10x10_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK,		"10x10_srgb",	DE_FALSE },
		{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK,		"12x10_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK,		"12x10_srgb",	DE_FALSE },
		{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK,		"12x12_unorm",	DE_TRUE },
		{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK,		"12x12_srgb",	DE_FALSE },
	};

	struct DecodeModeData
	{
		VkFormat		mode;
		std::string		name;
	};
	const DecodeModeData decodeModes[] =
	{
		{ VK_FORMAT_R16G16B16A16_SFLOAT,	"r16g16b16a16_sfloat" },
		{ VK_FORMAT_R8G8B8A8_UNORM,			"r8g8b8a8_unorm" },
		{ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,	"e5b9g9r9_ufloat_pack32" }
	};

	MovePtr<tcu::TestCaseGroup> astcDecodeModeTests(new tcu::TestCaseGroup(testCtx, "astc_decode_mode", "Intermediate decoding precision cases"));
	for (const FormatData& format : astcFormats)
	{
		for (const DecodeModeData& mode : decodeModes)
		{
			const TestParameters parameters =
			{
				IMAGE_TYPE_2D,
				UVec3(64u, 64u, 1u),
				format.format,
				format.isUnorm,
				mode.mode,
				VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
				VK_FORMAT_R8G8B8A8_UNORM,
				VK_IMAGE_USAGE_STORAGE_BIT
			};

			std::string name = format.name + "_to_" + mode.name;
			astcDecodeModeTests->addChild(new AstcDecodeModeCase(testCtx, name, "", parameters));
		}
	}

	return astcDecodeModeTests.release();
}

} // image
} // vkt
