/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2014 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 Shader Image Load & Store Tests.
 *//*--------------------------------------------------------------------*/

#include "es31fShaderImageLoadStoreTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluObjectWrapper.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "gluStrUtil.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluProgramInterfaceQuery.hpp"
#include "gluDrawUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVector.hpp"
#include "tcuImageCompare.hpp"
#include "tcuFloat.hpp"
#include "tcuVectorUtil.hpp"
#include "deStringUtil.hpp"
#include "deSharedPtr.hpp"
#include "deUniquePtr.hpp"
#include "deRandom.hpp"
#include "deMemory.h"
#include "glwFunctions.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"

#include <vector>
#include <string>
#include <algorithm>
#include <map>

using glu::RenderContext;
using tcu::TestLog;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::IVec3;
using tcu::IVec4;
using tcu::UVec2;
using tcu::UVec3;
using tcu::UVec4;
using tcu::TextureFormat;
using tcu::ConstPixelBufferAccess;
using tcu::PixelBufferAccess;
using de::toString;
using de::SharedPtr;
using de::UniquePtr;

using std::vector;
using std::string;

namespace deqp
{

using namespace gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

namespace gles31
{
namespace Functional
{

//! Default image sizes used in most test cases.
static inline IVec3 defaultImageSize (TextureType type)
{
	switch (type)
	{
		case TEXTURETYPE_BUFFER:	return IVec3(64,	1,		1);
		case TEXTURETYPE_2D:		return IVec3(64,	64,		1);
		case TEXTURETYPE_CUBE:		return IVec3(64,	64,		1);
		case TEXTURETYPE_3D:		return IVec3(64,	64,		8);
		case TEXTURETYPE_2D_ARRAY:	return IVec3(64,	64,		8);
		default:
			DE_ASSERT(false);
			return IVec3(-1);
	}
}

template <typename T, int Size>
static string arrayStr (const T (&arr)[Size])
{
	string result = "{ ";
	for (int i = 0; i < Size; i++)
		result += (i > 0 ? ", " : "") + toString(arr[i]);
	result += " }";
	return result;
}

template <typename T, int N>
static int arrayIndexOf (const T (&arr)[N], const T& e)
{
	return (int)(std::find(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr), e) - DE_ARRAY_BEGIN(arr));
}

static const char* getTextureTypeName (TextureType type)
{
	switch (type)
	{
		case TEXTURETYPE_BUFFER:	return "buffer";
		case TEXTURETYPE_2D:		return "2d";
		case TEXTURETYPE_CUBE:		return "cube";
		case TEXTURETYPE_3D:		return "3d";
		case TEXTURETYPE_2D_ARRAY:	return "2d_array";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static inline bool isFormatTypeUnsignedInteger (TextureFormat::ChannelType type)
{
	return type == TextureFormat::UNSIGNED_INT8		||
		   type == TextureFormat::UNSIGNED_INT16	||
		   type == TextureFormat::UNSIGNED_INT32;
}

static inline bool isFormatTypeSignedInteger (TextureFormat::ChannelType type)
{
	return type == TextureFormat::SIGNED_INT8	||
		   type == TextureFormat::SIGNED_INT16	||
		   type == TextureFormat::SIGNED_INT32;
}

static inline bool isFormatTypeInteger (TextureFormat::ChannelType type)
{
	return isFormatTypeUnsignedInteger(type) || isFormatTypeSignedInteger(type);
}

static inline bool isFormatTypeUnorm (TextureFormat::ChannelType type)
{
	return type == TextureFormat::UNORM_INT8	||
		   type == TextureFormat::UNORM_INT16	||
		   type == TextureFormat::UNORM_INT32;
}

static inline bool isFormatTypeSnorm (TextureFormat::ChannelType type)
{
	return type == TextureFormat::SNORM_INT8	||
		   type == TextureFormat::SNORM_INT16	||
		   type == TextureFormat::SNORM_INT32;
}

static inline bool isFormatSupportedForTextureBuffer (const TextureFormat& format)
{
	switch (format.order)
	{
		case TextureFormat::RGB:
			return format.type == TextureFormat::FLOAT				||
				   format.type == TextureFormat::SIGNED_INT32		||
				   format.type == TextureFormat::UNSIGNED_INT32;

		// \note Fallthroughs.
		case TextureFormat::R:
		case TextureFormat::RG:
		case TextureFormat::RGBA:
			return format.type == TextureFormat::UNORM_INT8			||
				   format.type == TextureFormat::HALF_FLOAT			||
				   format.type == TextureFormat::FLOAT				||
				   format.type == TextureFormat::SIGNED_INT8		||
				   format.type == TextureFormat::SIGNED_INT16		||
				   format.type == TextureFormat::SIGNED_INT32		||
				   format.type == TextureFormat::UNSIGNED_INT8		||
				   format.type == TextureFormat::UNSIGNED_INT16		||
				   format.type == TextureFormat::UNSIGNED_INT32;

		default:
			return false;
	}
}

static inline string getShaderImageFormatQualifier (const TextureFormat& format)
{
	const char* orderPart;
	const char* typePart;

	switch (format.order)
	{
		case TextureFormat::R:		orderPart = "r";		break;
		case TextureFormat::RGBA:	orderPart = "rgba";		break;
		default:
			DE_ASSERT(false);
			orderPart = DE_NULL;
	}

	switch (format.type)
	{
		case TextureFormat::FLOAT:				typePart = "32f";			break;
		case TextureFormat::HALF_FLOAT:			typePart = "16f";			break;

		case TextureFormat::UNSIGNED_INT32:		typePart = "32ui";			break;
		case TextureFormat::UNSIGNED_INT16:		typePart = "16ui";			break;
		case TextureFormat::UNSIGNED_INT8:		typePart = "8ui";			break;

		case TextureFormat::SIGNED_INT32:		typePart = "32i";			break;
		case TextureFormat::SIGNED_INT16:		typePart = "16i";			break;
		case TextureFormat::SIGNED_INT8:		typePart = "8i";			break;

		case TextureFormat::UNORM_INT16:		typePart = "16";			break;
		case TextureFormat::UNORM_INT8:			typePart = "8";				break;

		case TextureFormat::SNORM_INT16:		typePart = "16_snorm";		break;
		case TextureFormat::SNORM_INT8:			typePart = "8_snorm";		break;

		default:
			DE_ASSERT(false);
			typePart = DE_NULL;
	}

	return string() + orderPart + typePart;
}

static inline string getShaderSamplerOrImageType (TextureFormat::ChannelType formatType, TextureType textureType, bool isSampler)
{
	const char* const formatPart		= isFormatTypeUnsignedInteger(formatType)	? "u"
										: isFormatTypeSignedInteger(formatType)		? "i"
										: "";

	const char* const imageTypePart		= textureType == TEXTURETYPE_BUFFER		? "Buffer"
										: textureType == TEXTURETYPE_2D			? "2D"
										: textureType == TEXTURETYPE_3D			? "3D"
										: textureType == TEXTURETYPE_CUBE		? "Cube"
										: textureType == TEXTURETYPE_2D_ARRAY	? "2DArray"
										: DE_NULL;

	return string() + formatPart + (isSampler ? "sampler" : "image") + imageTypePart;
}

static inline string getShaderImageType (TextureFormat::ChannelType formatType, TextureType imageType)
{
	return getShaderSamplerOrImageType(formatType, imageType, false);
}

static inline string getShaderSamplerType (TextureFormat::ChannelType formatType, TextureType imageType)
{
	return getShaderSamplerOrImageType(formatType, imageType, true);
}

static inline deUint32 getGLTextureTarget (TextureType texType)
{
	switch (texType)
	{
		case TEXTURETYPE_BUFFER:	return GL_TEXTURE_BUFFER;
		case TEXTURETYPE_2D:		return GL_TEXTURE_2D;
		case TEXTURETYPE_3D:		return GL_TEXTURE_3D;
		case TEXTURETYPE_CUBE:		return GL_TEXTURE_CUBE_MAP;
		case TEXTURETYPE_2D_ARRAY:	return GL_TEXTURE_2D_ARRAY;
		default:
			DE_ASSERT(false);
			return (deUint32)-1;
	}
}

static deUint32 cubeFaceToGLFace (tcu::CubeFace face)
{
	switch (face)
	{
		case tcu::CUBEFACE_NEGATIVE_X: return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
		case tcu::CUBEFACE_POSITIVE_X: return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
		case tcu::CUBEFACE_NEGATIVE_Y: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
		case tcu::CUBEFACE_POSITIVE_Y: return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
		case tcu::CUBEFACE_NEGATIVE_Z: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
		case tcu::CUBEFACE_POSITIVE_Z: return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
		default:
			DE_ASSERT(false);
			return GL_NONE;
	}
}

static inline tcu::Texture1D* newOneLevelTexture1D (const tcu::TextureFormat& format, int w)
{
	tcu::Texture1D* const res = new tcu::Texture1D(format, w);
	res->allocLevel(0);
	return res;
}

static inline tcu::Texture2D* newOneLevelTexture2D (const tcu::TextureFormat& format, int w, int h)
{
	tcu::Texture2D* const res = new tcu::Texture2D(format, w, h);
	res->allocLevel(0);
	return res;
}

static inline tcu::TextureCube* newOneLevelTextureCube (const tcu::TextureFormat& format, int size)
{
	tcu::TextureCube* const res = new tcu::TextureCube(format, size);
	for (int i = 0; i < tcu::CUBEFACE_LAST; i++)
		res->allocLevel((tcu::CubeFace)i, 0);
	return res;
}

static inline tcu::Texture3D* newOneLevelTexture3D (const tcu::TextureFormat& format, int w, int h, int d)
{
	tcu::Texture3D* const res = new tcu::Texture3D(format, w, h, d);
	res->allocLevel(0);
	return res;
}

static inline tcu::Texture2DArray* newOneLevelTexture2DArray (const tcu::TextureFormat& format, int w, int h, int d)
{
	tcu::Texture2DArray* const res = new tcu::Texture2DArray(format, w, h, d);
	res->allocLevel(0);
	return res;
}

static inline TextureType textureLayerType (TextureType entireTextureType)
{
	switch (entireTextureType)
	{
		// Single-layer types.
		// \note Fallthrough.
		case TEXTURETYPE_BUFFER:
		case TEXTURETYPE_2D:
			return entireTextureType;

		// Multi-layer types with 2d layers.
		case TEXTURETYPE_3D:
		case TEXTURETYPE_CUBE:
		case TEXTURETYPE_2D_ARRAY:
			return TEXTURETYPE_2D;

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

static const char* const s_texBufExtString = "GL_EXT_texture_buffer";

static bool supportsES32orGL45(const RenderContext& renderContext)
{
	glu::ContextType contextType = renderContext.getType();
	return glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
		   glu::contextSupports(contextType, glu::ApiType::core(4, 5));
}

static inline void checkTextureTypeExtensions (const glu::ContextInfo& contextInfo, TextureType type, const RenderContext& renderContext)
{
	if (type == TEXTURETYPE_BUFFER && !contextInfo.isExtensionSupported(s_texBufExtString) && !supportsES32orGL45(renderContext))
		throw tcu::NotSupportedError("Test requires " + string(s_texBufExtString) + " extension");
}

static inline string textureTypeExtensionShaderRequires (TextureType type, const RenderContext& renderContext)
{
	if (!supportsES32orGL45(renderContext) && (type == TEXTURETYPE_BUFFER))
		return "#extension " + string(s_texBufExtString) + " : require\n";
	else
		return "";
}

static const char* const s_imageAtomicExtString = "GL_OES_shader_image_atomic";

static inline string imageAtomicExtensionShaderRequires (const RenderContext& renderContext)
{
	if (!supportsES32orGL45(renderContext))
		return "#extension " + string(s_imageAtomicExtString) + " : require\n";
	else
		return "";
}

namespace
{

enum AtomicOperation
{
	ATOMIC_OPERATION_ADD = 0,
	ATOMIC_OPERATION_MIN,
	ATOMIC_OPERATION_MAX,
	ATOMIC_OPERATION_AND,
	ATOMIC_OPERATION_OR,
	ATOMIC_OPERATION_XOR,
	ATOMIC_OPERATION_EXCHANGE,
	ATOMIC_OPERATION_COMP_SWAP,

	ATOMIC_OPERATION_LAST
};

//! 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 (AtomicOperation op)
{
	return op == ATOMIC_OPERATION_ADD	||
		   op == ATOMIC_OPERATION_MIN	||
		   op == ATOMIC_OPERATION_MAX	||
		   op == ATOMIC_OPERATION_AND	||
		   op == ATOMIC_OPERATION_OR	||
		   op == ATOMIC_OPERATION_XOR;
}

//! Computes the result of an atomic operation where "a" is the data operated on and "b" is the parameter to the atomic function.
int computeBinaryAtomicOperationResult (AtomicOperation op, int a, int b)
{
	switch (op)
	{
		case ATOMIC_OPERATION_ADD:			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;
		default:
			DE_ASSERT(false);
			return -1;
	}
}

//! \note For floats, only the exchange operation is supported.
float computeBinaryAtomicOperationResult (AtomicOperation op, float /*a*/, float b)
{
	switch (op)
	{
		case ATOMIC_OPERATION_EXCHANGE: return b;
		default:
			DE_ASSERT(false);
			return -1;
	}
}

static const char* getAtomicOperationCaseName (AtomicOperation op)
{
	switch (op)
	{
		case ATOMIC_OPERATION_ADD:			return "add";
		case ATOMIC_OPERATION_MIN:			return "min";
		case ATOMIC_OPERATION_MAX:			return "max";
		case ATOMIC_OPERATION_AND:			return "and";
		case ATOMIC_OPERATION_OR:			return "or";
		case ATOMIC_OPERATION_XOR:			return "xor";
		case ATOMIC_OPERATION_EXCHANGE:		return "exchange";
		case ATOMIC_OPERATION_COMP_SWAP:	return "comp_swap";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

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

//! In GLSL, when accessing cube images, the z coordinate is mapped to a cube face.
//! \note This is _not_ the same as casting the z to a tcu::CubeFace.
static inline tcu::CubeFace glslImageFuncZToCubeFace (int z)
{
	static const tcu::CubeFace faces[6] =
	{
		tcu::CUBEFACE_POSITIVE_X,
		tcu::CUBEFACE_NEGATIVE_X,
		tcu::CUBEFACE_POSITIVE_Y,
		tcu::CUBEFACE_NEGATIVE_Y,
		tcu::CUBEFACE_POSITIVE_Z,
		tcu::CUBEFACE_NEGATIVE_Z
	};

	DE_ASSERT(de::inBounds(z, 0, DE_LENGTH_OF_ARRAY(faces)));
	return faces[z];
}

class BufferMemMap
{
public:
	BufferMemMap (const glw::Functions& gl, deUint32 target, int offset, int size, deUint32 access)
		: m_gl		(gl)
		, m_target	(target)
		, m_ptr		(DE_NULL)
	{
		m_ptr = gl.mapBufferRange(target, offset, size, access);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
		TCU_CHECK(m_ptr);
	}

	~BufferMemMap (void)
	{
		m_gl.unmapBuffer(m_target);
	}

	void*	getPtr		(void) const { return m_ptr; }
	void*	operator*	(void) const { return m_ptr; }

private:
							BufferMemMap			(const BufferMemMap& other);
	BufferMemMap&			operator=				(const BufferMemMap& other);

	const glw::Functions&	m_gl;
	const deUint32			m_target;
	void*					m_ptr;
};

//! Utility for more readable uniform assignment logging; logs the name of the uniform when assigning. Handles the locations, querying them the first time they're assigned
//  \note Assumes that the appropriate program is in use when assigning uniforms.
class UniformAccessLogger
{
public:
	UniformAccessLogger (const glw::Functions& gl, TestLog& log, deUint32 programGL)
		: m_gl			(gl)
		, m_log			(log)
		, m_programGL	(programGL)
	{
	}

	void						assign1i (const string& name, int x);
	void						assign3f (const string& name, float x, float y, float z);

private:
	int							getLocation (const string& name);

	const glw::Functions&		m_gl;
	TestLog&					m_log;
	const deUint32				m_programGL;

	std::map<string, int>		m_uniformLocations;
};

int UniformAccessLogger::getLocation (const string& name)
{
	if (m_uniformLocations.find(name) == m_uniformLocations.end())
	{
		const int loc = m_gl.getUniformLocation(m_programGL, name.c_str());
		TCU_CHECK(loc != -1);
		m_uniformLocations[name] = loc;
	}
	return m_uniformLocations[name];
}

void UniformAccessLogger::assign1i (const string& name, int x)
{
	const int loc = getLocation(name);
	m_log << TestLog::Message << "// Assigning to uniform " << name << ": " << x << TestLog::EndMessage;
	m_gl.uniform1i(loc, x);
}

void UniformAccessLogger::assign3f (const string& name, float x, float y, float z)
{
	const int loc = getLocation(name);
	m_log << TestLog::Message << "// Assigning to uniform " << name << ": " << Vec3(x, y, z) << TestLog::EndMessage;
	m_gl.uniform3f(loc, x, y, z);
}

//! Class containing a (single-level) texture of a given type. Supports accessing pixels with coordinate convention similar to that in imageStore() and imageLoad() in shaders; useful especially for cube maps.
class LayeredImage
{
public:
												LayeredImage				(TextureType type, const TextureFormat& format, int w, int h, int d);

	TextureType									getImageType				(void) const { return m_type; }
	const IVec3&								getSize						(void) const { return m_size; }
	const TextureFormat&						getFormat					(void) const { return m_format; }

	// \note For cube maps, set/getPixel's z parameter specifies the cube face in the same manner as in imageStore/imageLoad in GL shaders (see glslImageFuncZToCubeFace), instead of directly as a tcu::CubeFace.

	template <typename ColorT>
	void										setPixel					(int x, int y, int z, const ColorT& color) const;

	Vec4										getPixel					(int x, int y, int z) const;
	IVec4										getPixelInt					(int x, int y, int z) const;
	UVec4										getPixelUint				(int x, int y, int z) const { return getPixelInt(x, y, z).asUint(); }

	PixelBufferAccess							getAccess					(void)							{ return getAccessInternal();				}
	PixelBufferAccess							getSliceAccess				(int slice)						{ return getSliceAccessInternal(slice);		}
	PixelBufferAccess							getCubeFaceAccess			(tcu::CubeFace face)			{ return getCubeFaceAccessInternal(face);	}

	ConstPixelBufferAccess						getAccess					(void)					const	{ return getAccessInternal();				}
	ConstPixelBufferAccess						getSliceAccess				(int slice)				const	{ return getSliceAccessInternal(slice);		}
	ConstPixelBufferAccess						getCubeFaceAccess			(tcu::CubeFace face)	const	{ return getCubeFaceAccessInternal(face);	}

private:
												LayeredImage				(const LayeredImage&);
	LayeredImage&								operator=					(const LayeredImage&);

	// Some helpers to reduce code duplication between const/non-const versions of getAccess and others.
	PixelBufferAccess							getAccessInternal			(void) const;
	PixelBufferAccess							getSliceAccessInternal		(int slice) const;
	PixelBufferAccess							getCubeFaceAccessInternal	(tcu::CubeFace face) const;

	const TextureType							m_type;
	const IVec3									m_size;
	const TextureFormat							m_format;

	// \note Depending on m_type, exactly one of the following will contain non-null.
	const SharedPtr<tcu::Texture1D>				m_texBuffer;
	const SharedPtr<tcu::Texture2D>				m_tex2D;
	const SharedPtr<tcu::TextureCube>			m_texCube;
	const SharedPtr<tcu::Texture3D>				m_tex3D;
	const SharedPtr<tcu::Texture2DArray>		m_tex2DArray;
};

LayeredImage::LayeredImage (TextureType type, const TextureFormat& format, int w, int h, int d)
	: m_type		(type)
	, m_size		(w, h, d)
	, m_format		(format)
	, m_texBuffer	(type == TEXTURETYPE_BUFFER		? SharedPtr<tcu::Texture1D>			(newOneLevelTexture1D		(format, w))		: SharedPtr<tcu::Texture1D>())
	, m_tex2D		(type == TEXTURETYPE_2D			? SharedPtr<tcu::Texture2D>			(newOneLevelTexture2D		(format, w, h))		: SharedPtr<tcu::Texture2D>())
	, m_texCube		(type == TEXTURETYPE_CUBE		? SharedPtr<tcu::TextureCube>		(newOneLevelTextureCube		(format, w))		: SharedPtr<tcu::TextureCube>())
	, m_tex3D		(type == TEXTURETYPE_3D			? SharedPtr<tcu::Texture3D>			(newOneLevelTexture3D		(format, w, h, d))	: SharedPtr<tcu::Texture3D>())
	, m_tex2DArray	(type == TEXTURETYPE_2D_ARRAY	? SharedPtr<tcu::Texture2DArray>	(newOneLevelTexture2DArray	(format, w, h, d))	: SharedPtr<tcu::Texture2DArray>())
{
	DE_ASSERT(m_size.z() == 1					||
			  m_type == TEXTURETYPE_3D			||
			  m_type == TEXTURETYPE_2D_ARRAY);

	DE_ASSERT(m_size.y() == 1					||
			  m_type == TEXTURETYPE_2D			||
			  m_type == TEXTURETYPE_CUBE		||
			  m_type == TEXTURETYPE_3D			||
			  m_type == TEXTURETYPE_2D_ARRAY);

	DE_ASSERT(w == h || type != TEXTURETYPE_CUBE);

	DE_ASSERT(m_texBuffer	!= DE_NULL ||
			  m_tex2D		!= DE_NULL ||
			  m_texCube		!= DE_NULL ||
			  m_tex3D		!= DE_NULL ||
			  m_tex2DArray	!= DE_NULL);
}

template <typename ColorT>
void LayeredImage::setPixel (int x, int y, int z, const ColorT& color) const
{
	const PixelBufferAccess access = m_type == TEXTURETYPE_BUFFER		? m_texBuffer->getLevel(0)
								   : m_type == TEXTURETYPE_2D			? m_tex2D->getLevel(0)
								   : m_type == TEXTURETYPE_CUBE			? m_texCube->getLevelFace(0, glslImageFuncZToCubeFace(z))
								   : m_type == TEXTURETYPE_3D			? m_tex3D->getLevel(0)
								   : m_type == TEXTURETYPE_2D_ARRAY		? m_tex2DArray->getLevel(0)
								   : PixelBufferAccess();

	access.setPixel(color, x, y, m_type == TEXTURETYPE_CUBE ? 0 : z);
}

Vec4 LayeredImage::getPixel (int x, int y, int z) const
{
	const ConstPixelBufferAccess access = m_type == TEXTURETYPE_CUBE ? getCubeFaceAccess(glslImageFuncZToCubeFace(z)) : getAccess();
	return access.getPixel(x, y, m_type == TEXTURETYPE_CUBE ? 0 : z);
}

IVec4 LayeredImage::getPixelInt (int x, int y, int z) const
{
	const ConstPixelBufferAccess access = m_type == TEXTURETYPE_CUBE ? getCubeFaceAccess(glslImageFuncZToCubeFace(z)) : getAccess();
	return access.getPixelInt(x, y, m_type == TEXTURETYPE_CUBE ? 0 : z);
}

PixelBufferAccess LayeredImage::getAccessInternal (void) const
{
	DE_ASSERT(m_type == TEXTURETYPE_BUFFER || m_type == TEXTURETYPE_2D || m_type == TEXTURETYPE_3D || m_type == TEXTURETYPE_2D_ARRAY);

	return m_type == TEXTURETYPE_BUFFER		? m_texBuffer->getLevel(0)
		 : m_type == TEXTURETYPE_2D			? m_tex2D->getLevel(0)
		 : m_type == TEXTURETYPE_3D			? m_tex3D->getLevel(0)
		 : m_type == TEXTURETYPE_2D_ARRAY	? m_tex2DArray->getLevel(0)
		 : PixelBufferAccess();
}

PixelBufferAccess LayeredImage::getSliceAccessInternal (int slice) const
{
	const PixelBufferAccess srcAccess = getAccessInternal();
	return tcu::getSubregion(srcAccess, 0, 0, slice, srcAccess.getWidth(), srcAccess.getHeight(), 1);
}

PixelBufferAccess LayeredImage::getCubeFaceAccessInternal (tcu::CubeFace face) const
{
	DE_ASSERT(m_type == TEXTURETYPE_CUBE);
	return m_texCube->getLevelFace(0, face);
}

//! Set texture storage or, if using buffer texture, setup buffer and attach to texture.
static void setTextureStorage (glu::CallLogWrapper& glLog, TextureType imageType, deUint32 internalFormat, const IVec3& imageSize, deUint32 textureBufGL)
{
	const deUint32 textureTarget = getGLTextureTarget(imageType);

	switch (imageType)
	{
		case TEXTURETYPE_BUFFER:
		{
			const TextureFormat		format		= glu::mapGLInternalFormat(internalFormat);
			const int				numBytes	= format.getPixelSize() * imageSize.x();
			DE_ASSERT(isFormatSupportedForTextureBuffer(format));
			glLog.glBindBuffer(GL_TEXTURE_BUFFER, textureBufGL);
			glLog.glBufferData(GL_TEXTURE_BUFFER, numBytes, DE_NULL, GL_STATIC_DRAW);
			glLog.glTexBuffer(GL_TEXTURE_BUFFER, internalFormat, textureBufGL);
			DE_ASSERT(imageSize.y() == 1 && imageSize.z() == 1);
			break;
		}

		// \note Fall-throughs.

		case TEXTURETYPE_2D:
		case TEXTURETYPE_CUBE:
			glLog.glTexStorage2D(textureTarget, 1, internalFormat, imageSize.x(), imageSize.y());
			DE_ASSERT(imageSize.z() == 1);
			break;

		case TEXTURETYPE_3D:
		case TEXTURETYPE_2D_ARRAY:
			glLog.glTexStorage3D(textureTarget, 1, internalFormat, imageSize.x(), imageSize.y(), imageSize.z());
			break;

		default:
			DE_ASSERT(false);
	}
}

static void uploadTexture (glu::CallLogWrapper& glLog, const LayeredImage& src, deUint32 textureBufGL)
{
	const deUint32				internalFormat	= glu::getInternalFormat(src.getFormat());
	const glu::TransferFormat	transferFormat	= glu::getTransferFormat(src.getFormat());
	const IVec3&				imageSize		= src.getSize();

	setTextureStorage(glLog, src.getImageType(), internalFormat, imageSize, textureBufGL);

	{
		const int	pixelSize = src.getFormat().getPixelSize();
		int			unpackAlignment;

		if (deIsPowerOfTwo32(pixelSize))
			unpackAlignment = 8;
		else
			unpackAlignment = 1;

		glLog.glPixelStorei(GL_UNPACK_ALIGNMENT, unpackAlignment);
	}

	if (src.getImageType() == TEXTURETYPE_BUFFER)
	{
		glLog.glBindBuffer(GL_TEXTURE_BUFFER, textureBufGL);
		glLog.glBufferData(GL_TEXTURE_BUFFER, src.getFormat().getPixelSize() * imageSize.x(), src.getAccess().getDataPtr(), GL_STATIC_DRAW);
	}
	else if (src.getImageType() == TEXTURETYPE_2D)
		glLog.glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageSize.x(), imageSize.y(), transferFormat.format, transferFormat.dataType, src.getAccess().getDataPtr());
	else if (src.getImageType() == TEXTURETYPE_CUBE)
	{
		for (int faceI = 0; faceI < tcu::CUBEFACE_LAST; faceI++)
		{
			const tcu::CubeFace face = (tcu::CubeFace)faceI;
			glLog.glTexSubImage2D(cubeFaceToGLFace(face), 0, 0, 0, imageSize.x(), imageSize.y(), transferFormat.format, transferFormat.dataType, src.getCubeFaceAccess(face).getDataPtr());
		}
	}
	else
	{
		DE_ASSERT(src.getImageType() == TEXTURETYPE_3D || src.getImageType() == TEXTURETYPE_2D_ARRAY);
		const deUint32 textureTarget = getGLTextureTarget(src.getImageType());
		glLog.glTexSubImage3D(textureTarget, 0, 0, 0, 0, imageSize.x(), imageSize.y(), imageSize.z(), transferFormat.format, transferFormat.dataType, src.getAccess().getDataPtr());
	}
}

static void readPixelsRGBAInteger32 (const PixelBufferAccess& dst, int originX, int originY, glu::CallLogWrapper& glLog)
{
	DE_ASSERT(dst.getDepth() == 1);

	if (isFormatTypeUnsignedInteger(dst.getFormat().type))
	{
		vector<UVec4> data(dst.getWidth()*dst.getHeight());

		glLog.glReadPixels(originX, originY, dst.getWidth(), dst.getHeight(), GL_RGBA_INTEGER, GL_UNSIGNED_INT, &data[0]);

		for (int y = 0; y < dst.getHeight(); y++)
		for (int x = 0; x < dst.getWidth(); x++)
			dst.setPixel(data[y*dst.getWidth() + x], x, y);
	}
	else if (isFormatTypeSignedInteger(dst.getFormat().type))
	{
		vector<IVec4> data(dst.getWidth()*dst.getHeight());

		glLog.glReadPixels(originX, originY, dst.getWidth(), dst.getHeight(), GL_RGBA_INTEGER, GL_INT, &data[0]);

		for (int y = 0; y < dst.getHeight(); y++)
		for (int x = 0; x < dst.getWidth(); x++)
			dst.setPixel(data[y*dst.getWidth() + x], x, y);
	}
	else
		DE_ASSERT(false);
}

//! Base for a functor for verifying and logging a 2d texture layer (2d image, cube face, 3d slice, 2d layer).
class ImageLayerVerifier
{
public:
	virtual bool	operator()				(TestLog&, const ConstPixelBufferAccess&, int sliceOrFaceNdx) const = 0;
	virtual			~ImageLayerVerifier		(void) {}
};

static void setTexParameteri (glu::CallLogWrapper& glLog, deUint32 target)
{
	if (target != GL_TEXTURE_BUFFER)
	{
		glLog.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glLog.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	}
}

//! Binds texture (one layer at a time) to color attachment of FBO and does glReadPixels(). Calls the verifier for each layer.
//! \note Not for buffer textures.
static bool readIntegerTextureViaFBOAndVerify (const RenderContext&			renderCtx,
											   glu::CallLogWrapper&			glLog,
											   deUint32						textureGL,
											   TextureType					textureType,
											   const TextureFormat&			textureFormat,
											   const IVec3&					textureSize,
											   const ImageLayerVerifier&	verifyLayer)
{
	DE_ASSERT(isFormatTypeInteger(textureFormat.type));
	DE_ASSERT(textureType != TEXTURETYPE_BUFFER);

	TestLog& log = glLog.getLog();

	const tcu::ScopedLogSection section(log, "Verification", "Result verification (bind texture layer-by-layer to FBO, read with glReadPixels())");

	const int			numSlicesOrFaces	= textureType == TEXTURETYPE_CUBE ? 6 : textureSize.z();
	const deUint32		textureTargetGL		= getGLTextureTarget(textureType);
	glu::Framebuffer	fbo					(renderCtx);
	tcu::TextureLevel	resultSlice			(textureFormat, textureSize.x(), textureSize.y());

	glLog.glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "Bind FBO");

	glLog.glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glMemoryBarrier");

	glLog.glActiveTexture(GL_TEXTURE0);
	glLog.glBindTexture(textureTargetGL, textureGL);
	setTexParameteri(glLog, textureTargetGL);

	for (int sliceOrFaceNdx = 0; sliceOrFaceNdx < numSlicesOrFaces; sliceOrFaceNdx++)
	{
		if (textureType == TEXTURETYPE_CUBE)
			glLog.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubeFaceToGLFace(glslImageFuncZToCubeFace(sliceOrFaceNdx)), textureGL, 0);
		else if (textureType == TEXTURETYPE_2D)
			glLog.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureGL, 0);
		else if (textureType == TEXTURETYPE_3D || textureType == TEXTURETYPE_2D_ARRAY)
			glLog.glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureGL, 0, sliceOrFaceNdx);
		else
			DE_ASSERT(false);

		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "Bind texture to framebuffer color attachment 0");

		TCU_CHECK(glLog.glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);

		readPixelsRGBAInteger32(resultSlice.getAccess(), 0, 0, glLog);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glReadPixels");

		if (!verifyLayer(log, resultSlice, sliceOrFaceNdx))
			return false;
	}

	return true;
}

//! Reads texture with texture() in compute shader, one layer at a time, putting values into a SSBO and reading with a mapping. Calls the verifier for each layer.
//! \note Not for buffer textures.
static bool readFloatOrNormTextureWithLookupsAndVerify (const RenderContext&		renderCtx,
														glu::CallLogWrapper&		glLog,
														deUint32					textureGL,
														TextureType					textureType,
														const TextureFormat&		textureFormat,
														const IVec3&				textureSize,
														const ImageLayerVerifier&	verifyLayer)
{
	DE_ASSERT(!isFormatTypeInteger(textureFormat.type));
	DE_ASSERT(textureType != TEXTURETYPE_BUFFER);

	TestLog& log = glLog.getLog();

	const tcu::ScopedLogSection section(log, "Verification", "Result verification (read texture layer-by-layer in compute shader with texture() into SSBO)");
	const std::string			glslVersionDeclaration = getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));

