/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 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  vktImageAtomicOperationTests.cpp
 * \brief Image atomic operation tests
 *//*--------------------------------------------------------------------*/

#include "vktImageAtomicOperationTests.hpp"
#include "vktImageAtomicSpirvShaders.hpp"

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"
#include "deSTLUtil.hpp"

#include "vktTestCaseUtil.hpp"
#include "vkPrograms.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vktImageTestsUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

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

namespace vkt
{
namespace image
{
namespace
{

using namespace vk;
using namespace std;
using de::toString;

using tcu::TextureFormat;
using tcu::IVec2;
using tcu::IVec3;
using tcu::UVec3;
using tcu::Vec4;
using tcu::IVec4;
using tcu::UVec4;
using tcu::CubeFace;
using tcu::Texture1D;
using tcu::Texture2D;
using tcu::Texture3D;
using tcu::Texture2DArray;
using tcu::TextureCube;
using tcu::PixelBufferAccess;
using tcu::ConstPixelBufferAccess;
using tcu::Vector;
using tcu::TestContext;

enum
{
	NUM_INVOCATIONS_PER_PIXEL = 5u
};

enum AtomicOperation
{
	ATOMIC_OPERATION_ADD = 0,
	ATOMIC_OPERATION_SUB,
	ATOMIC_OPERATION_INC,
	ATOMIC_OPERATION_DEC,
	ATOMIC_OPERATION_MIN,
	ATOMIC_OPERATION_MAX,
	ATOMIC_OPERATION_AND,
	ATOMIC_OPERATION_OR,
	ATOMIC_OPERATION_XOR,
	ATOMIC_OPERATION_EXCHANGE,
	ATOMIC_OPERATION_COMPARE_EXCHANGE,

