/*-------------------------------------------------------------------------
 * 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 atomic operation tests.
 *//*--------------------------------------------------------------------*/

#include "es31fShaderAtomicOpTests.hpp"
#include "gluShaderProgram.hpp"
#include "gluShaderUtil.hpp"
#include "gluRenderContext.hpp"
#include "gluObjectWrapper.hpp"
#include "gluProgramInterfaceQuery.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuFormatUtil.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include <algorithm>
#include <set>

namespace deqp
{
namespace gles31
{
namespace Functional
{

using std::string;
using std::vector;
using tcu::TestLog;
using tcu::UVec3;
using std::set;
using namespace glu;

template<typename T, int Size>
static inline T product (const tcu::Vector<T, Size>& v)
{
	T res = v[0];
	for (int ndx = 1; ndx < Size; ndx++)
		res *= v[ndx];
	return res;
}

class ShaderAtomicOpCase : public TestCase
{
public:
							ShaderAtomicOpCase	(Context& context, const char* name, const char* funcName, AtomicOperandType operandType, DataType type, Precision precision, const UVec3& workGroupSize);
							~ShaderAtomicOpCase	(void);

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

protected:
	virtual void			getInputs			(int numValues, int stride, void* inputs) const = 0;
	virtual bool			verify				(int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const = 0;

	const string			m_funcName;
	const AtomicOperandType	m_operandType;
	const DataType			m_type;
	const Precision			m_precision;

	const UVec3				m_workGroupSize;
	const UVec3				m_numWorkGroups;

	deUint32				m_initialValue;

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

	ShaderProgram*			m_program;
};

ShaderAtomicOpCase::ShaderAtomicOpCase (Context& context, const char* name, const char* funcName, AtomicOperandType operandType, DataType type, Precision precision, const UVec3& workGroupSize)
	: TestCase			(context, name, funcName)
	, m_funcName		(funcName)
	, m_operandType		(operandType)
	, m_type			(type)
	, m_precision		(precision)
	, m_workGroupSize	(workGroupSize)
	, m_numWorkGroups	(4,4,4)
	, m_initialValue	(0)
	, m_program			(DE_NULL)
{
}

ShaderAtomicOpCase::~ShaderAtomicOpCase (void)
{
	ShaderAtomicOpCase::deinit();
}

void ShaderAtomicOpCase::init (void)
{
	const bool			isSSBO		= m_operandType == ATOMIC_OPERAND_BUFFER_VARIABLE;
	const char*			precName	= getPrecisionName(m_precision);
	const char*			typeName	= getDataTypeName(m_type);

	const DataType		outType		= isSSBO ? m_type : glu::TYPE_UINT;
	const char*			outTypeName	= getDataTypeName(outType);

	const deUint32		numValues	= product(m_workGroupSize)*product(m_numWorkGroups);
	std::ostringstream	src;

	src << "#version 310 es\n"
		<< "layout(local_size_x = " << m_workGroupSize.x()
		<< ", local_size_y = " << m_workGroupSize.y()
		<< ", local_size_z = " << m_workGroupSize.z() << ") in;\n"
		<< "layout(binding = 0) buffer InOut\n"
		<< "{\n"
		<< "	" << precName << " " << typeName << " inputValues[" << numValues << "];\n"
		<< "	" << precName << " " << outTypeName << " outputValues[" << numValues << "];\n"
		<< "	" << (isSSBO ? "coherent " : "") << precName << " " << outTypeName << " groupValues[" << product(m_numWorkGroups) << "];\n"
		<< "} sb_inout;\n";

	if (!isSSBO)
		src << "shared " << precName << " " << typeName << " s_var;\n";

	src << "\n"
		<< "void main (void)\n"
		<< "{\n"
		<< "	uint localSize  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n"
		<< "	uint globalNdx  = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
		<< "	uint globalOffs = localSize*globalNdx;\n"
		<< "	uint offset     = globalOffs + gl_LocalInvocationIndex;\n"
		<< "\n";

	if (isSSBO)
	{
		DE_ASSERT(outType == m_type);
		src << "	sb_inout.outputValues[offset] = " << m_funcName << "(sb_inout.groupValues[globalNdx], sb_inout.inputValues[offset]);\n";
	}
	else
	{
		const string		castBeg	= outType != m_type ? (string(outTypeName) + "(") : string("");
		const char* const	castEnd	= outType != m_type ? ")" : "";

		src << "	if (gl_LocalInvocationIndex == 0u)\n"
			<< "		s_var = " << typeName << "(" << tcu::toHex(m_initialValue) << "u);\n"
			<< "	barrier();\n"
			<< "	" << precName << " " << typeName << " res = " << m_funcName << "(s_var, sb_inout.inputValues[offset]);\n"
			<< "	sb_inout.outputValues[offset] = " << castBeg << "res" << castEnd << ";\n"
			<< "	barrier();\n"
			<< "	if (gl_LocalInvocationIndex == 0u)\n"
			<< "		sb_inout.groupValues[globalNdx] = " << castBeg << "s_var" << castEnd << ";\n";
	}

	src << "}\n";

	DE_ASSERT(!m_program);
	m_program = new ShaderProgram(m_context.getRenderContext(), ProgramSources() << ComputeSource(src.str()));

	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
	{
		delete m_program;
		m_program = DE_NULL;
		throw tcu::TestError("Compile failed");
	}
}

void ShaderAtomicOpCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}

ShaderAtomicOpCase::IterateResult ShaderAtomicOpCase::iterate (void)
{
	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	const deUint32				program			= m_program->getProgram();
	const Buffer				inoutBuffer		(m_context.getRenderContext());
	const deUint32				blockNdx		= gl.getProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "InOut");
	const InterfaceBlockInfo	blockInfo		= getProgramInterfaceBlockInfo(gl, program, GL_SHADER_STORAGE_BLOCK, blockNdx);
	const deUint32				inVarNdx		= gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.inputValues[0]");
	const InterfaceVariableInfo	inVarInfo		= getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, inVarNdx);
	const deUint32				outVarNdx		= gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.outputValues[0]");
	const InterfaceVariableInfo	outVarInfo		= getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, outVarNdx);
	const deUint32				groupVarNdx		= gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.groupValues[0]");
	const InterfaceVariableInfo	groupVarInfo	= getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, groupVarNdx);
	const deUint32				numValues		= product(m_workGroupSize)*product(m_numWorkGroups);

	TCU_CHECK(inVarInfo.arraySize == numValues &&
			  outVarInfo.arraySize == numValues &&
			  groupVarInfo.arraySize == product(m_numWorkGroups));

	gl.useProgram(program);

	// Setup buffer.
	{
		vector<deUint8> bufData(blockInfo.dataSize);
		std::fill(bufData.begin(), bufData.end(), 0);

		getInputs((int)numValues, (int)inVarInfo.arrayStride, &bufData[0] + inVarInfo.offset);

		if (m_operandType == ATOMIC_OPERAND_BUFFER_VARIABLE)
		{
			for (deUint32 valNdx = 0; valNdx < product(m_numWorkGroups); valNdx++)
				*(deUint32*)(&bufData[0] + groupVarInfo.offset + groupVarInfo.arrayStride*valNdx) = m_initialValue;
		}

		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *inoutBuffer);
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockInfo.dataSize, &bufData[0], GL_STATIC_READ);
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *inoutBuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
	}

	gl.dispatchCompute(m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());

	// Read back and compare
	{
		const void*		resPtr		= gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, blockInfo.dataSize, GL_MAP_READ_BIT);
		bool			isOk		= true;

		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
		TCU_CHECK(resPtr);

		isOk = verify((int)numValues,
					  (int)inVarInfo.arrayStride, (const deUint8*)resPtr + inVarInfo.offset,
					  (int)outVarInfo.arrayStride, (const deUint8*)resPtr + outVarInfo.offset,
					  (int)groupVarInfo.arrayStride, (const deUint8*)resPtr + groupVarInfo.offset);

		gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()");

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Comparison failed");
	}

	return STOP;
}