	const glu::ShaderProgram program(renderCtx,
		glu::ProgramSources() << glu::ComputeSource(glslVersionDeclaration + "\n"
													"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
													"layout (binding = 0) buffer Output\n"
													"{\n"
													"	vec4 color[" + toString(textureSize.x()*textureSize.y()) + "];\n"
													"} sb_out;\n"
													"\n"
													"precision highp " + getShaderSamplerType(textureFormat.type, textureType) + ";\n"
													"\n"
													"uniform highp " + getShaderSamplerType(textureFormat.type, textureType) + " u_texture;\n"
													"uniform highp vec3 u_texCoordLD;\n"
													"uniform highp vec3 u_texCoordRD;\n"
													"uniform highp vec3 u_texCoordLU;\n"
													"uniform highp vec3 u_texCoordRU;\n"
													"\n"
													"void main (void)\n"
													"{\n"
													"	int gx = int(gl_GlobalInvocationID.x);\n"
													"	int gy = int(gl_GlobalInvocationID.y);\n"
													"	highp float s = (float(gx) + 0.5) / float(" + toString(textureSize.x()) + ");\n"
													"	highp float t = (float(gy) + 0.5) / float(" + toString(textureType == TEXTURETYPE_CUBE ? textureSize.x() : textureSize.y()) + ");\n"
													"	highp vec3 texCoord = u_texCoordLD*(1.0-s)*(1.0-t)\n"
													"	                    + u_texCoordRD*(    s)*(1.0-t)\n"
													"	                    + u_texCoordLU*(1.0-s)*(    t)\n"
													"	                    + u_texCoordRU*(    s)*(    t);\n"
													"	int ndx = gy*" + toString(textureSize.x()) + " + gx;\n"
													"	sb_out.color[ndx] = texture(u_texture, texCoord" + (textureType == TEXTURETYPE_2D ? ".xy" : "") + ");\n"
													"}\n"));

	glLog.glUseProgram(program.getProgram());

	log << program;

	if (!program.isOk())
	{
		log << TestLog::Message << "// Failure: failed to compile program" << TestLog::EndMessage;
		TCU_FAIL("Program compilation failed");
	}

	{
		const deUint32			textureTargetGL		= getGLTextureTarget(textureType);
		const glu::Buffer		outputBuffer		(renderCtx);
		UniformAccessLogger		uniforms			(renderCtx.getFunctions(), log, program.getProgram());

		// Setup texture.

		glLog.glActiveTexture(GL_TEXTURE0);
		glLog.glBindTexture(textureTargetGL, textureGL);
		setTexParameteri(glLog, textureTargetGL);

		uniforms.assign1i("u_texture", 0);

		// Setup output buffer.
		{
			const deUint32		blockIndex		= glLog.glGetProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
			const int			blockSize		= glu::getProgramResourceInt(renderCtx.getFunctions(), program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex, GL_BUFFER_DATA_SIZE);

			log << TestLog::Message << "// Got buffer data size = " << blockSize << TestLog::EndMessage;
			TCU_CHECK(blockSize > 0);

			glLog.glBindBuffer(GL_SHADER_STORAGE_BUFFER, *outputBuffer);
			glLog.glBufferData(GL_SHADER_STORAGE_BUFFER, blockSize, DE_NULL, GL_STREAM_READ);
			glLog.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *outputBuffer);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "SSB setup failed");
		}

