/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 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 Memory qualifiers tests
 *//*--------------------------------------------------------------------*/

#include "vktImageQualifiersTests.hpp"
#include "vktImageLoadStoreTests.hpp"
#include "vktImageTestsUtil.hpp"

#include "vkDefs.hpp"
#include "vkImageUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkPlatform.hpp"
#include "vkPrograms.hpp"
#include "vkMemUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "deDefs.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include "tcuImageCompare.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorType.hpp"

using namespace vk;

namespace vkt
{
namespace image
{
namespace
{

static const tcu::UVec3		g_localWorkGroupSizeBase	= tcu::UVec3(8, 8, 2);
static const deInt32		g_ShaderReadOffsetsX[4]		= { 1, 4, 7, 10 };
static const deInt32		g_ShaderReadOffsetsY[4]		= { 2, 5, 8, 11 };
static const deInt32		g_ShaderReadOffsetsZ[4]		= { 3, 6, 9, 12 };
static const char* const	g_ShaderReadOffsetsXStr		= "int[]( 1, 4, 7, 10 )";
static const char* const	g_ShaderReadOffsetsYStr		= "int[]( 2, 5, 8, 11 )";
static const char* const	g_ShaderReadOffsetsZStr		= "int[]( 3, 6, 9, 12 )";

const tcu::UVec3 getLocalWorkGroupSize (const ImageType imageType, const tcu::UVec3& imageSize)
{
	const tcu::UVec3 computeGridSize	= getShaderGridSize(imageType, imageSize);

	const tcu::UVec3 localWorkGroupSize = tcu::UVec3(de::min(g_localWorkGroupSizeBase.x(), computeGridSize.x()),
													 de::min(g_localWorkGroupSizeBase.y(), computeGridSize.y()),
													 de::min(g_localWorkGroupSizeBase.z(), computeGridSize.z()));
	return localWorkGroupSize;
}

const tcu::UVec3 getNumWorkGroups (const ImageType imageType, const tcu::UVec3& imageSize)
{
	const tcu::UVec3 computeGridSize	= getShaderGridSize(imageType, imageSize);
	const tcu::UVec3 localWorkGroupSize = getLocalWorkGroupSize(imageType, imageSize);

	return computeGridSize / localWorkGroupSize;
}

tcu::ConstPixelBufferAccess getLayerOrSlice (const ImageType					imageType,
											 const tcu::ConstPixelBufferAccess&	access,
											 const deUint32						layer)
{
	switch (imageType)
	{
		case IMAGE_TYPE_1D:
		case IMAGE_TYPE_2D:
		case IMAGE_TYPE_BUFFER:
			DE_ASSERT(layer == 0);
			return access;

		case IMAGE_TYPE_1D_ARRAY:
			return tcu::getSubregion(access, 0, layer, access.getWidth(), 1);

		case IMAGE_TYPE_2D_ARRAY:
		case IMAGE_TYPE_3D:
		case IMAGE_TYPE_CUBE:
		case IMAGE_TYPE_CUBE_ARRAY:
			return tcu::getSubregion(access, 0, 0, layer, access.getWidth(), access.getHeight(), 1);

		default:
			DE_FATAL("Unknown image type");
			return tcu::ConstPixelBufferAccess();
	}
}

bool comparePixelBuffers (tcu::TestContext&						testCtx,
						  const ImageType						imageType,
						  const tcu::UVec3&						imageSize,
						  const tcu::TextureFormat&				format,
						  const tcu::ConstPixelBufferAccess&	reference,
						  const tcu::ConstPixelBufferAccess&	result)
{
	DE_ASSERT(reference.getFormat() == result.getFormat());
	DE_ASSERT(reference.getSize() == result.getSize());

	const bool		 intFormat			= isIntFormat(mapTextureFormat(format)) || isUintFormat(mapTextureFormat(format));
	deUint32		 passedLayers		= 0;

	for (deUint32 layerNdx = 0; layerNdx < getNumLayers(imageType, imageSize); ++layerNdx)
	{
		const std::string comparisonName = "Comparison" + de::toString(layerNdx);

		std::string comparisonDesc = "Image Comparison, ";
		switch (imageType)
		{
			case IMAGE_TYPE_3D:
				comparisonDesc = comparisonDesc + "slice " + de::toString(layerNdx);
				break;

			case IMAGE_TYPE_CUBE:
			case IMAGE_TYPE_CUBE_ARRAY:
				comparisonDesc = comparisonDesc + "face " + de::toString(layerNdx % 6) + ", cube " + de::toString(layerNdx / 6);
				break;

			default:
				comparisonDesc = comparisonDesc + "layer " + de::toString(layerNdx);
				break;
		}

		const tcu::ConstPixelBufferAccess refLayer		= getLayerOrSlice(imageType, reference, layerNdx);
		const tcu::ConstPixelBufferAccess resultLayer	= getLayerOrSlice(imageType, result, layerNdx);

		bool ok = false;
		if (intFormat)
			ok = tcu::intThresholdCompare(testCtx.getLog(), comparisonName.c_str(), comparisonDesc.c_str(), refLayer, resultLayer, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
		else
			ok = tcu::floatThresholdCompare(testCtx.getLog(), comparisonName.c_str(), comparisonDesc.c_str(), refLayer, resultLayer, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);

		if (ok)
			++passedLayers;
	}

	return passedLayers == getNumLayers(imageType, imageSize);
}

const std::string getCoordStr (const ImageType		imageType,
							   const std::string&	x,
							   const std::string&	y,
							   const std::string&	z)
{
	switch (imageType)
	{
		case IMAGE_TYPE_1D:
		case IMAGE_TYPE_BUFFER:
			return x;

		case IMAGE_TYPE_1D_ARRAY:
		case IMAGE_TYPE_2D:
			return "ivec2(" + x + "," + y + ")";

		case IMAGE_TYPE_2D_ARRAY:
		case IMAGE_TYPE_3D:
		case IMAGE_TYPE_CUBE:
		case IMAGE_TYPE_CUBE_ARRAY:
			return "ivec3(" + x + "," + y + "," + z + ")";

		default:
			DE_ASSERT(false);
			return "";
	}
}

class MemoryQualifierTestCase : public vkt::TestCase
{
public:

	enum Qualifier
	{
		QUALIFIER_COHERENT = 0,
		QUALIFIER_VOLATILE,
		QUALIFIER_RESTRICT,
		QUALIFIER_LAST
	};

								MemoryQualifierTestCase		(tcu::TestContext&			testCtx,
															 const std::string&			name,
															 const std::string&			description,
															 const Qualifier			qualifier,
															 const ImageType			imageType,
															 const tcu::UVec3&			imageSize,
															 const tcu::TextureFormat&	format,
															 const glu::GLSLVersion		glslVersion);

	virtual						~MemoryQualifierTestCase	(void) {}

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

protected:

	const Qualifier				m_qualifier;
	const ImageType				m_imageType;
	const tcu::UVec3			m_imageSize;
	const tcu::TextureFormat	m_format;
	const glu::GLSLVersion		m_glslVersion;
};

MemoryQualifierTestCase::MemoryQualifierTestCase (tcu::TestContext&			testCtx,
												  const std::string&		name,
												  const std::string&		description,
												  const Qualifier			qualifier,
												  const ImageType			imageType,
												  const tcu::UVec3&			imageSize,
												  const tcu::TextureFormat&	format,
												  const glu::GLSLVersion	glslVersion)
	: vkt::TestCase(testCtx, name, description)
	, m_qualifier(qualifier)
	, m_imageType(imageType)
	, m_imageSize(imageSize)
	, m_format(format)
	, m_glslVersion(glslVersion)
{
}

void MemoryQualifierTestCase::checkSupport (Context& context) const
{
	if (m_imageType == IMAGE_TYPE_CUBE_ARRAY)
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);
}

void MemoryQualifierTestCase::initPrograms (SourceCollections& programCollection) const
{
	const char* const	versionDecl			= glu::getGLSLVersionDeclaration(m_glslVersion);

	const char* const	qualifierName		= m_qualifier == QUALIFIER_COHERENT ? "coherent"
											: m_qualifier == QUALIFIER_VOLATILE ? "volatile"
											: DE_NULL;

	const bool			uintFormat			= isUintFormat(mapTextureFormat(m_format));
	const bool			intFormat			= isIntFormat(mapTextureFormat(m_format));
	const std::string	colorVecTypeName	= std::string(uintFormat ? "u"	: intFormat ? "i" : "") + "vec4";
	const std::string	colorScalarTypeName = std::string(uintFormat ? "uint" : intFormat ? "int" : "float");
	const std::string	invocationCoord		= getCoordStr(m_imageType, "gx", "gy", "gz");
	const std::string	shaderImageFormat	= getShaderImageFormatQualifier(m_format);
	const std::string	shaderImageType		= getShaderImageType(m_format, m_imageType);

	const tcu::UVec3	localWorkGroupSize	= getLocalWorkGroupSize(m_imageType, m_imageSize);
	const std::string	localSizeX			= de::toString(localWorkGroupSize.x());
	const std::string	localSizeY			= de::toString(localWorkGroupSize.y());
	const std::string	localSizeZ			= de::toString(localWorkGroupSize.z());

	std::ostringstream	programBuffer;

	programBuffer
		<< versionDecl << "\n"
		<< "\n"
		<< "precision highp " << shaderImageType << ";\n"
		<< "\n"
		<< "layout (local_size_x = " << localSizeX << ", local_size_y = " << localSizeY << ", local_size_z = " + localSizeZ << ") in;\n"
		<< "layout (" << shaderImageFormat << ", binding=0) " << qualifierName << " uniform " << shaderImageType << " u_image;\n"
		<< "void main (void)\n"
		<< "{\n"
		<< "	int gx = int(gl_GlobalInvocationID.x);\n"
		<< "	int gy = int(gl_GlobalInvocationID.y);\n"
		<< "	int gz = int(gl_GlobalInvocationID.z);\n"
		<< "	imageStore(u_image, " << invocationCoord << ", " << colorVecTypeName << "(gx^gy^gz));\n"
		<< "\n"
		<< "	memoryBarrier();\n"
		<< "	barrier();\n"
		<< "\n"
		<< "	" << colorScalarTypeName << " sum = " << colorScalarTypeName << "(0);\n"
		<< "	int groupBaseX = gx/" << localSizeX << "*" << localSizeX << ";\n"
		<< "	int groupBaseY = gy/" << localSizeY << "*" << localSizeY << ";\n"
		<< "	int groupBaseZ = gz/" << localSizeZ << "*" << localSizeZ << ";\n"
		<< "	int xOffsets[] = " << g_ShaderReadOffsetsXStr << ";\n"
		<< "	int yOffsets[] = " << g_ShaderReadOffsetsYStr << ";\n"
		<< "	int zOffsets[] = " << g_ShaderReadOffsetsZStr << ";\n"
		<< "	for (int i = 0; i < " << de::toString(DE_LENGTH_OF_ARRAY(g_ShaderReadOffsetsX)) << "; i++)\n"
		<< "	{\n"
		<< "		int readX = groupBaseX + (gx + xOffsets[i]) % " + localSizeX + ";\n"
		<< "		int readY = groupBaseY + (gy + yOffsets[i]) % " + localSizeY + ";\n"
		<< "		int readZ = groupBaseZ + (gz + zOffsets[i]) % " + localSizeZ + ";\n"
		<< "		sum += imageLoad(u_image, " << getCoordStr(m_imageType, "readX", "readY", "readZ") << ").x;\n"
		<< "	}\n"
		<< "\n"
		<< "	memoryBarrier();\n"
		<< "	barrier();\n"
		<< "\n"
		<< "	imageStore(u_image, " + invocationCoord + ", " + colorVecTypeName + "(sum));\n"
		<< "}\n";

	programCollection.glslSources.add(m_name) << glu::ComputeSource(programBuffer.str());
}

class MemoryQualifierInstanceBase : public vkt::TestInstance
{
public:
									MemoryQualifierInstanceBase		(Context&					context,
																	 const std::string&			name,
																	 const ImageType			imageType,
																	 const tcu::UVec3&			imageSize,
																	 const tcu::TextureFormat&	format);