	ATOMIC_OPERATION_LAST
};

enum class ShaderReadType
{
	NORMAL = 0,
	SPARSE,
};

enum class ImageBackingType
{
	NORMAL = 0,
	SPARSE,
};

static 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 string("ivec2(" + x + "," + y + ")");
		case IMAGE_TYPE_2D_ARRAY:
		case IMAGE_TYPE_3D:
		case IMAGE_TYPE_CUBE:
		case IMAGE_TYPE_CUBE_ARRAY:
			return string("ivec3(" + x + "," + y + "," + z + ")");
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static string getComponentTypeStr (deUint32 componentWidth, bool intFormat, bool uintFormat, bool floatFormat)
{
	DE_ASSERT(intFormat || uintFormat || floatFormat);

	const bool is64 = (componentWidth == 64);

	if (intFormat)
		return (is64 ? "int64_t" : "int");
	if (uintFormat)
		return (is64 ? "uint64_t" : "uint");
	if (floatFormat)
		return (is64 ? "double" : "float");

	return "";
}

static string getVec4TypeStr (deUint32 componentWidth, bool intFormat, bool uintFormat, bool floatFormat)
{
	DE_ASSERT(intFormat || uintFormat || floatFormat);

	const bool is64 = (componentWidth == 64);

	if (intFormat)
		return (is64 ? "i64vec4" : "ivec4");
	if (uintFormat)
		return (is64 ? "u64vec4" : "uvec4");
	if (floatFormat)
		return (is64 ? "f64vec4" : "vec4");

	return "";
}

static string getAtomicFuncArgumentShaderStr (const AtomicOperation	op,
											  const string&			x,
											  const string&			y,
											  const string&			z,
											  const IVec3&			gridSize)
{
	switch (op)
	{
		case ATOMIC_OPERATION_ADD:
		case ATOMIC_OPERATION_AND:
		case ATOMIC_OPERATION_OR:
		case ATOMIC_OPERATION_XOR:
			return string("(" + x + "*" + x + " + " + y + "*" + y + " + " + z + "*" + z + ")");
		case ATOMIC_OPERATION_MIN:
		case ATOMIC_OPERATION_MAX:
			// multiply by (1-2*(value % 2) to make half of the data negative
			// this will result in generating large numbers for uint formats
			return string("((1 - 2*(" + x + " % 2)) * (" + x + "*" + x + " + " + y + "*" + y + " + " + z + "*" + z + "))");
		case ATOMIC_OPERATION_EXCHANGE:
		case ATOMIC_OPERATION_COMPARE_EXCHANGE:
			return string("((" + z + "*" + toString(gridSize.x()) + " + " + x + ")*" + toString(gridSize.y()) + " + " + y + ")");
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static string getAtomicOperationCaseName (const AtomicOperation op)
{
	switch (op)
	{
		case ATOMIC_OPERATION_ADD:				return string("add");
		case ATOMIC_OPERATION_SUB:				return string("sub");
		case ATOMIC_OPERATION_INC:				return string("inc");
		case ATOMIC_OPERATION_DEC:				return string("dec");
		case ATOMIC_OPERATION_MIN:				return string("min");
		case ATOMIC_OPERATION_MAX:				return string("max");
		case ATOMIC_OPERATION_AND:				return string("and");
		case ATOMIC_OPERATION_OR:				return string("or");
		case ATOMIC_OPERATION_XOR:				return string("xor");
		case ATOMIC_OPERATION_EXCHANGE:			return string("exchange");
		case ATOMIC_OPERATION_COMPARE_EXCHANGE:	return string("compare_exchange");
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static string getAtomicOperationShaderFuncName (const AtomicOperation op)
{
	switch (op)
	{
		case ATOMIC_OPERATION_ADD:				return string("imageAtomicAdd");
		case ATOMIC_OPERATION_MIN:				return string("imageAtomicMin");
		case ATOMIC_OPERATION_MAX:				return string("imageAtomicMax");
		case ATOMIC_OPERATION_AND:				return string("imageAtomicAnd");
		case ATOMIC_OPERATION_OR:				return string("imageAtomicOr");
		case ATOMIC_OPERATION_XOR:				return string("imageAtomicXor");
		case ATOMIC_OPERATION_EXCHANGE:			return string("imageAtomicExchange");
		case ATOMIC_OPERATION_COMPARE_EXCHANGE:	return string("imageAtomicCompSwap");
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

template <typename T>
T getOperationInitialValue (const AtomicOperation op)
{
	switch (op)
	{
		// \note 18 is just an arbitrary small nonzero value.
		case ATOMIC_OPERATION_ADD:				return 18;
		case ATOMIC_OPERATION_INC:				return 18;
		case ATOMIC_OPERATION_SUB:				return (1 << 24) - 1;
		case ATOMIC_OPERATION_DEC:				return (1 << 24) - 1;
		case ATOMIC_OPERATION_MIN:				return (1 << 15) - 1;
		case ATOMIC_OPERATION_MAX:				return 18;
		case ATOMIC_OPERATION_AND:				return (1 << 15) - 1;
		case ATOMIC_OPERATION_OR:				return 18;
		case ATOMIC_OPERATION_XOR:				return 18;
		case ATOMIC_OPERATION_EXCHANGE:			return 18;
		case ATOMIC_OPERATION_COMPARE_EXCHANGE:	return 18;
		default:
			DE_ASSERT(false);
			return 0xFFFFFFFF;
	}
}

template <>
deInt64 getOperationInitialValue<deInt64>(const AtomicOperation op)
{
	switch (op)
	{
		// \note 0x000000BEFFFFFF18 is just an arbitrary nonzero value.
		case ATOMIC_OPERATION_ADD:				return 0x000000BEFFFFFF18;
		case ATOMIC_OPERATION_INC:				return 0x000000BEFFFFFF18;
		case ATOMIC_OPERATION_SUB:				return (1ull << 56) - 1;
		case ATOMIC_OPERATION_DEC:				return (1ull << 56) - 1;
		case ATOMIC_OPERATION_MIN:				return (1ull << 47) - 1;
		case ATOMIC_OPERATION_MAX:				return 0x000000BEFFFFFF18;
		case ATOMIC_OPERATION_AND:				return (1ull << 47) - 1;
		case ATOMIC_OPERATION_OR:				return 0x000000BEFFFFFF18;
		case ATOMIC_OPERATION_XOR:				return 0x000000BEFFFFFF18;
		case ATOMIC_OPERATION_EXCHANGE:			return 0x000000BEFFFFFF18;
		case ATOMIC_OPERATION_COMPARE_EXCHANGE:	return 0x000000BEFFFFFF18;
		default:
			DE_ASSERT(false);
			return 0xFFFFFFFFFFFFFFFF;
	}
}

template <>
deUint64 getOperationInitialValue<deUint64>(const AtomicOperation op)
{
	return (deUint64)getOperationInitialValue<deInt64>(op);
}


template <typename T>
static T getAtomicFuncArgument (const AtomicOperation	op,
								const IVec3&			invocationID,
								const IVec3&			gridSize)
{
	const T x = static_cast<T>(invocationID.x());
	const T y = static_cast<T>(invocationID.y());
	const T z = static_cast<T>(invocationID.z());

	switch (op)
	{
		// \note Fall-throughs.
		case ATOMIC_OPERATION_ADD:
		case ATOMIC_OPERATION_SUB:
		case ATOMIC_OPERATION_AND:
		case ATOMIC_OPERATION_OR:
		case ATOMIC_OPERATION_XOR:
			return x*x + y*y + z*z;
		case ATOMIC_OPERATION_INC:
		case ATOMIC_OPERATION_DEC:
			return 1;
		case ATOMIC_OPERATION_MIN:
		case ATOMIC_OPERATION_MAX:
			// multiply half of the data by -1
			return (1-2*(x % 2))*(x*x + y*y + z*z);
		case ATOMIC_OPERATION_EXCHANGE:
		case ATOMIC_OPERATION_COMPARE_EXCHANGE:
			return (z*static_cast<T>(gridSize.x()) + x)*static_cast<T>(gridSize.y()) + y;
		default:
			DE_ASSERT(false);
			return -1;
	}
}

//! An order-independent operation is one for which the end result doesn't depend on the order in which the operations are carried (i.e. is both commutative and associative).
static bool isOrderIndependentAtomicOperation (const AtomicOperation op)
{
	return	op == ATOMIC_OPERATION_ADD ||
			op == ATOMIC_OPERATION_SUB ||
			op == ATOMIC_OPERATION_INC ||
			op == ATOMIC_OPERATION_DEC ||
			op == ATOMIC_OPERATION_MIN ||
			op == ATOMIC_OPERATION_MAX ||
			op == ATOMIC_OPERATION_AND ||
			op == ATOMIC_OPERATION_OR ||
			op == ATOMIC_OPERATION_XOR;
}

//! Checks if the operation needs an SPIR-V shader.
static bool isSpirvAtomicOperation (const AtomicOperation op)
{
	return	op == ATOMIC_OPERATION_SUB ||
			op == ATOMIC_OPERATION_INC ||
			op == ATOMIC_OPERATION_DEC;
}

//! Returns the SPIR-V assembler name of the given operation.
static std::string getSpirvAtomicOpName (const AtomicOperation op)
{
	switch (op)
	{
	case ATOMIC_OPERATION_SUB:	return "OpAtomicISub";
	case ATOMIC_OPERATION_INC:	return "OpAtomicIIncrement";
	case ATOMIC_OPERATION_DEC:	return "OpAtomicIDecrement";
	default:					break;
	}

	DE_ASSERT(false);
	return "";
}

//! Returns true if the given SPIR-V operation does not need the last argument, compared to OpAtomicIAdd.
static bool isSpirvAtomicNoLastArgOp (const AtomicOperation op)
{
	switch (op)
	{
	case ATOMIC_OPERATION_SUB:	return false;
	case ATOMIC_OPERATION_INC:	// fallthrough
	case ATOMIC_OPERATION_DEC:	return true;
	default:					break;
	}

	DE_ASSERT(false);
	return false;
}

//! Computes the result of an atomic operation where "a" is the data operated on and "b" is the parameter to the atomic function.
template <typename T>
static T computeBinaryAtomicOperationResult (const AtomicOperation op, const T a, const T b)
{
	switch (op)
	{
		case ATOMIC_OPERATION_INC:				// fallthrough.
		case ATOMIC_OPERATION_ADD:				return a + b;
		case ATOMIC_OPERATION_DEC:				// fallthrough.
		case ATOMIC_OPERATION_SUB:				return a - b;
		case ATOMIC_OPERATION_MIN:				return de::min(a, b);
		case ATOMIC_OPERATION_MAX:				return de::max(a, b);
		case ATOMIC_OPERATION_AND:				return a & b;
		case ATOMIC_OPERATION_OR:				return a | b;
		case ATOMIC_OPERATION_XOR:				return a ^ b;
		case ATOMIC_OPERATION_EXCHANGE:			return b;
		case ATOMIC_OPERATION_COMPARE_EXCHANGE:	return (a == (sizeof(T) == 8 ? 0xBEFFFFFF18 : 18)) ? b : a;
		default:
			DE_ASSERT(false);
			return -1;
	}
}

VkImageUsageFlags getUsageFlags (bool useTransfer)
{
	VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT;

	if (useTransfer)
		usageFlags |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);

	return usageFlags;
}

void AddFillReadShader (SourceCollections&			sourceCollections,
						const ImageType&			imageType,
						const tcu::TextureFormat&	format,
						const string&				componentType,
						const string&				vec4Type)
{
	const string	imageInCoord			= getCoordStr(imageType, "gx", "gy", "gz");
	const string	shaderImageFormatStr	= getShaderImageFormatQualifier(format);
	const string	shaderImageTypeStr		= getShaderImageType(format, imageType);
	const auto		componentWidth			= getFormatComponentWidth(mapTextureFormat(format), 0u);
	const string	extensions				= ((componentWidth == 64u)
											?	"#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require\n"
												"#extension GL_EXT_shader_image_int64 : require\n"
											:	"");


	const string fillShader =	"#version 450\n"
								+ extensions +
								"precision highp " + shaderImageTypeStr + ";\n"
								"\n"
								"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
								"layout (" + shaderImageFormatStr + ", binding=0) coherent uniform " + shaderImageTypeStr + " u_resultImage;\n"
								"\n"
								"layout(std430, binding = 1) buffer inputBuffer\n"
								"{\n"
								"	"+ componentType + " data[];\n"
								"} inBuffer;\n"
								"\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"
								"	uint index = gx + (gy * gl_NumWorkGroups.x) + (gz *gl_NumWorkGroups.x * gl_NumWorkGroups.y);\n"
								"	imageStore(u_resultImage, " + imageInCoord + ", " + vec4Type + "(inBuffer.data[index]));\n"
								"}\n";

	const string readShader =	"#version 450\n"
								+ extensions +
								"precision highp " + shaderImageTypeStr + ";\n"
								"\n"
								"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
								"layout (" + shaderImageFormatStr + ", binding=0) coherent uniform " + shaderImageTypeStr + " u_resultImage;\n"
								"\n"
								"layout(std430, binding = 1) buffer outputBuffer\n"
								"{\n"
								"	" + componentType + " data[];\n"
								"} outBuffer;\n"
								"\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"
								"	uint index = gx + (gy * gl_NumWorkGroups.x) + (gz *gl_NumWorkGroups.x * gl_NumWorkGroups.y);\n"
								"	outBuffer.data[index] = imageLoad(u_resultImage, " + imageInCoord + ").x;\n"
								"}\n";


	if ((imageType != IMAGE_TYPE_1D) &&
		(imageType != IMAGE_TYPE_1D_ARRAY) &&
		(imageType != IMAGE_TYPE_BUFFER))
	{
		const string readShaderResidency  = "#version 450\n"
											"#extension GL_ARB_sparse_texture2 : require\n"
											+ extensions +
											"precision highp " + shaderImageTypeStr + ";\n"
											"\n"
											"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
											"layout (" + shaderImageFormatStr + ", binding=0) coherent uniform " + shaderImageTypeStr + " u_resultImage;\n"
											"\n"
											"layout(std430, binding = 1) buffer outputBuffer\n"
											"{\n"
											"	" + componentType + " data[];\n"
											"} outBuffer;\n"
											"\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"
											"	uint index = gx + (gy * gl_NumWorkGroups.x) + (gz *gl_NumWorkGroups.x * gl_NumWorkGroups.y);\n"
											"	outBuffer.data[index] = imageLoad(u_resultImage, " + imageInCoord + ").x;\n"
											"	" + vec4Type + " sparseValue;\n"
											"	sparseImageLoadARB(u_resultImage, " + imageInCoord + ", sparseValue);\n"
											"	if (outBuffer.data[index] != sparseValue.x)\n"
											"		outBuffer.data[index] = " + vec4Type + "(1234).x;\n"
											"}\n";

		sourceCollections.glslSources.add("readShaderResidency") << glu::ComputeSource(readShaderResidency.c_str()) << vk::ShaderBuildOptions(sourceCollections.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
	}

	sourceCollections.glslSources.add("fillShader") << glu::ComputeSource(fillShader.c_str()) << vk::ShaderBuildOptions(sourceCollections.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
	sourceCollections.glslSources.add("readShader") << glu::ComputeSource(readShader.c_str()) << vk::ShaderBuildOptions(sourceCollections.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
}

//! Prepare the initial data for the image
static void initDataForImage (const VkDevice			device,
							  const DeviceInterface&	deviceInterface,
							  const TextureFormat&		format,
							  const AtomicOperation		operation,
							  const tcu::UVec3&			gridSize,
							  Buffer&					buffer)
{
	Allocation&				bufferAllocation	= buffer.getAllocation();
	const VkFormat			imageFormat			= mapTextureFormat(format);
	tcu::PixelBufferAccess	pixelBuffer			(format, gridSize.x(), gridSize.y(), gridSize.z(), bufferAllocation.getHostPtr());

	if (imageFormat == VK_FORMAT_R64_UINT || imageFormat == VK_FORMAT_R64_SINT)
	{
		const deInt64 initialValue(getOperationInitialValue<deInt64>(operation));

		for (deUint32 z = 0; z < gridSize.z(); z++)
		for (deUint32 y = 0; y < gridSize.y(); y++)
		for (deUint32 x = 0; x < gridSize.x(); x++)
		{
			*((deInt64*)pixelBuffer.getPixelPtr(x, y, z)) = initialValue;
		}
	}
	else
	{
		const tcu::IVec4 initialValue(getOperationInitialValue<deInt32>(operation));

		for (deUint32 z = 0; z < gridSize.z(); z++)
		for (deUint32 y = 0; y < gridSize.y(); y++)
		for (deUint32 x = 0; x < gridSize.x(); x++)
		{
			pixelBuffer.setPixel(initialValue, x, y, z);
		}
	}

	flushAlloc(deviceInterface, device, bufferAllocation);
}

void commonCheckSupport (Context& context, const tcu::TextureFormat& tcuFormat, ImageType imageType, AtomicOperation operation, bool useTransfer, ShaderReadType readType, ImageBackingType backingType)
{
	const VkFormat				format				= mapTextureFormat(tcuFormat);
	const VkImageType			vkImgType			= mapImageType(imageType);
	const VkFormatFeatureFlags	texelBufferSupport	= (VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT);
	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(),
																						context.getPhysicalDevice(), format);

	if ((imageType == IMAGE_TYPE_BUFFER) &&
		((formatProperties.bufferFeatures & texelBufferSupport) != texelBufferSupport))
		TCU_THROW(NotSupportedError, "Atomic storage texel buffers not supported");

	if (imageType == IMAGE_TYPE_CUBE_ARRAY)
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);

	if (backingType == ImageBackingType::SPARSE)
	{
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);

		switch (vkImgType)
		{
		case VK_IMAGE_TYPE_2D:	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE2D); break;
		case VK_IMAGE_TYPE_3D:	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_IMAGE3D); break;
		default:				DE_ASSERT(false); break;
		}

		if (!checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), format, vkImgType, VK_SAMPLE_COUNT_1_BIT, getUsageFlags(useTransfer), VK_IMAGE_TILING_OPTIMAL))
			TCU_THROW(NotSupportedError, "Format does not support sparse images");
	}

	if (isFloatFormat(format))
	{
		context.requireDeviceFunctionality("VK_EXT_shader_atomic_float");

		const VkFormatFeatureFlags	requiredFeatures	= (VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT);
		const auto&					atomicFloatFeatures	= context.getShaderAtomicFloatFeaturesEXT();

		if (!atomicFloatFeatures.shaderImageFloat32Atomics)
			TCU_THROW(NotSupportedError, "shaderImageFloat32Atomics not supported");

		if ((operation == ATOMIC_OPERATION_ADD) && !atomicFloatFeatures.shaderImageFloat32AtomicAdd)
			TCU_THROW(NotSupportedError, "shaderImageFloat32AtomicAdd not supported");

		if (operation == ATOMIC_OPERATION_MIN || operation == ATOMIC_OPERATION_MAX)
		{
			context.requireDeviceFunctionality("VK_EXT_shader_atomic_float2");
			if (!context.getShaderAtomicFloat2FeaturesEXT().shaderImageFloat32AtomicMinMax)
			{
				TCU_THROW(NotSupportedError, "shaderImageFloat32AtomicMinMax not supported");
			}
		}

		if ((formatProperties.optimalTilingFeatures & requiredFeatures) != requiredFeatures)
			TCU_FAIL("Required format feature bits not supported");

		if (backingType == ImageBackingType::SPARSE)
		{
			if (!atomicFloatFeatures.sparseImageFloat32Atomics)
				TCU_THROW(NotSupportedError, "sparseImageFloat32Atomics not supported");

			if (operation == ATOMIC_OPERATION_ADD && !atomicFloatFeatures.sparseImageFloat32AtomicAdd)
				TCU_THROW(NotSupportedError, "sparseImageFloat32AtomicAdd not supported");
		}

	}
	else if (format == VK_FORMAT_R64_UINT || format == VK_FORMAT_R64_SINT)
	{
		context.requireDeviceFunctionality("VK_EXT_shader_image_atomic_int64");

		const VkFormatFeatureFlags	requiredFeatures	= (VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT);
		const auto&					atomicInt64Features	= context.getShaderImageAtomicInt64FeaturesEXT();

		if (!atomicInt64Features.shaderImageInt64Atomics)
			TCU_THROW(NotSupportedError, "shaderImageInt64Atomics not supported");

		if (backingType == ImageBackingType::SPARSE && !atomicInt64Features.sparseImageInt64Atomics)
			TCU_THROW(NotSupportedError, "sparseImageInt64Atomics not supported");

		if ((formatProperties.optimalTilingFeatures & requiredFeatures) != requiredFeatures)
			TCU_FAIL("Mandatory format features not supported");
	}

	if (useTransfer)
	{
		const VkFormatFeatureFlags transferFeatures = (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
		if ((formatProperties.optimalTilingFeatures & transferFeatures) != transferFeatures)
			TCU_THROW(NotSupportedError, "Transfer features not supported for this format");
	}

	if (readType == ShaderReadType::SPARSE)
	{
		DE_ASSERT(imageType != IMAGE_TYPE_1D && imageType != IMAGE_TYPE_1D_ARRAY && imageType != IMAGE_TYPE_BUFFER);
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY);
	}
}

class BinaryAtomicEndResultCase : public vkt::TestCase
{
public:
								BinaryAtomicEndResultCase	(tcu::TestContext&			testCtx,
															 const string&				name,
															 const string&				description,
															 const ImageType			imageType,
															 const tcu::UVec3&			imageSize,
															 const tcu::TextureFormat&	format,
															 const AtomicOperation		operation,
															 const bool					useTransfer,
															 const ShaderReadType		shaderReadType,
															 const ImageBackingType		backingType,
															 const glu::GLSLVersion		glslVersion);

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

private:
	const ImageType				m_imageType;
	const tcu::UVec3			m_imageSize;
	const tcu::TextureFormat	m_format;
	const AtomicOperation		m_operation;
	const bool					m_useTransfer;
	const ShaderReadType		m_readType;
	const ImageBackingType		m_backingType;
	const glu::GLSLVersion		m_glslVersion;
};

BinaryAtomicEndResultCase::BinaryAtomicEndResultCase (tcu::TestContext&			testCtx,
													  const string&				name,
													  const string&				description,
													  const ImageType			imageType,
													  const tcu::UVec3&			imageSize,
													  const tcu::TextureFormat&	format,
													  const AtomicOperation		operation,
													  const bool				useTransfer,
													  const ShaderReadType		shaderReadType,
													  const ImageBackingType	backingType,
													  const glu::GLSLVersion	glslVersion)
	: TestCase		(testCtx, name, description)
	, m_imageType	(imageType)
	, m_imageSize	(imageSize)
	, m_format		(format)
	, m_operation	(operation)
	, m_useTransfer	(useTransfer)
	, m_readType	(shaderReadType)
	, m_backingType	(backingType)
	, m_glslVersion	(glslVersion)
{
}

void BinaryAtomicEndResultCase::checkSupport (Context& context) const
{
	commonCheckSupport(context, m_format, m_imageType, m_operation, m_useTransfer, m_readType, m_backingType);
}

void BinaryAtomicEndResultCase::initPrograms (SourceCollections& sourceCollections) const
{
	const VkFormat	imageFormat		= mapTextureFormat(m_format);
	const deUint32	componentWidth	= getFormatComponentWidth(imageFormat, 0);
	const bool		intFormat		= isIntFormat(imageFormat);
	const bool		uintFormat		= isUintFormat(imageFormat);
	const bool		floatFormat		= isFloatFormat(imageFormat);
	const string	type			= getComponentTypeStr(componentWidth, intFormat, uintFormat, floatFormat);
	const string	vec4Type		= getVec4TypeStr(componentWidth, intFormat, uintFormat, floatFormat);

	AddFillReadShader(sourceCollections, m_imageType, m_format, type, vec4Type);

	if (isSpirvAtomicOperation(m_operation))
	{
		const CaseVariant					caseVariant{m_imageType, m_format.order, m_format.type, CaseVariant::CHECK_TYPE_END_RESULTS};
		const tcu::StringTemplate			shaderTemplate{getSpirvAtomicOpShader(caseVariant)};
		std::map<std::string, std::string>	specializations;

		specializations["OPNAME"] = getSpirvAtomicOpName(m_operation);
		if (isSpirvAtomicNoLastArgOp(m_operation))
			specializations["LASTARG"] = "";

		sourceCollections.spirvAsmSources.add(m_name) << shaderTemplate.specialize(specializations);
	}
	else
	{
		const string	versionDecl				= glu::getGLSLVersionDeclaration(m_glslVersion);

		const UVec3		gridSize				= getShaderGridSize(m_imageType, m_imageSize);
		const string	atomicCoord				= getCoordStr(m_imageType, "gx % " + toString(gridSize.x()), "gy", "gz");

		const string	atomicArgExpr			= type + getAtomicFuncArgumentShaderStr(m_operation,
																						"gx", "gy", "gz",
																						IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z()));

		const string	compareExchangeStr		= (m_operation == ATOMIC_OPERATION_COMPARE_EXCHANGE) ?
												(componentWidth == 64 ?", 820338753304": ", 18") + string(uintFormat ? "u" : "") + string(componentWidth == 64 ? "l" : "")
												: "";
		const string	atomicInvocation		= getAtomicOperationShaderFuncName(m_operation) + "(u_resultImage, " + atomicCoord + compareExchangeStr + ", " + atomicArgExpr + ")";
		const string	shaderImageFormatStr	= getShaderImageFormatQualifier(m_format);
		const string	shaderImageTypeStr		= getShaderImageType(m_format, m_imageType);
		const string	extensions				= "#extension GL_EXT_shader_atomic_float : enable\n"
												  "#extension GL_EXT_shader_atomic_float2 : enable\n"
												  "#extension GL_KHR_memory_scope_semantics : enable";

		string source = versionDecl + "\n" + extensions + "\n";

		if (64 == componentWidth)
		{
			source +=	"#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require\n"
						"#extension GL_EXT_shader_image_int64 : require\n";
		}

		source +=	"precision highp " + shaderImageTypeStr + ";\n"
					"\n"
					"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
					"layout (" + shaderImageFormatStr + ", binding=0) coherent uniform " + shaderImageTypeStr + " u_resultImage;\n"
					"\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"
					"	" + atomicInvocation + ";\n"
					"}\n";

		sourceCollections.glslSources.add(m_name) << glu::ComputeSource(source.c_str());
	}
}

class BinaryAtomicIntermValuesCase : public vkt::TestCase
{
public:
								BinaryAtomicIntermValuesCase	(tcu::TestContext&			testCtx,
																 const string&				name,
																 const string&				description,
																 const ImageType			imageType,
																 const tcu::UVec3&			imageSize,
																 const tcu::TextureFormat&	format,
																 const AtomicOperation		operation,
																 const bool					useTransfer,
																 const ShaderReadType		shaderReadType,
																 const ImageBackingType		backingType,
																 const glu::GLSLVersion		glslVersion);

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

private:
	const ImageType				m_imageType;
	const tcu::UVec3			m_imageSize;
	const tcu::TextureFormat	m_format;
	const AtomicOperation		m_operation;
	const bool					m_useTransfer;
	const ShaderReadType		m_readType;
	const ImageBackingType		m_backingType;
	const glu::GLSLVersion		m_glslVersion;
};

BinaryAtomicIntermValuesCase::BinaryAtomicIntermValuesCase (TestContext&			testCtx,
															const string&			name,
															const string&			description,
															const ImageType			imageType,
															const tcu::UVec3&		imageSize,
															const TextureFormat&	format,
															const AtomicOperation	operation,
															const bool				useTransfer,
															const ShaderReadType	shaderReadType,
															const ImageBackingType	backingType,
															const glu::GLSLVersion	glslVersion)
	: TestCase		(testCtx, name, description)
	, m_imageType	(imageType)
	, m_imageSize	(imageSize)
	, m_format		(format)
	, m_operation	(operation)
	, m_useTransfer	(useTransfer)
	, m_readType	(shaderReadType)
	, m_backingType	(backingType)
	, m_glslVersion	(glslVersion)
{
}

void BinaryAtomicIntermValuesCase::checkSupport (Context& context) const
{
	commonCheckSupport(context, m_format, m_imageType, m_operation, m_useTransfer, m_readType, m_backingType);
}

void BinaryAtomicIntermValuesCase::initPrograms (SourceCollections& sourceCollections) const
{
	const VkFormat	imageFormat		= mapTextureFormat(m_format);
	const deUint32	componentWidth	= getFormatComponentWidth(imageFormat, 0);
	const bool		intFormat		= isIntFormat(imageFormat);
	const bool		uintFormat		= isUintFormat(imageFormat);
	const bool		floatFormat		= isFloatFormat(imageFormat);
	const string	type			= getComponentTypeStr(componentWidth, intFormat, uintFormat, floatFormat);
	const string	vec4Type		= getVec4TypeStr(componentWidth, intFormat, uintFormat, floatFormat);

	AddFillReadShader(sourceCollections, m_imageType, m_format, type, vec4Type);

	if (isSpirvAtomicOperation(m_operation))
	{
		const CaseVariant					caseVariant{m_imageType, m_format.order, m_format.type, CaseVariant::CHECK_TYPE_INTERMEDIATE_RESULTS};
		const tcu::StringTemplate			shaderTemplate{getSpirvAtomicOpShader(caseVariant)};
		std::map<std::string, std::string>	specializations;

		specializations["OPNAME"] = getSpirvAtomicOpName(m_operation);
		if (isSpirvAtomicNoLastArgOp(m_operation))
			specializations["LASTARG"] = "";

		sourceCollections.spirvAsmSources.add(m_name) << shaderTemplate.specialize(specializations);
	}
	else
	{
		const string	versionDecl				= glu::getGLSLVersionDeclaration(m_glslVersion);
		const UVec3		gridSize				= getShaderGridSize(m_imageType, m_imageSize);
		const string	atomicCoord				= getCoordStr(m_imageType, "gx % " + toString(gridSize.x()), "gy", "gz");
		const string	invocationCoord			= getCoordStr(m_imageType, "gx", "gy", "gz");
		const string	atomicArgExpr			= type + getAtomicFuncArgumentShaderStr(m_operation,
																						"gx", "gy", "gz",
																						IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z()));

		const string	compareExchangeStr		= (m_operation == ATOMIC_OPERATION_COMPARE_EXCHANGE) ?
												  (componentWidth == 64 ? ", 820338753304" : ", 18") + string(uintFormat ? "u" : "") + string(componentWidth == 64 ? "l" : "") :
												  "";
		const string	atomicInvocation		= getAtomicOperationShaderFuncName(m_operation) +
												"(u_resultImage, " + atomicCoord + compareExchangeStr + ", " + atomicArgExpr + ")";
		const string	shaderImageFormatStr	= getShaderImageFormatQualifier(m_format);
		const string	shaderImageTypeStr		= getShaderImageType(m_format, m_imageType);
		const string	extensions				= "#extension GL_EXT_shader_atomic_float : enable\n"
												  "#extension GL_EXT_shader_atomic_float2 : enable\n"
												  "#extension GL_KHR_memory_scope_semantics : enable";

		string source = versionDecl + "\n" + extensions + "\n"
						"\n";

		if (64 == componentWidth)
		{
			source +=	"#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require\n"
						"#extension GL_EXT_shader_image_int64 : require\n";
		}

			source +=	"precision highp " + shaderImageTypeStr + "; \n"
						"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
						"layout (" + shaderImageFormatStr + ", binding=0) coherent uniform " + shaderImageTypeStr + " u_resultImage;\n"
						"layout (" + shaderImageFormatStr + ", binding=1) writeonly uniform " + shaderImageTypeStr + " u_intermValuesImage;\n"
						"\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_intermValuesImage, " + invocationCoord + ", " + vec4Type + "(" + atomicInvocation + "));\n"
						"}\n";

		sourceCollections.glslSources.add(m_name) << glu::ComputeSource(source.c_str());
	}
}

class BinaryAtomicInstanceBase : public vkt::TestInstance
{
public:

								BinaryAtomicInstanceBase (Context&						context,
														  const string&					name,
														  const ImageType				imageType,
														  const tcu::UVec3&				imageSize,
														  const TextureFormat&			format,
														  const AtomicOperation			operation,
														  const bool					useTransfer,
														  const ShaderReadType			shaderReadType,
														  const ImageBackingType		backingType);

	tcu::TestStatus				iterate					 (void);

	virtual deUint32			getOutputBufferSize		 (void) const = 0;

	virtual void				prepareResources		 (const bool					useTransfer) = 0;
	virtual void				prepareDescriptors		 (const bool					isTexelBuffer) = 0;

	virtual void				commandsBeforeCompute	 (const VkCommandBuffer			cmdBuffer) const = 0;
	virtual void				commandsAfterCompute	 (const VkCommandBuffer			cmdBuffer,
														  const VkPipeline				pipeline,
														  const VkPipelineLayout		pipelineLayout,
														   const VkDescriptorSet		descriptorSet,
														  const VkDeviceSize&			range,
														  const bool					useTransfer) = 0;

	virtual bool				verifyResult			 (Allocation&					outputBufferAllocation,
														  const bool					is64Bit) const = 0;

protected:

	void						shaderFillImage			 (const VkCommandBuffer			cmdBuffer,
														  const VkBuffer&				buffer,
														  const VkPipeline				pipeline,
														  const VkPipelineLayout		pipelineLayout,
														  const VkDescriptorSet			descriptorSet,
														  const VkDeviceSize&			range,
														  const tcu::UVec3&				gridSize);