class ShaderAtomicAddCase : public ShaderAtomicOpCase
{
public:
	ShaderAtomicAddCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
		: ShaderAtomicOpCase(context, name, "atomicAdd", operandType, type, precision, UVec3(3,2,1))
	{
		m_initialValue = 1;
	}

protected:
	void getInputs (int numValues, int stride, void* inputs) const
	{
		de::Random	rnd			(deStringHash(getName()));
		const int	maxVal		= m_precision == PRECISION_LOWP ? 2 : 32;
		const int	minVal		= 1;

		// \todo [2013-09-04 pyry] Negative values!

		for (int valNdx = 0; valNdx < numValues; valNdx++)
			*(int*)((deUint8*)inputs + stride*valNdx) = rnd.getInt(minVal, maxVal);
	}

	bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const
	{
		const int	workGroupSize	= (int)product(m_workGroupSize);
		const int	numWorkGroups	= numValues/workGroupSize;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int	groupOffset		= groupNdx*workGroupSize;
			const int	groupOutput		= *(const deInt32*)((const deUint8*)groupOutputs + groupNdx*groupStride);
			set<int>	outValues;
			bool		maxFound		= false;
			int			valueSum		= (int)m_initialValue;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const int inputValue = *(const deInt32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx));
				valueSum += inputValue;
			}

			if (groupOutput != valueSum)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected sum " << valueSum << ", got " << groupOutput << TestLog::EndMessage;
				return false;
			}

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const int	inputValue		= *(const deInt32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx));
				const int	outputValue		= *(const deInt32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx));

				if (!de::inRange(outputValue, (int)m_initialValue, valueSum-inputValue))
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": expected value in range [" << m_initialValue << ", " << (valueSum-inputValue)
														   << "], got " << outputValue
									   << TestLog::EndMessage;
					return false;
				}

				if (outValues.find(outputValue) != outValues.end())
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": found duplicate value " << outputValue
									   << TestLog::EndMessage;
					return false;
				}

				outValues.insert(outputValue);
				if (outputValue == valueSum-inputValue)
					maxFound = true;
			}

			if (!maxFound)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: could not find maximum expected value from group " << groupNdx << TestLog::EndMessage;
				return false;
			}

			if (outValues.find((int)m_initialValue) == outValues.end())
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: could not find initial value from group " << groupNdx << TestLog::EndMessage;
				return false;
			}
		}

		return true;
	}
};