		// Dispatch one layer at a time, read back and verify.
		{
			const int							numSlicesOrFaces	= textureType == TEXTURETYPE_CUBE ? 6 : textureSize.z();
			tcu::TextureLevel					resultSlice			(textureFormat, textureSize.x(), textureSize.y());
			const PixelBufferAccess				resultSliceAccess	= resultSlice.getAccess();
			const deUint32						blockIndex			= glLog.glGetProgramResourceIndex(program.getProgram(), GL_SHADER_STORAGE_BLOCK, "Output");
			const int							blockSize			= glu::getProgramResourceInt(renderCtx.getFunctions(), program.getProgram(), GL_SHADER_STORAGE_BLOCK, blockIndex, GL_BUFFER_DATA_SIZE);
			const deUint32						valueIndex			= glLog.glGetProgramResourceIndex(program.getProgram(), GL_BUFFER_VARIABLE, "Output.color");
			const glu::InterfaceVariableInfo	valueInfo			= glu::getProgramInterfaceVariableInfo(renderCtx.getFunctions(), program.getProgram(), GL_BUFFER_VARIABLE, valueIndex);

			TCU_CHECK(valueInfo.arraySize == (deUint32)(textureSize.x()*textureSize.y()));

			glLog.glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);

			for (int sliceOrFaceNdx = 0; sliceOrFaceNdx < numSlicesOrFaces; sliceOrFaceNdx++)
			{
				if (textureType == TEXTURETYPE_CUBE)
				{
					vector<float> coords;
					computeQuadTexCoordCube(coords, glslImageFuncZToCubeFace(sliceOrFaceNdx));
					uniforms.assign3f("u_texCoordLD", coords[3*0 + 0], coords[3*0 + 1], coords[3*0 + 2]);
					uniforms.assign3f("u_texCoordRD", coords[3*2 + 0], coords[3*2 + 1], coords[3*2 + 2]);
					uniforms.assign3f("u_texCoordLU", coords[3*1 + 0], coords[3*1 + 1], coords[3*1 + 2]);
					uniforms.assign3f("u_texCoordRU", coords[3*3 + 0], coords[3*3 + 1], coords[3*3 + 2]);
				}
				else
				{
					const float z = textureType == TEXTURETYPE_3D ?
										((float)sliceOrFaceNdx + 0.5f) / (float)numSlicesOrFaces :
										(float)sliceOrFaceNdx;
					uniforms.assign3f("u_texCoordLD", 0.0f, 0.0f, z);
					uniforms.assign3f("u_texCoordRD", 1.0f, 0.0f, z);
					uniforms.assign3f("u_texCoordLU", 0.0f, 1.0f, z);
					uniforms.assign3f("u_texCoordRU", 1.0f, 1.0f, z);
				}

				glLog.glDispatchCompute(textureSize.x(), textureSize.y(), 1);

				{
					log << TestLog::Message << "// Note: mapping buffer and reading color values written" << TestLog::EndMessage;

					const BufferMemMap bufMap(renderCtx.getFunctions(), GL_SHADER_STORAGE_BUFFER, 0, blockSize, GL_MAP_READ_BIT);

					for (int y = 0; y < textureSize.y(); y++)
					for (int x = 0; x < textureSize.x(); x++)
					{
						const int				ndx			= y*textureSize.x() + x;
						const float* const		clrData		= (const float*)((const deUint8*)bufMap.getPtr() + valueInfo.offset + valueInfo.arrayStride*ndx);

						switch (textureFormat.order)
						{
							case TextureFormat::R:		resultSliceAccess.setPixel(Vec4(clrData[0]),											x, y); break;
							case TextureFormat::RGBA:	resultSliceAccess.setPixel(Vec4(clrData[0], clrData[1], clrData[2], clrData[3]),		x, y); break;
							default:
								DE_ASSERT(false);
						}
					}
				}

				if (!verifyLayer(log, resultSliceAccess, sliceOrFaceNdx))
					return false;
			}
		}

		return true;
	}
}

//! Read buffer texture by reading the corresponding buffer with a mapping.
static bool readBufferTextureWithMappingAndVerify (const RenderContext&			renderCtx,
												   glu::CallLogWrapper&			glLog,
												   deUint32						bufferGL,
												   const TextureFormat&			textureFormat,
												   int							imageSize,
												   const ImageLayerVerifier&	verifyLayer)
{
	tcu::TextureLevel			result			(textureFormat, imageSize, 1);
	const PixelBufferAccess		resultAccess	= result.getAccess();
	const int					dataSize		= imageSize * textureFormat.getPixelSize();

	const tcu::ScopedLogSection section(glLog.getLog(), "Verification", "Result verification (read texture's buffer with a mapping)");
	glLog.glBindBuffer(GL_TEXTURE_BUFFER, bufferGL);

	{
		const BufferMemMap bufMap(renderCtx.getFunctions(), GL_TEXTURE_BUFFER, 0, dataSize, GL_MAP_READ_BIT);
		deMemcpy(resultAccess.getDataPtr(), bufMap.getPtr(), dataSize);
	}

	return verifyLayer(glLog.getLog(), resultAccess, 0);
}

//! Calls the appropriate texture verification function depending on texture format or type.
static bool readTextureAndVerify (const RenderContext&			renderCtx,
								  glu::CallLogWrapper&			glLog,
								  deUint32						textureGL,
								  deUint32						bufferGL,
								  TextureType					textureType,
								  const TextureFormat&			textureFormat,
								  const IVec3&					imageSize,
								  const ImageLayerVerifier&		verifyLayer)
{
	if (textureType == TEXTURETYPE_BUFFER)
		return readBufferTextureWithMappingAndVerify(renderCtx, glLog, bufferGL, textureFormat, imageSize.x(), verifyLayer);
	else
		return isFormatTypeInteger(textureFormat.type) ? readIntegerTextureViaFBOAndVerify				(renderCtx, glLog, textureGL, textureType, textureFormat, imageSize, verifyLayer)
													   : readFloatOrNormTextureWithLookupsAndVerify		(renderCtx, glLog, textureGL, textureType, textureFormat, imageSize, verifyLayer);
}

//! An ImageLayerVerifier that simply compares the result slice to a slice in a reference image.
//! \note Holds the reference image as a reference (no pun intended) instead of a copy; caller must be aware of lifetime issues.
class ImageLayerComparer : public ImageLayerVerifier
{
public:
	ImageLayerComparer (const LayeredImage& reference,
						const IVec2& relevantRegion = IVec2(0) /* If given, only check this region of each slice. */)
		: m_reference		(reference)
		, m_relevantRegion	(relevantRegion.x() > 0 && relevantRegion.y() > 0 ? relevantRegion : reference.getSize().swizzle(0, 1))
	{
	}

	bool operator() (TestLog& log, const tcu::ConstPixelBufferAccess& resultSlice, int sliceOrFaceNdx) const
	{
		const bool						isCube				= m_reference.getImageType() == TEXTURETYPE_CUBE;
		const ConstPixelBufferAccess	referenceSlice		= tcu::getSubregion(isCube ? m_reference.getCubeFaceAccess(glslImageFuncZToCubeFace(sliceOrFaceNdx))
																					   : m_reference.getSliceAccess(sliceOrFaceNdx),
																				0, 0, m_relevantRegion.x(), m_relevantRegion.y());

		const string comparisonName = "Comparison" + toString(sliceOrFaceNdx);
		const string comparisonDesc = "Image Comparison, "
									+ (isCube ? "face " + string(glu::getCubeMapFaceName(cubeFaceToGLFace(glslImageFuncZToCubeFace(sliceOrFaceNdx))))
											  : "slice " + toString(sliceOrFaceNdx));

		if (isFormatTypeInteger(m_reference.getFormat().type))
			return tcu::intThresholdCompare(log, comparisonName.c_str(), comparisonDesc.c_str(), referenceSlice, resultSlice, UVec4(0), tcu::COMPARE_LOG_RESULT);
		else
			return tcu::floatThresholdCompare(log, comparisonName.c_str(), comparisonDesc.c_str(), referenceSlice, resultSlice, Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
	}

private:
	const LayeredImage&		m_reference;
	const IVec2				m_relevantRegion;
};

//! Case that just stores some computation results into an image.
class ImageStoreCase : public TestCase
{
public:
	enum CaseFlag
	{
		CASEFLAG_SINGLE_LAYER_BIND = 1 << 0 //!< If given, glBindImageTexture() is called with GL_FALSE <layered> argument, and for each layer the compute shader is separately dispatched.
	};

	ImageStoreCase (Context& context, const char* name, const char* description, const TextureFormat& format, TextureType textureType, deUint32 caseFlags = 0)
		: TestCase				(context, name, description)
		, m_format				(format)
		, m_textureType			(textureType)
		, m_singleLayerBind		((caseFlags & CASEFLAG_SINGLE_LAYER_BIND) != 0)
	{
	}

	void			init		(void) { checkTextureTypeExtensions(m_context.getContextInfo(), m_textureType, m_context.getRenderContext()); }
	IterateResult	iterate		(void);

private:
	const TextureFormat		m_format;
	const TextureType		m_textureType;
	const bool				m_singleLayerBind;
};

ImageStoreCase::IterateResult ImageStoreCase::iterate (void)
{
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	TestLog&					log						(m_testCtx.getLog());
	glu::CallLogWrapper			glLog					(renderCtx.getFunctions(), log);
	const deUint32				internalFormatGL		= glu::getInternalFormat(m_format);
	const deUint32				textureTargetGL			= getGLTextureTarget(m_textureType);
	const IVec3&				imageSize				= defaultImageSize(m_textureType);
	const int					numSlicesOrFaces		= m_textureType == TEXTURETYPE_CUBE ? 6 : imageSize.z();
	const int					maxImageDimension		= de::max(imageSize.x(), de::max(imageSize.y(), imageSize.z()));
	const float					storeColorScale			= isFormatTypeUnorm(m_format.type) ? 1.0f / (float)(maxImageDimension - 1)
														: isFormatTypeSnorm(m_format.type) ? 2.0f / (float)(maxImageDimension - 1)
														: 1.0f;
	const float					storeColorBias			= isFormatTypeSnorm(m_format.type) ? -1.0f : 0.0f;
	const glu::Buffer			textureBuf				(renderCtx); // \note Only really used if using buffer texture.
	const glu::Texture			texture					(renderCtx);

	glLog.enableLogging(true);

	// Setup texture.

	log << TestLog::Message << "// Created a texture (name " << *texture << ")" << TestLog::EndMessage;
	if (m_textureType == TEXTURETYPE_BUFFER)
		log << TestLog::Message << "// Created a buffer for the texture (name " << *textureBuf << ")" << TestLog::EndMessage;

	glLog.glActiveTexture(GL_TEXTURE0);
	glLog.glBindTexture(textureTargetGL, *texture);
	setTexParameteri(glLog, textureTargetGL);
	setTextureStorage(glLog, m_textureType, internalFormatGL, imageSize, *textureBuf);

	// Perform image stores in compute shader.

	{
		// Generate compute shader.

		const string		shaderImageFormatStr	= getShaderImageFormatQualifier(m_format);
		const TextureType	shaderImageType			= m_singleLayerBind ? textureLayerType(m_textureType) : m_textureType;
		const string		shaderImageTypeStr		= getShaderImageType(m_format.type, shaderImageType);
		const bool			isUintFormat			= isFormatTypeUnsignedInteger(m_format.type);
		const bool			isIntFormat				= isFormatTypeSignedInteger(m_format.type);
		const string		colorBaseExpr			= string(isUintFormat ? "u" : isIntFormat ? "i" : "") + "vec4(gx^gy^gz, "
																												 "(" + toString(imageSize.x()-1) + "-gx)^gy^gz, "
																												 "gx^(" + toString(imageSize.y()-1) + "-gy)^gz, "
																												 "(" + toString(imageSize.x()-1) + "-gx)^(" + toString(imageSize.y()-1) + "-gy)^gz)";
		const string		colorExpr				= colorBaseExpr + (storeColorScale == 1.0f ? "" : "*" + toString(storeColorScale))
																	+ (storeColorBias == 0.0f ? "" : " + float(" + toString(storeColorBias) + ")");
		const std::string	glslVersionDeclaration	= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));

		const glu::ShaderProgram program(renderCtx,
			glu::ProgramSources() << glu::ComputeSource(glslVersionDeclaration + "\n"
														+ textureTypeExtensionShaderRequires(shaderImageType, renderCtx) +
														"\n"
														"precision highp " + shaderImageTypeStr + ";\n"
														"\n"
														"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
														"layout (" + shaderImageFormatStr + ", binding=0) writeonly uniform " + shaderImageTypeStr + " u_image;\n"
														+ (m_singleLayerBind ? "uniform int u_layerNdx;\n" : "") +
														"\n"
														"void main (void)\n"
														"{\n"
														"	int gx = int(gl_GlobalInvocationID.x);\n"
														"	int gy = int(gl_GlobalInvocationID.y);\n"
														"	int gz = " + (m_singleLayerBind ? "u_layerNdx" : "int(gl_GlobalInvocationID.z)") + ";\n"
														+ (shaderImageType == TEXTURETYPE_BUFFER ?
															"	imageStore(u_image, gx, " + colorExpr + ");\n"
														 : shaderImageType == TEXTURETYPE_2D ?
															"	imageStore(u_image, ivec2(gx, gy), " + colorExpr + ");\n"
														 : shaderImageType == TEXTURETYPE_3D || shaderImageType == TEXTURETYPE_CUBE || shaderImageType == TEXTURETYPE_2D_ARRAY ?
															"	imageStore(u_image, ivec3(gx, gy, gz), " + colorExpr + ");\n"
														 : deFatalStr("Invalid TextureType")) +
														"}\n"));

		UniformAccessLogger uniforms(renderCtx.getFunctions(), log, program.getProgram());

		log << program;

		if (!program.isOk())
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program compilation failed");
			return STOP;
		}

		// Setup and dispatch.

		glLog.glUseProgram(program.getProgram());

		if (m_singleLayerBind)
		{
			for (int layerNdx = 0; layerNdx < numSlicesOrFaces; layerNdx++)
			{
				if (layerNdx > 0)
					glLog.glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

				uniforms.assign1i("u_layerNdx", layerNdx);

				glLog.glBindImageTexture(0, *texture, 0, GL_FALSE, layerNdx, GL_WRITE_ONLY, internalFormatGL);
				GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

				glLog.glDispatchCompute(imageSize.x(), imageSize.y(), 1);
				GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
			}
		}
		else
		{
			glLog.glBindImageTexture(0, *texture, 0, GL_TRUE, 0, GL_WRITE_ONLY, internalFormatGL);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

			glLog.glDispatchCompute(imageSize.x(), imageSize.y(), numSlicesOrFaces);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
		}
	}

	// Create reference, read texture and compare to reference.
	{
		const int		isIntegerFormat		= isFormatTypeInteger(m_format.type);
		LayeredImage	reference			(m_textureType, m_format, imageSize.x(), imageSize.y(), imageSize.z());

		DE_ASSERT(!isIntegerFormat || (storeColorScale == 1.0f && storeColorBias == 0.0f));

		for (int z = 0; z < numSlicesOrFaces; z++)
		for (int y = 0; y < imageSize.y(); y++)
		for (int x = 0; x < imageSize.x(); x++)
		{
			const IVec4 color(x^y^z, (imageSize.x()-1-x)^y^z, x^(imageSize.y()-1-y)^z, (imageSize.x()-1-x)^(imageSize.y()-1-y)^z);

			if (isIntegerFormat)
				reference.setPixel(x, y, z, color);
			else
				reference.setPixel(x, y, z, color.asFloat()*storeColorScale + storeColorBias);
		}

		const bool compareOk = readTextureAndVerify(renderCtx, glLog, *texture, *textureBuf, m_textureType, m_format, imageSize, ImageLayerComparer(reference));

		m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, compareOk ? "Pass" : "Image comparison failed");
		return STOP;
	}
}

//! Case that copies an image to another, using imageLoad() and imageStore(). Texture formats don't necessarily match image formats.
class ImageLoadAndStoreCase : public TestCase
{
public:
	enum CaseFlag
	{
		CASEFLAG_SINGLE_LAYER_BIND	= 1 << 0,	//!< If given, glBindImageTexture() is called with GL_FALSE <layered> argument, and for each layer the compute shader is separately dispatched.
		CASEFLAG_RESTRICT_IMAGES	= 1 << 1	//!< If given, images in shader will be qualified with "restrict".
	};

	ImageLoadAndStoreCase (Context& context, const char* name, const char* description, const TextureFormat& format, TextureType textureType, deUint32 caseFlags = 0)
		: TestCase				(context, name, description)
		, m_textureFormat		(format)
		, m_imageFormat			(format)
		, m_textureType			(textureType)
		, m_restrictImages		((caseFlags & CASEFLAG_RESTRICT_IMAGES)		!= 0)
		, m_singleLayerBind		((caseFlags & CASEFLAG_SINGLE_LAYER_BIND)	!= 0)
	{
	}

	ImageLoadAndStoreCase (Context& context, const char* name, const char* description, const TextureFormat& textureFormat, const TextureFormat& imageFormat, TextureType textureType, deUint32 caseFlags = 0)
		: TestCase				(context, name, description)
		, m_textureFormat		(textureFormat)
		, m_imageFormat			(imageFormat)
		, m_textureType			(textureType)
		, m_restrictImages		((caseFlags & CASEFLAG_RESTRICT_IMAGES)		!= 0)
		, m_singleLayerBind		((caseFlags & CASEFLAG_SINGLE_LAYER_BIND)	!= 0)
	{
		DE_ASSERT(textureFormat.getPixelSize() == imageFormat.getPixelSize());
	}

	void			init		(void) { checkTextureTypeExtensions(m_context.getContextInfo(), m_textureType, m_context.getRenderContext()); }
	IterateResult	iterate		(void);

private:
	template <TextureFormat::ChannelType ImageFormatType, typename TcuFloatType, typename TcuFloatStorageType>
	static void					replaceBadFloatReinterpretValues (LayeredImage& image, const TextureFormat& imageFormat);

	const TextureFormat			m_textureFormat;
	const TextureFormat			m_imageFormat;
	const TextureType			m_textureType;
	const bool					m_restrictImages;
	const bool					m_singleLayerBind;
};

template <TextureFormat::ChannelType ImageFormatType, typename TcuFloatType, typename TcuFloatTypeStorageType>
void ImageLoadAndStoreCase::replaceBadFloatReinterpretValues (LayeredImage& image, const TextureFormat& imageFormat)
{
	// Find potential bad values, such as nan or inf, and replace with something else.
	const int		pixelSize			= imageFormat.getPixelSize();
	const int		imageNumChannels	= imageFormat.order == tcu::TextureFormat::R	? 1
										: imageFormat.order == tcu::TextureFormat::RGBA	? 4
										: 0;
	const IVec3		imageSize			= image.getSize();
	const int		numSlicesOrFaces	= image.getImageType() == TEXTURETYPE_CUBE ? 6 : imageSize.z();

	DE_ASSERT(pixelSize % imageNumChannels == 0);

	for (int z = 0; z < numSlicesOrFaces; z++)
	{
		const PixelBufferAccess		sliceAccess		= image.getImageType() == TEXTURETYPE_CUBE ? image.getCubeFaceAccess((tcu::CubeFace)z) : image.getSliceAccess(z);
		const int					rowPitch		= sliceAccess.getRowPitch();
		void *const					data			= sliceAccess.getDataPtr();

		for (int y = 0; y < imageSize.y(); y++)
		for (int x = 0; x < imageSize.x(); x++)
		{
			void *const pixelData = (deUint8*)data + y*rowPitch + x*pixelSize;

			for (int c = 0; c < imageNumChannels; c++)
			{
				void *const			channelData		= (deUint8*)pixelData + c*pixelSize/imageNumChannels;
				const TcuFloatType	f				(*(TcuFloatTypeStorageType*)channelData);

				if (f.isDenorm() || f.isInf() || f.isNaN())
					*(TcuFloatTypeStorageType*)channelData = TcuFloatType(0.0f).bits();
			}
		}
	}
}