	void						createImageAndView		(VkFormat						imageFormat,
														 const tcu::UVec3&				imageExent,
														 bool							useTransfer,
														 de::MovePtr<Image>&			imagePtr,
														 Move<VkImageView>&				imageViewPtr);

	void						createImageResources	(const VkFormat&				imageFormat,
														 const bool						useTransfer);

	const string				m_name;
	const ImageType				m_imageType;
	const tcu::UVec3			m_imageSize;
	const TextureFormat			m_format;
	const AtomicOperation		m_operation;
	const bool					m_useTransfer;
	const ShaderReadType		m_readType;
	const ImageBackingType		m_backingType;

	de::MovePtr<Buffer>			m_inputBuffer;
	de::MovePtr<Buffer>			m_outputBuffer;
	Move<VkBufferView>			m_descResultBufferView;
	Move<VkBufferView>			m_descIntermResultsBufferView;
	Move<VkDescriptorPool>		m_descriptorPool;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkDescriptorSet>		m_descriptorSet;

	Move<VkDescriptorSetLayout>	m_descriptorSetLayoutNoTransfer;
	Move<VkDescriptorPool>		m_descriptorPoolNoTransfer;

	de::MovePtr<Image>			m_resultImage;
	Move<VkImageView>			m_resultImageView;

	std::vector<VkSemaphore>	m_waitSemaphores;
};

BinaryAtomicInstanceBase::BinaryAtomicInstanceBase (Context&				context,
													const string&			name,
													const ImageType			imageType,
													const tcu::UVec3&		imageSize,
													const TextureFormat&	format,
													const AtomicOperation	operation,
													const bool				useTransfer,
													const ShaderReadType	shaderReadType,
													const ImageBackingType	backingType)
	: vkt::TestInstance	(context)
	, m_name			(name)
	, m_imageType		(imageType)
	, m_imageSize		(imageSize)
	, m_format			(format)
	, m_operation		(operation)
	, m_useTransfer		(useTransfer)
	, m_readType		(shaderReadType)
	, m_backingType		(backingType)
{
}

tcu::TestStatus	BinaryAtomicInstanceBase::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();
	Allocator&				allocator			= m_context.getDefaultAllocator();
	const VkDeviceSize		imageSizeInBytes	= tcu::getPixelSize(m_format) * getNumPixels(m_imageType, m_imageSize);
	const VkDeviceSize		outBuffSizeInBytes	= getOutputBufferSize();
	const VkFormat			imageFormat			= mapTextureFormat(m_format);
	const bool				isTexelBuffer		= (m_imageType == IMAGE_TYPE_BUFFER);

	if (!isTexelBuffer)
	{
		createImageResources(imageFormat, m_useTransfer);
	}

	tcu::UVec3				gridSize			= getShaderGridSize(m_imageType, m_imageSize);

	//Prepare the buffer with the initial data for the image
	m_inputBuffer = de::MovePtr<Buffer>(new Buffer(deviceInterface,
													device,
													allocator,
													makeBufferCreateInfo(imageSizeInBytes,
																		 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
																		 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
																		 (isTexelBuffer ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT : static_cast<VkBufferUsageFlagBits>(0u))),
													MemoryRequirement::HostVisible));

	// Fill in buffer with initial data used for image.
	initDataForImage(device, deviceInterface, m_format, m_operation, gridSize, *m_inputBuffer);

	// Create a buffer to store shader output copied from result image
	m_outputBuffer = de::MovePtr<Buffer>(new Buffer(deviceInterface,
													device,
													allocator,
													makeBufferCreateInfo(outBuffSizeInBytes,
																		 VK_BUFFER_USAGE_TRANSFER_DST_BIT |
																		 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
																		 (isTexelBuffer ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT : static_cast<VkBufferUsageFlagBits>(0u))),
													MemoryRequirement::HostVisible));