static int getPrecisionNumIntegerBits (glu::Precision precision)
{
	switch (precision)
	{
		case glu::PRECISION_HIGHP:		return 32;
		case glu::PRECISION_MEDIUMP:	return 16;
		case glu::PRECISION_LOWP:		return 9;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

static deUint32 getPrecisionMask (int numPreciseBits)
{
	// \note: bit shift with larger or equal than var length is undefined, use 64 bit ints
	return (deUint32)((((deUint64)1u) << numPreciseBits) - 1) ;
}

static bool intEqualsAfterUintCast (deInt32 value, deUint32 casted, glu::Precision precision)
{
	// Bit format of 'casted' = [ uint -> highp uint promotion bits (0) ] [ sign extend bits (s) ] [ value bits ]
	//                                                                                             |--min len---|
	//                                                                    |---------------signed length---------|
	//                          |-------------------------------- highp uint length ----------------------------|

	const deUint32	reference		= (deUint32)value;
	const int		signBitOn		= value < 0;
	const int		numPreciseBits	= getPrecisionNumIntegerBits(precision);
	const deUint32	preciseMask		= getPrecisionMask(numPreciseBits);

	// Lowest N bits must match, N = minimum precision
	if ((reference & preciseMask) != (casted & preciseMask))
		return false;

	// Other lowest bits must match the sign and the remaining (topmost) if any must be 0
	for (int signedIntegerLength = numPreciseBits; signedIntegerLength <= 32; ++signedIntegerLength)
	{
		const deUint32 signBits = (signBitOn) ? (getPrecisionMask(signedIntegerLength)) : (0u);

		if ((signBits & ~preciseMask) == (casted & ~preciseMask))
			return true;
	}
	return false;
}

static bool containsAfterUintCast (const std::set<deInt32>& haystack, deUint32 needle, glu::Precision precision)
{
	for (std::set<deInt32>::const_iterator it = haystack.begin(); it != haystack.end(); ++it)
		if (intEqualsAfterUintCast(*it, needle, precision))
			return true;
	return false;
}

static bool containsAfterUintCast (const std::set<deUint32>& haystack, deInt32 needle, glu::Precision precision)
{
	for (std::set<deUint32>::const_iterator it = haystack.begin(); it != haystack.end(); ++it)
		if (intEqualsAfterUintCast(needle, *it, precision))
			return true;
	return false;
}

class ShaderAtomicMinCase : public ShaderAtomicOpCase
{
public:
	ShaderAtomicMinCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
		: ShaderAtomicOpCase(context, name, "atomicMin", operandType, type, precision, UVec3(3,2,1))
	{
		m_initialValue = m_precision == PRECISION_LOWP ? 100 : 1000;
	}

protected:
	void getInputs (int numValues, int stride, void* inputs) const
	{
		de::Random	rnd			(deStringHash(getName()));
		const bool	isSigned	= m_type == TYPE_INT;
		const int	maxVal		= m_precision == PRECISION_LOWP ? 100 : 1000;
		const int	minVal		= isSigned ? -maxVal : 0;

		for (int valNdx = 0; valNdx < numValues; valNdx++)
			*(int*)((deUint8*)inputs + stride*valNdx) = rnd.getInt(minVal, maxVal);
	}

	bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const
	{
		const int	workGroupSize	= (int)product(m_workGroupSize);
		const int	numWorkGroups	= numValues/workGroupSize;
		bool		anyError		= false;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int		groupOffset		= groupNdx*workGroupSize;
			const deUint32	groupOutput		= *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride);
			set<deInt32>	inValues;
			set<deUint32>	outValues;
			int				minValue		= (int)m_initialValue;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deInt32 inputValue = *(const deInt32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx));
				inValues.insert(inputValue);
				minValue = de::min(inputValue, minValue);
			}

			if (!intEqualsAfterUintCast(minValue, groupOutput, m_precision))
			{
				m_testCtx.getLog()
					<< TestLog::Message
					<< "ERROR: at group " << groupNdx
					<< ": expected minimum " << minValue << " (" << tcu::Format::Hex<8>((deUint32)minValue) << ")"
					<< ", got " << groupOutput << " (" << tcu::Format::Hex<8>(groupOutput) << ")"
					<< TestLog::EndMessage;
				anyError = true;
			}

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx));

				if (!containsAfterUintCast(inValues, outputValue, m_precision) &&
					!intEqualsAfterUintCast((deInt32)m_initialValue, outputValue, m_precision))
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": found unexpected value " << outputValue
														   << " (" << tcu::Format::Hex<8>(outputValue) << ")"
									   << TestLog::EndMessage;
					anyError = true;
				}

				outValues.insert(outputValue);
			}

			if (!containsAfterUintCast(outValues, (int)m_initialValue, m_precision))
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: could not find initial value from group " << groupNdx << TestLog::EndMessage;
				anyError = true;
			}
		}

		return !anyError;
	}
};