ImageLoadAndStoreCase::IterateResult ImageLoadAndStoreCase::iterate (void)
{
	const RenderContext&		renderCtx					= m_context.getRenderContext();
	TestLog&					log							(m_testCtx.getLog());
	glu::CallLogWrapper			glLog						(renderCtx.getFunctions(), log);
	const deUint32				textureInternalFormatGL		= glu::getInternalFormat(m_textureFormat);
	const deUint32				imageInternalFormatGL		= glu::getInternalFormat(m_imageFormat);
	const deUint32				textureTargetGL				= getGLTextureTarget(m_textureType);
	const IVec3&				imageSize					= defaultImageSize(m_textureType);
	const int					maxImageDimension			= de::max(imageSize.x(), de::max(imageSize.y(), imageSize.z()));
	const float					storeColorScale				= isFormatTypeUnorm(m_textureFormat.type) ? 1.0f / (float)(maxImageDimension - 1)
															: isFormatTypeSnorm(m_textureFormat.type) ? 2.0f / (float)(maxImageDimension - 1)
															: 1.0f;
	const float					storeColorBias				= isFormatTypeSnorm(m_textureFormat.type) ? -1.0f : 0.0f;
	const int					numSlicesOrFaces			= m_textureType == TEXTURETYPE_CUBE ? 6 : imageSize.z();
	const bool					isIntegerTextureFormat		= isFormatTypeInteger(m_textureFormat.type);
	const glu::Buffer			texture0Buf					(renderCtx);
	const glu::Buffer			texture1Buf					(renderCtx);
	const glu::Texture			texture0					(renderCtx);
	const glu::Texture			texture1					(renderCtx);
	LayeredImage				reference					(m_textureType, m_textureFormat, imageSize.x(), imageSize.y(), imageSize.z());

	glLog.enableLogging(true);

	// Setup textures.

	log << TestLog::Message << "// Created 2 textures (names " << *texture0 << " and " << *texture1 << ")" << TestLog::EndMessage;
	if (m_textureType == TEXTURETYPE_BUFFER)
		log << TestLog::Message << "// Created buffers for the textures (names " << *texture0Buf << " and " << *texture1Buf << ")" << TestLog::EndMessage;

	// First, fill reference with (a fairly arbitrary) initial pattern. This will be used as texture upload source data as well as for actual reference computation later on.

	DE_ASSERT(!isIntegerTextureFormat || (storeColorScale == 1.0f && storeColorBias == 0.0f));

	for (int z = 0; z < numSlicesOrFaces; z++)
	for (int y = 0; y < imageSize.y(); y++)
	for (int x = 0; x < imageSize.x(); x++)
	{
		const IVec4 color(x^y^z, (imageSize.x()-1-x)^y^z, x^(imageSize.y()-1-y)^z, (imageSize.x()-1-x)^(imageSize.y()-1-y)^z);

		if (isIntegerTextureFormat)
			reference.setPixel(x, y, z, color);
		else
			reference.setPixel(x, y, z, color.asFloat()*storeColorScale + storeColorBias);
	}

	// If re-interpreting the texture contents as floating point values, need to get rid of inf, nan etc.
	if (m_imageFormat.type == TextureFormat::HALF_FLOAT && m_textureFormat.type != TextureFormat::HALF_FLOAT)
		replaceBadFloatReinterpretValues<TextureFormat::HALF_FLOAT, tcu::Float16, deUint16>(reference, m_imageFormat);
	else if (m_imageFormat.type == TextureFormat::FLOAT && m_textureFormat.type != TextureFormat::FLOAT)
		replaceBadFloatReinterpretValues<TextureFormat::FLOAT, tcu::Float32, deUint32>(reference, m_imageFormat);

	// Upload initial pattern to texture 0.

	glLog.glActiveTexture(GL_TEXTURE0);
	glLog.glBindTexture(textureTargetGL, *texture0);
	setTexParameteri(glLog, textureTargetGL);

	log << TestLog::Message << "// Filling texture " << *texture0 << " with xor pattern" << TestLog::EndMessage;

	uploadTexture(glLog, reference, *texture0Buf);

	// Set storage for texture 1.

	glLog.glActiveTexture(GL_TEXTURE1);
	glLog.glBindTexture(textureTargetGL, *texture1);
	setTexParameteri(glLog, textureTargetGL);
	setTextureStorage(glLog, m_textureType, textureInternalFormatGL, imageSize, *texture1Buf);

	// Perform image loads and stores in compute shader and finalize reference computation.

	{
		// Generate compute shader.

		const char* const		maybeRestrict			= m_restrictImages ? "restrict" : "";
		const string			shaderImageFormatStr	= getShaderImageFormatQualifier(m_imageFormat);
		const TextureType		shaderImageType			= m_singleLayerBind ? textureLayerType(m_textureType) : m_textureType;
		const string			shaderImageTypeStr		= getShaderImageType(m_imageFormat.type, shaderImageType);
		const std::string		glslVersionDeclaration	= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));

		const glu::ShaderProgram program(renderCtx,
			glu::ProgramSources() << glu::ComputeSource(glslVersionDeclaration + "\n"
														+ textureTypeExtensionShaderRequires(shaderImageType, renderCtx) +
														"\n"
														"precision highp " + shaderImageTypeStr + ";\n"
														"\n"
														"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
														"layout (" + shaderImageFormatStr + ", binding=0) " + maybeRestrict + " readonly uniform " + shaderImageTypeStr + " u_image0;\n"
														"layout (" + shaderImageFormatStr + ", binding=1) " + maybeRestrict + " writeonly uniform " + shaderImageTypeStr + " u_image1;\n"
														"\n"
														"void main (void)\n"
														"{\n"
														+ (shaderImageType == TEXTURETYPE_BUFFER ?
															"	int pos = int(gl_GlobalInvocationID.x);\n"
															"	imageStore(u_image1, pos, imageLoad(u_image0, " + toString(imageSize.x()-1) + "-pos));\n"
														 : shaderImageType == TEXTURETYPE_2D ?
															"	ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n"
															"	imageStore(u_image1, pos, imageLoad(u_image0, ivec2(" + toString(imageSize.x()-1) + "-pos.x, pos.y)));\n"
														 : shaderImageType == TEXTURETYPE_3D || shaderImageType == TEXTURETYPE_CUBE || shaderImageType == TEXTURETYPE_2D_ARRAY ?
															"	ivec3 pos = ivec3(gl_GlobalInvocationID);\n"
															"	imageStore(u_image1, pos, imageLoad(u_image0, ivec3(" + toString(imageSize.x()-1) + "-pos.x, pos.y, pos.z)));\n"
														 : deFatalStr("Invalid TextureType")) +
														"}\n"));

		UniformAccessLogger uniforms(renderCtx.getFunctions(), log, program.getProgram());

		log << program;

		if (!program.isOk())
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program compilation failed");
			return STOP;
		}

		// Setup and dispatch.

		glLog.glUseProgram(program.getProgram());

		if (m_singleLayerBind)
		{
			for (int layerNdx = 0; layerNdx < numSlicesOrFaces; layerNdx++)
			{
				if (layerNdx > 0)
					glLog.glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

				glLog.glBindImageTexture(0, *texture0, 0, GL_FALSE, layerNdx, GL_READ_ONLY, imageInternalFormatGL);
				GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

				glLog.glBindImageTexture(1, *texture1, 0, GL_FALSE, layerNdx, GL_WRITE_ONLY, imageInternalFormatGL);
				GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

				glLog.glDispatchCompute(imageSize.x(), imageSize.y(), 1);
				GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
			}
		}
		else
		{
			glLog.glBindImageTexture(0, *texture0, 0, GL_TRUE, 0, GL_READ_ONLY, imageInternalFormatGL);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

			glLog.glBindImageTexture(1, *texture1, 0, GL_TRUE, 0, GL_WRITE_ONLY, imageInternalFormatGL);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

			glLog.glDispatchCompute(imageSize.x(), imageSize.y(), numSlicesOrFaces);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
		}

		// Finalize reference.

		if (m_textureFormat != m_imageFormat)
		{
			// Format re-interpretation case. Read data with image format and write back, with the same image format.
			// We do this because the data may change a little during lookups (e.g. unorm8 -> float; not all unorms can be exactly represented as floats).

			const int					pixelSize		= m_imageFormat.getPixelSize();
			tcu::TextureLevel			scratch			(m_imageFormat, 1, 1);
			const PixelBufferAccess		scratchAccess	= scratch.getAccess();

			for (int z = 0; z < numSlicesOrFaces; z++)
			{
				const PixelBufferAccess		sliceAccess		= m_textureType == TEXTURETYPE_CUBE ? reference.getCubeFaceAccess((tcu::CubeFace)z) : reference.getSliceAccess(z);
				const int					rowPitch		= sliceAccess.getRowPitch();
				void *const					data			= sliceAccess.getDataPtr();

				for (int y = 0; y < imageSize.y(); y++)
				for (int x = 0; x < imageSize.x(); x++)
				{
					void *const pixelData = (deUint8*)data + y*rowPitch + x*pixelSize;

					deMemcpy(scratchAccess.getDataPtr(), pixelData, pixelSize);

					if (isFormatTypeInteger(m_imageFormat.type))
						scratchAccess.setPixel(scratchAccess.getPixelUint(0, 0), 0, 0);
					else
						scratchAccess.setPixel(scratchAccess.getPixel(0, 0), 0, 0);

					deMemcpy(pixelData, scratchAccess.getDataPtr(), pixelSize);
				}
			}
		}

		for (int z = 0; z < numSlicesOrFaces; z++)
		for (int y = 0; y < imageSize.y(); y++)
		for (int x = 0; x < imageSize.x()/2; x++)
		{
			if (isIntegerTextureFormat)
			{
				const UVec4 temp = reference.getPixelUint(imageSize.x()-1-x, y, z);
				reference.setPixel(imageSize.x()-1-x, y, z, reference.getPixelUint(x, y, z));
				reference.setPixel(x, y, z, temp);
			}
			else
			{
				const Vec4 temp = reference.getPixel(imageSize.x()-1-x, y, z);
				reference.setPixel(imageSize.x()-1-x, y, z, reference.getPixel(x, y, z));
				reference.setPixel(x, y, z, temp);
			}
		}
	}

	// Read texture 1 and compare to reference.

	const bool compareOk = readTextureAndVerify(renderCtx, glLog, *texture1, *texture1Buf, m_textureType, m_textureFormat, imageSize, ImageLayerComparer(reference));

	m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, compareOk ? "Pass" : "Image comparison failed");
	return STOP;
}

enum AtomicOperationCaseType
{
	ATOMIC_OPERATION_CASE_TYPE_END_RESULT = 0,	//!< Atomic case checks the end result of the operations, and not the return values.
	ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES,	//!< Atomic case checks the return values of the atomic function, and not the end result.

	ATOMIC_OPERATION_CASE_TYPE_LAST
};

/*--------------------------------------------------------------------*//*!
 * \brief Binary atomic operation case.
 *
 * Case that performs binary atomic operations (i.e. any but compSwap) and
 * verifies according to the given AtomicOperationCaseType.
 *
 * For the "end result" case type, a single texture (and image) is created,
 * upon which the atomic operations operate. A compute shader is dispatched
 * with dimensions equal to the image size, except with a bigger X size
 * so that every pixel is operated on by multiple invocations. The end
 * results are verified in BinaryAtomicOperationCase::EndResultVerifier.
 * The return values of the atomic function calls are ignored.
 *
 * For the "return value" case type, the case does much the same operations
 * as in the "end result" case, but also creates an additional texture,
 * of size equal to the dispatch size, into which the return values of the
 * atomic functions are stored (with imageStore()). The return values are
 * verified in BinaryAtomicOperationCase::ReturnValueVerifier.
 * The end result values are not checked.
 *
 * The compute shader invocations contributing to a pixel (X, Y, Z) in the
 * end result image are the invocations with global IDs
 * (X, Y, Z), (X+W, Y, Z), (X+2*W, Y, Z), ..., (X+(N-1)*W, Y, W), where W
 * is the width of the end result image and N is
 * BinaryAtomicOperationCase::NUM_INVOCATIONS_PER_PIXEL.
 *//*--------------------------------------------------------------------*/
class BinaryAtomicOperationCase : public TestCase
{
public:
									BinaryAtomicOperationCase		(Context& context, const char* name, const char* description, const TextureFormat& format, TextureType imageType, AtomicOperation operation, AtomicOperationCaseType caseType)
		: TestCase		(context, name, description)
		, m_format		(format)
		, m_imageType	(imageType)
		, m_operation	(operation)
		, m_caseType	(caseType)
	{
		DE_ASSERT(m_format == TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32)	||
				  m_format == TextureFormat(TextureFormat::R, TextureFormat::SIGNED_INT32)		||
				  (m_format == TextureFormat(TextureFormat::R, TextureFormat::FLOAT) && m_operation == ATOMIC_OPERATION_EXCHANGE));

		DE_ASSERT(m_operation != ATOMIC_OPERATION_COMP_SWAP);
	}

	void							init							(void);
	IterateResult					iterate							(void);

private:
	class EndResultVerifier;
	class ReturnValueVerifier;

	static int						getOperationInitialValue		(AtomicOperation op); //!< Appropriate value with which to initialize the texture.
	//! Compute the argument given to the atomic function at the given invocation ID, when the entire dispatch has the given width and height.
	static int						getAtomicFuncArgument			(AtomicOperation op, const IVec3& invocationID, const IVec2& dispatchSizeXY);
	//! Generate the shader expression for the argument given to the atomic function. x, y and z are the identifiers for the invocation ID components.
	static string					getAtomicFuncArgumentShaderStr	(AtomicOperation op, const string& x, const string& y, const string& z, const IVec2& dispatchSizeXY);

	static const int				NUM_INVOCATIONS_PER_PIXEL = 5;

	const TextureFormat				m_format;
	const TextureType				m_imageType;
	const AtomicOperation			m_operation;
	const AtomicOperationCaseType	m_caseType;
};

int BinaryAtomicOperationCase::getOperationInitialValue (AtomicOperation op)
{
	switch (op)
	{
		// \note 18 is just an arbitrary small nonzero value.
		case ATOMIC_OPERATION_ADD:			return 18;
		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;
		default:
			DE_ASSERT(false);
			return -1;
	}
}

int BinaryAtomicOperationCase::getAtomicFuncArgument (AtomicOperation op, const IVec3& invocationID, const IVec2& dispatchSizeXY)
{
	const int x		= invocationID.x();
	const int y		= invocationID.y();
	const int z		= invocationID.z();
	const int wid	= dispatchSizeXY.x();
	const int hei	= dispatchSizeXY.y();

	switch (op)
	{
		// \note Fall-throughs.
		case ATOMIC_OPERATION_ADD:
		case ATOMIC_OPERATION_MIN:
		case ATOMIC_OPERATION_MAX:
		case ATOMIC_OPERATION_AND:
		case ATOMIC_OPERATION_OR:
		case ATOMIC_OPERATION_XOR:
			return x*x + y*y + z*z;

		case ATOMIC_OPERATION_EXCHANGE:
			return (z*wid + x)*hei + y;

		default:
			DE_ASSERT(false);
			return -1;
	}
}

string BinaryAtomicOperationCase::getAtomicFuncArgumentShaderStr (AtomicOperation op, const string& x, const string& y, const string& z, const IVec2& dispatchSizeXY)
{
	switch (op)
	{
		// \note Fall-throughs.
		case ATOMIC_OPERATION_ADD:
		case ATOMIC_OPERATION_MIN:
		case ATOMIC_OPERATION_MAX:
		case ATOMIC_OPERATION_AND:
		case ATOMIC_OPERATION_OR:
		case ATOMIC_OPERATION_XOR:
			return "("+ x+"*"+x +" + "+ y+"*"+y +" + "+ z+"*"+z +")";

		case ATOMIC_OPERATION_EXCHANGE:
			return "((" + z + "*" + toString(dispatchSizeXY.x()) + " + " + x + ")*" + toString(dispatchSizeXY.y()) + " + " + y + ")";

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

class BinaryAtomicOperationCase::EndResultVerifier : public ImageLayerVerifier
{
public:
	EndResultVerifier (AtomicOperation operation, TextureType imageType) : m_operation(operation), m_imageType(imageType) {}

	bool operator() (TestLog& log, const ConstPixelBufferAccess& resultSlice, int sliceOrFaceNdx) const
	{
		const bool		isIntegerFormat		= isFormatTypeInteger(resultSlice.getFormat().type);
		const IVec2		dispatchSizeXY		(NUM_INVOCATIONS_PER_PIXEL*resultSlice.getWidth(), resultSlice.getHeight());

		log << TestLog::Image("EndResults" + toString(sliceOrFaceNdx),
							  "Result Values, " + (m_imageType == TEXTURETYPE_CUBE ? "face " + string(glu::getCubeMapFaceName(cubeFaceToGLFace(glslImageFuncZToCubeFace(sliceOrFaceNdx))))
																				   : "slice " + toString(sliceOrFaceNdx)),
							  resultSlice);

		for (int y = 0; y < resultSlice.getHeight(); y++)
		for (int x = 0; x < resultSlice.getWidth(); x++)
		{
			union
			{
				int		i;
				float	f;
			} result;

			if (isIntegerFormat)
				result.i = resultSlice.getPixelInt(x, y).x();
			else
				result.f = resultSlice.getPixel(x, y).x();

			// Compute the arguments that were given to the atomic function in the invocations that contribute to this pixel.

			IVec3	invocationGlobalIDs[NUM_INVOCATIONS_PER_PIXEL];
			int		atomicArgs[NUM_INVOCATIONS_PER_PIXEL];

			for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL; i++)
			{
				const IVec3 gid(x + i*resultSlice.getWidth(), y, sliceOrFaceNdx);

				invocationGlobalIDs[i]	= gid;
				atomicArgs[i]			= getAtomicFuncArgument(m_operation, gid, dispatchSizeXY);
			}

			if (isOrderIndependentAtomicOperation(m_operation))
			{
				// Just accumulate the atomic args (and the initial value) according to the operation, and compare.

				DE_ASSERT(isIntegerFormat);

				int reference = getOperationInitialValue(m_operation);

				for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL; i++)
					reference = computeBinaryAtomicOperationResult(m_operation, reference, atomicArgs[i]);

				if (result.i != reference)
				{
					log << TestLog::Message << "// Failure: end result at pixel " << IVec2(x, y) << " of current layer is " << result.i << TestLog::EndMessage
						<< TestLog::Message << "// Note: relevant shader invocation global IDs are " << arrayStr(invocationGlobalIDs) << TestLog::EndMessage
						<< TestLog::Message << "// Note: data expression values for the IDs are " << arrayStr(atomicArgs) << TestLog::EndMessage
						<< TestLog::Message << "// Note: reference value is " << reference << TestLog::EndMessage;
					return false;
				}
			}
			else if (m_operation == ATOMIC_OPERATION_EXCHANGE)
			{
				// Check that the end result equals one of the atomic args.

				bool matchFound = false;

				for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL && !matchFound; i++)
					matchFound = isIntegerFormat ? result.i == atomicArgs[i]
												 : de::abs(result.f - (float)atomicArgs[i]) <= 0.01f;

				if (!matchFound)
				{
					log << TestLog::Message << "// Failure: invalid value at pixel " << IVec2(x, y) << ": got " << (isIntegerFormat ? toString(result.i) : toString(result.f)) << TestLog::EndMessage
											<< TestLog::Message << "// Note: expected one of " << arrayStr(atomicArgs) << TestLog::EndMessage;

					return false;
				}
			}
			else
				DE_ASSERT(false);
		}

		return true;
	}