	if (!isTexelBuffer)
	{
		prepareResources(m_useTransfer);
	}

	prepareDescriptors(isTexelBuffer);

	Move<VkDescriptorSet>	descriptorSetFillImage;
	Move<VkShaderModule>	shaderModuleFillImage;
	Move<VkPipelineLayout>	pipelineLayoutFillImage;
	Move<VkPipeline>		pipelineFillImage;

	Move<VkDescriptorSet>	descriptorSetReadImage;
	Move<VkShaderModule>	shaderModuleReadImage;
	Move<VkPipelineLayout>	pipelineLayoutReadImage;
	Move<VkPipeline>		pipelineReadImage;

	if (!m_useTransfer)
	{
		m_descriptorSetLayoutNoTransfer =
			DescriptorSetLayoutBuilder()
			.addSingleBinding((isTexelBuffer ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE), VK_SHADER_STAGE_COMPUTE_BIT)
			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
			.build(deviceInterface, device);

		m_descriptorPoolNoTransfer =
			DescriptorPoolBuilder()
			.addType((isTexelBuffer ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE), 2)
			.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2)
			.build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);

		descriptorSetFillImage = makeDescriptorSet(deviceInterface,
			device,
			*m_descriptorPoolNoTransfer,
			*m_descriptorSetLayoutNoTransfer);

		descriptorSetReadImage = makeDescriptorSet(deviceInterface,
			device,
			*m_descriptorPoolNoTransfer,
			*m_descriptorSetLayoutNoTransfer);

		shaderModuleFillImage	= createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fillShader"), 0);
		pipelineLayoutFillImage	= makePipelineLayout(deviceInterface, device, *m_descriptorSetLayoutNoTransfer);
		pipelineFillImage		= makeComputePipeline(deviceInterface, device, *pipelineLayoutFillImage, *shaderModuleFillImage);

		if (m_readType == ShaderReadType::SPARSE)
		{
			shaderModuleReadImage = createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("readShaderResidency"), 0);
		}
		else
		{
			shaderModuleReadImage = createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("readShader"), 0);
		}
		pipelineLayoutReadImage = makePipelineLayout(deviceInterface, device, *m_descriptorSetLayoutNoTransfer);
		pipelineReadImage		= makeComputePipeline(deviceInterface, device, *pipelineLayoutFillImage, *shaderModuleReadImage);
	}

	// Create pipeline
	const Unique<VkShaderModule>	shaderModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get(m_name), 0));
	const Unique<VkPipelineLayout>	pipelineLayout(makePipelineLayout(deviceInterface, device, *m_descriptorSetLayout));
	const 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));

	beginCommandBuffer(deviceInterface, *cmdBuffer);

	if (!isTexelBuffer)
	{
		if (m_useTransfer)
		{
			const vector<VkBufferImageCopy>	bufferImageCopy(1, makeBufferImageCopy(makeExtent3D(getLayerSize(m_imageType, m_imageSize)), getNumLayers(m_imageType, m_imageSize)));
			copyBufferToImage(deviceInterface,
							  *cmdBuffer,
							  *(*m_inputBuffer),
							  imageSizeInBytes,
							  bufferImageCopy,
							  VK_IMAGE_ASPECT_COLOR_BIT,
							  1,
							  getNumLayers(m_imageType, m_imageSize), m_resultImage->get(), VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
		}
		else
		{
			shaderFillImage(*cmdBuffer, *(*m_inputBuffer), *pipelineFillImage, *pipelineLayoutFillImage, *descriptorSetFillImage, imageSizeInBytes, gridSize);
		}
		commandsBeforeCompute(*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);

	deviceInterface.cmdDispatch(*cmdBuffer, NUM_INVOCATIONS_PER_PIXEL * gridSize.x(), gridSize.y(), gridSize.z());

	commandsAfterCompute(*cmdBuffer,
						 *pipelineReadImage,
						 *pipelineLayoutReadImage,
						 *descriptorSetReadImage,
						 outBuffSizeInBytes,
						 m_useTransfer);

	const VkBufferMemoryBarrier	outputBufferPreHostReadBarrier
		= makeBufferMemoryBarrier(((m_useTransfer || isTexelBuffer) ? VK_ACCESS_TRANSFER_WRITE_BIT : VK_ACCESS_SHADER_WRITE_BIT),
								  VK_ACCESS_HOST_READ_BIT,
								  m_outputBuffer->get(),
								  0ull,
								  outBuffSizeInBytes);

	deviceInterface.cmdPipelineBarrier(*cmdBuffer,
									   ((m_useTransfer || isTexelBuffer) ? VK_PIPELINE_STAGE_TRANSFER_BIT : VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
									   VK_PIPELINE_STAGE_HOST_BIT,
									   DE_FALSE, 0u, DE_NULL,
									   1u, &outputBufferPreHostReadBarrier, 0u, DE_NULL);

	endCommandBuffer(deviceInterface, *cmdBuffer);

	std::vector<VkPipelineStageFlags> waitStages(m_waitSemaphores.size(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
	submitCommandsAndWait(deviceInterface, device, queue, *cmdBuffer, false, 1u,
		static_cast<deUint32>(m_waitSemaphores.size()), de::dataOrNull(m_waitSemaphores), de::dataOrNull(waitStages));

	Allocation& outputBufferAllocation = m_outputBuffer->getAllocation();

	invalidateAlloc(deviceInterface, device, outputBufferAllocation);

	if (verifyResult(outputBufferAllocation, (imageFormat == VK_FORMAT_R64_UINT || imageFormat == VK_FORMAT_R64_SINT)))
		return tcu::TestStatus::pass("Comparison succeeded");
	else
		return tcu::TestStatus::fail("Comparison failed");
}

void BinaryAtomicInstanceBase::shaderFillImage (const VkCommandBuffer	cmdBuffer,
												const VkBuffer&			buffer,
												const VkPipeline		pipeline,
												const VkPipelineLayout	pipelineLayout,
												const VkDescriptorSet	descriptorSet,
												const VkDeviceSize&		range,
												const tcu::UVec3&		gridSize)
{
	const VkDevice					device					= m_context.getDevice();
	const DeviceInterface&			deviceInterface			= m_context.getDeviceInterface();
	const VkDescriptorImageInfo		descResultImageInfo		= makeDescriptorImageInfo(DE_NULL, *m_resultImageView, VK_IMAGE_LAYOUT_GENERAL);
	const VkDescriptorBufferInfo	descResultBufferInfo	= makeDescriptorBufferInfo(buffer, 0, range);
	const VkImageSubresourceRange	subresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));

	DescriptorSetUpdateBuilder()
		.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descResultImageInfo)
		.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descResultBufferInfo)
		.update(deviceInterface, device);

	const VkImageMemoryBarrier imageBarrierPre = makeImageMemoryBarrier(0,
																		VK_ACCESS_SHADER_WRITE_BIT,
																		VK_IMAGE_LAYOUT_UNDEFINED,
																		VK_IMAGE_LAYOUT_GENERAL,
																		m_resultImage->get(),
																		subresourceRange);

	deviceInterface.cmdPipelineBarrier(	cmdBuffer,
										VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
										VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
										(VkDependencyFlags)0,
										0, (const VkMemoryBarrier*)DE_NULL,
										0, (const VkBufferMemoryBarrier*)DE_NULL,
										1, &imageBarrierPre);

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

	deviceInterface.cmdDispatch(cmdBuffer, gridSize.x(), gridSize.y(), gridSize.z());

	const VkImageMemoryBarrier imageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT,
																		 VK_ACCESS_SHADER_READ_BIT,
																		 VK_IMAGE_LAYOUT_GENERAL,
																		 VK_IMAGE_LAYOUT_GENERAL,
																		 m_resultImage->get(),
																		 subresourceRange);

	deviceInterface.cmdPipelineBarrier(	cmdBuffer,
										VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
										VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
										(VkDependencyFlags)0,
										0, (const VkMemoryBarrier*)DE_NULL,
										0, (const VkBufferMemoryBarrier*)DE_NULL,
										1, &imageBarrierPost);
}

void BinaryAtomicInstanceBase::createImageAndView	(VkFormat						imageFormat,
													 const tcu::UVec3&				imageExent,
													 bool							useTransfer,
													 de::MovePtr<Image>&			imagePtr,
													 Move<VkImageView>&				imageViewPtr)
{
	const VkDevice			device			= m_context.getDevice();
	const DeviceInterface&	deviceInterface	= m_context.getDeviceInterface();
	Allocator&				allocator		= m_context.getDefaultAllocator();
	const VkImageUsageFlags	usageFlags		= getUsageFlags(useTransfer);
	VkImageCreateFlags		createFlags		= 0u;

	if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
		createFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;

	const auto numLayers = getNumLayers(m_imageType, m_imageSize);

	VkImageCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
		DE_NULL,												// const void*				pNext;
		createFlags,											// VkImageCreateFlags		flags;
		mapImageType(m_imageType),								// VkImageType				imageType;
		imageFormat,											// VkFormat					format;
		makeExtent3D(imageExent),								// VkExtent3D				extent;
		1u,														// deUint32					mipLevels;
		numLayers,												// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
		usageFlags,												// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
		0u,														// deUint32					queueFamilyIndexCount;
		DE_NULL,												// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
	};

	if (m_backingType == ImageBackingType::SPARSE)
	{
		const auto&		vki				= m_context.getInstanceInterface();
		const auto		physicalDevice	= m_context.getPhysicalDevice();
		const auto		sparseQueue		= m_context.getSparseQueue();
		const auto		sparseQueueIdx	= m_context.getSparseQueueFamilyIndex();
		const auto		universalQIdx	= m_context.getUniversalQueueFamilyIndex();
		const deUint32	queueIndices[]	= { universalQIdx, sparseQueueIdx };

		createInfo.flags |= (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);

		if (sparseQueueIdx != universalQIdx)
		{
			createInfo.sharingMode				= VK_SHARING_MODE_CONCURRENT;
			createInfo.queueFamilyIndexCount	= static_cast<deUint32>(DE_LENGTH_OF_ARRAY(queueIndices));
			createInfo.pQueueFamilyIndices		= queueIndices;
		}

		const auto sparseImage = new SparseImage(deviceInterface, device, physicalDevice, vki, createInfo, sparseQueue, allocator, m_format);
		m_waitSemaphores.push_back(sparseImage->getSemaphore());
		imagePtr = de::MovePtr<Image>(sparseImage);
	}
	else
		imagePtr = de::MovePtr<Image>(new Image(deviceInterface, device, allocator, createInfo, MemoryRequirement::Any));

	const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers);

	imageViewPtr = makeImageView(deviceInterface, device, imagePtr->get(), mapImageViewType(m_imageType), imageFormat, subresourceRange);
}