class ShaderAtomicMaxCase : public ShaderAtomicOpCase
{
public:
	ShaderAtomicMaxCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
		: ShaderAtomicOpCase(context, name, "atomicMax", operandType, type, precision, UVec3(3,2,1))
	{
		const bool isSigned = m_type == TYPE_INT;
		m_initialValue = isSigned ? (m_precision == PRECISION_LOWP ? -100 : -1000) : 0;
	}

protected:
	void getInputs (int numValues, int stride, void* inputs) const
	{
		de::Random	rnd			(deStringHash(getName()));
		const bool	isSigned	= m_type == TYPE_INT;
		const int	maxVal		= m_precision == PRECISION_LOWP ? 100 : 1000;
		const int	minVal		= isSigned ? -maxVal : 0;

		for (int valNdx = 0; valNdx < numValues; valNdx++)
			*(int*)((deUint8*)inputs + stride*valNdx) = rnd.getInt(minVal, maxVal);
	}

	bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const
	{
		const int	workGroupSize	= (int)product(m_workGroupSize);
		const int	numWorkGroups	= numValues/workGroupSize;
		bool		anyError		= false;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int		groupOffset		= groupNdx*workGroupSize;
			const deUint32	groupOutput		= *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride);
			set<int>		inValues;
			set<deUint32>	outValues;
			int				maxValue		= (int)m_initialValue;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deInt32 inputValue = *(const deInt32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx));
				inValues.insert(inputValue);
				maxValue = de::max(maxValue, inputValue);
			}

			if (!intEqualsAfterUintCast(maxValue, groupOutput, m_precision))
			{
				m_testCtx.getLog()
					<< TestLog::Message
					<< "ERROR: at group " << groupNdx
					<< ": expected maximum " << maxValue << " (" << tcu::Format::Hex<8>((deUint32)maxValue) << ")"
					<< ", got " << groupOutput << " (" << tcu::Format::Hex<8>(groupOutput) << ")"
					<< TestLog::EndMessage;
				anyError = true;
			}

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx));

				if (!containsAfterUintCast(inValues, outputValue, m_precision) &&
					!intEqualsAfterUintCast((deInt32)m_initialValue, outputValue, m_precision))
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": found unexpected value " << outputValue
														   << " (" << tcu::Format::Hex<8>(outputValue) << ")"
									   << TestLog::EndMessage;
					anyError = true;
				}

				outValues.insert(outputValue);
			}

			if (!containsAfterUintCast(outValues, (int)m_initialValue, m_precision))
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: could not find initial value from group " << groupNdx << TestLog::EndMessage;
				anyError = true;
			}
		}

		return !anyError;
	}
};

class ShaderAtomicAndCase : public ShaderAtomicOpCase
{
public:
	ShaderAtomicAndCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
		: ShaderAtomicOpCase(context, name, "atomicAnd", operandType, type, precision, UVec3(3,2,1))
	{
		const int		numBits		= m_precision == PRECISION_HIGHP ? 32 :
									  m_precision == PRECISION_MEDIUMP ? 16 : 8;
		const deUint32	valueMask	= numBits == 32 ? ~0u : (1u<<numBits)-1u;
		m_initialValue = ~((1u<<(numBits-1u)) | 1u) & valueMask; // All bits except lowest and highest set.
	}

protected:
	void getInputs (int numValues, int stride, void* inputs) const
	{
		de::Random		rnd				(deStringHash(getName()));
		const int		workGroupSize	= (int)product(m_workGroupSize);
		const int		numWorkGroups	= numValues/workGroupSize;
		const int		numBits			= m_precision == PRECISION_HIGHP ? 32 :
										  m_precision == PRECISION_MEDIUMP ? 16 : 8;
		const deUint32	valueMask		= numBits == 32 ? ~0u : (1u<<numBits)-1u;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int		groupOffset		= groupNdx*workGroupSize;
			const deUint32	groupMask		= 1<<rnd.getInt(0, numBits-2); // One bit is always set.

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
				*(deUint32*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = (rnd.getUint32() & valueMask) | groupMask;
		}
	}

	bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const
	{
		const int		workGroupSize	= (int)product(m_workGroupSize);
		const int		numWorkGroups	= numValues/workGroupSize;
		const int		numBits			= m_precision == PRECISION_HIGHP ? 32 :
										  m_precision == PRECISION_MEDIUMP ? 16 : 8;
		const deUint32	compareMask		= (m_type == TYPE_UINT || numBits == 32) ? ~0u : (1u<<numBits)-1u;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int		groupOffset		= groupNdx*workGroupSize;
			const deUint32	groupOutput		= *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride);
			deUint32		expectedValue	= m_initialValue;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 inputValue = *(const deUint32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx));
				expectedValue &= inputValue;
			}

			if ((groupOutput & compareMask) != (expectedValue & compareMask))
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected " << tcu::toHex(expectedValue) << ", got " << tcu::toHex(groupOutput) << TestLog::EndMessage;
				return false;
			}

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx));

				if ((compareMask & (outputValue & ~m_initialValue)) != 0)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": found unexpected value " << tcu::toHex(outputValue)
									   << TestLog::EndMessage;
					return false;
				}
			}
		}

		return true;
	}
};

class ShaderAtomicOrCase : public ShaderAtomicOpCase
{
public:
	ShaderAtomicOrCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
		: ShaderAtomicOpCase(context, name, "atomicOr", operandType, type, precision, UVec3(3,2,1))
	{
		m_initialValue = 1u; // Lowest bit set.
	}

protected:
	void getInputs (int numValues, int stride, void* inputs) const
	{
		de::Random		rnd				(deStringHash(getName()));
		const int		workGroupSize	= (int)product(m_workGroupSize);
		const int		numWorkGroups	= numValues/workGroupSize;
		const int		numBits			= m_precision == PRECISION_HIGHP ? 32 :
										  m_precision == PRECISION_MEDIUMP ? 16 : 8;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int groupOffset = groupNdx*workGroupSize;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
				*(deUint32*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = 1u<<rnd.getInt(0, numBits-1);
		}
	}

	bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const
	{
		const int		workGroupSize	= (int)product(m_workGroupSize);
		const int		numWorkGroups	= numValues/workGroupSize;
		const int		numBits			= m_precision == PRECISION_HIGHP ? 32 :
										  m_precision == PRECISION_MEDIUMP ? 16 : 8;
		const deUint32	compareMask		= (m_type == TYPE_UINT || numBits == 32) ? ~0u : (1u<<numBits)-1u;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int		groupOffset		= groupNdx*workGroupSize;
			const deUint32	groupOutput		= *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride);
			deUint32		expectedValue	= m_initialValue;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 inputValue = *(const deUint32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx));
				expectedValue |= inputValue;
			}

			if ((groupOutput & compareMask) != (expectedValue & compareMask))
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected " << tcu::toHex(expectedValue) << ", got " << tcu::toHex(groupOutput) << TestLog::EndMessage;
				return false;
			}

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx));

				if ((compareMask & (outputValue & m_initialValue)) == 0)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": found unexpected value " << tcu::toHex(outputValue)
									   << TestLog::EndMessage;
					return false;
				}
			}
		}

		return true;
	}
};

class ShaderAtomicXorCase : public ShaderAtomicOpCase
{
public:
	ShaderAtomicXorCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
		: ShaderAtomicOpCase(context, name, "atomicXor", operandType, type, precision, UVec3(3,2,1))
	{
		m_initialValue = 0;
	}

protected:
	void getInputs (int numValues, int stride, void* inputs) const
	{
		de::Random		rnd				(deStringHash(getName()));
		const int		workGroupSize	= (int)product(m_workGroupSize);
		const int		numWorkGroups	= numValues/workGroupSize;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int groupOffset = groupNdx*workGroupSize;

			// First uses random bit-pattern.
			*(deUint32*)((deUint8*)inputs + stride*(groupOffset)) = rnd.getUint32();

			// Rest have either all or no bits set.
			for (int localNdx = 1; localNdx < workGroupSize; localNdx++)
				*(deUint32*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = rnd.getBool() ? ~0u : 0u;
		}
	}

	bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const
	{
		const int		workGroupSize	= (int)product(m_workGroupSize);
		const int		numWorkGroups	= numValues/workGroupSize;
		const int		numBits			= m_precision == PRECISION_HIGHP ? 32 :
										  m_precision == PRECISION_MEDIUMP ? 16 : 8;
		const deUint32	compareMask		= numBits == 32 ? ~0u : (1u<<numBits)-1u;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int		groupOffset		= groupNdx*workGroupSize;
			const deUint32	groupOutput		= *(const deUint32*)((const deUint8*)groupOutputs + groupNdx*groupStride);
			const deUint32	randomValue		= *(const deInt32*)((const deUint8*)inputs + inputStride*groupOffset);
			const deUint32	expected0		= randomValue ^ 0u;
			const deUint32	expected1		= randomValue ^ ~0u;
			int				numXorZeros		= (m_initialValue == 0) ? 1 : 0;

			for (int localNdx = 1; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 inputValue = *(const deUint32*)((const deUint8*)inputs + inputStride*(groupOffset+localNdx));
				if (inputValue == 0)
					numXorZeros += 1;
			}

			const deUint32 expected = (numXorZeros%2 == 0) ? expected0 : expected1;

			if ((groupOutput & compareMask) != (expected & compareMask))
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected " << tcu::toHex(expected0)
													   << " or " << tcu::toHex(expected1) << " (compare mask " << tcu::toHex(compareMask)
													   << "), got " << tcu::toHex(groupOutput) << TestLog::EndMessage;
				return false;
			}

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const deUint32 outputValue = *(const deUint32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx));

				if ((outputValue & compareMask) != 0 &&
					(outputValue & compareMask) != compareMask &&
					(outputValue & compareMask) != (expected0&compareMask) &&
					(outputValue & compareMask) != (expected1&compareMask))
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": found unexpected value " << tcu::toHex(outputValue)
									   << TestLog::EndMessage;
					return false;
				}
			}
		}

		return true;
	}
};

class ShaderAtomicExchangeCase : public ShaderAtomicOpCase
{
public:
	ShaderAtomicExchangeCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
		: ShaderAtomicOpCase(context, name, "atomicExchange", operandType, type, precision, UVec3(3,2,1))
	{
		m_initialValue = 0;
	}

protected:
	void getInputs (int numValues, int stride, void* inputs) const
	{
		const int	workGroupSize	= (int)product(m_workGroupSize);
		const int	numWorkGroups	= numValues/workGroupSize;

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int groupOffset = groupNdx*workGroupSize;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
				*(int*)((deUint8*)inputs + stride*(groupOffset+localNdx)) = localNdx+1;
		}
	}

	bool verify (int numValues, int inputStride, const void* inputs, int outputStride, const void* outputs, int groupStride, const void* groupOutputs) const
	{
		const int	workGroupSize	= (int)product(m_workGroupSize);
		const int	numWorkGroups	= numValues/workGroupSize;

		DE_UNREF(inputStride && inputs);

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int	groupOffset		= groupNdx*workGroupSize;
			const int	groupOutput		= *(const deInt32*)((const deUint8*)groupOutputs + groupNdx*groupStride);
			set<int>	usedValues;

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const int outputValue = *(const deInt32*)((const deUint8*)outputs + outputStride*(groupOffset+localNdx));

				if (!de::inRange(outputValue, 0, workGroupSize) || usedValues.find(outputValue) != usedValues.end())
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": found unexpected value " << outputValue
									   << TestLog::EndMessage;
					return false;
				}
				usedValues.insert(outputValue);
			}

			if (!de::inRange(groupOutput, 0, workGroupSize) || usedValues.find(groupOutput) != usedValues.end())
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": unexpected final value" << groupOutput << TestLog::EndMessage;
				return false;
			}
		}

		return true;
	}
};

class ShaderAtomicCompSwapCase : public TestCase
{
public:
									ShaderAtomicCompSwapCase	(Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision);
									~ShaderAtomicCompSwapCase	(void);

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

protected:

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

	const AtomicOperandType			m_operandType;
	const DataType					m_type;
	const Precision					m_precision;

	const UVec3						m_workGroupSize;
	const UVec3						m_numWorkGroups;

	ShaderProgram*					m_program;
};

ShaderAtomicCompSwapCase::ShaderAtomicCompSwapCase (Context& context, const char* name, AtomicOperandType operandType, DataType type, Precision precision)
	: TestCase			(context, name, "atomicCompSwap() Test")
	, m_operandType		(operandType)
	, m_type			(type)
	, m_precision		(precision)
	, m_workGroupSize	(3,2,1)
	, m_numWorkGroups	(4,4,4)
	, m_program			(DE_NULL)
{
}

ShaderAtomicCompSwapCase::~ShaderAtomicCompSwapCase (void)
{
	ShaderAtomicCompSwapCase::deinit();
}