	virtual							~MemoryQualifierInstanceBase	(void) {};

	virtual tcu::TestStatus			iterate							(void);

	virtual void					prepareResources				(const VkDeviceSize			bufferSizeInBytes) = 0;

	virtual void					prepareDescriptors				(void) = 0;

	virtual void					commandsBeforeCompute			(const VkCommandBuffer		cmdBuffer,
																	 const VkDeviceSize			bufferSizeInBytes) const = 0;

	virtual void					commandsAfterCompute			(const VkCommandBuffer		cmdBuffer,
																	 const VkDeviceSize			bufferSizeInBytes) const = 0;

protected:

	tcu::TextureLevel				generateReferenceImage			(void) const;

	const std::string				m_name;
	const ImageType					m_imageType;
	const tcu::UVec3				m_imageSize;
	const tcu::TextureFormat		m_format;

	de::MovePtr<Buffer>				m_buffer;
	Move<VkDescriptorPool>			m_descriptorPool;
	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
	Move<VkDescriptorSet>			m_descriptorSet;
};

MemoryQualifierInstanceBase::MemoryQualifierInstanceBase (Context&					context,
														  const std::string&		name,
														  const ImageType			imageType,
														  const tcu::UVec3&			imageSize,
														  const tcu::TextureFormat&	format)
	: vkt::TestInstance(context)
	, m_name(name)
	, m_imageType(imageType)
	, m_imageSize(imageSize)
	, m_format(format)
{
}

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