void BinaryAtomicInstanceBase::createImageResources (const VkFormat&	imageFormat,
													 const bool			useTransfer)
{
	//Create the image that is going to store results of atomic operations
	createImageAndView(imageFormat, getLayerSize(m_imageType, m_imageSize), useTransfer, m_resultImage, m_resultImageView);
}

class BinaryAtomicEndResultInstance : public BinaryAtomicInstanceBase
{
public:

						BinaryAtomicEndResultInstance  (Context&					context,
														const string&				name,
														const ImageType				imageType,
														const tcu::UVec3&			imageSize,
														const TextureFormat&		format,
														const AtomicOperation		operation,
														const bool					useTransfer,
														const ShaderReadType		shaderReadType,
														const ImageBackingType		backingType)
							: BinaryAtomicInstanceBase(context, name, imageType, imageSize, format, operation, useTransfer, shaderReadType, backingType) {}

	virtual deUint32	getOutputBufferSize			   (void) const;

	virtual void		prepareResources			   (const bool					useTransfer) { DE_UNREF(useTransfer); }
	virtual void		prepareDescriptors			   (const bool					isTexelBuffer);

	virtual void		commandsBeforeCompute		   (const VkCommandBuffer) const {}
	virtual void		commandsAfterCompute		   (const VkCommandBuffer		cmdBuffer,
														const VkPipeline			pipeline,
														const VkPipelineLayout		pipelineLayout,
														const VkDescriptorSet		descriptorSet,
														const VkDeviceSize&			range,
														const bool					useTransfer);

	virtual bool		verifyResult				   (Allocation&					outputBufferAllocation,
														const bool					is64Bit) const;

protected:

	template <typename T>
	bool				isValueCorrect				   (const T						resultValue,
														deInt32						x,
														deInt32						y,
														deInt32						z,
														const UVec3&				gridSize,
														const IVec3					extendedGridSize) const;
};

deUint32 BinaryAtomicEndResultInstance::getOutputBufferSize (void) const
{
	return tcu::getPixelSize(m_format) * getNumPixels(m_imageType, m_imageSize);
}

void BinaryAtomicEndResultInstance::prepareDescriptors (const bool	isTexelBuffer)
{
	const VkDescriptorType	descriptorType	= isTexelBuffer ?
											VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER :
											VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
	const VkDevice			device			= m_context.getDevice();
	const DeviceInterface&	deviceInterface = m_context.getDeviceInterface();

	m_descriptorSetLayout =
		DescriptorSetLayoutBuilder()
		.addSingleBinding(descriptorType, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(deviceInterface, device);

	m_descriptorPool =
		DescriptorPoolBuilder()
		.addType(descriptorType)
		.build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	m_descriptorSet = makeDescriptorSet(deviceInterface, device, *m_descriptorPool, *m_descriptorSetLayout);

	if (isTexelBuffer)
	{
		m_descResultBufferView = makeBufferView(deviceInterface, device, *(*m_inputBuffer), mapTextureFormat(m_format), 0, VK_WHOLE_SIZE);

		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &(m_descResultBufferView.get()))
			.update(deviceInterface, device);
	}
	else
	{
		const VkDescriptorImageInfo	descResultImageInfo = makeDescriptorImageInfo(DE_NULL, *m_resultImageView, VK_IMAGE_LAYOUT_GENERAL);

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

void BinaryAtomicEndResultInstance::commandsAfterCompute (const VkCommandBuffer		cmdBuffer,
														  const VkPipeline			pipeline,
														  const VkPipelineLayout	pipelineLayout,
														  const VkDescriptorSet		descriptorSet,
														  const VkDeviceSize&		range,
														  const bool				useTransfer)
{
	const DeviceInterface&			deviceInterface		= m_context.getDeviceInterface();
	const VkImageSubresourceRange	subresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));
	const UVec3						layerSize			= getLayerSize(m_imageType, m_imageSize);

	if (m_imageType == IMAGE_TYPE_BUFFER)
	{
		m_outputBuffer = m_inputBuffer;
	}
	else if (useTransfer)
	{
		const VkImageMemoryBarrier	resultImagePostDispatchBarrier =
			makeImageMemoryBarrier(	VK_ACCESS_SHADER_WRITE_BIT,
									VK_ACCESS_TRANSFER_READ_BIT,
									VK_IMAGE_LAYOUT_GENERAL,
									VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
									m_resultImage->get(),
									subresourceRange);

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

		const VkBufferImageCopy		bufferImageCopyParams = makeBufferImageCopy(makeExtent3D(layerSize), getNumLayers(m_imageType, m_imageSize));

		deviceInterface.cmdCopyImageToBuffer(cmdBuffer, m_resultImage->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_outputBuffer->get(), 1u, &bufferImageCopyParams);
	}
	else
	{
		const VkDevice					device					= m_context.getDevice();
		const VkDescriptorImageInfo		descResultImageInfo		= makeDescriptorImageInfo(DE_NULL, *m_resultImageView, VK_IMAGE_LAYOUT_GENERAL);
		const VkDescriptorBufferInfo	descResultBufferInfo	= makeDescriptorBufferInfo(m_outputBuffer->get(), 0, range);

		DescriptorSetUpdateBuilder()
			.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descResultImageInfo)
			.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descResultBufferInfo)
			.update(deviceInterface, device);

		const VkImageMemoryBarrier	resultImagePostDispatchBarrier =
			makeImageMemoryBarrier(	VK_ACCESS_SHADER_WRITE_BIT,
									VK_ACCESS_SHADER_READ_BIT,
									VK_IMAGE_LAYOUT_GENERAL,
									VK_IMAGE_LAYOUT_GENERAL,
									m_resultImage->get(),
									subresourceRange);

		deviceInterface.cmdPipelineBarrier(	cmdBuffer,
											VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
											VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
											DE_FALSE, 0u, DE_NULL, 0u, DE_NULL,
											1u, &resultImagePostDispatchBarrier);

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

		switch (m_imageType)
		{
			case IMAGE_TYPE_1D_ARRAY:
				deviceInterface.cmdDispatch(cmdBuffer, layerSize.x(), subresourceRange.layerCount, layerSize.z());
				break;
			case IMAGE_TYPE_2D_ARRAY:
			case IMAGE_TYPE_CUBE:
			case IMAGE_TYPE_CUBE_ARRAY:
				deviceInterface.cmdDispatch(cmdBuffer, layerSize.x(), layerSize.y(), subresourceRange.layerCount);
				break;
			default:
				deviceInterface.cmdDispatch(cmdBuffer, layerSize.x(), layerSize.y(), layerSize.z());
				break;
		}
	}
}

bool BinaryAtomicEndResultInstance::verifyResult (Allocation&	outputBufferAllocation,
												  const bool	is64Bit) const
{
	const UVec3	gridSize			= getShaderGridSize(m_imageType, m_imageSize);
	const IVec3 extendedGridSize	= IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z());

	tcu::ConstPixelBufferAccess resultBuffer(m_format, gridSize.x(), gridSize.y(), gridSize.z(), outputBufferAllocation.getHostPtr());

	for (deInt32 z = 0; z < resultBuffer.getDepth();  z++)
	for (deInt32 y = 0; y < resultBuffer.getHeight(); y++)
	for (deInt32 x = 0; x < resultBuffer.getWidth();  x++)
	{
		const void* resultValue = resultBuffer.getPixelPtr(x, y, z);
		deInt32 floatToIntValue = 0;
		bool isFloatValue = false;
		if (isFloatFormat(mapTextureFormat(m_format)))
		{
			isFloatValue = true;
			floatToIntValue = static_cast<deInt32>(*((float*)resultValue));
		}

		if (isOrderIndependentAtomicOperation(m_operation))
		{
			if (isUintFormat(mapTextureFormat(m_format)))
			{
				if(is64Bit)
				{
					if (!isValueCorrect<deUint64>(*((deUint64*)resultValue), x, y, z, gridSize, extendedGridSize))
						return false;
				}
				else
				{
					if (!isValueCorrect<deUint32>(*((deUint32*)resultValue), x, y, z, gridSize, extendedGridSize))
						return false;
				}
			}
			else if (isIntFormat(mapTextureFormat(m_format)))
			{
				if (is64Bit)
				{
					if (!isValueCorrect<deInt64>(*((deInt64*)resultValue), x, y, z, gridSize, extendedGridSize))
						return false;
				}
				else
				{
					if (!isValueCorrect<deInt32>(*((deInt32*)resultValue), x, y, z, gridSize, extendedGridSize))
						return false;
				}
			}
			else
			{
				// 32-bit floating point
				if (!isValueCorrect<deInt32>(floatToIntValue, x, y, z, gridSize, extendedGridSize))
					return false;
			}
		}
		else if (m_operation == ATOMIC_OPERATION_EXCHANGE)
		{
			// Check if the end result equals one of the atomic args.
			bool matchFound = false;

			for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL) && !matchFound; i++)
			{
				const IVec3 gid(x + i*gridSize.x(), y, z);
				matchFound = is64Bit ?
					(*((deInt64*)resultValue) == getAtomicFuncArgument<deInt64>(m_operation, gid, extendedGridSize)) :
					isFloatValue ?
					floatToIntValue == getAtomicFuncArgument<deInt32>(m_operation, gid, extendedGridSize) :
					(*((deInt32*)resultValue) == getAtomicFuncArgument<deInt32>(m_operation, gid, extendedGridSize));

			}

			if (!matchFound)
				return false;
		}
		else if (m_operation == ATOMIC_OPERATION_COMPARE_EXCHANGE)
		{
			// Check if the end result equals one of the atomic args.
			bool matchFound = false;

			for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL) && !matchFound; i++)
			{
				const IVec3 gid(x + i*gridSize.x(), y, z);
				matchFound = is64Bit ?
					(*((deInt64*)resultValue) == getAtomicFuncArgument<deInt64>(m_operation, gid, extendedGridSize)) :
					isFloatValue ?
					floatToIntValue == getAtomicFuncArgument<deInt32>(m_operation, gid, extendedGridSize) :
					(*((deInt32*)resultValue) == getAtomicFuncArgument<deInt32>(m_operation, gid, extendedGridSize));
			}

			if (!matchFound)
				return false;
		}
		else
			DE_ASSERT(false);
	}
	return true;
}