private:
	const AtomicOperation	m_operation;
	const TextureType		m_imageType;
};

class BinaryAtomicOperationCase::ReturnValueVerifier : public ImageLayerVerifier
{
public:
	//! \note endResultImageLayerSize is (width, height) of the image operated on by the atomic ops, and not the size of the image where the return values are stored.
	ReturnValueVerifier (AtomicOperation operation, TextureType imageType, const IVec2& endResultImageLayerSize) : m_operation(operation), m_imageType(imageType), m_endResultImageLayerSize(endResultImageLayerSize) {}

	bool operator() (TestLog& log, const ConstPixelBufferAccess& resultSlice, int sliceOrFaceNdx) const
	{
		const bool		isIntegerFormat		(isFormatTypeInteger(resultSlice.getFormat().type));
		const IVec2		dispatchSizeXY	(resultSlice.getWidth(), resultSlice.getHeight());

		DE_ASSERT(resultSlice.getWidth()	== NUM_INVOCATIONS_PER_PIXEL*m_endResultImageLayerSize.x()	&&
				  resultSlice.getHeight()	== m_endResultImageLayerSize.y()							&&
				  resultSlice.getDepth()	== 1);

		log << TestLog::Image("ReturnValues" + toString(sliceOrFaceNdx),
							  "Per-Invocation Return Values, "
								   + (m_imageType == TEXTURETYPE_CUBE ? "face " + string(glu::getCubeMapFaceName(cubeFaceToGLFace(glslImageFuncZToCubeFace(sliceOrFaceNdx))))
																	  : "slice " + toString(sliceOrFaceNdx)),
							  resultSlice);

		for (int y = 0; y < m_endResultImageLayerSize.y(); y++)
		for (int x = 0; x < m_endResultImageLayerSize.x(); x++)
		{
			union IntFloatArr
			{
				int		i[NUM_INVOCATIONS_PER_PIXEL];
				float	f[NUM_INVOCATIONS_PER_PIXEL];
			};

			// Get the atomic function args and return values for all the invocations that contribute to the pixel (x, y) in the current end result slice.

			IntFloatArr		returnValues;
			IntFloatArr		atomicArgs;
			IVec3			invocationGlobalIDs[NUM_INVOCATIONS_PER_PIXEL];
			IVec2			pixelCoords[NUM_INVOCATIONS_PER_PIXEL];

			for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL; i++)
			{
				const IVec2 pixCoord	(x + i*m_endResultImageLayerSize.x(), y);
				const IVec3 gid			(pixCoord.x(), pixCoord.y(), sliceOrFaceNdx);

				invocationGlobalIDs[i]	= gid;
				pixelCoords[i]			= pixCoord;

				if (isIntegerFormat)
				{
					returnValues.i[i]	= resultSlice.getPixelInt(gid.x(), y).x();
					atomicArgs.i[i]		= getAtomicFuncArgument(m_operation, gid, dispatchSizeXY);
				}
				else
				{
					returnValues.f[i]	= resultSlice.getPixel(gid.x(), y).x();
					atomicArgs.f[i]		= (float)getAtomicFuncArgument(m_operation, gid, dispatchSizeXY);
				}
			}

			// Verify that the return values form a valid sequence.

			{
				const bool success = isIntegerFormat ? verifyOperationAccumulationIntermediateValues(m_operation,
																									 getOperationInitialValue(m_operation),
																									 atomicArgs.i,
																									 returnValues.i)

													 : verifyOperationAccumulationIntermediateValues(m_operation,
																									 (float)getOperationInitialValue(m_operation),
																									 atomicArgs.f,
																									 returnValues.f);

				if (!success)
				{
					log << TestLog::Message << "// Failure: intermediate return values at pixels " << arrayStr(pixelCoords) << " of current layer are "
											<< (isIntegerFormat ? arrayStr(returnValues.i) : arrayStr(returnValues.f)) << TestLog::EndMessage
						<< TestLog::Message << "// Note: relevant shader invocation global IDs are " << arrayStr(invocationGlobalIDs) << TestLog::EndMessage
						<< TestLog::Message << "// Note: data expression values for the IDs are "
											<< (isIntegerFormat ? arrayStr(atomicArgs.i) : arrayStr(atomicArgs.f))
											<< "; return values are not a valid result for any order of operations" << TestLog::EndMessage;
					return false;
				}
			}
		}

		return true;
	}

private:
	const AtomicOperation	m_operation;
	const TextureType		m_imageType;
	const IVec2				m_endResultImageLayerSize;

	//! Check whether there exists an ordering of args such that { init*A", init*A*B, ..., init*A*B*...*LAST } is the "returnValues" sequence, where { A, B, ..., LAST } is args, and * denotes the operation.
	//	That is, whether "returnValues" is a valid sequence of intermediate return values when "operation" has been accumulated on "args" (and "init") in some arbitrary order.
	template <typename T>
	static bool verifyOperationAccumulationIntermediateValues (AtomicOperation operation, T init, const T (&args)[NUM_INVOCATIONS_PER_PIXEL], const T (&returnValues)[NUM_INVOCATIONS_PER_PIXEL])
	{
		bool argsUsed[NUM_INVOCATIONS_PER_PIXEL] = { false };

		return verifyRecursive(operation, 0, init, argsUsed, args, returnValues);
	}

	static bool compare (int a, int b)		{ return a == b; }
	static bool compare (float a, float b)	{ return de::abs(a - b) <= 0.01f; }

	//! Depth-first search for verifying the return value sequence.
	template <typename T>
	static bool verifyRecursive (AtomicOperation operation, int index, T valueSoFar, bool (&argsUsed)[NUM_INVOCATIONS_PER_PIXEL], const T (&args)[NUM_INVOCATIONS_PER_PIXEL], const T (&returnValues)[NUM_INVOCATIONS_PER_PIXEL])
	{
		if (index < NUM_INVOCATIONS_PER_PIXEL)
		{
			for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL; i++)
			{
				if (!argsUsed[i] && compare(returnValues[i], valueSoFar))
				{
					argsUsed[i] = true;
					if (verifyRecursive(operation, index+1, computeBinaryAtomicOperationResult(operation, valueSoFar, args[i]), argsUsed, args, returnValues))
						return true;
					argsUsed[i] = false;
				}
			}

			return false;
		}
		else
			return true;
	}
};

void BinaryAtomicOperationCase::init (void)
{
	const glu::RenderContext& renderContext = m_context.getRenderContext();
	if (!m_context.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic") && !supportsES32orGL45(renderContext))
		throw tcu::NotSupportedError("Test requires OES_shader_image_atomic extension");

	checkTextureTypeExtensions(m_context.getContextInfo(), m_imageType, renderContext);
}

BinaryAtomicOperationCase::IterateResult BinaryAtomicOperationCase::iterate (void)
{
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	TestLog&					log						(m_testCtx.getLog());
	glu::CallLogWrapper			glLog					(renderCtx.getFunctions(), log);
	const deUint32				internalFormatGL		= glu::getInternalFormat(m_format);
	const deUint32				textureTargetGL			= getGLTextureTarget(m_imageType);
	const IVec3&				imageSize				= defaultImageSize(m_imageType);
	const int					numSlicesOrFaces		= m_imageType == TEXTURETYPE_CUBE ? 6 : imageSize.z();
	const bool					isUintFormat			= isFormatTypeUnsignedInteger(m_format.type);
	const bool					isIntFormat				= isFormatTypeSignedInteger(m_format.type);
	const glu::Buffer			endResultTextureBuf		(renderCtx);
	const glu::Buffer			returnValueTextureBuf	(renderCtx);
	const glu::Texture			endResultTexture		(renderCtx); //!< Texture for the final result; i.e. the texture on which the atomic operations are done. Size imageSize.
	const glu::Texture			returnValueTexture		(renderCtx); //!< Texture into which the return values are stored if m_caseType == CASETYPE_RETURN_VALUES.
																	 //	  Size imageSize*IVec3(N, 1, 1) or, for cube maps, imageSize*IVec3(N, N, 1) where N is NUM_INVOCATIONS_PER_PIXEL.

	glLog.enableLogging(true);

	// Setup textures.

	log << TestLog::Message << "// Created a texture (name " << *endResultTexture << ") to act as the target of atomic operations" << TestLog::EndMessage;
	if (m_imageType == TEXTURETYPE_BUFFER)
		log << TestLog::Message << "// Created a buffer for the texture (name " << *endResultTextureBuf << ")" << TestLog::EndMessage;

	if (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES)
	{
		log << TestLog::Message << "// Created a texture (name " << *returnValueTexture << ") to which the intermediate return values of the atomic operation are stored" << TestLog::EndMessage;
		if (m_imageType == TEXTURETYPE_BUFFER)
			log << TestLog::Message << "// Created a buffer for the texture (name " << *returnValueTextureBuf << ")" << TestLog::EndMessage;
	}

	// Fill endResultTexture with initial pattern.

	{
		const LayeredImage imageData(m_imageType, m_format, imageSize.x(), imageSize.y(), imageSize.z());

		{
			const IVec4 initial(getOperationInitialValue(m_operation));

			for (int z = 0; z < numSlicesOrFaces; z++)
			for (int y = 0; y < imageSize.y(); y++)
			for (int x = 0; x < imageSize.x(); x++)
				imageData.setPixel(x, y, z, initial);
		}

		// Upload initial pattern to endResultTexture and bind to image.

		glLog.glActiveTexture(GL_TEXTURE0);
		glLog.glBindTexture(textureTargetGL, *endResultTexture);
		setTexParameteri(glLog, textureTargetGL);

		log << TestLog::Message << "// Filling end-result texture with initial pattern (initial value " << getOperationInitialValue(m_operation) << ")" << TestLog::EndMessage;

		uploadTexture(glLog, imageData, *endResultTextureBuf);
	}

	glLog.glBindImageTexture(0, *endResultTexture, 0, GL_TRUE, 0, GL_READ_WRITE, internalFormatGL);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

	if (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES)
	{
		// Set storage for returnValueTexture and bind to image.

		glLog.glActiveTexture(GL_TEXTURE1);
		glLog.glBindTexture(textureTargetGL, *returnValueTexture);
		setTexParameteri(glLog, textureTargetGL);

		log << TestLog::Message << "// Setting storage of return-value texture" << TestLog::EndMessage;
		setTextureStorage(glLog, m_imageType, internalFormatGL, imageSize * (m_imageType == TEXTURETYPE_CUBE ? IVec3(NUM_INVOCATIONS_PER_PIXEL, NUM_INVOCATIONS_PER_PIXEL,	1)
																											 : IVec3(NUM_INVOCATIONS_PER_PIXEL, 1,							1)),
						  *returnValueTextureBuf);

		glLog.glBindImageTexture(1, *returnValueTexture, 0, GL_TRUE, 0, GL_WRITE_ONLY, internalFormatGL);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");
	}

	// Perform image stores in compute shader and finalize reference computation.

	{
		// Generate compute shader.

		const string colorVecTypeName		= string(isUintFormat ? "u" : isIntFormat ? "i" : "") + "vec4";
		const string atomicCoord			= m_imageType == TEXTURETYPE_BUFFER		? "gx % " + toString(imageSize.x())
											: m_imageType == TEXTURETYPE_2D			? "ivec2(gx % " + toString(imageSize.x()) + ", gy)"
											: "ivec3(gx % " + toString(imageSize.x()) + ", gy, gz)";
		const string invocationCoord		= m_imageType == TEXTURETYPE_BUFFER		? "gx"
											: m_imageType == TEXTURETYPE_2D			? "ivec2(gx, gy)"
											: "ivec3(gx, gy, gz)";
		const string atomicArgExpr			= (isUintFormat		? "uint"
											 : isIntFormat		? ""
											 : "float")
												+ getAtomicFuncArgumentShaderStr(m_operation, "gx", "gy", "gz", IVec2(NUM_INVOCATIONS_PER_PIXEL*imageSize.x(), imageSize.y()));
		const string atomicInvocation		= string() + getAtomicOperationShaderFuncName(m_operation) + "(u_results, " + atomicCoord + ", " + atomicArgExpr + ")";
		const string shaderImageFormatStr	= getShaderImageFormatQualifier(m_format);
		const string shaderImageTypeStr		= getShaderImageType(m_format.type, m_imageType);
		const std::string		glslVersionDeclaration	= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));

		const glu::ShaderProgram program(renderCtx,
			glu::ProgramSources() << glu::ComputeSource(glslVersionDeclaration + "\n"
														+ imageAtomicExtensionShaderRequires(renderCtx)
														+ textureTypeExtensionShaderRequires(m_imageType, renderCtx) +
														"\n"
														"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_results;\n"
														+ (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES ?
															  "layout (" + shaderImageFormatStr + ", binding=1) writeonly uniform " + shaderImageTypeStr + " u_returnValues;\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"
														+ (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES ?
															"	imageStore(u_returnValues, " + invocationCoord + ", " + colorVecTypeName + "(" + atomicInvocation + "));\n"
														 : m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT ?
															"	" + atomicInvocation + ";\n"
														 : deFatalStr("Invalid AtomicOperationCaseType")) +
														"}\n"));

		UniformAccessLogger uniforms(renderCtx.getFunctions(), log, program.getProgram());

		log << program;

		if (!program.isOk())
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program compilation failed");
			return STOP;
		}

		// Setup and dispatch.

		glLog.glUseProgram(program.getProgram());

		glLog.glDispatchCompute(NUM_INVOCATIONS_PER_PIXEL*imageSize.x(), imageSize.y(), numSlicesOrFaces);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
	}

	// Read texture and check.

	{
		const deUint32								textureToCheckGL	= m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT		? *endResultTexture
																		: m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES	? *returnValueTexture
																		: (deUint32)-1;
		const deUint32								textureToCheckBufGL	= m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT		? *endResultTextureBuf
																		: m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES	? *returnValueTextureBuf
																		: (deUint32)-1;

		const IVec3									textureToCheckSize	= imageSize * IVec3(m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT ? 1 : NUM_INVOCATIONS_PER_PIXEL, 1, 1);
		const UniquePtr<const ImageLayerVerifier>	verifier			(m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT		? new EndResultVerifier(m_operation, m_imageType)
																	   : m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES		? new ReturnValueVerifier(m_operation, m_imageType, imageSize.swizzle(0, 1))
																	   : (ImageLayerVerifier*)DE_NULL);

		if (readTextureAndVerify(renderCtx, glLog, textureToCheckGL, textureToCheckBufGL, m_imageType, m_format, textureToCheckSize, *verifier))
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");

		return STOP;
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Atomic compSwap operation case.
 *
 * Similar in principle to BinaryAtomicOperationCase, but separated for
 * convenience, since the atomic function is somewhat different. Like
 * BinaryAtomicOperationCase, this has separate cases for checking end
 * result and return values.
 *//*--------------------------------------------------------------------*/
class AtomicCompSwapCase : public TestCase
{
public:
									AtomicCompSwapCase		(Context& context, const char* name, const char* description, const TextureFormat& format, TextureType imageType, AtomicOperationCaseType caseType)
		: TestCase		(context, name, description)
		, m_format		(format)
		, m_imageType	(imageType)
		, m_caseType	(caseType)
	{
		DE_ASSERT(m_format == TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32)	||
				  m_format == TextureFormat(TextureFormat::R, TextureFormat::SIGNED_INT32));
	}

	void							init					(void);
	IterateResult					iterate					(void);

private:
	class EndResultVerifier;
	class ReturnValueVerifier;

	static int						getCompareArg			(const IVec3& invocationID, int imageWidth);
	static int						getAssignArg			(const IVec3& invocationID, int imageWidth);
	static string					getCompareArgShaderStr	(const string& x, const string& y, const string& z, int imageWidth);
	static string					getAssignArgShaderStr	(const string& x, const string& y, const string& z, int imageWidth);

	static const int				NUM_INVOCATIONS_PER_PIXEL = 5;

	const TextureFormat				m_format;
	const TextureType				m_imageType;
	const AtomicOperationCaseType	m_caseType;
};

int AtomicCompSwapCase::getCompareArg (const IVec3& invocationID, int imageWidth)
{
	const int x							= invocationID.x();
	const int y							= invocationID.y();
	const int z							= invocationID.z();
	const int wrapX						= x % imageWidth;
	const int curPixelInvocationNdx		= x / imageWidth;

	return wrapX*wrapX + y*y + z*z + curPixelInvocationNdx*42;
}

int AtomicCompSwapCase::getAssignArg (const IVec3& invocationID, int imageWidth)
{
	return getCompareArg(IVec3(invocationID.x() + imageWidth, invocationID.y(), invocationID.z()), imageWidth);
}

string AtomicCompSwapCase::getCompareArgShaderStr (const string& x, const string& y, const string& z, int imageWidth)
{
	const string wrapX					= "(" + x + "%" + toString(imageWidth) + ")";
	const string curPixelInvocationNdx	= "(" + x + "/" + toString(imageWidth) + ")";

	return "(" +wrapX+"*"+wrapX+ " + " +y+"*"+y+ " + " +z+"*"+z+ " + " + curPixelInvocationNdx + "*42)";
}

