/*-------------------------------------------------------------------------
 * 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"
														 : DE_NULL) +
														"}\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"
														 : DE_NULL) +
														"}\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 DE_NULL;
	}
}

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"
														 : DE_NULL) +
														"}\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"
																		: DE_NULL;

					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())
													: DE_NULL;

						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