void ShaderAtomicCompSwapCase::init (void)
{
	const bool			isSSBO		= m_operandType == ATOMIC_OPERAND_BUFFER_VARIABLE;
	const char*			precName	= getPrecisionName(m_precision);
	const char*			typeName	= getDataTypeName(m_type);
	const deUint32		numValues	= product(m_workGroupSize)*product(m_numWorkGroups);
	std::ostringstream	src;

	src << "#version 310 es\n"
		<< "layout(local_size_x = " << m_workGroupSize.x()
		<< ", local_size_y = " << m_workGroupSize.y()
		<< ", local_size_z = " << m_workGroupSize.z() << ") in;\n"
		<< "layout(binding = 0) buffer InOut\n"
		<< "{\n"
		<< "	" << precName << " " << typeName << " compareValues[" << numValues << "];\n"
		<< "	" << precName << " " << typeName << " exchangeValues[" << numValues << "];\n"
		<< "	" << precName << " " << typeName << " outputValues[" << numValues << "];\n"
		<< "	" << (isSSBO ? "coherent " : "") << precName << " " << typeName << " groupValues[" << product(m_numWorkGroups) << "];\n"
		<< "} sb_inout;\n";

	if (!isSSBO)
		src << "shared " << precName << " " << typeName << " s_var;\n";

	src << "\n"
		<< "void main (void)\n"
		<< "{\n"
		<< "	uint localSize  = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z;\n"
		<< "	uint globalNdx  = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
		<< "	uint globalOffs = localSize*globalNdx;\n"
		<< "	uint offset     = globalOffs + gl_LocalInvocationIndex;\n"
		<< "\n";

	if (!isSSBO)
	{
		src << "	if (gl_LocalInvocationIndex == 0u)\n"
			<< "		s_var = " << typeName << "(" << 0 << ");\n"
			<< "\n";
	}

	src << "	" << precName << " " << typeName << " compare = sb_inout.compareValues[offset];\n"
		<< "	" << precName << " " << typeName << " exchange = sb_inout.exchangeValues[offset];\n"
		<< "	" << precName << " " << typeName << " result;\n"
		<< "	bool swapDone = false;\n"
		<< "\n"
		<< "	for (uint ndx = 0u; ndx < localSize; ndx++)\n"
		<< "	{\n"
		<< "		barrier();\n"
		<< "		if (!swapDone)\n"
		<< "		{\n"
		<< "			result = atomicCompSwap(" << (isSSBO ? "sb_inout.groupValues[globalNdx]" : "s_var") << ", compare, exchange);\n"
		<< "			if (result == compare)\n"
		<< "				swapDone = true;\n"
		<< "		}\n"
		<< "	}\n"
		<< "\n"
		<< "	sb_inout.outputValues[offset] = result;\n";

	if (!isSSBO)
	{
		src << "	barrier();\n"
			<< "	if (gl_LocalInvocationIndex == 0u)\n"
			<< "		sb_inout.groupValues[globalNdx] = s_var;\n";
	}

	src << "}\n";

	DE_ASSERT(!m_program);
	m_program = new ShaderProgram(m_context.getRenderContext(), ProgramSources() << ComputeSource(src.str()));

	m_testCtx.getLog() << *m_program;

	if (!m_program->isOk())
	{
		delete m_program;
		m_program = DE_NULL;
		throw tcu::TestError("Compile failed");
	}
}

void ShaderAtomicCompSwapCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}