string AtomicCompSwapCase::getAssignArgShaderStr (const string& x, const string& y, const string& z, int imageWidth)
{
	const string wrapX					= "(" + x + "%" + toString(imageWidth) + ")";
	const string curPixelInvocationNdx	= "(" + x + "/" + toString(imageWidth) + " + 1)";

	return "(" +wrapX+"*"+wrapX+ " + " +y+"*"+y+ " + " +z+"*"+z+ " + " + curPixelInvocationNdx + "*42)";
}

void AtomicCompSwapCase::init (void)
{
	const glu::RenderContext& renderContext = m_context.getRenderContext();
	if (!m_context.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic") && !supportsES32orGL45(renderContext))
		throw tcu::NotSupportedError("Test requires OES_shader_image_atomic extension");

	checkTextureTypeExtensions(m_context.getContextInfo(), m_imageType, renderContext);
}

class AtomicCompSwapCase::EndResultVerifier : public ImageLayerVerifier
{
public:
	EndResultVerifier (TextureType imageType, int imageWidth) : m_imageType(imageType), m_imageWidth(imageWidth) {}

	bool operator() (TestLog& log, const ConstPixelBufferAccess& resultSlice, int sliceOrFaceNdx) const
	{
		DE_ASSERT(isFormatTypeInteger(resultSlice.getFormat().type));
		DE_ASSERT(resultSlice.getWidth() == m_imageWidth);

		log << TestLog::Image("EndResults" + toString(sliceOrFaceNdx),
							  "Result Values, " + (m_imageType == TEXTURETYPE_CUBE ? "face " + string(glu::getCubeMapFaceName(cubeFaceToGLFace(glslImageFuncZToCubeFace(sliceOrFaceNdx))))
																				   : "slice " + toString(sliceOrFaceNdx)),
							  resultSlice);

		for (int y = 0; y < resultSlice.getHeight(); y++)
		for (int x = 0; x < resultSlice.getWidth(); x++)
		{
			// Compute the value-to-assign arguments that were given to the atomic function in the invocations that contribute to this pixel.
			// One of those should be the result.

			const int	result = resultSlice.getPixelInt(x, y).x();
			IVec3		invocationGlobalIDs[NUM_INVOCATIONS_PER_PIXEL];
			int			assignArgs[NUM_INVOCATIONS_PER_PIXEL];

			for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL; i++)
			{
				const IVec3 gid(x + i*resultSlice.getWidth(), y, sliceOrFaceNdx);

				invocationGlobalIDs[i]	= gid;
				assignArgs[i]			= getAssignArg(gid, m_imageWidth);
			}

			{
				bool matchFound = false;
				for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL && !matchFound; i++)
					matchFound = result == assignArgs[i];

				if (!matchFound)
				{
					log << TestLog::Message << "// Failure: invalid value at pixel " << IVec2(x, y) << ": got " << result << TestLog::EndMessage
						<< TestLog::Message << "// Note: relevant shader invocation global IDs are " << arrayStr(invocationGlobalIDs) << TestLog::EndMessage
						<< TestLog::Message << "// Note: expected one of " << arrayStr(assignArgs)
											<< " (those are the values given as the 'data' argument in the invocations that contribute to this pixel)"
											<< TestLog::EndMessage;
					return false;
				}
			}
		}

		return true;
	}

private:
	const TextureType	m_imageType;
	const int			m_imageWidth;
};

class AtomicCompSwapCase::ReturnValueVerifier : public ImageLayerVerifier
{
public:
	//! \note endResultImageLayerSize is (width, height) of the image operated on by the atomic ops, and not the size of the image where the return values are stored.
	ReturnValueVerifier (TextureType imageType, int endResultImageWidth) : m_imageType(imageType), m_endResultImageWidth(endResultImageWidth) {}

	bool operator() (TestLog& log, const ConstPixelBufferAccess& resultSlice, int sliceOrFaceNdx) const
	{
		DE_ASSERT(isFormatTypeInteger(resultSlice.getFormat().type));
		DE_ASSERT(resultSlice.getWidth() == NUM_INVOCATIONS_PER_PIXEL*m_endResultImageWidth);

		log << TestLog::Image("ReturnValues" + toString(sliceOrFaceNdx),
							  "Per-Invocation Return Values, "
								   + (m_imageType == TEXTURETYPE_CUBE ? "face " + string(glu::getCubeMapFaceName(cubeFaceToGLFace(glslImageFuncZToCubeFace(sliceOrFaceNdx))))
																	  : "slice " + toString(sliceOrFaceNdx)),
							  resultSlice);

		for (int y = 0; y < resultSlice.getHeight(); y++)
		for (int x = 0; x < m_endResultImageWidth; x++)
		{
			// Get the atomic function args and return values for all the invocations that contribute to the pixel (x, y) in the current end result slice.

			int		returnValues[NUM_INVOCATIONS_PER_PIXEL];
			int		compareArgs[NUM_INVOCATIONS_PER_PIXEL];
			IVec3	invocationGlobalIDs[NUM_INVOCATIONS_PER_PIXEL];
			IVec2	pixelCoords[NUM_INVOCATIONS_PER_PIXEL];

			for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL; i++)
			{
				const IVec2 pixCoord	(x + i*m_endResultImageWidth, y);
				const IVec3 gid			(pixCoord.x(), pixCoord.y(), sliceOrFaceNdx);

				pixelCoords[i]			= pixCoord;
				invocationGlobalIDs[i]	= gid;
				returnValues[i]			= resultSlice.getPixelInt(gid.x(), y).x();
				compareArgs[i]			= getCompareArg(gid, m_endResultImageWidth);
			}

			// Verify that the return values form a valid sequence.
			// Due to the way the compare and assign arguments to the atomic calls are organized
			// among the different invocations contributing to the same pixel -- i.e. one invocation
			// compares to A and assigns B, another compares to B and assigns C, and so on, where
			// A<B<C etc -- the first value in the return value sequence must be A, and each following
			// value must be either the same as or the smallest value (among A, B, C, ...) bigger than
			// the one just before it. E.g. sequences A A A A A A A A, A B C D E F G H and
			// A A B B B C D E are all valid sequences (if there were 8 invocations contributing
			// to each pixel).

			{
				int failingNdx = -1;

				{
					int currentAtomicValueNdx = 0;
					for (int i = 0; i < NUM_INVOCATIONS_PER_PIXEL; i++)
					{
						if (returnValues[i] == compareArgs[currentAtomicValueNdx])
							continue;
						if (i > 0 && returnValues[i] == compareArgs[currentAtomicValueNdx+1])
						{
							currentAtomicValueNdx++;
							continue;
						}
						failingNdx = i;
						break;
					}
				}

				if (failingNdx >= 0)
				{
					log << TestLog::Message << "// Failure: intermediate return values at pixels " << arrayStr(pixelCoords) << " of current layer are "
											<< arrayStr(returnValues) << TestLog::EndMessage
						<< TestLog::Message << "// Note: relevant shader invocation global IDs are " << arrayStr(invocationGlobalIDs) << TestLog::EndMessage
						<< TestLog::Message << "// Note: 'compare' argument values for the IDs are " << arrayStr(compareArgs) << TestLog::EndMessage
						<< TestLog::Message << "// Note: expected the return value sequence to fulfill the following conditions:\n"
											<< "// - first value is " << compareArgs[0] << "\n"
											<< "// - each value other than the first is either the same as the one just before it, or the smallest value (in the sequence "
											<< arrayStr(compareArgs) << ") bigger than the one just before it" << TestLog::EndMessage;
					if (failingNdx == 0)
						log << TestLog::Message << "// Note: the first return value (" << returnValues[0] << ") isn't " << compareArgs[0] << TestLog::EndMessage;
					else
						log << TestLog::Message << "// Note: the return value at index " << failingNdx << " (value " << returnValues[failingNdx] << ") "
												<< "is neither " << returnValues[failingNdx-1] << " (the one just before it) "
												<< "nor " << compareArgs[arrayIndexOf(compareArgs, returnValues[failingNdx-1])+1] << " (the smallest value bigger than the one just before it)"
												<< TestLog::EndMessage;

					return false;
				}
			}
		}

		return true;
	}

private:
	const TextureType	m_imageType;
	const int			m_endResultImageWidth;
};

AtomicCompSwapCase::IterateResult AtomicCompSwapCase::iterate (void)
{
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	TestLog&					log						(m_testCtx.getLog());
	glu::CallLogWrapper			glLog					(renderCtx.getFunctions(), log);
	const deUint32				internalFormatGL		= glu::getInternalFormat(m_format);
	const deUint32				textureTargetGL			= getGLTextureTarget(m_imageType);
	const IVec3&				imageSize				= defaultImageSize(m_imageType);
	const int					numSlicesOrFaces		= m_imageType == TEXTURETYPE_CUBE ? 6 : imageSize.z();
	const bool					isUintFormat			= isFormatTypeUnsignedInteger(m_format.type);
	const bool					isIntFormat				= isFormatTypeSignedInteger(m_format.type);
	const glu::Buffer			endResultTextureBuf		(renderCtx);
	const glu::Buffer			returnValueTextureBuf	(renderCtx);
	const glu::Texture			endResultTexture		(renderCtx); //!< Texture for the final result; i.e. the texture on which the atomic operations are done. Size imageSize.
	const glu::Texture			returnValueTexture		(renderCtx); //!< Texture into which the return values are stored if m_caseType == CASETYPE_RETURN_VALUES.
																	 //	  Size imageSize*IVec3(N, 1, 1) or, for cube maps, imageSize*IVec3(N, N, 1) where N is NUM_INVOCATIONS_PER_PIXEL.

	DE_ASSERT(isUintFormat || isIntFormat);

	glLog.enableLogging(true);

	// Setup textures.

	log << TestLog::Message << "// Created a texture (name " << *endResultTexture << ") to act as the target of atomic operations" << TestLog::EndMessage;
	if (m_imageType == TEXTURETYPE_BUFFER)
		log << TestLog::Message << "// Created a buffer for the texture (name " << *endResultTextureBuf << ")" << TestLog::EndMessage;

	if (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES)
	{
		log << TestLog::Message << "// Created a texture (name " << *returnValueTexture << ") to which the intermediate return values of the atomic operation are stored" << TestLog::EndMessage;
		if (m_imageType == TEXTURETYPE_BUFFER)
			log << TestLog::Message << "// Created a buffer for the texture (name " << *returnValueTextureBuf << ")" << TestLog::EndMessage;
	}

	// Fill endResultTexture with initial pattern.

	{
		const LayeredImage imageData(m_imageType, m_format, imageSize.x(), imageSize.y(), imageSize.z());

		{
			for (int z = 0; z < numSlicesOrFaces; z++)
			for (int y = 0; y < imageSize.y(); y++)
			for (int x = 0; x < imageSize.x(); x++)
				imageData.setPixel(x, y, z, IVec4(getCompareArg(IVec3(x, y, z), imageSize.x())));
		}

		// Upload initial pattern to endResultTexture and bind to image.

		glLog.glActiveTexture(GL_TEXTURE0);
		glLog.glBindTexture(textureTargetGL, *endResultTexture);
		setTexParameteri(glLog, textureTargetGL);

		log << TestLog::Message << "// Filling end-result texture with initial pattern" << TestLog::EndMessage;

		uploadTexture(glLog, imageData, *endResultTextureBuf);
	}

	glLog.glBindImageTexture(0, *endResultTexture, 0, GL_TRUE, 0, GL_READ_WRITE, internalFormatGL);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

	if (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES)
	{
		// Set storage for returnValueTexture and bind to image.

		glLog.glActiveTexture(GL_TEXTURE1);
		glLog.glBindTexture(textureTargetGL, *returnValueTexture);
		setTexParameteri(glLog, textureTargetGL);

		log << TestLog::Message << "// Setting storage of return-value texture" << TestLog::EndMessage;
		setTextureStorage(glLog, m_imageType, internalFormatGL, imageSize * (m_imageType == TEXTURETYPE_CUBE ? IVec3(NUM_INVOCATIONS_PER_PIXEL, NUM_INVOCATIONS_PER_PIXEL,	1)
																											 : IVec3(NUM_INVOCATIONS_PER_PIXEL, 1,							1)),
						  *returnValueTextureBuf);

		glLog.glBindImageTexture(1, *returnValueTexture, 0, GL_TRUE, 0, GL_WRITE_ONLY, internalFormatGL);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");
	}

	// Perform atomics in compute shader.

	{
		// Generate compute shader.

		const string colorScalarTypeName	= isUintFormat ? "uint" : isIntFormat ? "int" : DE_NULL;
		const string colorVecTypeName		= string(isUintFormat ? "u" : isIntFormat ? "i" : DE_NULL) + "vec4";
		const string atomicCoord			= m_imageType == TEXTURETYPE_BUFFER		? "gx % " + toString(imageSize.x())
											: m_imageType == TEXTURETYPE_2D			? "ivec2(gx % " + toString(imageSize.x()) + ", gy)"
											: "ivec3(gx % " + toString(imageSize.x()) + ", gy, gz)";
		const string invocationCoord		= m_imageType == TEXTURETYPE_BUFFER		? "gx"
											: m_imageType == TEXTURETYPE_2D			? "ivec2(gx, gy)"
											: "ivec3(gx, gy, gz)";
		const string shaderImageFormatStr	= getShaderImageFormatQualifier(m_format);
		const string shaderImageTypeStr		= getShaderImageType(m_format.type, m_imageType);
		const string glslVersionDeclaration	= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));

		const glu::ShaderProgram program(renderCtx,
			glu::ProgramSources() << glu::ComputeSource(glslVersionDeclaration + "\n"
														+ imageAtomicExtensionShaderRequires(renderCtx)
														+ textureTypeExtensionShaderRequires(m_imageType, renderCtx) +
														"\n"
														"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_results;\n"
														+ (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES ?
															  "layout (" + shaderImageFormatStr + ", binding=1) writeonly uniform " + shaderImageTypeStr + " u_returnValues;\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"
														"	" + colorScalarTypeName + " compare = " + colorScalarTypeName + getCompareArgShaderStr("gx", "gy", "gz", imageSize.x()) + ";\n"
														"	" + colorScalarTypeName + " data    = " + colorScalarTypeName + getAssignArgShaderStr("gx", "gy", "gz", imageSize.x()) + ";\n"
														"	" + colorScalarTypeName + " status  = " + colorScalarTypeName + "(-1);\n"
														"	status = imageAtomicCompSwap(u_results, " + atomicCoord + ", compare, data);\n"
														+ (m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES ?
															"	imageStore(u_returnValues, " + invocationCoord + ", " + colorVecTypeName + "(status));\n" :
															"") +
														"}\n"));

		UniformAccessLogger uniforms(renderCtx.getFunctions(), log, program.getProgram());

		log << program;

		if (!program.isOk())
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program compilation failed");
			return STOP;
		}

		// Setup and dispatch.

		glLog.glUseProgram(program.getProgram());

		glLog.glDispatchCompute(NUM_INVOCATIONS_PER_PIXEL*imageSize.x(), imageSize.y(), numSlicesOrFaces);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
	}

	// Create reference, read texture and compare.

	{
		const deUint32								textureToCheckGL	= m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT		? *endResultTexture
																		: m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES	? *returnValueTexture
																		: (deUint32)-1;

		const deUint32								textureToCheckBufGL	= m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT		? *endResultTextureBuf
																		: m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES	? *returnValueTextureBuf
																		: (deUint32)-1;

		// The relevant region of the texture being checked (potentially
		// different from actual texture size for cube maps, because cube maps
		// may have unused pixels due to square size restriction).
		const IVec3									relevantRegion		= imageSize * (m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT	? IVec3(1,							1,							1)
																					 :														  IVec3(NUM_INVOCATIONS_PER_PIXEL,	1,							1));

		const UniquePtr<const ImageLayerVerifier>	verifier			(m_caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT		? new EndResultVerifier(m_imageType, imageSize.x())
																	   : m_caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES		? new ReturnValueVerifier(m_imageType, imageSize.x())
																	   : (ImageLayerVerifier*)DE_NULL);

		if (readTextureAndVerify(renderCtx, glLog, textureToCheckGL, textureToCheckBufGL, m_imageType, m_format, relevantRegion, *verifier))
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");

		return STOP;
	}
}

//! Case testing the "coherent" or "volatile" qualifier, along with memoryBarrier() and barrier().
class CoherenceCase : public TestCase
{
public:
	enum Qualifier
	{
		QUALIFIER_COHERENT = 0,
		QUALIFIER_VOLATILE,

		QUALIFIER_LAST
	};

	CoherenceCase (Context& context, const char* name, const char* description, const TextureFormat& format, TextureType imageType, Qualifier qualifier)
		: TestCase		(context, name, description)
		, m_format		(format)
		, m_imageType	(imageType)
		, m_qualifier	(qualifier)
	{
		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(CoherenceCase::SHADER_READ_OFFSETS_Y) == DE_LENGTH_OF_ARRAY(CoherenceCase::SHADER_READ_OFFSETS_X) &&
						 DE_LENGTH_OF_ARRAY(CoherenceCase::SHADER_READ_OFFSETS_Z) == DE_LENGTH_OF_ARRAY(CoherenceCase::SHADER_READ_OFFSETS_X));

		DE_ASSERT(qualifier == QUALIFIER_COHERENT || qualifier == QUALIFIER_VOLATILE);

		DE_ASSERT(m_format == TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32)	||
				  m_format == TextureFormat(TextureFormat::R, TextureFormat::SIGNED_INT32)		||
				  m_format == TextureFormat(TextureFormat::R, TextureFormat::FLOAT));
	}

	void			init		(void) { checkTextureTypeExtensions(m_context.getContextInfo(), m_imageType, m_context.getRenderContext()); }
	IterateResult	iterate		(void);

private:
	static const int			SHADER_READ_OFFSETS_X[4];
	static const int			SHADER_READ_OFFSETS_Y[4];
	static const int			SHADER_READ_OFFSETS_Z[4];
	static const char* const	SHADER_READ_OFFSETS_X_STR;
	static const char* const	SHADER_READ_OFFSETS_Y_STR;
	static const char* const	SHADER_READ_OFFSETS_Z_STR;

	const TextureFormat		m_format;
	const TextureType		m_imageType;
	const Qualifier			m_qualifier;
};