template <typename T>
bool BinaryAtomicEndResultInstance::isValueCorrect(const T resultValue, deInt32 x, deInt32 y, deInt32 z, const UVec3& gridSize, const IVec3 extendedGridSize) const
{
	T reference = getOperationInitialValue<T>(m_operation);
	for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL); i++)
	{
		const IVec3 gid(x + i*gridSize.x(), y, z);
		T			arg = getAtomicFuncArgument<T>(m_operation, gid, extendedGridSize);
		reference = computeBinaryAtomicOperationResult(m_operation, reference, arg);
	}
	return (resultValue == reference);
}

TestInstance* BinaryAtomicEndResultCase::createInstance (Context& context) const
{
	return new BinaryAtomicEndResultInstance(context, m_name, m_imageType, m_imageSize, m_format, m_operation, m_useTransfer, m_readType, m_backingType);
}

class BinaryAtomicIntermValuesInstance : public BinaryAtomicInstanceBase
{
public:

						BinaryAtomicIntermValuesInstance   (Context&				context,
															const string&			name,
															const ImageType			imageType,
															const tcu::UVec3&		imageSize,
															const TextureFormat&	format,
															const AtomicOperation	operation,
															const bool				useTransfer,
															const ShaderReadType	shaderReadType,
															const ImageBackingType	backingType)
							: BinaryAtomicInstanceBase(context, name, imageType, imageSize, format, operation, useTransfer, shaderReadType, backingType) {}

	virtual deUint32	getOutputBufferSize				   (void) const;

	virtual void		prepareResources				   (const bool				useTransfer);
	virtual void		prepareDescriptors				   (const bool				isTexelBuffer);

	virtual void		commandsBeforeCompute			   (const VkCommandBuffer	cmdBuffer) const;
	virtual void		commandsAfterCompute			   (const VkCommandBuffer	cmdBuffer,
															const VkPipeline		pipeline,
															const VkPipelineLayout	pipelineLayout,
															const VkDescriptorSet	descriptorSet,
															const VkDeviceSize&		range,
															const bool				useTransfer);

	virtual bool		verifyResult					   (Allocation&				outputBufferAllocation,
															const bool				is64Bit) const;

protected:

	template <typename T>
	bool				areValuesCorrect				   (tcu::ConstPixelBufferAccess& resultBuffer,
															const bool isFloatingPoint,
															deInt32 x,
															deInt32 y,
															deInt32 z,
															const UVec3& gridSize,
															const IVec3 extendedGridSize) const;

	template <typename T>
	bool				verifyRecursive					   (const deInt32			index,
															const T					valueSoFar,
															bool					argsUsed[NUM_INVOCATIONS_PER_PIXEL],
															const T					atomicArgs[NUM_INVOCATIONS_PER_PIXEL],
															const T					resultValues[NUM_INVOCATIONS_PER_PIXEL]) const;
	de::MovePtr<Image>	m_intermResultsImage;
	Move<VkImageView>	m_intermResultsImageView;
};

deUint32 BinaryAtomicIntermValuesInstance::getOutputBufferSize (void) const
{
	return NUM_INVOCATIONS_PER_PIXEL * tcu::getPixelSize(m_format) * getNumPixels(m_imageType, m_imageSize);
}

void BinaryAtomicIntermValuesInstance::prepareResources (const bool useTransfer)
{
	const UVec3 layerSize			= getLayerSize(m_imageType, m_imageSize);
	const bool  isCubeBasedImage	= (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY);
	const UVec3 extendedLayerSize	= isCubeBasedImage	? UVec3(NUM_INVOCATIONS_PER_PIXEL * layerSize.x(), NUM_INVOCATIONS_PER_PIXEL * layerSize.y(), layerSize.z())
														: UVec3(NUM_INVOCATIONS_PER_PIXEL * layerSize.x(), layerSize.y(), layerSize.z());

	createImageAndView(mapTextureFormat(m_format), extendedLayerSize, useTransfer, m_intermResultsImage, m_intermResultsImageView);
}

void BinaryAtomicIntermValuesInstance::prepareDescriptors (const bool	isTexelBuffer)
{
	const VkDescriptorType	descriptorType	= isTexelBuffer ?
											VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER :
											VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;

	const VkDevice			device			= m_context.getDevice();
	const DeviceInterface&	deviceInterface = m_context.getDeviceInterface();

	m_descriptorSetLayout =
		DescriptorSetLayoutBuilder()
		.addSingleBinding(descriptorType, VK_SHADER_STAGE_COMPUTE_BIT)
		.addSingleBinding(descriptorType, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(deviceInterface, device);

	m_descriptorPool =
		DescriptorPoolBuilder()
		.addType(descriptorType, 2u)
		.build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	m_descriptorSet = makeDescriptorSet(deviceInterface, device, *m_descriptorPool, *m_descriptorSetLayout);

	if (isTexelBuffer)
	{
		m_descResultBufferView			= makeBufferView(deviceInterface, device, *(*m_inputBuffer), mapTextureFormat(m_format), 0, VK_WHOLE_SIZE);
		m_descIntermResultsBufferView	= makeBufferView(deviceInterface, device, *(*m_outputBuffer), mapTextureFormat(m_format), 0, VK_WHOLE_SIZE);

		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &(m_descResultBufferView.get()))
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &(m_descIntermResultsBufferView.get()))
			.update(deviceInterface, device);
	}
	else
	{
		const VkDescriptorImageInfo	descResultImageInfo			= makeDescriptorImageInfo(DE_NULL, *m_resultImageView, VK_IMAGE_LAYOUT_GENERAL);
		const VkDescriptorImageInfo	descIntermResultsImageInfo	= makeDescriptorImageInfo(DE_NULL, *m_intermResultsImageView, VK_IMAGE_LAYOUT_GENERAL);

		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &descResultImageInfo)
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &descIntermResultsImageInfo)
			.update(deviceInterface, device);
	}
}

void BinaryAtomicIntermValuesInstance::commandsBeforeCompute (const VkCommandBuffer cmdBuffer) 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	imagePreDispatchBarrier =
		makeImageMemoryBarrier(	0u,
								VK_ACCESS_SHADER_WRITE_BIT,
								VK_IMAGE_LAYOUT_UNDEFINED,
								VK_IMAGE_LAYOUT_GENERAL,
								m_intermResultsImage->get(),
								subresourceRange);

	deviceInterface.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, DE_FALSE, 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePreDispatchBarrier);
}

void BinaryAtomicIntermValuesInstance::commandsAfterCompute (const VkCommandBuffer		cmdBuffer,
															 const VkPipeline			pipeline,
															 const VkPipelineLayout		pipelineLayout,
															 const VkDescriptorSet		descriptorSet,
															 const VkDeviceSize&		range,
															 const bool					useTransfer)
{
	// nothing is needed for texel image buffer
	if (m_imageType == IMAGE_TYPE_BUFFER)
		return;

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

	if (useTransfer)
	{
		const VkImageMemoryBarrier	imagePostDispatchBarrier =
			makeImageMemoryBarrier(	VK_ACCESS_SHADER_WRITE_BIT,
									VK_ACCESS_TRANSFER_READ_BIT,
									VK_IMAGE_LAYOUT_GENERAL,
									VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
									m_intermResultsImage->get(),
									subresourceRange);

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

		const UVec3					extendedLayerSize		= UVec3(NUM_INVOCATIONS_PER_PIXEL * layerSize.x(), layerSize.y(), layerSize.z());
		const VkBufferImageCopy		bufferImageCopyParams	= makeBufferImageCopy(makeExtent3D(extendedLayerSize), getNumLayers(m_imageType, m_imageSize));

		deviceInterface.cmdCopyImageToBuffer(cmdBuffer, m_intermResultsImage->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_outputBuffer->get(), 1u, &bufferImageCopyParams);
	}
	else
	{
		const VkDevice					device					= m_context.getDevice();
		const VkDescriptorImageInfo		descResultImageInfo		= makeDescriptorImageInfo(DE_NULL, *m_intermResultsImageView, VK_IMAGE_LAYOUT_GENERAL);
		const VkDescriptorBufferInfo	descResultBufferInfo	= makeDescriptorBufferInfo(m_outputBuffer->get(), 0, range);

		DescriptorSetUpdateBuilder()
			.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descResultImageInfo)
			.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descResultBufferInfo)
			.update(deviceInterface, device);

		const VkImageMemoryBarrier	resultImagePostDispatchBarrier =
		makeImageMemoryBarrier(	VK_ACCESS_SHADER_WRITE_BIT,
								VK_ACCESS_SHADER_READ_BIT,
								VK_IMAGE_LAYOUT_GENERAL,
								VK_IMAGE_LAYOUT_GENERAL,
								m_intermResultsImage->get(),
								subresourceRange);

		deviceInterface.cmdPipelineBarrier(	cmdBuffer,
									VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
									VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
									DE_FALSE, 0u, DE_NULL, 0u, DE_NULL,
									1u, &resultImagePostDispatchBarrier);

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

		switch (m_imageType)
		{
			case IMAGE_TYPE_1D_ARRAY:
				deviceInterface.cmdDispatch(cmdBuffer, NUM_INVOCATIONS_PER_PIXEL * layerSize.x(), subresourceRange.layerCount, layerSize.z());
				break;
			case IMAGE_TYPE_2D_ARRAY:
			case IMAGE_TYPE_CUBE:
			case IMAGE_TYPE_CUBE_ARRAY:
				deviceInterface.cmdDispatch(cmdBuffer, NUM_INVOCATIONS_PER_PIXEL * layerSize.x(), layerSize.y(), subresourceRange.layerCount);
				break;
			default:
				deviceInterface.cmdDispatch(cmdBuffer, NUM_INVOCATIONS_PER_PIXEL * layerSize.x(), layerSize.y(), layerSize.z());
				break;
		}
	}
}