ShaderAtomicOpCase::IterateResult ShaderAtomicCompSwapCase::iterate (void)
{
	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	const deUint32				program			= m_program->getProgram();
	const Buffer				inoutBuffer		(m_context.getRenderContext());
	const deUint32				blockNdx		= gl.getProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "InOut");
	const InterfaceBlockInfo	blockInfo		= getProgramInterfaceBlockInfo(gl, program, GL_SHADER_STORAGE_BLOCK, blockNdx);
	const deUint32				cmpVarNdx		= gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.compareValues[0]");
	const InterfaceVariableInfo	cmpVarInfo		= getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, cmpVarNdx);
	const deUint32				exhVarNdx		= gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.exchangeValues[0]");
	const InterfaceVariableInfo	exhVarInfo		= getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, exhVarNdx);
	const deUint32				outVarNdx		= gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.outputValues[0]");
	const InterfaceVariableInfo	outVarInfo		= getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, outVarNdx);
	const deUint32				groupVarNdx		= gl.getProgramResourceIndex(program, GL_BUFFER_VARIABLE, "InOut.groupValues[0]");
	const InterfaceVariableInfo	groupVarInfo	= getProgramInterfaceVariableInfo(gl, program, GL_BUFFER_VARIABLE, groupVarNdx);
	const deUint32				numValues		= product(m_workGroupSize)*product(m_numWorkGroups);

	TCU_CHECK(cmpVarInfo.arraySize == numValues &&
			  exhVarInfo.arraySize == numValues &&
			  outVarInfo.arraySize == numValues &&
			  groupVarInfo.arraySize == product(m_numWorkGroups));

	gl.useProgram(program);

	// \todo [2013-09-05 pyry] Use randomized input values!

	// Setup buffer.
	{
		const deUint32	workGroupSize	= product(m_workGroupSize);
		vector<deUint8>	bufData			(blockInfo.dataSize);

		std::fill(bufData.begin(), bufData.end(), 0);

		for (deUint32 ndx = 0; ndx < numValues; ndx++)
			*(deUint32*)(&bufData[0] + cmpVarInfo.offset + cmpVarInfo.arrayStride*ndx) = ndx%workGroupSize;

		for (deUint32 ndx = 0; ndx < numValues; ndx++)
			*(deUint32*)(&bufData[0] + exhVarInfo.offset + exhVarInfo.arrayStride*ndx) = (ndx%workGroupSize)+1;

		gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, *inoutBuffer);
		gl.bufferData(GL_SHADER_STORAGE_BUFFER, blockInfo.dataSize, &bufData[0], GL_STATIC_READ);
		gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, *inoutBuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Output buffer setup failed");
	}

	gl.dispatchCompute(m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());

	// Read back and compare
	{
		const void*		resPtr			= gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, blockInfo.dataSize, GL_MAP_READ_BIT);
		const int		numWorkGroups	= (int)product(m_numWorkGroups);
		const int		workGroupSize	= (int)product(m_workGroupSize);
		bool			isOk			= true;

		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
		TCU_CHECK(resPtr);

		for (int groupNdx = 0; groupNdx < numWorkGroups; groupNdx++)
		{
			const int	groupOffset		= groupNdx*workGroupSize;
			const int	groupOutput		= *(const deInt32*)((const deUint8*)resPtr + groupVarInfo.offset + groupNdx*groupVarInfo.arrayStride);

			for (int localNdx = 0; localNdx < workGroupSize; localNdx++)
			{
				const int	refValue		= localNdx;
				const int	outputValue		= *(const deInt32*)((const deUint8*)resPtr + outVarInfo.offset + outVarInfo.arrayStride*(groupOffset+localNdx));

				if (outputValue != refValue)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ", invocation " << localNdx
														   << ": expected " << refValue << ", got " << outputValue
									   << TestLog::EndMessage;
					isOk = false;
					break;
				}
			}

			if (groupOutput != workGroupSize)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: at group " << groupNdx << ": expected" << workGroupSize << ", got " << groupOutput << TestLog::EndMessage;
				isOk = false;
				break;
			}
		}

		gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer()");

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Comparison failed");
	}

	return STOP;
}

ShaderAtomicOpTests::ShaderAtomicOpTests (Context& context, const char* name, AtomicOperandType operandType)
	: TestCaseGroup	(context, name, "Atomic Operation Tests")
	, m_operandType	(operandType)
{
}

ShaderAtomicOpTests::~ShaderAtomicOpTests (void)
{
}

template<typename T>
static tcu::TestCaseGroup* createAtomicOpGroup (Context& context, AtomicOperandType operandType, const char* groupName)
{
	tcu::TestCaseGroup *const group = new tcu::TestCaseGroup(context.getTestContext(), groupName, (string("Atomic ") + groupName).c_str());
	try
	{
		for (int precNdx = 0; precNdx < PRECISION_LAST; precNdx++)
		{
			for (int typeNdx = 0; typeNdx < 2; typeNdx++)
			{
				const Precision		precision		= Precision(precNdx);
				const DataType		type			= typeNdx > 0 ? TYPE_INT : TYPE_UINT;
				const string		caseName		= string(getPrecisionName(precision)) + "_" + getDataTypeName(type);

				group->addChild(new T(context, caseName.c_str(), operandType, type, precision));
			}
		}

		return group;
	}
	catch (...)
	{
		delete group;
		throw;
	}
}

void ShaderAtomicOpTests::init (void)
{
	addChild(createAtomicOpGroup<ShaderAtomicAddCase>		(m_context, m_operandType, "add"));
	addChild(createAtomicOpGroup<ShaderAtomicMinCase>		(m_context, m_operandType, "min"));
	addChild(createAtomicOpGroup<ShaderAtomicMaxCase>		(m_context, m_operandType, "max"));
	addChild(createAtomicOpGroup<ShaderAtomicAndCase>		(m_context, m_operandType, "and"));
	addChild(createAtomicOpGroup<ShaderAtomicOrCase>		(m_context, m_operandType, "or"));
	addChild(createAtomicOpGroup<ShaderAtomicXorCase>		(m_context, m_operandType, "xor"));
	addChild(createAtomicOpGroup<ShaderAtomicExchangeCase>	(m_context, m_operandType, "exchange"));
	addChild(createAtomicOpGroup<ShaderAtomicCompSwapCase>	(m_context, m_operandType, "compswap"));
}

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