const int			CoherenceCase::SHADER_READ_OFFSETS_X[4]		=		{ 1, 4, 7, 10 };
const int			CoherenceCase::SHADER_READ_OFFSETS_Y[4]		=		{ 2, 5, 8, 11 };
const int			CoherenceCase::SHADER_READ_OFFSETS_Z[4]		=		{ 3, 6, 9, 12 };
const char* const	CoherenceCase::SHADER_READ_OFFSETS_X_STR	= "int[]( 1, 4, 7, 10 )";
const char* const	CoherenceCase::SHADER_READ_OFFSETS_Y_STR	= "int[]( 2, 5, 8, 11 )";
const char* const	CoherenceCase::SHADER_READ_OFFSETS_Z_STR	= "int[]( 3, 6, 9, 12 )";

CoherenceCase::IterateResult CoherenceCase::iterate (void)
{
	const RenderContext&		renderCtx					= m_context.getRenderContext();
	TestLog&					log							(m_testCtx.getLog());
	glu::CallLogWrapper			glLog						(renderCtx.getFunctions(), log);
	const deUint32				internalFormatGL			= glu::getInternalFormat(m_format);
	const deUint32				textureTargetGL				= getGLTextureTarget(m_imageType);
	const IVec3&				imageSize					= defaultImageSize(m_imageType);
	const int					numSlicesOrFaces			= m_imageType == TEXTURETYPE_CUBE ? 6 : imageSize.z();
	const bool					isUintFormat				= isFormatTypeUnsignedInteger(m_format.type);
	const bool					isIntFormat					= isFormatTypeSignedInteger(m_format.type);
	const char* const			qualifierName				= m_qualifier == QUALIFIER_COHERENT ? "coherent"
															: m_qualifier == QUALIFIER_VOLATILE ? "volatile"
															: DE_NULL;
	const glu::Buffer			textureBuf					(renderCtx);
	const glu::Texture			texture						(renderCtx);
	const IVec3					numGroups					= IVec3(16, de::min(16, imageSize.y()), de::min(2, numSlicesOrFaces));
	const IVec3					workItemSize				= IVec3(imageSize.x(), imageSize.y(), numSlicesOrFaces);
	const IVec3					localSize					= workItemSize / numGroups;
	const IVec3					minReqMaxLocalSize			= IVec3(128, 128, 64);
	const int					minReqMaxLocalInvocations	= 128;

	DE_ASSERT(workItemSize == localSize*numGroups);
	DE_ASSERT(tcu::boolAll(tcu::lessThanEqual(localSize, minReqMaxLocalSize)));
	DE_ASSERT(localSize.x()*localSize.y()*localSize.z() <= minReqMaxLocalInvocations);
	DE_UNREF(minReqMaxLocalSize);
	DE_UNREF(minReqMaxLocalInvocations);

	glLog.enableLogging(true);

	// Setup texture.

	log << TestLog::Message << "// Created a texture (name " << *texture << ")" << TestLog::EndMessage;
	if (m_imageType == TEXTURETYPE_BUFFER)
		log << TestLog::Message << "// Created a buffer for the texture (name " << *textureBuf << ")" << TestLog::EndMessage;

	glLog.glActiveTexture(GL_TEXTURE0);
	glLog.glBindTexture(textureTargetGL, *texture);
	setTexParameteri(glLog, textureTargetGL);
	setTextureStorage(glLog, m_imageType, internalFormatGL, imageSize, *textureBuf);
	glLog.glBindImageTexture(0, *texture, 0, GL_TRUE, 0, GL_READ_WRITE, internalFormatGL);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

	// Perform computations in compute shader.

	{
		// Generate compute shader.

		const string		colorVecTypeName		= string(isUintFormat ? "u" : isIntFormat ? "i" : "") + "vec4";
		const char* const	colorScalarTypeName		= isUintFormat ? "uint" : isIntFormat ? "int" : "float";
		const string		invocationCoord			= m_imageType == TEXTURETYPE_BUFFER		? "gx"
													: m_imageType == TEXTURETYPE_2D			? "ivec2(gx, gy)"
													: "ivec3(gx, gy, gz)";
		const string		shaderImageFormatStr	= getShaderImageFormatQualifier(m_format);
		const string		shaderImageTypeStr		= getShaderImageType(m_format.type, m_imageType);
		const string		localSizeX				= de::toString(localSize.x());
		const string		localSizeY				= de::toString(localSize.y());
		const string		localSizeZ				= de::toString(localSize.z());
		const std::string	glslVersionDeclaration	= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));


		const glu::ShaderProgram program(renderCtx,
			glu::ProgramSources() << glu::ComputeSource(glslVersionDeclaration + "\n"
														+ textureTypeExtensionShaderRequires(m_imageType, renderCtx) +
														"\n"
														"precision highp " + shaderImageTypeStr + ";\n"
														"\n"
														"layout (local_size_x = " + localSizeX
															+ ", local_size_y = " + localSizeY
															+ ", local_size_z = " + localSizeZ
															+ ") in;\n"
														"layout (" + shaderImageFormatStr + ", binding=0) " + qualifierName + " uniform " + shaderImageTypeStr + " 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[] = " + SHADER_READ_OFFSETS_X_STR + ";\n"
														"	int yOffsets[] = " + SHADER_READ_OFFSETS_Y_STR + ";\n"
														"	int zOffsets[] = " + SHADER_READ_OFFSETS_Z_STR + ";\n"
														"	for (int i = 0; i < " + toString(DE_LENGTH_OF_ARRAY(SHADER_READ_OFFSETS_X)) + "; 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, " + (m_imageType == TEXTURETYPE_BUFFER	? "readX"
																							 : m_imageType == TEXTURETYPE_2D		? "ivec2(readX, readY)"
																							 : "ivec3(readX, readY, readZ)") + ").x;\n"
														"	}\n"
														"\n"
														"	memoryBarrier();\n"
														"	barrier();\n"
														"\n"
														"	imageStore(u_image, " + invocationCoord + ", " + colorVecTypeName + "(sum));\n"
														"}\n"));

		UniformAccessLogger uniforms(renderCtx.getFunctions(), log, program.getProgram());

		log << program;

		if (!program.isOk())
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program compilation failed");
			return STOP;
		}

		// Setup and dispatch.

		glLog.glUseProgram(program.getProgram());

		glLog.glDispatchCompute(numGroups.x(), numGroups.y(), numGroups.z());
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
	}

	// Create reference, read texture and compare.

	{
		LayeredImage reference(m_imageType, m_format, imageSize.x(), imageSize.y(), imageSize.z());

		{
			LayeredImage base(m_imageType, m_format, imageSize.x(), imageSize.y(), imageSize.z());
			for (int z = 0; z < numSlicesOrFaces; z++)
			for (int y = 0; y < imageSize.y(); y++)
			for (int x = 0; x < imageSize.x(); x++)
				base.setPixel(x, y, z, IVec4(x^y^z));

			for (int z = 0; z < numSlicesOrFaces; z++)
			for (int y = 0; y < imageSize.y(); y++)
			for (int x = 0; x < imageSize.x(); x++)
			{
				const int	groupBaseX	= x / localSize.x() * localSize.x();
				const int	groupBaseY	= y / localSize.y() * localSize.y();
				const int	groupBaseZ	= z / localSize.z() * localSize.z();
				int			sum			= 0;
				for (int i = 0; i < DE_LENGTH_OF_ARRAY(SHADER_READ_OFFSETS_X); i++)
					sum += base.getPixelInt(groupBaseX + (x + SHADER_READ_OFFSETS_X[i]) % localSize.x(),
											groupBaseY + (y + SHADER_READ_OFFSETS_Y[i]) % localSize.y(),
											groupBaseZ + (z + SHADER_READ_OFFSETS_Z[i]) % localSize.z()).x();

				reference.setPixel(x, y, z, IVec4(sum));
			}
		}

		if (readTextureAndVerify(renderCtx, glLog, *texture, *textureBuf, m_imageType, m_format, imageSize, ImageLayerComparer(reference)))
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");

		return STOP;
	}
}

class R32UIImageSingleValueVerifier : public ImageLayerVerifier
{
public:
	R32UIImageSingleValueVerifier (const deUint32 value)					: m_min(value),	m_max(value)	{}
	R32UIImageSingleValueVerifier (const deUint32 min, const deUint32 max)	: m_min(min),	m_max(max)		{}

	bool operator() (TestLog& log, const ConstPixelBufferAccess& resultSlice, int) const
	{
		DE_ASSERT(resultSlice.getWidth() == 1 && resultSlice.getHeight() == 1 && resultSlice.getDepth() == 1);
		DE_ASSERT(resultSlice.getFormat() == TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32));

		log << TestLog::Message << "// Note: expecting to get value " << (m_min == m_max ? toString(m_min) : "in range [" + toString(m_min) + ", " + toString(m_max) + "]") << TestLog::EndMessage;

		const deUint32 resultValue = resultSlice.getPixelUint(0, 0).x();
		if (!de::inRange(resultValue, m_min, m_max))
		{
			log << TestLog::Message << "// Failure: got value " << resultValue << TestLog::EndMessage;
			return false;
		}
		else
		{
			log << TestLog::Message << "// Success: got value " << resultValue << TestLog::EndMessage;
			return true;
		}
	}

private:
	const deUint32 m_min;
	const deUint32 m_max;
};

//! Tests the imageSize() GLSL function. Stores result in a 1x1 R32UI image. The image with which imageSize() is called isn't read or written, and
//  can thus be qualifier readonly, writeonly, or both.
class ImageSizeCase : public TestCase
{
public:
	enum ImageAccess
	{
		IMAGEACCESS_READ_ONLY = 0,
		IMAGEACCESS_WRITE_ONLY,
		IMAGEACCESS_READ_ONLY_WRITE_ONLY,

		IMAGEACCESS_LAST
	};

	ImageSizeCase (Context& context, const char* name, const char* description, const TextureFormat& format, TextureType imageType, const IVec3& size, ImageAccess imageAccess)
		: TestCase			(context, name, description)
		, m_format			(format)
		, m_imageType		(imageType)
		, m_imageSize		(size)
		, m_imageAccess		(imageAccess)
	{
	}

	void			init		(void) { checkTextureTypeExtensions(m_context.getContextInfo(), m_imageType, m_context.getRenderContext()); }
	IterateResult	iterate		(void);

private:
	const TextureFormat		m_format;
	const TextureType		m_imageType;
	const IVec3				m_imageSize;
	const ImageAccess		m_imageAccess;
};

ImageSizeCase::IterateResult ImageSizeCase::iterate (void)
{
	const RenderContext&		renderCtx				= m_context.getRenderContext();
	TestLog&					log						(m_testCtx.getLog());
	glu::CallLogWrapper			glLog					(renderCtx.getFunctions(), log);
	const deUint32				internalFormatGL		= glu::getInternalFormat(m_format);
	const deUint32				textureTargetGL			= getGLTextureTarget(m_imageType);
	const glu::Buffer			mainTextureBuf			(renderCtx);
	const glu::Texture			mainTexture				(renderCtx);
	const glu::Texture			shaderOutResultTexture	(renderCtx);

	glLog.enableLogging(true);

	// Setup textures.

	log << TestLog::Message << "// Created a texture (name " << *mainTexture << ")" << TestLog::EndMessage;
	if (m_imageType == TEXTURETYPE_BUFFER)
		log << TestLog::Message << "// Created a buffer for the texture (name " << *mainTextureBuf << ")" << TestLog::EndMessage;
	log << TestLog::Message << "// Created a texture (name " << *shaderOutResultTexture << ") for storing the shader output" << TestLog::EndMessage;

	glLog.glActiveTexture(GL_TEXTURE0);
	glLog.glBindTexture(textureTargetGL, *mainTexture);
	setTexParameteri(glLog, textureTargetGL);
	setTextureStorage(glLog, m_imageType, internalFormatGL, m_imageSize, *mainTextureBuf);
	glLog.glBindImageTexture(0, *mainTexture, 0, GL_TRUE, 0, GL_READ_WRITE, internalFormatGL);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

	glLog.glActiveTexture(GL_TEXTURE1);
	glLog.glBindTexture(GL_TEXTURE_2D, *shaderOutResultTexture);
	setTexParameteri(glLog, GL_TEXTURE_2D);
	setTextureStorage(glLog, TEXTURETYPE_2D, GL_R32UI, IVec3(1, 1, 1), 0 /* always 2d texture, no buffer needed */);
	glLog.glBindImageTexture(1, *shaderOutResultTexture, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32UI);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

	// Read texture size in compute shader.

	{
		// Generate compute shader.

		const char* const	shaderImageAccessStr	= m_imageAccess == IMAGEACCESS_READ_ONLY			? "readonly"
													: m_imageAccess == IMAGEACCESS_WRITE_ONLY			? "writeonly"
													: m_imageAccess == IMAGEACCESS_READ_ONLY_WRITE_ONLY	? "readonly writeonly"
													: DE_NULL;
		const string		shaderImageFormatStr	= getShaderImageFormatQualifier(m_format);
		const string		shaderImageTypeStr		= getShaderImageType(m_format.type, m_imageType);
		const string		glslVersionDeclaration	= glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));

		const glu::ShaderProgram program(renderCtx,
			glu::ProgramSources() << glu::ComputeSource(glslVersionDeclaration + "\n"
														+ textureTypeExtensionShaderRequires(m_imageType, renderCtx) +
														"\n"
														"precision highp " + shaderImageTypeStr + ";\n"
														"precision highp uimage2D;\n"
														"\n"
														"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
														"layout (" + shaderImageFormatStr + ", binding=0) " + shaderImageAccessStr + " uniform " + shaderImageTypeStr + " u_image;\n"
														"layout (r32ui, binding=1) writeonly uniform uimage2D u_result;\n"
														"void main (void)\n"
														"{\n"
														+ (m_imageType == TEXTURETYPE_BUFFER ?
															"	int result = imageSize(u_image);\n"
														 : m_imageType == TEXTURETYPE_2D || m_imageType == TEXTURETYPE_CUBE ?
															"	ivec2 size = imageSize(u_image);\n"
															"	int result = size.y*1000 + size.x;\n"
														 : m_imageType == TEXTURETYPE_3D || m_imageType == TEXTURETYPE_2D_ARRAY ?
															"	ivec3 size = imageSize(u_image);\n"
															"	int result = size.z*1000000 + size.y*1000 + size.x;\n"
														 : DE_NULL) +
														"	imageStore(u_result, ivec2(0, 0), uvec4(result));\n"
														"}\n"));

		UniformAccessLogger uniforms(renderCtx.getFunctions(), log, program.getProgram());

		log << program;

		if (!program.isOk())
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program compilation failed");
			return STOP;
		}

		// Setup and dispatch.

		glLog.glUseProgram(program.getProgram());

		glLog.glDispatchCompute(1, 1, 1);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glDispatchCompute");
	}

	// Read texture and compare to reference.

	{
		const deUint32	referenceOutput		= m_imageType == TEXTURETYPE_BUFFER										? (deUint32)(												  m_imageSize.x())
											: m_imageType == TEXTURETYPE_2D || m_imageType == TEXTURETYPE_CUBE		? (deUint32)(						   m_imageSize.y()*1000 + m_imageSize.x())
											: m_imageType == TEXTURETYPE_3D || m_imageType == TEXTURETYPE_2D_ARRAY	? (deUint32)(m_imageSize.z()*1000000 + m_imageSize.y()*1000 + m_imageSize.x())
											: (deUint32)-1;

		if (readIntegerTextureViaFBOAndVerify(renderCtx, glLog, *shaderOutResultTexture, TEXTURETYPE_2D, TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32),
											  IVec3(1, 1, 1), R32UIImageSingleValueVerifier(referenceOutput)))
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got wrong value");

		return STOP;
	}
}

//! Case testing the control over early/late fragment tests.
class EarlyFragmentTestsCase : public TestCase
{
public:
	enum TestType
	{
		TESTTYPE_DEPTH = 0,
		TESTTYPE_STENCIL,

		TESTTYPE_LAST
	};

	enum RenderTargetType
	{
		RENDERTARGET_DEFAULT = 0,
		RENDERTARGET_FBO,
		RENDERTARGET_FBO_WITHOUT_TEST_ATTACHMENT,

		RENDERTARGET_LAST
	};


	EarlyFragmentTestsCase (Context& context, const char* name, const char* description, TestType type, bool useEarlyTests, RenderTargetType renderTarget)
		: TestCase			(context, name, description)
		, m_type			(type)
		, m_useEarlyTests	(useEarlyTests)
		, m_renderTarget	(renderTarget)
	{
	}

	void init (void)
	{
		if (m_context.getContextInfo().getInt(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) == 0)
			throw tcu::NotSupportedError("GL_MAX_FRAGMENT_IMAGE_UNIFORMS is zero");

		if (!m_context.getContextInfo().isExtensionSupported("GL_OES_shader_image_atomic") && !supportsES32orGL45(m_context.getRenderContext()))
			throw tcu::NotSupportedError("Test requires OES_shader_image_atomic extension");

		if (m_type == TESTTYPE_DEPTH				&&
			m_renderTarget == RENDERTARGET_DEFAULT	&&
			m_context.getRenderTarget().getDepthBits() == 0)
		{
			throw tcu::NotSupportedError("Test requires depth buffer");
		}

		if (m_type == TESTTYPE_STENCIL				&&
			m_renderTarget == RENDERTARGET_DEFAULT	&&
			m_context.getRenderTarget().getStencilBits() == 0)
		{
			throw tcu::NotSupportedError("Test requires stencil buffer");
		}

		if (m_renderTarget == RENDERTARGET_DEFAULT	&&
			(m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE))
			throw tcu::NotSupportedError("Render target must have at least " + toString(RENDER_SIZE) + " width and height");
	}

	IterateResult iterate (void);

private:
	static const int		RENDER_SIZE;

	const TestType			m_type;
	const bool				m_useEarlyTests;
	const RenderTargetType	m_renderTarget;
};

const int EarlyFragmentTestsCase::RENDER_SIZE = 32;