bool BinaryAtomicIntermValuesInstance::verifyResult (Allocation&	outputBufferAllocation,
													 const bool		is64Bit) const
{
	const UVec3	gridSize		 = getShaderGridSize(m_imageType, m_imageSize);
	const IVec3 extendedGridSize = IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z());

	tcu::ConstPixelBufferAccess resultBuffer(m_format, extendedGridSize.x(), extendedGridSize.y(), extendedGridSize.z(), outputBufferAllocation.getHostPtr());

	for (deInt32 z = 0; z < resultBuffer.getDepth(); z++)
	for (deInt32 y = 0; y < resultBuffer.getHeight(); y++)
	for (deUint32 x = 0; x < gridSize.x(); x++)
	{
		if (isUintFormat(mapTextureFormat(m_format)))
		{
			if (is64Bit)
			{
				if (!areValuesCorrect<deUint64>(resultBuffer, false, x, y, z, gridSize, extendedGridSize))
					return false;
			}
			else
			{
				if (!areValuesCorrect<deUint32>(resultBuffer, false, x, y, z, gridSize, extendedGridSize))
					return false;
			}
		}
		else if (isIntFormat(mapTextureFormat(m_format)))
		{
			if (is64Bit)
			{
				if (!areValuesCorrect<deInt64>(resultBuffer, false, x, y, z, gridSize, extendedGridSize))
					return false;
			}
			else
			{
				if (!areValuesCorrect<deInt32>(resultBuffer, false, x, y, z, gridSize, extendedGridSize))
					return false;
			}
		}
		else
		{
			// 32-bit floating point
			if (!areValuesCorrect<deInt32>(resultBuffer, true, x, y, z, gridSize, extendedGridSize))
				return false;
		}
	}

	return true;
}

template <typename T>
bool BinaryAtomicIntermValuesInstance::areValuesCorrect(tcu::ConstPixelBufferAccess& resultBuffer, const bool isFloatingPoint, deInt32 x, deInt32 y, deInt32 z, const UVec3& gridSize, const IVec3 extendedGridSize) const
{
	T		resultValues[NUM_INVOCATIONS_PER_PIXEL];
	T		atomicArgs[NUM_INVOCATIONS_PER_PIXEL];
	bool	argsUsed[NUM_INVOCATIONS_PER_PIXEL];

	for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL); i++)
	{
		IVec3 gid(x + i*gridSize.x(), y, z);
		T data = *((T*)resultBuffer.getPixelPtr(gid.x(), gid.y(), gid.z()));
		if (isFloatingPoint)
		{
			float fData;
			deMemcpy(&fData, &data, sizeof(fData));
			data = static_cast<T>(fData);
		}
		resultValues[i] = data;
		atomicArgs[i]	= getAtomicFuncArgument<T>(m_operation, gid, extendedGridSize);
		argsUsed[i]		= false;
	}

	// Verify that the return values form a valid sequence.
	return verifyRecursive(0, getOperationInitialValue<T>(m_operation), argsUsed, atomicArgs, resultValues);
}

template <typename T>
bool BinaryAtomicIntermValuesInstance::verifyRecursive (const deInt32	index,
														const T			valueSoFar,
														bool			argsUsed[NUM_INVOCATIONS_PER_PIXEL],
														const T			atomicArgs[NUM_INVOCATIONS_PER_PIXEL],
														const T			resultValues[NUM_INVOCATIONS_PER_PIXEL]) const
{
	if (index >= static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL))
		return true;

	for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL); i++)
	{
		if (!argsUsed[i] && resultValues[i] == valueSoFar)
		{
			argsUsed[i] = true;

			if (verifyRecursive(index + 1, computeBinaryAtomicOperationResult(m_operation, valueSoFar, atomicArgs[i]), argsUsed, atomicArgs, resultValues))
			{
				return true;
			}

			argsUsed[i] = false;
		}
	}

	return false;
}

TestInstance* BinaryAtomicIntermValuesCase::createInstance (Context& context) const
{
	return new BinaryAtomicIntermValuesInstance(context, m_name, m_imageType, m_imageSize, m_format, m_operation, m_useTransfer, m_readType, m_backingType);
}

} // anonymous ns

tcu::TestCaseGroup* createImageAtomicOperationTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> imageAtomicOperationsTests(new tcu::TestCaseGroup(testCtx, "atomic_operations", "Atomic image operations cases"));

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

	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(48u, 48u, 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))
	};

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

	const struct
	{
		ShaderReadType		type;
		const char*			name;
	} readTypes[] =
	{
		{	ShaderReadType::NORMAL,	"normal_read"	},
		{	ShaderReadType::SPARSE,	"sparse_read"	},
	};

	const struct
	{
		ImageBackingType	type;
		const char*			name;
	} backingTypes[] =
	{
		{	ImageBackingType::NORMAL,	"normal_img"	},
		{	ImageBackingType::SPARSE,	"sparse_img"	},
	};

	for (deUint32 operationI = 0; operationI < ATOMIC_OPERATION_LAST; operationI++)
	{
		const AtomicOperation operation = (AtomicOperation)operationI;

		de::MovePtr<tcu::TestCaseGroup> operationGroup(new tcu::TestCaseGroup(testCtx, getAtomicOperationCaseName(operation).c_str(), ""));

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

			de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));

			for (int useTransferIdx = 0; useTransferIdx < 2; ++useTransferIdx)
			{
				const bool				useTransfer	= (useTransferIdx > 0);
				const string			groupName	= (!useTransfer ? "no" : "") + string("transfer");

				de::MovePtr<tcu::TestCaseGroup> transferGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));

				for (int readTypeIdx = 0; readTypeIdx < DE_LENGTH_OF_ARRAY(readTypes); ++readTypeIdx)
				{
					const auto& readType = readTypes[readTypeIdx];

					de::MovePtr<tcu::TestCaseGroup> readTypeGroup(new tcu::TestCaseGroup(testCtx, readType.name, ""));

					for (int backingTypeIdx = 0; backingTypeIdx < DE_LENGTH_OF_ARRAY(backingTypes); ++backingTypeIdx)
					{
						const auto& backingType = backingTypes[backingTypeIdx];

						de::MovePtr<tcu::TestCaseGroup> backingTypeGroup(new tcu::TestCaseGroup(testCtx, backingType.name, ""));

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

							// Need SPIRV programs in vktImageAtomicSpirvShaders.cpp
							if (imageType == IMAGE_TYPE_BUFFER && (format.type != tcu::TextureFormat::FLOAT))
							{
								continue;
							}

							// Only 2D and 3D images may support sparse residency.
							const auto vkImageType = mapImageType(imageType);
							if (backingType.type == ImageBackingType::SPARSE && (vkImageType != VK_IMAGE_TYPE_2D && vkImageType != VK_IMAGE_TYPE_3D))
								continue;

							// Only some operations are supported on floating-point
							if (format.type == tcu::TextureFormat::FLOAT)
							{
								if (operation != ATOMIC_OPERATION_ADD &&
									operation != ATOMIC_OPERATION_EXCHANGE &&
									operation != ATOMIC_OPERATION_MIN &&
									operation != ATOMIC_OPERATION_MAX)
								{
									continue;
								}
							}

							if (readType.type == ShaderReadType::SPARSE)
							{
								// When using transfer, shader reads will not be used, so avoid creating two identical cases.
								if (useTransfer)
									continue;

								// Sparse reads are not supported for all types of images.
								if (imageType == IMAGE_TYPE_1D || imageType == IMAGE_TYPE_1D_ARRAY || imageType == IMAGE_TYPE_BUFFER)
									continue;
							}

							//!< Atomic case checks the end result of the operations, and not the intermediate return values
							const string caseEndResult = formatName + "_end_result";
							backingTypeGroup->addChild(new BinaryAtomicEndResultCase(testCtx, caseEndResult, "", imageType, imageSize, format, operation, useTransfer, readType.type, backingType.type, glu::GLSL_VERSION_450));

							//!< Atomic case checks the return values of the atomic function and not the end result.
							const string caseIntermValues = formatName + "_intermediate_values";
							backingTypeGroup->addChild(new BinaryAtomicIntermValuesCase(testCtx, caseIntermValues, "", imageType, imageSize, format, operation, useTransfer, readType.type, backingType.type, glu::GLSL_VERSION_450));
						}

						readTypeGroup->addChild(backingTypeGroup.release());
					}

					transferGroup->addChild(readTypeGroup.release());
				}

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

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

		imageAtomicOperationsTests->addChild(operationGroup.release());
	}

	return imageAtomicOperationsTests.release();
}

} // image
} // vkt