	const VkDeviceSize	bufferSizeInBytes = getNumPixels(m_imageType, m_imageSize) * tcu::getPixelSize(m_format);

	// Prepare resources for the test
	prepareResources(bufferSizeInBytes);

	// Prepare descriptor sets
	prepareDescriptors();

	// Create compute shader
	const vk::Unique<VkShaderModule> shaderModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get(m_name), 0u));

	// Create compute pipeline
	const vk::Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(deviceInterface, device, *m_descriptorSetLayout));
	const vk::Unique<VkPipeline> pipeline(makeComputePipeline(deviceInterface, device, *pipelineLayout, *shaderModule));

	// Create command buffer
	const Unique<VkCommandPool> cmdPool(createCommandPool(deviceInterface, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer> cmdBuffer(allocateCommandBuffer(deviceInterface, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	// Start recording commands
	beginCommandBuffer(deviceInterface, *cmdBuffer);

	deviceInterface.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
	deviceInterface.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);

	commandsBeforeCompute(*cmdBuffer, bufferSizeInBytes);

	const tcu::UVec3 numGroups = getNumWorkGroups(m_imageType, m_imageSize);
	deviceInterface.cmdDispatch(*cmdBuffer, numGroups.x(), numGroups.y(), numGroups.z());

	commandsAfterCompute(*cmdBuffer, bufferSizeInBytes);

	endCommandBuffer(deviceInterface, *cmdBuffer);

	// Submit and wait for completion
	submitCommandsAndWait(deviceInterface, device, queue, *cmdBuffer);

	// Retrieve data from buffer to host memory
	const Allocation& allocation = m_buffer->getAllocation();
	invalidateMappedMemoryRange(deviceInterface, device, allocation.getMemory(), allocation.getOffset(), bufferSizeInBytes);

	const tcu::UVec3 computeGridSize = getShaderGridSize(m_imageType, m_imageSize);
	tcu::ConstPixelBufferAccess resultPixelBuffer(m_format, computeGridSize.x(), computeGridSize.y(), computeGridSize.z(), allocation.getHostPtr());

	// Create a reference image
	tcu::TextureLevel referenceImage = generateReferenceImage();
	tcu::ConstPixelBufferAccess referencePixelBuffer = referenceImage.getAccess();

	// Validate the result
	if (comparePixelBuffers(m_context.getTestContext(), m_imageType, m_imageSize, m_format, referencePixelBuffer, resultPixelBuffer))
		return tcu::TestStatus::pass("Passed");
	else
		return tcu::TestStatus::fail("Image comparison failed");
}

tcu::TextureLevel MemoryQualifierInstanceBase::generateReferenceImage (void) const
{
	// Generate a reference image data using the storage format
	const tcu::UVec3 computeGridSize = getShaderGridSize(m_imageType, m_imageSize);

	tcu::TextureLevel base(m_format, computeGridSize.x(), computeGridSize.y(), computeGridSize.z());
	tcu::PixelBufferAccess baseAccess = base.getAccess();

	tcu::TextureLevel reference(m_format, computeGridSize.x(), computeGridSize.y(), computeGridSize.z());
	tcu::PixelBufferAccess referenceAccess = reference.getAccess();

	for (deInt32 z = 0; z < baseAccess.getDepth(); ++z)
		for (deInt32 y = 0; y < baseAccess.getHeight(); ++y)
			for (deInt32 x = 0; x < baseAccess.getWidth(); ++x)
			{
				baseAccess.setPixel(tcu::IVec4(x^y^z), x, y, z);
			}

	const tcu::UVec3 localWorkGroupSize = getLocalWorkGroupSize(m_imageType, m_imageSize);

	for (deInt32 z = 0; z < referenceAccess.getDepth(); ++z)
		for (deInt32 y = 0; y < referenceAccess.getHeight(); ++y)
			for (deInt32 x = 0; x < referenceAccess.getWidth(); ++x)
			{
				const deInt32	groupBaseX	= x / localWorkGroupSize.x() * localWorkGroupSize.x();
				const deInt32	groupBaseY	= y / localWorkGroupSize.y() * localWorkGroupSize.y();
				const deInt32	groupBaseZ	= z / localWorkGroupSize.z() * localWorkGroupSize.z();
				deInt32			sum			= 0;

				for (deInt32 i = 0; i < DE_LENGTH_OF_ARRAY(g_ShaderReadOffsetsX); i++)
				{
					sum += baseAccess.getPixelInt(
						groupBaseX + (x + g_ShaderReadOffsetsX[i]) % localWorkGroupSize.x(),
						groupBaseY + (y + g_ShaderReadOffsetsY[i]) % localWorkGroupSize.y(),
						groupBaseZ + (z + g_ShaderReadOffsetsZ[i]) % localWorkGroupSize.z()).x();
				}

				referenceAccess.setPixel(tcu::IVec4(sum), x, y, z);
			}

	return reference;
}

class MemoryQualifierInstanceImage : public MemoryQualifierInstanceBase
{
public:
						MemoryQualifierInstanceImage	(Context&					context,
														 const std::string&			name,
														 const ImageType			imageType,
														 const tcu::UVec3&			imageSize,
														 const tcu::TextureFormat&	format)
							: MemoryQualifierInstanceBase(context, name, imageType, imageSize, format) {}

	virtual				~MemoryQualifierInstanceImage	(void) {};

	virtual void		prepareResources				(const VkDeviceSize			bufferSizeInBytes);

	virtual void		prepareDescriptors				(void);

	virtual void		commandsBeforeCompute			(const VkCommandBuffer		cmdBuffer,
														 const VkDeviceSize			bufferSizeInBytes) const;

	virtual void		commandsAfterCompute			(const VkCommandBuffer		cmdBuffer,
														 const VkDeviceSize			bufferSizeInBytes) const;
protected:

	de::MovePtr<Image>	m_image;
	Move<VkImageView>	m_imageView;
};

void MemoryQualifierInstanceImage::prepareResources (const VkDeviceSize bufferSizeInBytes)
{
	const VkDevice			device			= m_context.getDevice();
	const DeviceInterface&	deviceInterface = m_context.getDeviceInterface();
	Allocator&				allocator		= m_context.getDefaultAllocator();

	// Create image
	const VkImageCreateInfo imageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType;
		DE_NULL,														// const void*				pNext;
		m_imageType == IMAGE_TYPE_CUBE ||
		m_imageType	== IMAGE_TYPE_CUBE_ARRAY
		? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0u,	// VkImageCreateFlags		flags;
		mapImageType(m_imageType),										// VkImageType				imageType;
		mapTextureFormat(m_format),										// VkFormat					format;
		makeExtent3D(getLayerSize(m_imageType, m_imageSize)),			// VkExtent3D				extent;
		1u,																// deUint32					mipLevels;
		getNumLayers(m_imageType, m_imageSize),							// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling;
		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_STORAGE_BIT,	// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharingMode;
		0u,																// deUint32					queueFamilyIndexCount;
		DE_NULL,														// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout			initialLayout;
	};

	m_image = de::MovePtr<Image>(new Image(deviceInterface, device, allocator, imageCreateInfo, MemoryRequirement::Any));

	// Create imageView
	const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));
	m_imageView = makeImageView(deviceInterface, device, m_image->get(), mapImageViewType(m_imageType), mapTextureFormat(m_format), subresourceRange);

	// Create a buffer to store shader output (copied from image data)
	const VkBufferCreateInfo	bufferCreateInfo = makeBufferCreateInfo(bufferSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	m_buffer = de::MovePtr<Buffer>(new Buffer(deviceInterface, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
}

void MemoryQualifierInstanceImage::prepareDescriptors (void)
{
	const VkDevice			device			= m_context.getDevice();
	const DeviceInterface&	deviceInterface = m_context.getDeviceInterface();

	// Create descriptor pool
	m_descriptorPool =
		DescriptorPoolBuilder()
		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
		.build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	// Create descriptor set layout
	m_descriptorSetLayout =
		DescriptorSetLayoutBuilder()
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(deviceInterface, device);

	// Allocate descriptor set
	m_descriptorSet = makeDescriptorSet(deviceInterface, device, *m_descriptorPool, *m_descriptorSetLayout);

	// Set the bindings
	const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
		.update(deviceInterface, device);
}

void MemoryQualifierInstanceImage::commandsBeforeCompute (const VkCommandBuffer cmdBuffer, const VkDeviceSize bufferSizeInBytes) const
{
	DE_UNREF(bufferSizeInBytes);

	const DeviceInterface&			deviceInterface	 = m_context.getDeviceInterface();
	const VkImageSubresourceRange	subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));

	const VkImageMemoryBarrier imageLayoutBarrier
		= makeImageMemoryBarrier(0u,
								 VK_ACCESS_SHADER_READ_BIT,
								 VK_IMAGE_LAYOUT_UNDEFINED,
								 VK_IMAGE_LAYOUT_GENERAL,
								 m_image->get(),
								 subresourceRange);

	deviceInterface.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageLayoutBarrier);
}