EarlyFragmentTestsCase::IterateResult EarlyFragmentTestsCase::iterate (void)
{
	const RenderContext&			renderCtx			= m_context.getRenderContext();
	TestLog&						log					(m_testCtx.getLog());
	glu::CallLogWrapper				glLog				(renderCtx.getFunctions(), log);
	de::Random						rnd					(deStringHash(getName()));
	const bool						expectPartialResult	= m_useEarlyTests && m_renderTarget != RENDERTARGET_FBO_WITHOUT_TEST_ATTACHMENT;
	const int						viewportWidth		= RENDER_SIZE;
	const int						viewportHeight		= RENDER_SIZE;
	const int						viewportX			= (m_renderTarget == RENDERTARGET_DEFAULT) ? (rnd.getInt(0, renderCtx.getRenderTarget().getWidth() - viewportWidth))	: (0);
	const int						viewportY			= (m_renderTarget == RENDERTARGET_DEFAULT) ? (rnd.getInt(0, renderCtx.getRenderTarget().getHeight() - viewportHeight))	: (0);
	const glu::Texture				texture				(renderCtx);
	de::MovePtr<glu::Framebuffer>	fbo;
	de::MovePtr<glu::Renderbuffer>	colorAttachment;
	de::MovePtr<glu::Renderbuffer>	testAttachment;

	glLog.enableLogging(true);

	// Setup texture.

	log << TestLog::Message << "// Created a texture (name " << *texture << ")" << TestLog::EndMessage;

	glLog.glActiveTexture(GL_TEXTURE0);
	glLog.glBindTexture(GL_TEXTURE_2D, *texture);
	setTexParameteri(glLog, GL_TEXTURE_2D);
	{
		LayeredImage src(TEXTURETYPE_2D, TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32), 1, 1, 1);
		src.setPixel(0, 0, 0, IVec4(0));
		uploadTexture(glLog, src, 0 /* always 2d texture, no buffer needed */);
	}
	glLog.glBindImageTexture(0, *texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32UI);
	GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "glBindImageTexture");

	// Set up framebuffer
	if (m_renderTarget == RENDERTARGET_FBO ||
		m_renderTarget == RENDERTARGET_FBO_WITHOUT_TEST_ATTACHMENT)
	{
		fbo				= de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(renderCtx));
		colorAttachment	= de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(renderCtx));
		testAttachment	= de::MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(renderCtx));

		glLog.glBindRenderbuffer(GL_RENDERBUFFER, **colorAttachment);
		glLog.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDER_SIZE, RENDER_SIZE);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "gen color attachment rb");

		glLog.glBindFramebuffer(GL_FRAMEBUFFER, **fbo);
		glLog.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **colorAttachment);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "set fbo color attachment");

		if (m_renderTarget == RENDERTARGET_FBO && m_type == TESTTYPE_DEPTH)
		{
			glLog.glBindRenderbuffer(GL_RENDERBUFFER, **testAttachment);
			glLog.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, RENDER_SIZE, RENDER_SIZE);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "gen depth attachment rb");

			glLog.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, **testAttachment);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "set fbo depth attachment");
		}
		else if (m_renderTarget == RENDERTARGET_FBO && m_type == TESTTYPE_STENCIL)
		{
			glLog.glBindRenderbuffer(GL_RENDERBUFFER, **testAttachment);
			glLog.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, RENDER_SIZE, RENDER_SIZE);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "gen stencil attachment rb");

			glLog.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, **testAttachment);
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "set fbo stencil attachment");
		}

		glLog.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **colorAttachment);
		GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "setup fbo");
		TCU_CHECK(glLog.glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
	}

	// Set up appropriate conditions for the test.

	glLog.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glLog.glClear(GL_COLOR_BUFFER_BIT);

	if (m_type == TESTTYPE_DEPTH)
	{
		glLog.glClearDepthf(0.5f);
		glLog.glClear(GL_DEPTH_BUFFER_BIT);
		glLog.glEnable(GL_DEPTH_TEST);
	}
	else if (m_type == TESTTYPE_STENCIL)
	{
		glLog.glClearStencil(0);
		glLog.glClear(GL_STENCIL_BUFFER_BIT);
		glLog.glScissor(viewportX, viewportY, viewportWidth/2, viewportHeight);
		glLog.glEnable(GL_SCISSOR_TEST);
		glLog.glClearStencil(1);
		glLog.glClear(GL_STENCIL_BUFFER_BIT);
		glLog.glDisable(GL_SCISSOR_TEST);
		glLog.glStencilFunc(GL_EQUAL, 1, 1);
		glLog.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
		glLog.glEnable(GL_STENCIL_TEST);
	}
	else
		DE_ASSERT(false);

	// Perform image stores in fragment shader.

	{
		const std::string glslVersionDeclaration = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(renderCtx.getType()));

		// Generate fragment shader.

		const glu::ShaderProgram program(renderCtx,
			glu::ProgramSources() << glu::VertexSource(		glslVersionDeclaration + "\n"
															"\n"
															"highp in vec3 a_position;\n"
															"\n"
															"void main (void)\n"
															"{\n"
															"	gl_Position = vec4(a_position, 1.0);\n"
															"}\n")

								  << glu::FragmentSource(	glslVersionDeclaration + "\n"
															+ imageAtomicExtensionShaderRequires(renderCtx) +
															"\n"
															+ string(m_useEarlyTests ? "layout (early_fragment_tests) in;\n\n" : "") +
															"layout (location = 0) out highp vec4 o_color;\n"
															"\n"
															"precision highp uimage2D;\n"
															"\n"
															"layout (r32ui, binding=0) coherent uniform uimage2D u_image;\n"
															"\n"
															"void main (void)\n"
															"{\n"
															"	imageAtomicAdd(u_image, ivec2(0, 0), uint(1));\n"
															"	o_color = vec4(1.0);\n"
															"}\n"));

		UniformAccessLogger uniforms(renderCtx.getFunctions(), log, program.getProgram());

		log << program;

		if (!program.isOk())
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Program compilation failed");
			return STOP;
		}

		// Setup and draw full-viewport quad.

		glLog.glUseProgram(program.getProgram());

		{
			static const float vertexPositions[4*3] =
			{
				-1.0, -1.0, -1.0f,
				 1.0, -1.0,  0.0f,
				-1.0,  1.0,  0.0f,
				 1.0,  1.0,  1.0f,
			};

			static const deUint16 indices[6] = { 0, 1, 2, 2, 1, 3 };

			const glu::VertexArrayBinding attrBindings[] =
			{
				glu::va::Float("a_position", 3, 4, 0, &vertexPositions[0])
			};

			glLog.glViewport(viewportX, viewportY, viewportWidth, viewportHeight);

			glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
				glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
			GLU_EXPECT_NO_ERROR(renderCtx.getFunctions().getError(), "Draw failed");
		}
	}

	// Log rendered result for convenience.
	{
		tcu::Surface rendered(viewportWidth, viewportHeight);
		glu::readPixels(renderCtx, viewportX, viewportY, rendered.getAccess());
		log << TestLog::Image("Rendered", "Rendered image", rendered);
	}

	// Read counter value and check.
	{
		const int numSamples		= de::max(1, renderCtx.getRenderTarget().getNumSamples());
		const int expectedCounter	= expectPartialResult ? viewportWidth*viewportHeight/2				: viewportWidth*viewportHeight;
		const int tolerance			= expectPartialResult ? de::max(viewportWidth, viewportHeight)*3	: 0;
		const int expectedMin		= de::max(0, expectedCounter - tolerance);
		const int expectedMax		= (expectedCounter + tolerance) * numSamples;

		if (readIntegerTextureViaFBOAndVerify(renderCtx, glLog, *texture, TEXTURETYPE_2D, TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT32),
											  IVec3(1, 1, 1), R32UIImageSingleValueVerifier(expectedMin, expectedMax)))
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got wrong value");

		return STOP;
	}
}

} // anonymous

ShaderImageLoadStoreTests::ShaderImageLoadStoreTests (Context& context)
	: TestCaseGroup(context, "image_load_store", "Shader Image Load & Store Tests")
{
}

ShaderImageLoadStoreTests::~ShaderImageLoadStoreTests (void)
{
}

void ShaderImageLoadStoreTests::init (void)
{
	// Per-image-type tests.

	{
		static const TextureType imageTypes[] =
		{
			TEXTURETYPE_2D,
			TEXTURETYPE_CUBE,
			TEXTURETYPE_3D,
			TEXTURETYPE_2D_ARRAY,
			TEXTURETYPE_BUFFER
		};

		static const TextureFormat formats[] =
		{
			TextureFormat(TextureFormat::RGBA,	TextureFormat::FLOAT),
			TextureFormat(TextureFormat::RGBA,	TextureFormat::HALF_FLOAT),
			TextureFormat(TextureFormat::R,		TextureFormat::FLOAT),

			TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT32),
			TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT16),
			TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8),
			TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT32),

			TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT32),
			TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT16),
			TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8),
			TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT32),

			TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8),

			TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT8)
		};

		for (int imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageTypes); imageTypeNdx++)
		{
			const TextureType		imageType			= imageTypes[imageTypeNdx];
			TestCaseGroup* const	imageTypeGroup		= new TestCaseGroup(m_context, getTextureTypeName(imageType), "");
			addChild(imageTypeGroup);

			TestCaseGroup* const	storeGroup			= new TestCaseGroup(m_context, "store",					"Plain imageStore() cases");
			TestCaseGroup* const	loadStoreGroup		= new TestCaseGroup(m_context, "load_store",			"Cases with imageLoad() followed by imageStore()");
			TestCaseGroup* const	atomicGroup			= new TestCaseGroup(m_context, "atomic",				"Atomic image operation cases");
			TestCaseGroup* const	qualifierGroup		= new TestCaseGroup(m_context, "qualifiers",			"Coherent, volatile and restrict");
			TestCaseGroup* const	reinterpretGroup	= new TestCaseGroup(m_context, "format_reinterpret",	"Cases with differing texture and image formats");
			TestCaseGroup* const	imageSizeGroup		= new TestCaseGroup(m_context, "image_size",			"imageSize() cases");
			imageTypeGroup->addChild(storeGroup);
			imageTypeGroup->addChild(loadStoreGroup);
			imageTypeGroup->addChild(atomicGroup);
			imageTypeGroup->addChild(qualifierGroup);
			imageTypeGroup->addChild(reinterpretGroup);
			imageTypeGroup->addChild(imageSizeGroup);

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

				if (imageType == TEXTURETYPE_BUFFER && !isFormatSupportedForTextureBuffer(format))
					continue;

				// Store cases.

				storeGroup->addChild(new ImageStoreCase(m_context, formatName.c_str(), "", format, imageType));
				if (textureLayerType(imageType) != imageType)
					storeGroup->addChild(new ImageStoreCase(m_context, (formatName + "_single_layer").c_str(), "", format, imageType, ImageStoreCase::CASEFLAG_SINGLE_LAYER_BIND));

				// Load & store.

				loadStoreGroup->addChild(new ImageLoadAndStoreCase(m_context, formatName.c_str(), "", format, imageType));
				if (textureLayerType(imageType) != imageType)
					loadStoreGroup->addChild(new ImageLoadAndStoreCase(m_context, (formatName + "_single_layer").c_str(), "", format, imageType, ImageLoadAndStoreCase::CASEFLAG_SINGLE_LAYER_BIND));

				if (format.order == TextureFormat::R)
				{
					// Atomic operations.

					for (int operationI = 0; operationI < ATOMIC_OPERATION_LAST; operationI++)
					{
						for (int atomicCaseTypeI = 0; atomicCaseTypeI < ATOMIC_OPERATION_CASE_TYPE_LAST; atomicCaseTypeI++)
						{
							const AtomicOperation operation = (AtomicOperation)operationI;

							if (format.type == TextureFormat::FLOAT && operation != ATOMIC_OPERATION_EXCHANGE)
								continue;

							const AtomicOperationCaseType	caseType		= (AtomicOperationCaseType)atomicCaseTypeI;
							const string					caseTypeName	= caseType == ATOMIC_OPERATION_CASE_TYPE_END_RESULT		? "result"
																			: caseType == ATOMIC_OPERATION_CASE_TYPE_RETURN_VALUES	? "return_value"
																			: DE_NULL;
							const string					caseName		= string() + getAtomicOperationCaseName(operation) + "_" + formatName + "_" + caseTypeName;

							if (operation == ATOMIC_OPERATION_COMP_SWAP)
								atomicGroup->addChild(new AtomicCompSwapCase(m_context, caseName.c_str(), "", format, imageType, caseType));
							else
								atomicGroup->addChild(new BinaryAtomicOperationCase(m_context, caseName.c_str(), "", format, imageType, operation, caseType));
						}
					}

					// Coherence.

					for (int coherenceQualifierI = 0; coherenceQualifierI < CoherenceCase::QUALIFIER_LAST; coherenceQualifierI++)
					{
						const CoherenceCase::Qualifier	coherenceQualifier		= (CoherenceCase::Qualifier)coherenceQualifierI;
						const char* const				coherenceQualifierName	= coherenceQualifier == CoherenceCase::QUALIFIER_COHERENT ? "coherent"
																				: coherenceQualifier == CoherenceCase::QUALIFIER_VOLATILE ? "volatile"
																				: DE_NULL;
						const string					caseName				= string() + coherenceQualifierName + "_" + formatName;

						qualifierGroup->addChild(new CoherenceCase(m_context, caseName.c_str(), "", format, imageType, coherenceQualifier));
					}
				}
			}

			// Restrict.
			qualifierGroup->addChild(new ImageLoadAndStoreCase(m_context, "restrict", "", TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), imageType, ImageLoadAndStoreCase::CASEFLAG_RESTRICT_IMAGES));

			// Format re-interpretation.

			for (int texFmtNdx = 0; texFmtNdx < DE_LENGTH_OF_ARRAY(formats); texFmtNdx++)
			for (int imgFmtNdx = 0; imgFmtNdx < DE_LENGTH_OF_ARRAY(formats); imgFmtNdx++)
			{
				const TextureFormat& texFmt = formats[texFmtNdx];
				const TextureFormat& imgFmt = formats[imgFmtNdx];

				if (imageType == TEXTURETYPE_BUFFER && !isFormatSupportedForTextureBuffer(texFmt))
					continue;

				if (texFmt != imgFmt && texFmt.getPixelSize() == imgFmt.getPixelSize())
					reinterpretGroup->addChild(new ImageLoadAndStoreCase(m_context,
																		 (getShaderImageFormatQualifier(texFmt) + "_" + getShaderImageFormatQualifier(imgFmt)).c_str(), "",
																		 texFmt, imgFmt, imageType));
			}

			// imageSize().

			{
				static const IVec3 baseImageSizes[] =
				{
					IVec3(32, 32, 32),
					IVec3(12, 34, 56),
					IVec3(1,   1,  1),
					IVec3(7,   1,  1)
				};

				for (int imageAccessI = 0; imageAccessI < ImageSizeCase::IMAGEACCESS_LAST; imageAccessI++)
				{
					const ImageSizeCase::ImageAccess	imageAccess		= (ImageSizeCase::ImageAccess)imageAccessI;
					const char* const					imageAccessStr	= imageAccess == ImageSizeCase::IMAGEACCESS_READ_ONLY				? "readonly"
																		: imageAccess == ImageSizeCase::IMAGEACCESS_WRITE_ONLY				? "writeonly"
																		: imageAccess == ImageSizeCase::IMAGEACCESS_READ_ONLY_WRITE_ONLY	? "readonly_writeonly"
																		: deFatalStr("Invalid ImageAccess");

					for (int imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(baseImageSizes); imageSizeNdx++)
					{
						const IVec3&	baseSize	= baseImageSizes[imageSizeNdx];
						const IVec3		imageSize	= imageType == TEXTURETYPE_BUFFER		? IVec3(baseSize.x(), 1, 1)
													: imageType == TEXTURETYPE_2D			? IVec3(baseSize.x(), baseSize.y(), 1)
													: imageType == TEXTURETYPE_CUBE			? IVec3(baseSize.x(), baseSize.x(), 1)
													: imageType == TEXTURETYPE_3D			? baseSize
													: imageType == TEXTURETYPE_2D_ARRAY		? baseSize
													: IVec3(-1, -1, -1);

						const string	sizeStr		= imageType == TEXTURETYPE_BUFFER		? toString(imageSize.x())
													: imageType == TEXTURETYPE_2D			? toString(imageSize.x()) + "x" + toString(imageSize.y())
													: imageType == TEXTURETYPE_CUBE			? toString(imageSize.x()) + "x" + toString(imageSize.y())
													: imageType == TEXTURETYPE_3D			? toString(imageSize.x()) + "x" + toString(imageSize.y()) + "x" + toString(imageSize.z())
													: imageType == TEXTURETYPE_2D_ARRAY		? toString(imageSize.x()) + "x" + toString(imageSize.y()) + "x" + toString(imageSize.z())
													: deFatalStr("Invalid TextureType");

						const string	caseName	= string() + imageAccessStr + "_" + sizeStr;

						imageSizeGroup->addChild(new ImageSizeCase(m_context, caseName.c_str(), "", TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), imageType, imageSize, imageAccess));
					}
				}
			}
		}
	}

	// early_fragment_tests cases.

	{
		TestCaseGroup* const earlyTestsGroup = new TestCaseGroup(m_context, "early_fragment_tests", "");
		addChild(earlyTestsGroup);

		for (int testRenderTargetI = 0; testRenderTargetI < EarlyFragmentTestsCase::RENDERTARGET_LAST; testRenderTargetI++)
		for (int useEarlyTestsI = 0; useEarlyTestsI <= 1; useEarlyTestsI++)
		for (int testTypeI = 0; testTypeI < EarlyFragmentTestsCase::TESTTYPE_LAST; testTypeI++)
		{
			const EarlyFragmentTestsCase::RenderTargetType	targetType		= (EarlyFragmentTestsCase::RenderTargetType)testRenderTargetI;
			const bool										useEarlyTests	= useEarlyTestsI != 0;
			const EarlyFragmentTestsCase::TestType			testType		= (EarlyFragmentTestsCase::TestType)testTypeI;

			const string									testTypeName	= testType == EarlyFragmentTestsCase::TESTTYPE_DEPTH	? "depth"
																			: testType == EarlyFragmentTestsCase::TESTTYPE_STENCIL	? "stencil"
																			: DE_NULL;

			const string									targetName		= targetType == EarlyFragmentTestsCase::RENDERTARGET_FBO							? (std::string("_fbo"))
																			: targetType == EarlyFragmentTestsCase::RENDERTARGET_FBO_WITHOUT_TEST_ATTACHMENT	? (std::string("_fbo_with_no_") + testTypeName)
																			: std::string("");

			const string									caseName		= string(useEarlyTests ? "" : "no_") + "early_fragment_tests_" + testTypeName + targetName;

			const string									caseDesc		= string(useEarlyTests ? "Specify" : "Don't specify")
																			+ " early_fragment_tests, use the " + testTypeName + " test"
																			+ ((targetType == EarlyFragmentTestsCase::RENDERTARGET_FBO)								? (", render to fbo")
																			   : (targetType == EarlyFragmentTestsCase::RENDERTARGET_FBO_WITHOUT_TEST_ATTACHMENT)	? (", render to fbo without relevant buffer")
																			   : (""));

			earlyTestsGroup->addChild(new EarlyFragmentTestsCase(m_context, caseName.c_str(), caseDesc.c_str(), testType, useEarlyTests, targetType));
		}
	}
}

} // Functional
} // gles31
} // deqp