void MemoryQualifierInstanceImage::commandsAfterCompute (const VkCommandBuffer cmdBuffer, const VkDeviceSize bufferSizeInBytes) const
{
	const DeviceInterface&			deviceInterface	 = m_context.getDeviceInterface();
	const VkImageSubresourceRange	subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));

	const VkImageMemoryBarrier imagePreCopyBarrier
		= makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT,
								 VK_ACCESS_TRANSFER_READ_BIT,
								 VK_IMAGE_LAYOUT_GENERAL,
								 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
								 m_image->get(),
								 subresourceRange);

	deviceInterface.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePreCopyBarrier);

	const VkBufferImageCopy copyParams = makeBufferImageCopy(makeExtent3D(getLayerSize(m_imageType, m_imageSize)), getNumLayers(m_imageType, m_imageSize));
	deviceInterface.cmdCopyImageToBuffer(cmdBuffer, m_image->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_buffer->get(), 1u, &copyParams);

	const VkBufferMemoryBarrier bufferPostCopyBarrier
		= makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT,
								  VK_ACCESS_HOST_READ_BIT,
								  m_buffer->get(),
								  0ull,
								  bufferSizeInBytes);

	deviceInterface.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferPostCopyBarrier, 0u, DE_NULL);
}

class MemoryQualifierInstanceBuffer : public MemoryQualifierInstanceBase
{
public:
						MemoryQualifierInstanceBuffer	(Context&					context,
														 const std::string&			name,
														 const ImageType			imageType,
														 const tcu::UVec3&			imageSize,
														 const tcu::TextureFormat&	format)
							: MemoryQualifierInstanceBase(context, name, imageType, imageSize, format) {}

	virtual				~MemoryQualifierInstanceBuffer	(void) {};

	virtual void		prepareResources				(const VkDeviceSize			bufferSizeInBytes);

	virtual void		prepareDescriptors				(void);

	virtual void		commandsBeforeCompute			(const VkCommandBuffer,
														 const VkDeviceSize) const {}

	virtual void		commandsAfterCompute			(const VkCommandBuffer		cmdBuffer,
														 const VkDeviceSize			bufferSizeInBytes) const;
protected:

	Move<VkBufferView>	m_bufferView;
};

void MemoryQualifierInstanceBuffer::prepareResources (const VkDeviceSize bufferSizeInBytes)
{
	const VkDevice			device			= m_context.getDevice();
	const DeviceInterface&	deviceInterface = m_context.getDeviceInterface();
	Allocator&				allocator		= m_context.getDefaultAllocator();

	// Create a buffer to store shader output
	const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeInBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
	m_buffer = de::MovePtr<Buffer>(new Buffer(deviceInterface, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));

	m_bufferView = makeBufferView(deviceInterface, device, m_buffer->get(), mapTextureFormat(m_format), 0ull, bufferSizeInBytes);
}

void MemoryQualifierInstanceBuffer::prepareDescriptors (void)
{
	const VkDevice			device			= m_context.getDevice();
	const DeviceInterface&	deviceInterface = m_context.getDeviceInterface();

	// Create descriptor pool
	m_descriptorPool =
		DescriptorPoolBuilder()
		.addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
		.build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	// Create descriptor set layout
	m_descriptorSetLayout =
		DescriptorSetLayoutBuilder()
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(deviceInterface, device);

	// Allocate descriptor set
	m_descriptorSet = makeDescriptorSet(deviceInterface, device, *m_descriptorPool, *m_descriptorSetLayout);

	// Set the bindings
	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, &m_bufferView.get())
		.update(deviceInterface, device);
}

void MemoryQualifierInstanceBuffer::commandsAfterCompute (const VkCommandBuffer cmdBuffer, const VkDeviceSize bufferSizeInBytes) const
{
	const DeviceInterface&	deviceInterface = m_context.getDeviceInterface();

	const VkBufferMemoryBarrier shaderWriteBarrier
		= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT,
								  VK_ACCESS_HOST_READ_BIT,
								  m_buffer->get(),
								  0ull,
								  bufferSizeInBytes);

	deviceInterface.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL);
}

TestInstance* MemoryQualifierTestCase::createInstance (Context& context) const
{
	if ( m_imageType == IMAGE_TYPE_BUFFER )
		return new MemoryQualifierInstanceBuffer(context, m_name, m_imageType, m_imageSize, m_format);
	else
		return new MemoryQualifierInstanceImage(context, m_name, m_imageType, m_imageSize, m_format);
}

} // anonymous ns

tcu::TestCaseGroup* createImageQualifiersTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> imageQualifiersTests(new tcu::TestCaseGroup(testCtx, "qualifiers", "Coherent, volatile and restrict"));

	struct ImageParams
	{
		ImageParams(const ImageType imageType, const tcu::UVec3& imageSize)
			: m_imageType	(imageType)
			, m_imageSize	(imageSize)
		{
		}
		ImageType	m_imageType;
		tcu::UVec3	m_imageSize;
	};

	static const ImageParams imageParamsArray[] =
	{
		ImageParams(IMAGE_TYPE_1D,			tcu::UVec3(64u, 1u,  1u)),
		ImageParams(IMAGE_TYPE_1D_ARRAY,	tcu::UVec3(64u, 1u,  8u)),
		ImageParams(IMAGE_TYPE_2D,			tcu::UVec3(64u, 64u, 1u)),
		ImageParams(IMAGE_TYPE_2D_ARRAY,	tcu::UVec3(64u, 64u, 8u)),
		ImageParams(IMAGE_TYPE_3D,			tcu::UVec3(64u, 64u, 8u)),
		ImageParams(IMAGE_TYPE_CUBE,		tcu::UVec3(64u, 64u, 1u)),
		ImageParams(IMAGE_TYPE_CUBE_ARRAY,	tcu::UVec3(64u, 64u, 2u)),
		ImageParams(IMAGE_TYPE_BUFFER,		tcu::UVec3(64u, 1u,  1u))
	};

	static const tcu::TextureFormat formats[] =
	{
		tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT),
		tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNSIGNED_INT32),
		tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT32),
	};

	for (deUint32 qualifierI = 0; qualifierI < MemoryQualifierTestCase::QUALIFIER_LAST; ++qualifierI)
	{
		const MemoryQualifierTestCase::Qualifier	memoryQualifier		= (MemoryQualifierTestCase::Qualifier)qualifierI;
		const char* const							memoryQualifierName =
			memoryQualifier == MemoryQualifierTestCase::QUALIFIER_COHERENT ? "coherent" :
			memoryQualifier == MemoryQualifierTestCase::QUALIFIER_VOLATILE ? "volatile" :
			memoryQualifier == MemoryQualifierTestCase::QUALIFIER_RESTRICT ? "restrict" :
			DE_NULL;

		de::MovePtr<tcu::TestCaseGroup> qualifierGroup(new tcu::TestCaseGroup(testCtx, memoryQualifierName, ""));

		for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParamsArray); imageTypeNdx++)
		{
			const ImageType		imageType = imageParamsArray[imageTypeNdx].m_imageType;
			const tcu::UVec3	imageSize = imageParamsArray[imageTypeNdx].m_imageSize;

			if (memoryQualifier == MemoryQualifierTestCase::QUALIFIER_RESTRICT)
			{
				de::MovePtr<TestCase> restrictCase = createImageQualifierRestrictCase(testCtx, imageType, getImageTypeName(imageType));
				qualifierGroup->addChild(restrictCase.release());
			}
			else
			{
				de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));

				for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
				{
					const tcu::TextureFormat&	format		= formats[formatNdx];
					const std::string			formatName	= getShaderImageFormatQualifier(formats[formatNdx]);

					imageTypeGroup->addChild(
						new MemoryQualifierTestCase(testCtx, formatName, "", memoryQualifier, imageType, imageSize, format, glu::GLSL_VERSION_440));
				}

				qualifierGroup->addChild(imageTypeGroup.release());
			}
		}

		imageQualifiersTests->addChild(qualifierGroup.release());
	}

	return imageQualifiersTests.release();
}

} // image
} // vkt
