/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) 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 Draw tests
 *//*--------------------------------------------------------------------*/

#include "glsDrawTest.hpp"

#include "deRandom.h"
#include "deRandom.hpp"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "deFloat16.h"
#include "deUniquePtr.hpp"
#include "deArrayUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuPixelFormat.hpp"
#include "tcuRGBA.hpp"
#include "tcuSurface.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuImageCompare.hpp"
#include "tcuFloat.hpp"
#include "tcuTextureUtil.hpp"

#include "gluPixelTransfer.hpp"
#include "gluCallLogWrapper.hpp"

#include "sglrContext.hpp"
#include "sglrReferenceContext.hpp"
#include "sglrGLContext.hpp"

#include "rrGenericVector.hpp"

#include <cstring>
#include <cmath>
#include <vector>
#include <sstream>
#include <limits>

#include "glwDefs.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gls
{
namespace
{

using tcu::TestLog;
using namespace glw; // GL types

const int MAX_RENDER_TARGET_SIZE = 512;

// Utils

static GLenum targetToGL (DrawTestSpec::Target target)
{
	static const GLenum targets[] =
	{
		GL_ELEMENT_ARRAY_BUFFER,	// TARGET_ELEMENT_ARRAY = 0,
		GL_ARRAY_BUFFER				// TARGET_ARRAY,
	};

	return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target);
}

static GLenum usageToGL (DrawTestSpec::Usage usage)
{
	static const GLenum usages[] =
	{
		GL_DYNAMIC_DRAW,	// USAGE_DYNAMIC_DRAW = 0,
		GL_STATIC_DRAW,		// USAGE_STATIC_DRAW,
		GL_STREAM_DRAW,		// USAGE_STREAM_DRAW,

		GL_STREAM_READ,		// USAGE_STREAM_READ,
		GL_STREAM_COPY,		// USAGE_STREAM_COPY,

		GL_STATIC_READ,		// USAGE_STATIC_READ,
		GL_STATIC_COPY,		// USAGE_STATIC_COPY,

		GL_DYNAMIC_READ,	// USAGE_DYNAMIC_READ,
		GL_DYNAMIC_COPY		// USAGE_DYNAMIC_COPY,
	};

	return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage);
}

static GLenum inputTypeToGL (DrawTestSpec::InputType type)
{
	static const GLenum types[] =
	{
		GL_FLOAT,				// INPUTTYPE_FLOAT = 0,
		GL_FIXED,				// INPUTTYPE_FIXED,
		GL_DOUBLE,				// INPUTTYPE_DOUBLE
		GL_BYTE,				// INPUTTYPE_BYTE,
		GL_SHORT,				// INPUTTYPE_SHORT,
		GL_UNSIGNED_BYTE,		// INPUTTYPE_UNSIGNED_BYTE,
		GL_UNSIGNED_SHORT,		// INPUTTYPE_UNSIGNED_SHORT,

		GL_INT,					// INPUTTYPE_INT,
		GL_UNSIGNED_INT,		// INPUTTYPE_UNSIGNED_INT,
		GL_HALF_FLOAT,			// INPUTTYPE_HALF,
		GL_UNSIGNED_INT_2_10_10_10_REV, // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
		GL_INT_2_10_10_10_REV			// INPUTTYPE_INT_2_10_10_10,
	};

	return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type);
}

static std::string outputTypeToGLType (DrawTestSpec::OutputType type)
{
	static const char* types[] =
	{
		"float",		// OUTPUTTYPE_FLOAT = 0,
		"vec2",			// OUTPUTTYPE_VEC2,
		"vec3",			// OUTPUTTYPE_VEC3,
		"vec4",			// OUTPUTTYPE_VEC4,

		"int",			// OUTPUTTYPE_INT,
		"uint",			// OUTPUTTYPE_UINT,

		"ivec2",		// OUTPUTTYPE_IVEC2,
		"ivec3",		// OUTPUTTYPE_IVEC3,
		"ivec4",		// OUTPUTTYPE_IVEC4,

		"uvec2",		// OUTPUTTYPE_UVEC2,
		"uvec3",		// OUTPUTTYPE_UVEC3,
		"uvec4",		// OUTPUTTYPE_UVEC4,
	};

	return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type);
}

static GLenum primitiveToGL (DrawTestSpec::Primitive primitive)
{
	static const GLenum primitives[] =
	{
		GL_POINTS,						// PRIMITIVE_POINTS = 0,
		GL_TRIANGLES,					// PRIMITIVE_TRIANGLES,
		GL_TRIANGLE_FAN,				// PRIMITIVE_TRIANGLE_FAN,
		GL_TRIANGLE_STRIP,				// PRIMITIVE_TRIANGLE_STRIP,
		GL_LINES,						// PRIMITIVE_LINES
		GL_LINE_STRIP,					// PRIMITIVE_LINE_STRIP
		GL_LINE_LOOP,					// PRIMITIVE_LINE_LOOP
		GL_LINES_ADJACENCY,				// PRIMITIVE_LINES_ADJACENCY
		GL_LINE_STRIP_ADJACENCY,		// PRIMITIVE_LINE_STRIP_ADJACENCY
		GL_TRIANGLES_ADJACENCY,			// PRIMITIVE_TRIANGLES_ADJACENCY
		GL_TRIANGLE_STRIP_ADJACENCY,	// PRIMITIVE_TRIANGLE_STRIP_ADJACENCY
	};

	return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive);
}

static deUint32 indexTypeToGL (DrawTestSpec::IndexType indexType)
{
	static const GLenum indexTypes[] =
	{
		GL_UNSIGNED_BYTE,	// INDEXTYPE_BYTE = 0,
		GL_UNSIGNED_SHORT,	// INDEXTYPE_SHORT,
		GL_UNSIGNED_INT,	// INDEXTYPE_INT,
	};

	return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)indexType);
}

static bool inputTypeIsFloatType (DrawTestSpec::InputType type)
{
	if (type == DrawTestSpec::INPUTTYPE_FLOAT)
		return true;
	if (type == DrawTestSpec::INPUTTYPE_FIXED)
		return true;
	if (type == DrawTestSpec::INPUTTYPE_HALF)
		return true;
	if (type == DrawTestSpec::INPUTTYPE_DOUBLE)
		return true;
	return false;
}

static bool outputTypeIsFloatType (DrawTestSpec::OutputType type)
{
	if (type == DrawTestSpec::OUTPUTTYPE_FLOAT
		|| type == DrawTestSpec::OUTPUTTYPE_VEC2
		|| type == DrawTestSpec::OUTPUTTYPE_VEC3
		|| type == DrawTestSpec::OUTPUTTYPE_VEC4)
		return true;

	return false;
}

static bool outputTypeIsIntType (DrawTestSpec::OutputType type)
{
	if (type == DrawTestSpec::OUTPUTTYPE_INT
		|| type == DrawTestSpec::OUTPUTTYPE_IVEC2
		|| type == DrawTestSpec::OUTPUTTYPE_IVEC3
		|| type == DrawTestSpec::OUTPUTTYPE_IVEC4)
		return true;

	return false;
}

static bool outputTypeIsUintType (DrawTestSpec::OutputType type)
{
	if (type == DrawTestSpec::OUTPUTTYPE_UINT
		|| type == DrawTestSpec::OUTPUTTYPE_UVEC2
		|| type == DrawTestSpec::OUTPUTTYPE_UVEC3
		|| type == DrawTestSpec::OUTPUTTYPE_UVEC4)
		return true;

	return false;
}

static size_t getElementCount (DrawTestSpec::Primitive primitive, size_t primitiveCount)
{
	switch (primitive)
	{
		case DrawTestSpec::PRIMITIVE_POINTS:						return primitiveCount;
		case DrawTestSpec::PRIMITIVE_TRIANGLES:						return primitiveCount * 3;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:					return primitiveCount + 2;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:				return primitiveCount + 2;
		case DrawTestSpec::PRIMITIVE_LINES:							return primitiveCount * 2;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP:					return primitiveCount + 1;
		case DrawTestSpec::PRIMITIVE_LINE_LOOP:						return (primitiveCount==1) ? (2) : (primitiveCount);
		case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:				return primitiveCount * 4;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:			return primitiveCount + 3;
		case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:			return primitiveCount * 6;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:		return primitiveCount * 2 + 4;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

struct MethodInfo
{
	bool indexed;
	bool instanced;
	bool ranged;
	bool first;
	bool baseVertex;
	bool indirect;
};

static MethodInfo getMethodInfo (gls::DrawTestSpec::DrawMethod method)
{
	static const MethodInfo infos[] =
	{
		//	indexed		instanced	ranged		first		baseVertex	indirect
		{	false,		false,		false,		true,		false,		false	}, //!< DRAWMETHOD_DRAWARRAYS,
		{	false,		true,		false,		true,		false,		false	}, //!< DRAWMETHOD_DRAWARRAYS_INSTANCED,
		{	false,		true,		false,		true,		false,		true	}, //!< DRAWMETHOD_DRAWARRAYS_INDIRECT,
		{	true,		false,		false,		false,		false,		false	}, //!< DRAWMETHOD_DRAWELEMENTS,
		{	true,		false,		true,		false,		false,		false	}, //!< DRAWMETHOD_DRAWELEMENTS_RANGED,
		{	true,		true,		false,		false,		false,		false	}, //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED,
		{	true,		true,		false,		false,		true,		true	}, //!< DRAWMETHOD_DRAWELEMENTS_INDIRECT,
		{	true,		false,		false,		false,		true,		false	}, //!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
		{	true,		true,		false,		false,		true,		false	}, //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
		{	true,		false,		true,		false,		true,		false	}, //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
	};

	return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(infos, (int)method);
}

template<class T>
inline static void alignmentSafeAssignment (char* dst, T val)
{
	std::memcpy(dst, &val, sizeof(T));
}

static bool checkSpecsShaderCompatible (const DrawTestSpec& a, const DrawTestSpec& b)
{
	// Only the attributes matter
	if (a.attribs.size() != b.attribs.size())
		return false;

	for (size_t ndx = 0; ndx < a.attribs.size(); ++ndx)
	{
		// Only the output type (== shader input type) matters and the usage in the shader.

		if (a.attribs[ndx].additionalPositionAttribute != b.attribs[ndx].additionalPositionAttribute)
			return false;

		// component counts need not to match
		if (outputTypeIsFloatType(a.attribs[ndx].outputType) && outputTypeIsFloatType(b.attribs[ndx].outputType))
			continue;
		if (outputTypeIsIntType(a.attribs[ndx].outputType) && outputTypeIsIntType(b.attribs[ndx].outputType))
			continue;
		if (outputTypeIsUintType(a.attribs[ndx].outputType) && outputTypeIsUintType(b.attribs[ndx].outputType))
			continue;

		return false;
	}

	return true;
}

// generate random vectors in a way that does not depend on argument evaluation order

tcu::Vec4 generateRandomVec4 (de::Random& random)
{
	tcu::Vec4 retVal;

	for (int i = 0; i < 4; ++i)
		retVal[i] = random.getFloat();

	return retVal;
}

tcu::IVec4 generateRandomIVec4 (de::Random& random)
{
	tcu::IVec4 retVal;

	for (int i = 0; i < 4; ++i)
		retVal[i] = random.getUint32();

	return retVal;
}

tcu::UVec4 generateRandomUVec4 (de::Random& random)
{
	tcu::UVec4 retVal;

	for (int i = 0; i < 4; ++i)
		retVal[i] = random.getUint32();

	return retVal;
}

// IterationLogSectionEmitter

class IterationLogSectionEmitter
{
public:
								IterationLogSectionEmitter		(tcu::TestLog& log, size_t testIteration, size_t testIterations, const std::string& description, bool enabled);
								~IterationLogSectionEmitter		(void);
private:
								IterationLogSectionEmitter		(const IterationLogSectionEmitter&); // delete
	IterationLogSectionEmitter&	operator=						(const IterationLogSectionEmitter&); // delete

	tcu::TestLog&				m_log;
	bool						m_enabled;
};

IterationLogSectionEmitter::IterationLogSectionEmitter (tcu::TestLog& log, size_t testIteration, size_t testIterations, const std::string& description, bool enabled)
	: m_log		(log)
	, m_enabled	(enabled)
{
	if (m_enabled)
	{
		std::ostringstream buf;
		buf << "Iteration " << (testIteration+1) << "/" << testIterations;

		if (!description.empty())
			buf << " - " << description;

		m_log << tcu::TestLog::Section(buf.str(), buf.str());
	}
}

IterationLogSectionEmitter::~IterationLogSectionEmitter (void)
{
	if (m_enabled)
		m_log << tcu::TestLog::EndSection;
}

// GLValue

class GLValue
{
public:

	template<class Type>
	class WrappedType
	{
	public:
		static WrappedType<Type>	create			(Type value)							{ WrappedType<Type> v; v.m_value = value; return v; }
		inline Type					getValue		(void) const							{ return m_value; }

		inline WrappedType<Type>	operator+		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value + other.getValue())); }
		inline WrappedType<Type>	operator*		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value * other.getValue())); }
		inline WrappedType<Type>	operator/		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value / other.getValue())); }
		inline WrappedType<Type>	operator-		(const WrappedType<Type>& other) const	{ return WrappedType<Type>::create((Type)(m_value - other.getValue())); }

		inline WrappedType<Type>&	operator+=		(const WrappedType<Type>& other)		{ m_value += other.getValue(); return *this; }
		inline WrappedType<Type>&	operator*=		(const WrappedType<Type>& other)		{ m_value *= other.getValue(); return *this; }
		inline WrappedType<Type>&	operator/=		(const WrappedType<Type>& other)		{ m_value /= other.getValue(); return *this; }
		inline WrappedType<Type>&	operator-=		(const WrappedType<Type>& other)		{ m_value -= other.getValue(); return *this; }

		inline bool					operator==		(const WrappedType<Type>& other) const	{ return m_value == other.m_value; }
		inline bool					operator!=		(const WrappedType<Type>& other) const	{ return m_value != other.m_value; }
		inline bool					operator<		(const WrappedType<Type>& other) const	{ return m_value < other.m_value; }
		inline bool					operator>		(const WrappedType<Type>& other) const	{ return m_value > other.m_value; }
		inline bool					operator<=		(const WrappedType<Type>& other) const	{ return m_value <= other.m_value; }
		inline bool					operator>=		(const WrappedType<Type>& other) const	{ return m_value >= other.m_value; }

		inline						operator Type	(void) const							{ return m_value; }
		template<class T>
		inline T					to				(void) const							{ return (T)m_value; }
	private:
		Type	m_value;
	};

	typedef WrappedType<deInt16>	Short;
	typedef WrappedType<deUint16>	Ushort;

	typedef WrappedType<deInt8>		Byte;
	typedef WrappedType<deUint8>	Ubyte;

	typedef WrappedType<float>		Float;
	typedef WrappedType<double>		Double;

	typedef WrappedType<deInt32>	Int;
	typedef WrappedType<deUint32>	Uint;

	class Half
	{
	public:
		static Half			create			(float value)				{ Half h; h.m_value = floatToHalf(value); return h; }
		inline deFloat16	getValue		(void) const				{ return m_value; }

		inline Half			operator+		(const Half& other) const	{ return create(halfToFloat(m_value) + halfToFloat(other.getValue())); }
		inline Half			operator*		(const Half& other) const	{ return create(halfToFloat(m_value) * halfToFloat(other.getValue())); }
		inline Half			operator/		(const Half& other) const	{ return create(halfToFloat(m_value) / halfToFloat(other.getValue())); }
		inline Half			operator-		(const Half& other) const	{ return create(halfToFloat(m_value) - halfToFloat(other.getValue())); }

		inline Half&		operator+=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; }
		inline Half&		operator*=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value)); return *this; }
		inline Half&		operator/=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value)); return *this; }
		inline Half&		operator-=		(const Half& other)			{ m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value)); return *this; }

		inline bool			operator==		(const Half& other) const	{ return m_value == other.m_value; }
		inline bool			operator!=		(const Half& other) const	{ return m_value != other.m_value; }
		inline bool			operator<		(const Half& other) const	{ return halfToFloat(m_value) < halfToFloat(other.m_value); }
		inline bool			operator>		(const Half& other) const	{ return halfToFloat(m_value) > halfToFloat(other.m_value); }
		inline bool			operator<=		(const Half& other) const	{ return halfToFloat(m_value) <= halfToFloat(other.m_value); }
		inline bool			operator>=		(const Half& other) const	{ return halfToFloat(m_value) >= halfToFloat(other.m_value); }

		template<class T>
		inline T			to				(void) const				{ return (T)halfToFloat(m_value); }

		inline static deFloat16	floatToHalf		(float f);
		inline static float		halfToFloat		(deFloat16 h);
	private:
		deFloat16 m_value;
	};

	class Fixed
	{
	public:
		static Fixed		create			(deInt32 value)				{ Fixed v; v.m_value = value; return v; }
		inline deInt32		getValue		(void) const				{ return m_value; }

		inline Fixed		operator+		(const Fixed& other) const	{ return create(m_value + other.getValue()); }
		inline Fixed		operator*		(const Fixed& other) const	{ return create(m_value * other.getValue()); }
		inline Fixed		operator/		(const Fixed& other) const	{ return create(m_value / other.getValue()); }
		inline Fixed		operator-		(const Fixed& other) const	{ return create(m_value - other.getValue()); }

		inline Fixed&		operator+=		(const Fixed& other)		{ m_value += other.getValue(); return *this; }
		inline Fixed&		operator*=		(const Fixed& other)		{ m_value *= other.getValue(); return *this; }
		inline Fixed&		operator/=		(const Fixed& other)		{ m_value /= other.getValue(); return *this; }
		inline Fixed&		operator-=		(const Fixed& other)		{ m_value -= other.getValue(); return *this; }

		inline bool			operator==		(const Fixed& other) const	{ return m_value == other.m_value; }
		inline bool			operator!=		(const Fixed& other) const	{ return m_value != other.m_value; }
		inline bool			operator<		(const Fixed& other) const	{ return m_value < other.m_value; }
		inline bool			operator>		(const Fixed& other) const	{ return m_value > other.m_value; }
		inline bool			operator<=		(const Fixed& other) const	{ return m_value <= other.m_value; }
		inline bool			operator>=		(const Fixed& other) const	{ return m_value >= other.m_value; }

		inline				operator deInt32 (void) const				{ return m_value; }
		template<class T>
		inline T			to				(void) const				{ return (T)m_value; }
	private:
		deInt32				m_value;
	};

	// \todo [mika] This is pretty messy
						GLValue			(void)			: type(DrawTestSpec::INPUTTYPE_LAST) {}
	explicit			GLValue			(Float value)	: type(DrawTestSpec::INPUTTYPE_FLOAT),				fl(value)	{}
	explicit			GLValue			(Fixed value)	: type(DrawTestSpec::INPUTTYPE_FIXED),				fi(value)	{}
	explicit			GLValue			(Byte value)	: type(DrawTestSpec::INPUTTYPE_BYTE),				b(value)	{}
	explicit			GLValue			(Ubyte value)	: type(DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE),		ub(value)	{}
	explicit			GLValue			(Short value)	: type(DrawTestSpec::INPUTTYPE_SHORT),				s(value)	{}
	explicit			GLValue			(Ushort value)	: type(DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT),		us(value)	{}
	explicit			GLValue			(Int value)		: type(DrawTestSpec::INPUTTYPE_INT),				i(value)	{}
	explicit			GLValue			(Uint value)	: type(DrawTestSpec::INPUTTYPE_UNSIGNED_INT),		ui(value)	{}
	explicit			GLValue			(Half value)	: type(DrawTestSpec::INPUTTYPE_HALF),				h(value)	{}
	explicit			GLValue			(Double value)	: type(DrawTestSpec::INPUTTYPE_DOUBLE),				d(value)	{}

	float				toFloat			(void) const;

	static GLValue		getMaxValue		(DrawTestSpec::InputType type);
	static GLValue		getMinValue		(DrawTestSpec::InputType type);

	DrawTestSpec::InputType	type;

	union
	{
		Float		fl;
		Fixed		fi;
		Double		d;
		Byte		b;
		Ubyte		ub;
		Short		s;
		Ushort		us;
		Int			i;
		Uint		ui;
		Half		h;
	};
};

inline deFloat16 GLValue::Half::floatToHalf (float f)
{
	// No denorm support.
	tcu::Float<deUint16, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f);
	DE_ASSERT(!v.isNaN() && !v.isInf());
	return v.bits();
}

inline float GLValue::Half::halfToFloat (deFloat16 h)
{
	return tcu::Float16((deUint16)h).asFloat();
}

float GLValue::toFloat (void) const
{
	switch (type)
	{
		case DrawTestSpec::INPUTTYPE_FLOAT:
			return fl.getValue();
			break;

		case DrawTestSpec::INPUTTYPE_BYTE:
			return b.getValue();
			break;

		case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE:
			return ub.getValue();
			break;

		case DrawTestSpec::INPUTTYPE_SHORT:
			return s.getValue();
			break;

		case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT:
			return us.getValue();
			break;

		case DrawTestSpec::INPUTTYPE_FIXED:
		{
			int maxValue = 65536;
			return (float)(double(2 * fi.getValue() + 1) / (maxValue - 1));

			break;
		}

		case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
			return (float)ui.getValue();
			break;

		case DrawTestSpec::INPUTTYPE_INT:
			return (float)i.getValue();
			break;

		case DrawTestSpec::INPUTTYPE_HALF:
			return h.to<float>();
			break;

		case DrawTestSpec::INPUTTYPE_DOUBLE:
			return d.to<float>();
			break;

		default:
			DE_ASSERT(false);
			return 0.0f;
			break;
	};
}

GLValue GLValue::getMaxValue (DrawTestSpec::InputType type)
{
	GLValue rangesHi[(int)DrawTestSpec::INPUTTYPE_LAST];

	rangesHi[(int)DrawTestSpec::INPUTTYPE_FLOAT]			= GLValue(Float::create(127.0f));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_DOUBLE]			= GLValue(Double::create(127.0f));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_BYTE]				= GLValue(Byte::create(127));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE]	= GLValue(Ubyte::create(255));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT]	= GLValue(Ushort::create(65530));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_SHORT]			= GLValue(Short::create(32760));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_FIXED]			= GLValue(Fixed::create(32760));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_INT]				= GLValue(Int::create(2147483647));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT]		= GLValue(Uint::create(4294967295u));
	rangesHi[(int)DrawTestSpec::INPUTTYPE_HALF]				= GLValue(Half::create(256.0f));

	return rangesHi[(int)type];
}

GLValue GLValue::getMinValue (DrawTestSpec::InputType type)
{
	GLValue rangesLo[(int)DrawTestSpec::INPUTTYPE_LAST];

	rangesLo[(int)DrawTestSpec::INPUTTYPE_FLOAT]			= GLValue(Float::create(-127.0f));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_DOUBLE]			= GLValue(Double::create(-127.0f));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_BYTE]				= GLValue(Byte::create(-127));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE]	= GLValue(Ubyte::create(0));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT]	= GLValue(Ushort::create(0));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_SHORT]			= GLValue(Short::create(-32760));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_FIXED]			= GLValue(Fixed::create(-32760));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_INT]				= GLValue(Int::create(-2147483647));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT]		= GLValue(Uint::create(0));
	rangesLo[(int)DrawTestSpec::INPUTTYPE_HALF]				= GLValue(Half::create(-256.0f));

	return rangesLo[(int)type];
}

template<typename T>
struct GLValueTypeTraits;

template<> struct GLValueTypeTraits<GLValue::Float>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FLOAT;			};
template<> struct GLValueTypeTraits<GLValue::Double> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_DOUBLE;			};
template<> struct GLValueTypeTraits<GLValue::Byte>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_BYTE;			};
template<> struct GLValueTypeTraits<GLValue::Ubyte>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE;	};
template<> struct GLValueTypeTraits<GLValue::Ushort> { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT;	};
template<> struct GLValueTypeTraits<GLValue::Short>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_SHORT;			};
template<> struct GLValueTypeTraits<GLValue::Fixed>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FIXED;			};
template<> struct GLValueTypeTraits<GLValue::Int>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_INT;			};
template<> struct GLValueTypeTraits<GLValue::Uint>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_INT;	};
template<> struct GLValueTypeTraits<GLValue::Half>	 { static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_HALF;			};

template<typename T>
inline T extractGLValue (const GLValue& v);

template<> GLValue::Float	inline extractGLValue<GLValue::Float>		(const GLValue& v) { return v.fl; };
template<> GLValue::Double	inline extractGLValue<GLValue::Double>		(const GLValue& v) { return v.d; };
template<> GLValue::Byte	inline extractGLValue<GLValue::Byte>		(const GLValue& v) { return v.b; };
template<> GLValue::Ubyte	inline extractGLValue<GLValue::Ubyte>		(const GLValue& v) { return v.ub; };
template<> GLValue::Ushort	inline extractGLValue<GLValue::Ushort>		(const GLValue& v) { return v.us; };
template<> GLValue::Short	inline extractGLValue<GLValue::Short>		(const GLValue& v) { return v.s; };
template<> GLValue::Fixed	inline extractGLValue<GLValue::Fixed>		(const GLValue& v) { return v.fi; };
template<> GLValue::Int		inline extractGLValue<GLValue::Int>			(const GLValue& v) { return v.i; };
template<> GLValue::Uint	inline extractGLValue<GLValue::Uint>		(const GLValue& v) { return v.ui; };
template<> GLValue::Half	inline extractGLValue<GLValue::Half>		(const GLValue& v) { return v.h; };

template<class T>
inline T getRandom (deRandom& rnd, T min, T max);

template<>
inline GLValue::Float getRandom (deRandom& rnd, GLValue::Float min, GLValue::Float max)
{
	if (max < min)
		return min;

	return GLValue::Float::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>()));
}

template<>
inline GLValue::Double getRandom (deRandom& rnd, GLValue::Double min, GLValue::Double max)
{
	if (max < min)
		return min;

	return GLValue::Double::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>()));
}

template<>
inline GLValue::Short getRandom (deRandom& rnd, GLValue::Short min, GLValue::Short max)
{
	if (max < min)
		return min;

	return GLValue::Short::create((min == max ? min : (deInt16)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template<>
inline GLValue::Ushort getRandom (deRandom& rnd, GLValue::Ushort min, GLValue::Ushort max)
{
	if (max < min)
		return min;

	return GLValue::Ushort::create((min == max ? min : (deUint16)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template<>
inline GLValue::Byte getRandom (deRandom& rnd, GLValue::Byte min, GLValue::Byte max)
{
	if (max < min)
		return min;

	return GLValue::Byte::create((min == max ? min : (deInt8)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template<>
inline GLValue::Ubyte getRandom (deRandom& rnd, GLValue::Ubyte min, GLValue::Ubyte max)
{
	if (max < min)
		return min;

	return GLValue::Ubyte::create((min == max ? min : (deUint8)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
}

template<>
inline GLValue::Fixed getRandom (deRandom& rnd, GLValue::Fixed min, GLValue::Fixed max)
{
	if (max < min)
		return min;

	return GLValue::Fixed::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>()))));
}

template<>
inline GLValue::Half getRandom (deRandom& rnd, GLValue::Half min, GLValue::Half max)
{
	if (max < min)
		return min;

	float fMax = max.to<float>();
	float fMin = min.to<float>();
	GLValue::Half h = GLValue::Half::create(fMin + deRandom_getFloat(&rnd) * (fMax - fMin));
	return h;
}

template<>
inline GLValue::Int getRandom (deRandom& rnd, GLValue::Int min, GLValue::Int max)
{
	if (max < min)
		return min;

	return GLValue::Int::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>()))));
}

template<>
inline GLValue::Uint getRandom (deRandom& rnd, GLValue::Uint min, GLValue::Uint max)
{
	if (max < min)
		return min;

	return GLValue::Uint::create((min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<deUint32>() - min.to<deUint32>()))));
}

// Minimum difference required between coordinates
template<class T>
inline T minValue (void);

template<>
inline GLValue::Float minValue (void)
{
	return GLValue::Float::create(4 * 1.0f);
}

template<>
inline GLValue::Double minValue (void)
{
	return GLValue::Double::create(4 * 1.0f);
}

template<>
inline GLValue::Short minValue (void)
{
	return GLValue::Short::create(4 * 256);
}

template<>
inline GLValue::Ushort minValue (void)
{
	return GLValue::Ushort::create(4 * 256);
}

template<>
inline GLValue::Byte minValue (void)
{
	return GLValue::Byte::create(4 * 1);
}

template<>
inline GLValue::Ubyte minValue (void)
{
	return GLValue::Ubyte::create(4 * 2);
}

template<>
inline GLValue::Fixed minValue (void)
{
	return GLValue::Fixed::create(4 * 1);
}

template<>
inline GLValue::Int minValue (void)
{
	return GLValue::Int::create(4 * 16777216);
}

template<>
inline GLValue::Uint minValue (void)
{
	return GLValue::Uint::create(4 * 16777216);
}

template<>
inline GLValue::Half minValue (void)
{
	return GLValue::Half::create(4 * 1.0f);
}

template<class T>
inline T abs (T val);

template<>
inline GLValue::Fixed abs (GLValue::Fixed val)
{
	return GLValue::Fixed::create(0x7FFFu & val.getValue());
}

template<>
inline GLValue::Ubyte abs (GLValue::Ubyte val)
{
	return val;
}

template<>
inline GLValue::Byte abs (GLValue::Byte val)
{
	return GLValue::Byte::create(0x7Fu & val.getValue());
}

template<>
inline GLValue::Ushort abs (GLValue::Ushort val)
{
	return val;
}

template<>
inline GLValue::Short abs (GLValue::Short val)
{
	return GLValue::Short::create(0x7FFFu & val.getValue());
}

template<>
inline GLValue::Float abs (GLValue::Float val)
{
	return GLValue::Float::create(std::fabs(val.to<float>()));
}

template<>
inline GLValue::Double abs (GLValue::Double val)
{
	return GLValue::Double::create(std::fabs(val.to<float>()));
}

template<>
inline GLValue::Uint abs (GLValue::Uint val)
{
	return val;
}

template<>
inline GLValue::Int abs (GLValue::Int val)
{
	return GLValue::Int::create(0x7FFFFFFFu & val.getValue());
}

template<>
inline GLValue::Half abs (GLValue::Half val)
{
	return GLValue::Half::create(std::fabs(val.to<float>()));
}

// AttriuteArray

class AttributeArray
{
public:
								AttributeArray		(DrawTestSpec::Storage storage, sglr::Context& context);
								~AttributeArray		(void);

	void						data				(DrawTestSpec::Target target, size_t size, const char* data, DrawTestSpec::Usage usage);
	void						subdata				(DrawTestSpec::Target target, int offset, int size, const char* data);
	void						setupArray			(bool bound, int offset, int size, DrawTestSpec::InputType inType, DrawTestSpec::OutputType outType, bool normalized, int stride, int instanceDivisor, const rr::GenericVec4& defaultAttrib, bool isPositionAttr, bool bgraComponentOrder);
	void						bindAttribute		(deUint32 loc);
	void						bindIndexArray		(DrawTestSpec::Target storage);

	int							getComponentCount	(void) const { return m_componentCount; }
	DrawTestSpec::Target		getTarget			(void) const { return m_target; }
	DrawTestSpec::InputType		getInputType		(void) const { return m_inputType; }
	DrawTestSpec::OutputType	getOutputType		(void) const { return m_outputType; }
	DrawTestSpec::Storage		getStorageType		(void) const { return m_storage; }
	bool						getNormalized		(void) const { return m_normalize; }
	int							getStride			(void) const { return m_stride; }
	bool						isBound				(void) const { return m_bound; }
	bool						isPositionAttribute	(void) const { return m_isPositionAttr; }

private:
	DrawTestSpec::Storage		m_storage;
	sglr::Context&				m_ctx;
	deUint32					m_glBuffer;

	int							m_size;
	char*						m_data;
	int							m_componentCount;
	bool						m_bound;
	DrawTestSpec::Target		m_target;
	DrawTestSpec::InputType		m_inputType;
	DrawTestSpec::OutputType	m_outputType;
	bool						m_normalize;
	int							m_stride;
	int							m_offset;
	rr::GenericVec4				m_defaultAttrib;
	int							m_instanceDivisor;
	bool						m_isPositionAttr;
	bool						m_bgraOrder;
};

AttributeArray::AttributeArray (DrawTestSpec::Storage storage, sglr::Context& context)
	: m_storage			(storage)
	, m_ctx				(context)
	, m_glBuffer		(0)
	, m_size			(0)
	, m_data			(DE_NULL)
	, m_componentCount	(1)
	, m_bound			(false)
	, m_target			(DrawTestSpec::TARGET_ARRAY)
	, m_inputType		(DrawTestSpec::INPUTTYPE_FLOAT)
	, m_outputType		(DrawTestSpec::OUTPUTTYPE_VEC4)
	, m_normalize		(false)
	, m_stride			(0)
	, m_offset			(0)
	, m_instanceDivisor	(0)
	, m_isPositionAttr	(false)
	, m_bgraOrder		(false)
{
	if (m_storage == DrawTestSpec::STORAGE_BUFFER)
	{
		m_ctx.genBuffers(1, &m_glBuffer);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glGenBuffers()");
	}
}

AttributeArray::~AttributeArray	(void)
{
	if (m_storage == DrawTestSpec::STORAGE_BUFFER)
	{
		m_ctx.deleteBuffers(1, &m_glBuffer);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDeleteBuffers()");
	}
	else if (m_storage == DrawTestSpec::STORAGE_USER)
		delete[] m_data;
	else
		DE_ASSERT(false);
}

void AttributeArray::data (DrawTestSpec::Target target, size_t size, const char* ptr, DrawTestSpec::Usage usage)
{
	m_size = (int)size;
	m_target = target;

	if (m_storage == DrawTestSpec::STORAGE_BUFFER)
	{
		m_ctx.bindBuffer(targetToGL(target), m_glBuffer);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

		m_ctx.bufferData(targetToGL(target), size, ptr, usageToGL(usage));
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBufferData()");
	}
	else if (m_storage == DrawTestSpec::STORAGE_USER)
	{
		if (m_data)
			delete[] m_data;

		m_data = new char[size];
		std::memcpy(m_data, ptr, size);
	}
	else
		DE_ASSERT(false);
}

void AttributeArray::subdata (DrawTestSpec::Target target, int offset, int size, const char* ptr)
{
	m_target = target;

	if (m_storage == DrawTestSpec::STORAGE_BUFFER)
	{
		m_ctx.bindBuffer(targetToGL(target), m_glBuffer);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

		m_ctx.bufferSubData(targetToGL(target), offset, size, ptr);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBufferSubData()");
	}
	else if (m_storage == DrawTestSpec::STORAGE_USER)
		std::memcpy(m_data + offset, ptr, size);
	else
		DE_ASSERT(false);
}

void AttributeArray::setupArray (bool bound, int offset, int size, DrawTestSpec::InputType inputType, DrawTestSpec::OutputType outType, bool normalized, int stride, int instanceDivisor, const rr::GenericVec4& defaultAttrib, bool isPositionAttr, bool bgraComponentOrder)
{
	m_componentCount	= size;
	m_bound				= bound;
	m_inputType			= inputType;
	m_outputType		= outType;
	m_normalize			= normalized;
	m_stride			= stride;
	m_offset			= offset;
	m_defaultAttrib		= defaultAttrib;
	m_instanceDivisor	= instanceDivisor;
	m_isPositionAttr	= isPositionAttr;
	m_bgraOrder			= bgraComponentOrder;
}

void AttributeArray::bindAttribute (deUint32 loc)
{
	if (!isBound())
	{
		switch (m_inputType)
		{
			case DrawTestSpec::INPUTTYPE_FLOAT:
			{
				tcu::Vec4 attr = m_defaultAttrib.get<float>();

				switch (m_componentCount)
				{
					case 1: m_ctx.vertexAttrib1f(loc, attr.x()); break;
					case 2: m_ctx.vertexAttrib2f(loc, attr.x(), attr.y()); break;
					case 3: m_ctx.vertexAttrib3f(loc, attr.x(), attr.y(), attr.z()); break;
					case 4: m_ctx.vertexAttrib4f(loc, attr.x(), attr.y(), attr.z(), attr.w()); break;
					default: DE_ASSERT(DE_FALSE); break;
				}
				break;
			}
			case DrawTestSpec::INPUTTYPE_INT:
			{
				tcu::IVec4 attr = m_defaultAttrib.get<deInt32>();
				m_ctx.vertexAttribI4i(loc, attr.x(), attr.y(), attr.z(), attr.w());
				break;
			}
			case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
			{
				tcu::UVec4 attr = m_defaultAttrib.get<deUint32>();
				m_ctx.vertexAttribI4ui(loc, attr.x(), attr.y(), attr.z(), attr.w());
				break;
			}
			default:
				DE_ASSERT(DE_FALSE);
				break;
		}
	}
	else
	{
		const deUint8* basePtr = DE_NULL;

		if (m_storage == DrawTestSpec::STORAGE_BUFFER)
		{
			m_ctx.bindBuffer(targetToGL(m_target), m_glBuffer);
			GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

			basePtr = DE_NULL;
		}
		else if (m_storage == DrawTestSpec::STORAGE_USER)
		{
			m_ctx.bindBuffer(targetToGL(m_target), 0);
			GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

			basePtr = (const deUint8*)m_data;
		}
		else
			DE_ASSERT(DE_FALSE);

		if (!inputTypeIsFloatType(m_inputType))
		{
			// Input is not float type

			if (outputTypeIsFloatType(m_outputType))
			{
				const int size = (m_bgraOrder) ? (GL_BGRA) : (m_componentCount);

				DE_ASSERT(!(m_bgraOrder && m_componentCount != 4));

				// Output type is float type
				m_ctx.vertexAttribPointer(loc, size, inputTypeToGL(m_inputType), m_normalize, m_stride, basePtr + m_offset);
				GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()");
			}
			else
			{
				// Output type is int type
				m_ctx.vertexAttribIPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_stride, basePtr + m_offset);
				GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()");
			}
		}
		else
		{
			// Input type is float type

			// Output type must be float type
			DE_ASSERT(outputTypeIsFloatType(m_outputType));

			m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, basePtr + m_offset);
			GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()");
		}

		if (m_instanceDivisor)
			m_ctx.vertexAttribDivisor(loc, m_instanceDivisor);
	}
}

void AttributeArray::bindIndexArray (DrawTestSpec::Target target)
{
	if (m_storage == DrawTestSpec::STORAGE_USER)
	{
	}
	else if (m_storage == DrawTestSpec::STORAGE_BUFFER)
	{
		m_ctx.bindBuffer(targetToGL(target), m_glBuffer);
	}
}

// DrawTestShaderProgram

class DrawTestShaderProgram : public sglr::ShaderProgram
{
public:
												DrawTestShaderProgram		(const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays);

	void										shadeVertices				(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void										shadeFragments				(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	static std::string							genVertexSource				(const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays);
	static std::string							genFragmentSource			(const glu::RenderContext& ctx);
	static void									generateShaderParams		(std::map<std::string, std::string>& params, glu::ContextType type);
	static rr::GenericVecType					mapOutputType				(const DrawTestSpec::OutputType& type);
	static int									getComponentCount			(const DrawTestSpec::OutputType& type);

	static sglr::pdec::ShaderProgramDeclaration createProgramDeclaration	(const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays);

	std::vector<int>							m_componentCount;
	std::vector<bool>							m_isCoord;
	std::vector<rr::GenericVecType>				m_attrType;
};

DrawTestShaderProgram::DrawTestShaderProgram (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays)
	: sglr::ShaderProgram	(createProgramDeclaration(ctx, arrays))
	, m_componentCount		(arrays.size())
	, m_isCoord				(arrays.size())
	, m_attrType			(arrays.size())
{
	for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
	{
		m_componentCount[arrayNdx]	= getComponentCount(arrays[arrayNdx]->getOutputType());
		m_isCoord[arrayNdx]			= arrays[arrayNdx]->isPositionAttribute();
		m_attrType[arrayNdx]		= mapOutputType(arrays[arrayNdx]->getOutputType());
	}
}

template <typename T>
void calcShaderColorCoord (tcu::Vec2& coord, tcu::Vec3& color, const tcu::Vector<T, 4>& attribValue, bool isCoordinate, int numComponents)
{
	if (isCoordinate)
		switch (numComponents)
		{
			case 1:	coord += tcu::Vec2((float)attribValue.x(),							(float)attribValue.x());							break;
			case 2:	coord += tcu::Vec2((float)attribValue.x(),							(float)attribValue.y());							break;
			case 3:	coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(),	(float)attribValue.y());							break;
			case 4:	coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(),	(float)attribValue.y() + (float)attribValue.w());	break;

			default:
				DE_ASSERT(false);
		}
	else
	{
		switch (numComponents)
		{
			case 1:
				color = color * (float)attribValue.x();
				break;

			case 2:
				color.x() = color.x() * (float)attribValue.x();
				color.y() = color.y() * (float)attribValue.y();
				break;

			case 3:
				color.x() = color.x() * (float)attribValue.x();
				color.y() = color.y() * (float)attribValue.y();
				color.z() = color.z() * (float)attribValue.z();
				break;

			case 4:
				color.x() = color.x() * (float)attribValue.x() * (float)attribValue.w();
				color.y() = color.y() * (float)attribValue.y() * (float)attribValue.w();
				color.z() = color.z() * (float)attribValue.z() * (float)attribValue.w();
				break;

			default:
				DE_ASSERT(false);
		}
	}
}

void DrawTestShaderProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
{
	const float	u_coordScale = getUniformByName("u_coordScale").value.f;
	const float u_colorScale = getUniformByName("u_colorScale").value.f;

	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
	{
		const size_t varyingLocColor = 0;

		rr::VertexPacket& packet = *packets[packetNdx];

		// Calc output color
		tcu::Vec2 coord = tcu::Vec2(0.0, 0.0);
		tcu::Vec3 color = tcu::Vec3(1.0, 1.0, 1.0);

		for (int attribNdx = 0; attribNdx < (int)m_attrType.size(); attribNdx++)
		{
			const int	numComponents	= m_componentCount[attribNdx];
			const bool	isCoord			= m_isCoord[attribNdx];

			switch (m_attrType[attribNdx])
			{
				case rr::GENERICVECTYPE_FLOAT:	calcShaderColorCoord(coord, color, rr::readVertexAttribFloat(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), isCoord, numComponents);	break;
				case rr::GENERICVECTYPE_INT32:	calcShaderColorCoord(coord, color, rr::readVertexAttribInt	(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), isCoord, numComponents);	break;
				case rr::GENERICVECTYPE_UINT32:	calcShaderColorCoord(coord, color, rr::readVertexAttribUint	(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx), isCoord, numComponents);	break;
				default:
					DE_ASSERT(false);
			}
		}

		// Transform position
		{
			packet.position = tcu::Vec4(u_coordScale * coord.x(), u_coordScale * coord.y(), 1.0f, 1.0f);
			packet.pointSize = 1.0f;
		}

		// Pass color to FS
		{
			packet.outputs[varyingLocColor] = tcu::Vec4(u_colorScale * color.x(), u_colorScale * color.y(), u_colorScale * color.z(), 1.0f) * 0.5f + tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
		}
	}
}

void DrawTestShaderProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
{
	const size_t varyingLocColor = 0;

	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
	{
		rr::FragmentPacket& packet = packets[packetNdx];

		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readVarying<float>(packet, context, varyingLocColor, fragNdx));
	}
}

std::string DrawTestShaderProgram::genVertexSource (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays)
{
	std::map<std::string, std::string>	params;
	std::stringstream					vertexShaderTmpl;

	generateShaderParams(params, ctx.getType());

	vertexShaderTmpl << "${VTX_HDR}";

	for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
	{
		vertexShaderTmpl
			<< "${VTX_IN} highp " << outputTypeToGLType(arrays[arrayNdx]->getOutputType()) << " a_" << arrayNdx << ";\n";
	}

	vertexShaderTmpl <<
		"uniform highp float u_coordScale;\n"
		"uniform highp float u_colorScale;\n"
		"${VTX_OUT} ${COL_PRECISION} vec4 v_color;\n"
		"void main(void)\n"
		"{\n"
		"\tgl_PointSize = 1.0;\n"
		"\thighp vec2 coord = vec2(0.0, 0.0);\n"
		"\thighp vec3 color = vec3(1.0, 1.0, 1.0);\n";

	for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
	{
		const bool isPositionAttr = arrays[arrayNdx]->isPositionAttribute();

		if (isPositionAttr)
		{
			switch (arrays[arrayNdx]->getOutputType())
			{
				case (DrawTestSpec::OUTPUTTYPE_FLOAT):
				case (DrawTestSpec::OUTPUTTYPE_INT):
				case (DrawTestSpec::OUTPUTTYPE_UINT):
					vertexShaderTmpl <<
						"\tcoord += vec2(float(a_" << arrayNdx << "), float(a_" << arrayNdx << "));\n";
					break;

				case (DrawTestSpec::OUTPUTTYPE_VEC2):
				case (DrawTestSpec::OUTPUTTYPE_IVEC2):
				case (DrawTestSpec::OUTPUTTYPE_UVEC2):
					vertexShaderTmpl <<
						"\tcoord += vec2(a_" << arrayNdx << ".xy);\n";
					break;

				case (DrawTestSpec::OUTPUTTYPE_VEC3):
				case (DrawTestSpec::OUTPUTTYPE_IVEC3):
				case (DrawTestSpec::OUTPUTTYPE_UVEC3):
					vertexShaderTmpl <<
						"\tcoord += vec2(a_" << arrayNdx << ".xy);\n"
						"\tcoord.x += float(a_" << arrayNdx << ".z);\n";
					break;

				case (DrawTestSpec::OUTPUTTYPE_VEC4):
				case (DrawTestSpec::OUTPUTTYPE_IVEC4):
				case (DrawTestSpec::OUTPUTTYPE_UVEC4):
					vertexShaderTmpl <<
						"\tcoord += vec2(a_" << arrayNdx << ".xy);\n"
						"\tcoord += vec2(a_" << arrayNdx << ".zw);\n";
					break;

				default:
					DE_ASSERT(false);
					break;
			}
		}
		else
		{
			switch (arrays[arrayNdx]->getOutputType())
			{
				case (DrawTestSpec::OUTPUTTYPE_FLOAT):
				case (DrawTestSpec::OUTPUTTYPE_INT):
				case (DrawTestSpec::OUTPUTTYPE_UINT):
					vertexShaderTmpl <<
						"\tcolor = color * float(a_" << arrayNdx << ");\n";
					break;

				case (DrawTestSpec::OUTPUTTYPE_VEC2):
				case (DrawTestSpec::OUTPUTTYPE_IVEC2):
				case (DrawTestSpec::OUTPUTTYPE_UVEC2):
					vertexShaderTmpl <<
						"\tcolor.rg = color.rg * vec2(a_" << arrayNdx << ".xy);\n";
					break;

				case (DrawTestSpec::OUTPUTTYPE_VEC3):
				case (DrawTestSpec::OUTPUTTYPE_IVEC3):
				case (DrawTestSpec::OUTPUTTYPE_UVEC3):
					vertexShaderTmpl <<
						"\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz);\n";
					break;

				case (DrawTestSpec::OUTPUTTYPE_VEC4):
				case (DrawTestSpec::OUTPUTTYPE_IVEC4):
				case (DrawTestSpec::OUTPUTTYPE_UVEC4):
					vertexShaderTmpl <<
						"\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz) * float(a_" << arrayNdx << ".w);\n";
					break;

				default:
					DE_ASSERT(false);
					break;
			}
		}
	}

	vertexShaderTmpl <<
		"\tv_color = vec4(u_colorScale * color, 1.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);\n"
		"\tgl_Position = vec4(u_coordScale * coord, 1.0, 1.0);\n"
		"}\n";

	return tcu::StringTemplate(vertexShaderTmpl.str().c_str()).specialize(params);
}

std::string DrawTestShaderProgram::genFragmentSource (const glu::RenderContext& ctx)
{
	std::map<std::string, std::string> params;

	generateShaderParams(params, ctx.getType());

	static const char* fragmentShaderTmpl =
		"${FRAG_HDR}"
		"${FRAG_IN} ${COL_PRECISION} vec4 v_color;\n"
		"void main(void)\n"
		"{\n"
		"\t${FRAG_COLOR} = v_color;\n"
		"}\n";

	return tcu::StringTemplate(fragmentShaderTmpl).specialize(params);
}

void DrawTestShaderProgram::generateShaderParams (std::map<std::string, std::string>& params, glu::ContextType type)
{
	if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_300_ES))
	{
		params["VTX_IN"]		= "in";
		params["VTX_OUT"]		= "out";
		params["FRAG_IN"]		= "in";
		params["FRAG_COLOR"]	= "dEQP_FragColor";
		params["VTX_HDR"]		= "#version 300 es\n";
		params["FRAG_HDR"]		= "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
		params["COL_PRECISION"]	= "mediump";
	}
	else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_100_ES))
	{
		params["VTX_IN"]		= "attribute";
		params["VTX_OUT"]		= "varying";
		params["FRAG_IN"]		= "varying";
		params["FRAG_COLOR"]	= "gl_FragColor";
		params["VTX_HDR"]		= "";
		params["FRAG_HDR"]		= "";
		params["COL_PRECISION"]	= "mediump";
	}
	else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_430))
	{
		params["VTX_IN"]		= "in";
		params["VTX_OUT"]		= "out";
		params["FRAG_IN"]		= "in";
		params["FRAG_COLOR"]	= "dEQP_FragColor";
		params["VTX_HDR"]		= "#version 430\n";
		params["FRAG_HDR"]		= "#version 430\nlayout(location = 0) out highp vec4 dEQP_FragColor;\n";
		params["COL_PRECISION"]	= "highp";
	}
	else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_330))
	{
		params["VTX_IN"]		= "in";
		params["VTX_OUT"]		= "out";
		params["FRAG_IN"]		= "in";
		params["FRAG_COLOR"]	= "dEQP_FragColor";
		params["VTX_HDR"]		= "#version 330\n";
		params["FRAG_HDR"]		= "#version 330\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
		params["COL_PRECISION"]	= "mediump";
	}
	else
		DE_ASSERT(DE_FALSE);
}

rr::GenericVecType DrawTestShaderProgram::mapOutputType (const DrawTestSpec::OutputType& type)
{
	switch (type)
	{
		case (DrawTestSpec::OUTPUTTYPE_FLOAT):
		case (DrawTestSpec::OUTPUTTYPE_VEC2):
		case (DrawTestSpec::OUTPUTTYPE_VEC3):
		case (DrawTestSpec::OUTPUTTYPE_VEC4):
			return rr::GENERICVECTYPE_FLOAT;

		case (DrawTestSpec::OUTPUTTYPE_INT):
		case (DrawTestSpec::OUTPUTTYPE_IVEC2):
		case (DrawTestSpec::OUTPUTTYPE_IVEC3):
		case (DrawTestSpec::OUTPUTTYPE_IVEC4):
			return rr::GENERICVECTYPE_INT32;

		case (DrawTestSpec::OUTPUTTYPE_UINT):
		case (DrawTestSpec::OUTPUTTYPE_UVEC2):
		case (DrawTestSpec::OUTPUTTYPE_UVEC3):
		case (DrawTestSpec::OUTPUTTYPE_UVEC4):
			return rr::GENERICVECTYPE_UINT32;

		default:
			DE_ASSERT(false);
			return rr::GENERICVECTYPE_LAST;
	}
}

int DrawTestShaderProgram::getComponentCount (const DrawTestSpec::OutputType& type)
{
	switch (type)
	{
		case (DrawTestSpec::OUTPUTTYPE_FLOAT):
		case (DrawTestSpec::OUTPUTTYPE_INT):
		case (DrawTestSpec::OUTPUTTYPE_UINT):
			return 1;

		case (DrawTestSpec::OUTPUTTYPE_VEC2):
		case (DrawTestSpec::OUTPUTTYPE_IVEC2):
		case (DrawTestSpec::OUTPUTTYPE_UVEC2):
			return 2;

		case (DrawTestSpec::OUTPUTTYPE_VEC3):
		case (DrawTestSpec::OUTPUTTYPE_IVEC3):
		case (DrawTestSpec::OUTPUTTYPE_UVEC3):
			return 3;

		case (DrawTestSpec::OUTPUTTYPE_VEC4):
		case (DrawTestSpec::OUTPUTTYPE_IVEC4):
		case (DrawTestSpec::OUTPUTTYPE_UVEC4):
			return 4;

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

sglr::pdec::ShaderProgramDeclaration DrawTestShaderProgram::createProgramDeclaration (const glu::RenderContext& ctx, const std::vector<AttributeArray*>& arrays)
{
	sglr::pdec::ShaderProgramDeclaration decl;

	for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
		decl << sglr::pdec::VertexAttribute(std::string("a_") + de::toString(arrayNdx), mapOutputType(arrays[arrayNdx]->getOutputType()));

	decl << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT);
	decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT);

	decl << sglr::pdec::VertexSource(genVertexSource(ctx, arrays));
	decl << sglr::pdec::FragmentSource(genFragmentSource(ctx));

	decl << sglr::pdec::Uniform("u_coordScale", glu::TYPE_FLOAT);
	decl << sglr::pdec::Uniform("u_colorScale", glu::TYPE_FLOAT);

	return decl;
}

class RandomArrayGenerator
{
public:
	static char*			generateArray			(int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type);
	static char*			generateIndices			(int seed, int elementCount, DrawTestSpec::IndexType type, int offset, int min, int max, int indexBase);
	static rr::GenericVec4	generateAttributeValue	(int seed, DrawTestSpec::InputType type);

private:
	template<typename T>
	static char*			createIndices			(int seed, int elementCount, int offset, int min, int max, int indexBase);
	static void				setData					(char* data, DrawTestSpec::InputType type, deRandom& rnd, GLValue min, GLValue max);

	static char*			generateBasicArray		(int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type);
	template<typename T, typename GLType>
	static char*			createBasicArray		(int seed, int elementCount, int componentCount, int offset, int stride);
	static char*			generatePackedArray		(int seed, int elementCount, int componentCount, int offset, int stride);
};

void RandomArrayGenerator::setData (char* data, DrawTestSpec::InputType type, deRandom& rnd, GLValue min, GLValue max)
{
	switch (type)
	{
		case DrawTestSpec::INPUTTYPE_FLOAT:
		{
			alignmentSafeAssignment<float>(data, getRandom<GLValue::Float>(rnd, min.fl, max.fl));
			break;
		}

		case DrawTestSpec::INPUTTYPE_SHORT:
		{
			alignmentSafeAssignment<deInt16>(data, getRandom<GLValue::Short>(rnd, min.s, max.s));
			break;
		}

		case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT:
		{
			alignmentSafeAssignment<deUint16>(data, getRandom<GLValue::Ushort>(rnd, min.us, max.us));
			break;
		}

		case DrawTestSpec::INPUTTYPE_BYTE:
		{
			alignmentSafeAssignment<deInt8>(data, getRandom<GLValue::Byte>(rnd, min.b, max.b));
			break;
		}

		case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE:
		{
			alignmentSafeAssignment<deUint8>(data, getRandom<GLValue::Ubyte>(rnd, min.ub, max.ub));
			break;
		}

		case DrawTestSpec::INPUTTYPE_FIXED:
		{
			alignmentSafeAssignment<deInt32>(data, getRandom<GLValue::Fixed>(rnd, min.fi, max.fi));
			break;
		}

		case DrawTestSpec::INPUTTYPE_INT:
		{
			alignmentSafeAssignment<deInt32>(data, getRandom<GLValue::Int>(rnd, min.i, max.i));
			break;
		}

		case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
		{
			alignmentSafeAssignment<deUint32>(data, getRandom<GLValue::Uint>(rnd, min.ui, max.ui));
			break;
		}

		case DrawTestSpec::INPUTTYPE_HALF:
		{
			alignmentSafeAssignment<deFloat16>(data, getRandom<GLValue::Half>(rnd, min.h, max.h).getValue());
			break;
		}

		default:
			DE_ASSERT(false);
			break;
	}
}

char* RandomArrayGenerator::generateArray (int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type)
{
	if (type == DrawTestSpec::INPUTTYPE_INT_2_10_10_10 || type == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
		return generatePackedArray(seed, elementCount, componentCount, offset, stride);
	else
		return generateBasicArray(seed, elementCount, componentCount, offset, stride, type);
}

char* RandomArrayGenerator::generateBasicArray (int seed, int elementCount, int componentCount, int offset, int stride, DrawTestSpec::InputType type)
{
	switch (type)
	{
		case DrawTestSpec::INPUTTYPE_FLOAT:				return createBasicArray<float,		GLValue::Float>	(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_DOUBLE:			return createBasicArray<double,		GLValue::Double>(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_SHORT:				return createBasicArray<deInt16,	GLValue::Short>	(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT:	return createBasicArray<deUint16,	GLValue::Ushort>(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_BYTE:				return createBasicArray<deInt8,		GLValue::Byte>	(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE:		return createBasicArray<deUint8,	GLValue::Ubyte>	(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_FIXED:				return createBasicArray<deInt32,	GLValue::Fixed>	(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_INT:				return createBasicArray<deInt32,	GLValue::Int>	(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:		return createBasicArray<deUint32,	GLValue::Uint>	(seed, elementCount, componentCount, offset, stride);
		case DrawTestSpec::INPUTTYPE_HALF:				return createBasicArray<deFloat16,	GLValue::Half>	(seed, elementCount, componentCount, offset, stride);
		default:
			DE_ASSERT(false);
			break;
	}
	return DE_NULL;
}

#if (DE_COMPILER == DE_COMPILER_GCC) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
	// GCC 4.8/4.9 incorrectly emits array-bounds warning from createBasicArray()
#	define GCC_ARRAY_BOUNDS_FALSE_NEGATIVE 1
#endif

#if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE)
#	pragma GCC diagnostic push
#	pragma GCC diagnostic ignored "-Warray-bounds"
#endif

template<typename T, typename GLType>
char* RandomArrayGenerator::createBasicArray (int seed, int elementCount, int componentCount, int offset, int stride)
{
	DE_ASSERT(componentCount >= 1 && componentCount <= 4);

	const GLType min = extractGLValue<GLType>(GLValue::getMinValue(GLValueTypeTraits<GLType>::Type));
	const GLType max = extractGLValue<GLType>(GLValue::getMaxValue(GLValueTypeTraits<GLType>::Type));

	const size_t componentSize	= sizeof(T);
	const size_t elementSize	= componentSize * componentCount;
	const size_t bufferSize		= offset + (elementCount - 1) * stride + elementSize;

	char* data = new char[bufferSize];
	char* writePtr = data + offset;

	GLType previousComponents[4];

	deRandom rnd;
	deRandom_init(&rnd, seed);

	for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++)
	{
		GLType components[4];

		for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
		{
			components[componentNdx] = getRandom<GLType>(rnd, min, max);

			// Try to not create vertex near previous
			if (vertexNdx != 0 && abs(components[componentNdx] - previousComponents[componentNdx]) < minValue<GLType>())
			{
				// Too close, try again (but only once)
				components[componentNdx] = getRandom<GLType>(rnd, min, max);
			}
		}

		for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
			previousComponents[componentNdx] = components[componentNdx];

		for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
			alignmentSafeAssignment(writePtr + componentNdx*componentSize, components[componentNdx].getValue());

		writePtr += stride;
	}

	return data;
}

#if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE)
#	pragma GCC diagnostic pop
#endif

char* RandomArrayGenerator::generatePackedArray (int seed, int elementCount, int componentCount, int offset, int stride)
{
	DE_ASSERT(componentCount == 4);
	DE_UNREF(componentCount);

	const deUint32 limit10		= (1 << 10);
	const deUint32 limit2		= (1 << 2);
	const size_t elementSize	= 4;
	const size_t bufferSize		= offset + (elementCount - 1) * stride + elementSize;

	char* data = new char[bufferSize];
	char* writePtr = data + offset;

	deRandom rnd;
	deRandom_init(&rnd, seed);

	for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++)
	{
		const deUint32 x			= deRandom_getUint32(&rnd) % limit10;
		const deUint32 y			= deRandom_getUint32(&rnd) % limit10;
		const deUint32 z			= deRandom_getUint32(&rnd) % limit10;
		const deUint32 w			= deRandom_getUint32(&rnd) % limit2;
		const deUint32 packedValue	= (w << 30) | (z << 20) | (y << 10) | (x);

		alignmentSafeAssignment(writePtr, packedValue);
		writePtr += stride;
	}

	return data;
}

char* RandomArrayGenerator::generateIndices (int seed, int elementCount, DrawTestSpec::IndexType type, int offset, int min, int max, int indexBase)
{
	char* data = DE_NULL;

	switch (type)
	{
		case DrawTestSpec::INDEXTYPE_BYTE:
			data = createIndices<deUint8>(seed, elementCount, offset, min, max, indexBase);
			break;

		case DrawTestSpec::INDEXTYPE_SHORT:
			data = createIndices<deUint16>(seed, elementCount, offset, min, max, indexBase);
			break;

		case DrawTestSpec::INDEXTYPE_INT:
			data = createIndices<deUint32>(seed, elementCount, offset, min, max, indexBase);
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	return data;
}

template<typename T>
char* RandomArrayGenerator::createIndices (int seed, int elementCount, int offset, int min, int max, int indexBase)
{
	const size_t elementSize	= sizeof(T);
	const size_t bufferSize		= offset + elementCount * elementSize;

	char* data = new char[bufferSize];
	char* writePtr = data + offset;

	deUint32 oldNdx1 = deUint32(-1);
	deUint32 oldNdx2 = deUint32(-1);

	deRandom rnd;
	deRandom_init(&rnd, seed);

	DE_ASSERT(indexBase >= 0); // watch for underflows

	if (min < 0 || (size_t)min > std::numeric_limits<T>::max() ||
		max < 0 || (size_t)max > std::numeric_limits<T>::max() ||
		min > max)
		DE_FATAL("Invalid range");

	for (int elementNdx = 0; elementNdx < elementCount; ++elementNdx)
	{
		deUint32 ndx = getRandom(rnd, GLValue::Uint::create(min), GLValue::Uint::create(max)).getValue();

		// Try not to generate same index as any of previous two. This prevents
		// generation of degenerate triangles and lines. If [min, max] is too
		// small this cannot be guaranteed.

		if (ndx == oldNdx1)			++ndx;
		if (ndx > (deUint32)max)	ndx = min;
		if (ndx == oldNdx2)			++ndx;
		if (ndx > (deUint32)max)	ndx = min;
		if (ndx == oldNdx1)			++ndx;
		if (ndx > (deUint32)max)	ndx = min;

		oldNdx2 = oldNdx1;
		oldNdx1 = ndx;

		ndx += indexBase;

		alignmentSafeAssignment<T>(writePtr + elementSize * elementNdx, T(ndx));
	}

	return data;
}

rr::GenericVec4	RandomArrayGenerator::generateAttributeValue (int seed, DrawTestSpec::InputType type)
{
	de::Random random(seed);

	switch (type)
	{
		case DrawTestSpec::INPUTTYPE_FLOAT:
			return rr::GenericVec4(generateRandomVec4(random));

		case DrawTestSpec::INPUTTYPE_INT:
			return rr::GenericVec4(generateRandomIVec4(random));

		case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
			return rr::GenericVec4(generateRandomUVec4(random));

		default:
			DE_ASSERT(false);
			return rr::GenericVec4(tcu::Vec4(1, 1, 1, 1));
	}
}

} // anonymous

// AttributePack

class AttributePack
{
public:

								AttributePack		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, sglr::Context& drawContext, const tcu::UVec2& screenSize, bool useVao, bool logEnabled);
								~AttributePack		(void);

	AttributeArray*				getArray			(int i);
	int							getArrayCount		(void);

	void						newArray			(DrawTestSpec::Storage storage);
	void						clearArrays			(void);
	void						updateProgram		(void);

	void						render				(DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex, int vertexCount, DrawTestSpec::IndexType indexType, const void* indexOffset, int rangeStart, int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale, float colorScale, AttributeArray* indexArray);

	const tcu::Surface&			getSurface			(void) const { return m_screen; }
private:
	tcu::TestContext&			m_testCtx;
	glu::RenderContext&			m_renderCtx;
	sglr::Context&				m_ctx;

	std::vector<AttributeArray*>m_arrays;
	sglr::ShaderProgram*		m_program;
	tcu::Surface				m_screen;
	const bool					m_useVao;
	const bool					m_logEnabled;
	deUint32					m_programID;
	deUint32					m_vaoID;
};

AttributePack::AttributePack (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, sglr::Context& drawContext, const tcu::UVec2& screenSize, bool useVao, bool logEnabled)
	: m_testCtx		(testCtx)
	, m_renderCtx	(renderCtx)
	, m_ctx			(drawContext)
	, m_program		(DE_NULL)
	, m_screen		(screenSize.x(), screenSize.y())
	, m_useVao		(useVao)
	, m_logEnabled	(logEnabled)
	, m_programID	(0)
	, m_vaoID		(0)
{
	if (m_useVao)
		m_ctx.genVertexArrays(1, &m_vaoID);
}

AttributePack::~AttributePack (void)
{
	clearArrays();

	if (m_programID)
		m_ctx.deleteProgram(m_programID);

	if (m_program)
		delete m_program;

	if (m_useVao)
		m_ctx.deleteVertexArrays(1, &m_vaoID);
}

AttributeArray* AttributePack::getArray (int i)
{
	return m_arrays.at(i);
}

int AttributePack::getArrayCount (void)
{
	return (int)m_arrays.size();
}

void AttributePack::newArray (DrawTestSpec::Storage storage)
{
	m_arrays.push_back(new AttributeArray(storage, m_ctx));
}

void AttributePack::clearArrays (void)
{
	for (std::vector<AttributeArray*>::iterator itr = m_arrays.begin(); itr != m_arrays.end(); itr++)
		delete *itr;
	m_arrays.clear();
}

void AttributePack::updateProgram (void)
{
	if (m_programID)
		m_ctx.deleteProgram(m_programID);
	if (m_program)
		delete m_program;

	m_program = new DrawTestShaderProgram(m_renderCtx, m_arrays);
	m_programID = m_ctx.createProgram(m_program);
}

void AttributePack::render (DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex, int vertexCount, DrawTestSpec::IndexType indexType, const void* indexOffset, int rangeStart, int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale, float colorScale, AttributeArray* indexArray)
{
	DE_ASSERT(m_program != DE_NULL);
	DE_ASSERT(m_programID != 0);

	m_ctx.viewport(0, 0, m_screen.getWidth(), m_screen.getHeight());
	m_ctx.clearColor(0.0, 0.0, 0.0, 1.0);
	m_ctx.clear(GL_COLOR_BUFFER_BIT);

	m_ctx.useProgram(m_programID);
	GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glUseProgram()");

	m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_coordScale"), coordScale);
	m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_colorScale"), colorScale);

	if (m_useVao)
		m_ctx.bindVertexArray(m_vaoID);

	if (indexArray)
		indexArray->bindIndexArray(DrawTestSpec::TARGET_ELEMENT_ARRAY);

	for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++)
	{
		std::stringstream attribName;
		attribName << "a_" << arrayNdx;

		deUint32 loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str());

		if (m_arrays[arrayNdx]->isBound())
		{
			m_ctx.enableVertexAttribArray(loc);
			GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glEnableVertexAttribArray()");
		}

		m_arrays[arrayNdx]->bindAttribute(loc);
	}

	if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS)
	{
		m_ctx.drawArrays(primitiveToGL(primitive), firstVertex, vertexCount);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArrays()");
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED)
	{
		m_ctx.drawArraysInstanced(primitiveToGL(primitive), firstVertex, vertexCount, instanceCount);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysInstanced()");
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS)
	{
		m_ctx.drawElements(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElements()");
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED)
	{
		m_ctx.drawRangeElements(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount, indexTypeToGL(indexType), indexOffset);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElements()");
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED)
	{
		m_ctx.drawElementsInstanced(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset, instanceCount);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstanced()");
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT)
	{
		struct DrawCommand
		{
			GLuint count;
			GLuint primCount;
			GLuint first;
			GLuint reservedMustBeZero;
		};
		deUint8* buffer = new deUint8[sizeof(DrawCommand) + indirectOffset];

		{
			DrawCommand command;

			command.count				= vertexCount;
			command.primCount			= instanceCount;
			command.first				= firstVertex;
			command.reservedMustBeZero	= 0;

			memcpy(buffer + indirectOffset, &command, sizeof(command));

			if (m_logEnabled)
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "DrawArraysIndirectCommand:\n"
					<< "\tcount: " << command.count << "\n"
					<< "\tprimCount: " << command.primCount << "\n"
					<< "\tfirst: " << command.first << "\n"
					<< "\treservedMustBeZero: " << command.reservedMustBeZero << "\n"
					<< tcu::TestLog::EndMessage;
		}

		GLuint indirectBuf = 0;
		m_ctx.genBuffers(1, &indirectBuf);
		m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf);
		m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW);
		delete [] buffer;

		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer");

		m_ctx.drawArraysIndirect(primitiveToGL(primitive), (const deInt8*)DE_NULL + indirectOffset);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()");

		m_ctx.deleteBuffers(1, &indirectBuf);
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT)
	{
		struct DrawCommand
		{
			GLuint count;
			GLuint primCount;
			GLuint firstIndex;
			GLint  baseVertex;
			GLuint reservedMustBeZero;
		};
		deUint8* buffer = new deUint8[sizeof(DrawCommand) + indirectOffset];

		{
			DrawCommand command;

			// index offset must be converted to firstIndex by dividing with the index element size
			DE_ASSERT(((const deUint8*)indexOffset - (const deUint8*)DE_NULL) % gls::DrawTestSpec::indexTypeSize(indexType) == 0); // \note This is checked in spec validation

			command.count				= vertexCount;
			command.primCount			= instanceCount;
			command.firstIndex			= (glw::GLuint)(((const deUint8*)indexOffset - (const deUint8*)DE_NULL) / gls::DrawTestSpec::indexTypeSize(indexType));
			command.baseVertex			= baseVertex;
			command.reservedMustBeZero	= 0;

			memcpy(buffer + indirectOffset, &command, sizeof(command));

			if (m_logEnabled)
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "DrawElementsIndirectCommand:\n"
					<< "\tcount: " << command.count << "\n"
					<< "\tprimCount: " << command.primCount << "\n"
					<< "\tfirstIndex: " << command.firstIndex << "\n"
					<< "\tbaseVertex: " << command.baseVertex << "\n"
					<< "\treservedMustBeZero: " << command.reservedMustBeZero << "\n"
					<< tcu::TestLog::EndMessage;
		}

		GLuint indirectBuf = 0;
		m_ctx.genBuffers(1, &indirectBuf);
		m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf);
		m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW);
		delete [] buffer;

		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer");

		m_ctx.drawElementsIndirect(primitiveToGL(primitive), indexTypeToGL(indexType), (const deInt8*)DE_NULL + indirectOffset);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()");

		m_ctx.deleteBuffers(1, &indirectBuf);
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
	{
		m_ctx.drawElementsBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset, baseVertex);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsBaseVertex()");
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
	{
		m_ctx.drawElementsInstancedBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset, instanceCount, baseVertex);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstancedBaseVertex()");
	}
	else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
	{
		m_ctx.drawRangeElementsBaseVertex(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount, indexTypeToGL(indexType), indexOffset, baseVertex);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElementsBaseVertex()");
	}
	else
		DE_ASSERT(DE_FALSE);

	for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++)
	{
		if (m_arrays[arrayNdx]->isBound())
		{
			std::stringstream attribName;
			attribName << "a_" << arrayNdx;

			deUint32 loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str());

			m_ctx.disableVertexAttribArray(loc);
			GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDisableVertexAttribArray()");
		}
	}

	if (m_useVao)
		m_ctx.bindVertexArray(0);

	m_ctx.useProgram(0);
	m_ctx.readPixels(m_screen, 0, 0, m_screen.getWidth(), m_screen.getHeight());
}

// DrawTestSpec

DrawTestSpec::AttributeSpec	DrawTestSpec::AttributeSpec::createAttributeArray (InputType inputType, OutputType outputType, Storage storage, Usage usage, int componentCount, int offset, int stride, bool normalize, int instanceDivisor)
{
	DrawTestSpec::AttributeSpec spec;

	spec.inputType			= inputType;
	spec.outputType			= outputType;
	spec.storage			= storage;
	spec.usage				= usage;
	spec.componentCount		= componentCount;
	spec.offset				= offset;
	spec.stride				= stride;
	spec.normalize			= normalize;
	spec.instanceDivisor	= instanceDivisor;

	spec.useDefaultAttribute= false;

	return spec;
}

DrawTestSpec::AttributeSpec	DrawTestSpec::AttributeSpec::createDefaultAttribute (InputType inputType, OutputType outputType, int componentCount)
{
	DE_ASSERT(inputType == INPUTTYPE_INT || inputType == INPUTTYPE_UNSIGNED_INT || inputType == INPUTTYPE_FLOAT);
	DE_ASSERT(inputType == INPUTTYPE_FLOAT || componentCount == 4);

	DrawTestSpec::AttributeSpec spec;

	spec.inputType				= inputType;
	spec.outputType				= outputType;
	spec.storage				= DrawTestSpec::STORAGE_LAST;
	spec.usage					= DrawTestSpec::USAGE_LAST;
	spec.componentCount			= componentCount;
	spec.offset					= 0;
	spec.stride					= 0;
	spec.normalize				= 0;
	spec.instanceDivisor		= 0;

	spec.useDefaultAttribute	= true;

	return spec;
}

DrawTestSpec::AttributeSpec::AttributeSpec (void)
{
	inputType					= DrawTestSpec::INPUTTYPE_LAST;
	outputType					= DrawTestSpec::OUTPUTTYPE_LAST;
	storage						= DrawTestSpec::STORAGE_LAST;
	usage						= DrawTestSpec::USAGE_LAST;
	componentCount				= 0;
	offset						= 0;
	stride						= 0;
	normalize					= false;
	instanceDivisor				= 0;
	useDefaultAttribute			= false;
	additionalPositionAttribute = false;
	bgraComponentOrder			= false;
}

int DrawTestSpec::AttributeSpec::hash (void) const
{
	if (useDefaultAttribute)
	{
		return 1 * int(inputType) + 7 * int(outputType) + 13 * componentCount;
	}
	else
	{
		return 1 * int(inputType) + 2 * int(outputType) + 3 * int(storage) + 5 * int(usage) + 7 * componentCount + 11 * offset + 13 * stride + 17 * (normalize ? 0 : 1) + 19 * instanceDivisor;
	}
}

bool DrawTestSpec::AttributeSpec::valid (glu::ApiType ctxType) const
{
	const bool inputTypeFloat				= inputType == DrawTestSpec::INPUTTYPE_FLOAT || inputType  == DrawTestSpec::INPUTTYPE_FIXED || inputType == DrawTestSpec::INPUTTYPE_HALF;
	const bool inputTypeUnsignedInteger		= inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE || inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT || inputType  == DrawTestSpec::INPUTTYPE_UNSIGNED_INT || inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10;
	const bool inputTypeSignedInteger		= inputType == DrawTestSpec::INPUTTYPE_BYTE  || inputType == DrawTestSpec::INPUTTYPE_SHORT || inputType == DrawTestSpec::INPUTTYPE_INT || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;
	const bool inputTypePacked				= inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;

	const bool outputTypeFloat				= outputType == DrawTestSpec::OUTPUTTYPE_FLOAT || outputType == DrawTestSpec::OUTPUTTYPE_VEC2  || outputType == DrawTestSpec::OUTPUTTYPE_VEC3  || outputType == DrawTestSpec::OUTPUTTYPE_VEC4;
	const bool outputTypeSignedInteger		= outputType == DrawTestSpec::OUTPUTTYPE_INT   || outputType == DrawTestSpec::OUTPUTTYPE_IVEC2 || outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_IVEC4;
	const bool outputTypeUnsignedInteger	= outputType == DrawTestSpec::OUTPUTTYPE_UINT  || outputType == DrawTestSpec::OUTPUTTYPE_UVEC2 || outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_UVEC4;

	if (useDefaultAttribute)
	{
		if (inputType != DrawTestSpec::INPUTTYPE_INT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT && inputType != DrawTestSpec::INPUTTYPE_FLOAT)
			return false;

		if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && componentCount != 4)
			return false;

		// no casting allowed (undefined results)
		if (inputType == DrawTestSpec::INPUTTYPE_INT && !outputTypeSignedInteger)
			return false;
		if (inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT && !outputTypeUnsignedInteger)
			return false;
	}

	if (inputTypePacked && componentCount != 4)
		return false;

	// Invalid conversions:

	// float -> [u]int
	if (inputTypeFloat && !outputTypeFloat)
		return false;

	// uint -> int		(undefined results)
	if (inputTypeUnsignedInteger && outputTypeSignedInteger)
		return false;

	// int -> uint		(undefined results)
	if (inputTypeSignedInteger && outputTypeUnsignedInteger)
		return false;

	// packed -> non-float (packed formats are converted to floats)
	if (inputTypePacked && !outputTypeFloat)
		return false;

	// Invalid normalize. Normalize is only valid if output type is float
	if (normalize && !outputTypeFloat)
		return false;

	// Allow reverse order (GL_BGRA) only for packed and 4-component ubyte
	if (bgraComponentOrder && componentCount != 4)
		return false;
	if (bgraComponentOrder && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 && inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10 && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE)
		return false;
	if (bgraComponentOrder && normalize != true)
		return false;

	// GLES2 limits
	if (ctxType == glu::ApiType::es(2,0))
	{
		if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && inputType != DrawTestSpec::INPUTTYPE_FIXED &&
			inputType != DrawTestSpec::INPUTTYPE_BYTE  && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE &&
			inputType != DrawTestSpec::INPUTTYPE_SHORT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT)
			return false;

		if (!outputTypeFloat)
			return false;

		if (bgraComponentOrder)
			return false;
	}

	// GLES3 limits
	if (ctxType.getProfile() == glu::PROFILE_ES && ctxType.getMajorVersion() == 3)
	{
		if (bgraComponentOrder)
			return false;
	}

	// No user pointers in GL core
	if (ctxType.getProfile() == glu::PROFILE_CORE)
	{
		if (!useDefaultAttribute && storage == DrawTestSpec::STORAGE_USER)
			return false;
	}

	return true;
}

bool DrawTestSpec::AttributeSpec::isBufferAligned (void) const
{
	const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;

	// Buffer alignment, offset is a multiple of underlying data type size?
	if (storage == STORAGE_BUFFER)
	{
		int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType);
		if (inputTypePacked)
			dataTypeSize = 4;

		if (offset % dataTypeSize != 0)
			return false;
	}

	return true;
}

bool DrawTestSpec::AttributeSpec::isBufferStrideAligned (void) const
{
	const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;

	// Buffer alignment, offset is a multiple of underlying data type size?
	if (storage == STORAGE_BUFFER)
	{
		int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType);
		if (inputTypePacked)
			dataTypeSize = 4;

		if (stride % dataTypeSize != 0)
			return false;
	}

	return true;
}

std::string DrawTestSpec::targetToString(Target target)
{
	static const char* targets[] =
	{
		"element_array",	// TARGET_ELEMENT_ARRAY = 0,
		"array"				// TARGET_ARRAY,
	};

	return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target);
}

std::string DrawTestSpec::inputTypeToString(InputType type)
{
	static const char* types[] =
	{
		"float",			// INPUTTYPE_FLOAT = 0,
		"fixed",			// INPUTTYPE_FIXED,
		"double",			// INPUTTYPE_DOUBLE

		"byte",				// INPUTTYPE_BYTE,
		"short",			// INPUTTYPE_SHORT,

		"unsigned_byte",	// INPUTTYPE_UNSIGNED_BYTE,
		"unsigned_short",	// INPUTTYPE_UNSIGNED_SHORT,

		"int",						// INPUTTYPE_INT,
		"unsigned_int",				// INPUTTYPE_UNSIGNED_INT,
		"half",						// INPUTTYPE_HALF,
		"unsigned_int2_10_10_10",	// INPUTTYPE_UNSIGNED_INT_2_10_10_10,
		"int2_10_10_10"				// INPUTTYPE_INT_2_10_10_10,
	};

	return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type);
}

std::string DrawTestSpec::outputTypeToString(OutputType type)
{
	static const char* types[] =
	{
		"float",		// OUTPUTTYPE_FLOAT = 0,
		"vec2",			// OUTPUTTYPE_VEC2,
		"vec3",			// OUTPUTTYPE_VEC3,
		"vec4",			// OUTPUTTYPE_VEC4,

		"int",			// OUTPUTTYPE_INT,
		"uint",			// OUTPUTTYPE_UINT,

		"ivec2",		// OUTPUTTYPE_IVEC2,
		"ivec3",		// OUTPUTTYPE_IVEC3,
		"ivec4",		// OUTPUTTYPE_IVEC4,

		"uvec2",		// OUTPUTTYPE_UVEC2,
		"uvec3",		// OUTPUTTYPE_UVEC3,
		"uvec4",		// OUTPUTTYPE_UVEC4,
	};

	return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type);
}

std::string DrawTestSpec::usageTypeToString(Usage usage)
{
	static const char* usages[] =
	{
		"dynamic_draw",	// USAGE_DYNAMIC_DRAW = 0,
		"static_draw",	// USAGE_STATIC_DRAW,
		"stream_draw",	// USAGE_STREAM_DRAW,

		"stream_read",	// USAGE_STREAM_READ,
		"stream_copy",	// USAGE_STREAM_COPY,

		"static_read",	// USAGE_STATIC_READ,
		"static_copy",	// USAGE_STATIC_COPY,

		"dynamic_read",	// USAGE_DYNAMIC_READ,
		"dynamic_copy",	// USAGE_DYNAMIC_COPY,
	};

	return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage);
}

std::string	DrawTestSpec::storageToString (Storage storage)
{
	static const char* storages[] =
	{
		"user_ptr",	// STORAGE_USER = 0,
		"buffer"	// STORAGE_BUFFER,
	};

	return de::getSizedArrayElement<DrawTestSpec::STORAGE_LAST>(storages, (int)storage);
}

std::string DrawTestSpec::primitiveToString (Primitive primitive)
{
	static const char* primitives[] =
	{
		"points",					// PRIMITIVE_POINTS ,
		"triangles",				// PRIMITIVE_TRIANGLES,
		"triangle_fan",				// PRIMITIVE_TRIANGLE_FAN,
		"triangle_strip",			// PRIMITIVE_TRIANGLE_STRIP,
		"lines",					// PRIMITIVE_LINES
		"line_strip",				// PRIMITIVE_LINE_STRIP
		"line_loop",				// PRIMITIVE_LINE_LOOP
		"lines_adjacency",			// PRIMITIVE_LINES_ADJACENCY
		"line_strip_adjacency",		// PRIMITIVE_LINE_STRIP_ADJACENCY
		"triangles_adjacency",		// PRIMITIVE_TRIANGLES_ADJACENCY
		"triangle_strip_adjacency",	// PRIMITIVE_TRIANGLE_STRIP_ADJACENCY
	};

	return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive);
}

std::string DrawTestSpec::indexTypeToString (IndexType type)
{
	static const char* indexTypes[] =
	{
		"byte",		// INDEXTYPE_BYTE = 0,
		"short",	// INDEXTYPE_SHORT,
		"int",		// INDEXTYPE_INT,
	};

	return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)type);
}

std::string DrawTestSpec::drawMethodToString (DrawTestSpec::DrawMethod method)
{
	static const char* methods[] =
	{
		"draw_arrays",							//!< DRAWMETHOD_DRAWARRAYS
		"draw_arrays_instanced",				//!< DRAWMETHOD_DRAWARRAYS_INSTANCED
		"draw_arrays_indirect",					//!< DRAWMETHOD_DRAWARRAYS_INDIRECT
		"draw_elements",						//!< DRAWMETHOD_DRAWELEMENTS
		"draw_range_elements",					//!< DRAWMETHOD_DRAWELEMENTS_RANGED
		"draw_elements_instanced",				//!< DRAWMETHOD_DRAWELEMENTS_INSTANCED
		"draw_elements_indirect",				//!< DRAWMETHOD_DRAWELEMENTS_INDIRECT
		"draw_elements_base_vertex",			//!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
		"draw_elements_instanced_base_vertex",	//!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
		"draw_range_elements_base_vertex",		//!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
	};

	return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(methods, (int)method);
}

int DrawTestSpec::inputTypeSize (InputType type)
{
	static const int size[] =
	{
		(int)sizeof(float),			// INPUTTYPE_FLOAT = 0,
		(int)sizeof(deInt32),		// INPUTTYPE_FIXED,
		(int)sizeof(double),		// INPUTTYPE_DOUBLE

		(int)sizeof(deInt8),		// INPUTTYPE_BYTE,
		(int)sizeof(deInt16),		// INPUTTYPE_SHORT,

		(int)sizeof(deUint8),		// INPUTTYPE_UNSIGNED_BYTE,
		(int)sizeof(deUint16),		// INPUTTYPE_UNSIGNED_SHORT,

		(int)sizeof(deInt32),		// INPUTTYPE_INT,
		(int)sizeof(deUint32),		// INPUTTYPE_UNSIGNED_INT,
		(int)sizeof(deFloat16),		// INPUTTYPE_HALF,
		(int)sizeof(deUint32) / 4,	// INPUTTYPE_UNSIGNED_INT_2_10_10_10,
		(int)sizeof(deUint32) / 4	// INPUTTYPE_INT_2_10_10_10,
	};

	return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(size, (int)type);
}

int DrawTestSpec::indexTypeSize (IndexType type)
{
	static const int size[] =
	{
		sizeof(deUint8),	// INDEXTYPE_BYTE,
		sizeof(deUint16),	// INDEXTYPE_SHORT,
		sizeof(deUint32),	// INDEXTYPE_INT,
	};

	return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(size, (int)type);
}

std::string DrawTestSpec::getName (void) const
{
	const MethodInfo	methodInfo	= getMethodInfo(drawMethod);
	const bool			hasFirst	= methodInfo.first;
	const bool			instanced	= methodInfo.instanced;
	const bool			ranged		= methodInfo.ranged;
	const bool			indexed		= methodInfo.indexed;

	std::stringstream name;

	for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
	{
		const AttributeSpec& attrib = attribs[ndx];

		if (attribs.size() > 1)
			name << "attrib" << ndx << "_";

		if (ndx == 0|| attrib.additionalPositionAttribute)
			name << "pos_";
		else
			name << "col_";

		if (attrib.useDefaultAttribute)
		{
			name
				<< "non_array_"
				<< DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "_"
				<< attrib.componentCount << "_"
				<< DrawTestSpec::outputTypeToString(attrib.outputType) << "_";
		}
		else
		{
			name
				<< DrawTestSpec::storageToString(attrib.storage) << "_"
				<< attrib.offset << "_"
				<< attrib.stride << "_"
				<< DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType);
			if (attrib.inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 && attrib.inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
				name << attrib.componentCount;
			name
				<< "_"
				<< (attrib.normalize ? "normalized_" : "")
				<< DrawTestSpec::outputTypeToString(attrib.outputType) << "_"
				<< DrawTestSpec::usageTypeToString(attrib.usage) << "_"
				<< attrib.instanceDivisor << "_";
		}
	}

	if (indexed)
		name
			<< "index_" << DrawTestSpec::indexTypeToString(indexType) << "_"
			<< DrawTestSpec::storageToString(indexStorage) << "_"
			<< "offset" << indexPointerOffset << "_";
	if (hasFirst)
		name << "first" << first << "_";
	if (ranged)
		name << "ranged_" << indexMin << "_" << indexMax << "_";
	if (instanced)
		name << "instances" << instanceCount << "_";

	switch (primitive)
	{
		case DrawTestSpec::PRIMITIVE_POINTS:
			name << "points_";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLES:
			name << "triangles_";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
			name << "triangle_fan_";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
			name << "triangle_strip_";
			break;
		case DrawTestSpec::PRIMITIVE_LINES:
			name << "lines_";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP:
			name << "line_strip_";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_LOOP:
			name << "line_loop_";
			break;
		case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
			name << "line_adjancency";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
			name << "line_strip_adjancency";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
			name << "triangles_adjancency";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
			name << "triangle_strip_adjancency";
			break;
		default:
			DE_ASSERT(false);
			break;
	}

	name << primitiveCount;

	return name.str();
}

std::string DrawTestSpec::getDesc (void) const
{
	std::stringstream desc;

	for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
	{
		const AttributeSpec& attrib = attribs[ndx];

		if (attrib.useDefaultAttribute)
		{
			desc
				<< "Attribute " << ndx << ": default, " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position ,") : ("color ,"))
				<< "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << ", "
				<< "input component count " << attrib.componentCount << ", "
				<< "used as " << DrawTestSpec::outputTypeToString(attrib.outputType) << ", ";
		}
		else
		{
			desc
				<< "Attribute " << ndx << ": " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position ,") : ("color ,"))
				<< "Storage in " << DrawTestSpec::storageToString(attrib.storage) << ", "
				<< "stride " << attrib.stride << ", "
				<< "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << ", "
				<< "input component count " << attrib.componentCount << ", "
				<< (attrib.normalize ? "normalized, " : "")
				<< "used as " << DrawTestSpec::outputTypeToString(attrib.outputType) << ", "
				<< "instance divisor " << attrib.instanceDivisor << ", ";
		}
	}

	if (drawMethod == DRAWMETHOD_DRAWARRAYS)
	{
		desc
			<< "drawArrays(), "
			<< "first " << first << ", ";
	}
	else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED)
	{
		desc
			<< "drawArraysInstanced(), "
			<< "first " << first << ", "
			<< "instance count " << instanceCount << ", ";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS)
	{
		desc
			<< "drawElements(), "
			<< "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
			<< "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
			<< "index offset " << indexPointerOffset << ", ";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED)
	{
		desc
			<< "drawElementsRanged(), "
			<< "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
			<< "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
			<< "index offset " << indexPointerOffset << ", "
			<< "range start " << indexMin << ", "
			<< "range end " << indexMax << ", ";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED)
	{
		desc
			<< "drawElementsInstanced(), "
			<< "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
			<< "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
			<< "index offset " << indexPointerOffset << ", "
			<< "instance count " << instanceCount << ", ";
	}
	else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT)
	{
		desc
			<< "drawArraysIndirect(), "
			<< "first " << first << ", "
			<< "instance count " << instanceCount << ", "
			<< "indirect offset " << indirectOffset << ", ";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
	{
		desc
			<< "drawElementsIndirect(), "
			<< "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
			<< "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
			<< "index offset " << indexPointerOffset << ", "
			<< "instance count " << instanceCount << ", "
			<< "indirect offset " << indirectOffset << ", "
			<< "base vertex " << baseVertex << ", ";
	}
	else
		DE_ASSERT(DE_FALSE);

	desc << primitiveCount;

	switch (primitive)
	{
		case DrawTestSpec::PRIMITIVE_POINTS:
			desc << "points";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLES:
			desc << "triangles";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
			desc << "triangles (fan)";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
			desc << "triangles (strip)";
			break;
		case DrawTestSpec::PRIMITIVE_LINES:
			desc << "lines";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP:
			desc << "lines (strip)";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_LOOP:
			desc << "lines (loop)";
			break;
		case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
			desc << "lines (adjancency)";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
			desc << "lines (strip, adjancency)";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
			desc << "triangles (adjancency)";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
			desc << "triangles (strip, adjancency)";
			break;
		default:
			DE_ASSERT(false);
			break;
	}

	return desc.str();
}

std::string DrawTestSpec::getMultilineDesc (void) const
{
	std::stringstream desc;

	for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
	{
		const AttributeSpec& attrib = attribs[ndx];

		if (attrib.useDefaultAttribute)
		{
			desc
				<< "Attribute " << ndx << ": default, " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position\n") : ("color\n"))
				<< "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "\n"
				<< "\tinput component count " << attrib.componentCount << "\n"
				<< "\tused as " << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n";
		}
		else
		{
			desc
				<< "Attribute " << ndx << ": " << ((ndx == 0|| attrib.additionalPositionAttribute) ? ("position\n") : ("color\n"))
				<< "\tStorage in " << DrawTestSpec::storageToString(attrib.storage) << "\n"
				<< "\tstride " << attrib.stride << "\n"
				<< "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "\n"
				<< "\tinput component count " << attrib.componentCount << "\n"
				<< (attrib.normalize ? "\tnormalized\n" : "")
				<< "\tused as " << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n"
				<< "\tinstance divisor " << attrib.instanceDivisor << "\n";
		}
	}

	if (drawMethod == DRAWMETHOD_DRAWARRAYS)
	{
		desc
			<< "drawArrays()\n"
			<< "\tfirst " << first << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED)
	{
		desc
			<< "drawArraysInstanced()\n"
			<< "\tfirst " << first << "\n"
			<< "\tinstance count " << instanceCount << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS)
	{
		desc
			<< "drawElements()\n"
			<< "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
			<< "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
			<< "\tindex offset " << indexPointerOffset << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED)
	{
		desc
			<< "drawElementsRanged()\n"
			<< "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
			<< "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
			<< "\tindex offset " << indexPointerOffset << "\n"
			<< "\trange start " << indexMin << "\n"
			<< "\trange end " << indexMax << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED)
	{
		desc
			<< "drawElementsInstanced()\n"
			<< "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
			<< "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
			<< "\tindex offset " << indexPointerOffset << "\n"
			<< "\tinstance count " << instanceCount << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT)
	{
		desc
			<< "drawArraysIndirect()\n"
			<< "\tfirst " << first << "\n"
			<< "\tinstance count " << instanceCount << "\n"
			<< "\tindirect offset " << indirectOffset << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
	{
		desc
			<< "drawElementsIndirect()\n"
			<< "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
			<< "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
			<< "\tindex offset " << indexPointerOffset << "\n"
			<< "\tinstance count " << instanceCount << "\n"
			<< "\tindirect offset " << indirectOffset << "\n"
			<< "\tbase vertex " << baseVertex << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
	{
		desc
			<< "drawElementsBaseVertex()\n"
			<< "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
			<< "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
			<< "\tindex offset " << indexPointerOffset << "\n"
			<< "\tbase vertex " << baseVertex << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
	{
		desc
			<< "drawElementsInstancedBaseVertex()\n"
			<< "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
			<< "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
			<< "\tindex offset " << indexPointerOffset << "\n"
			<< "\tinstance count " << instanceCount << "\n"
			<< "\tbase vertex " << baseVertex << "\n";
	}
	else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
	{
		desc
			<< "drawRangeElementsBaseVertex()\n"
			<< "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
			<< "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
			<< "\tindex offset " << indexPointerOffset << "\n"
			<< "\tbase vertex " << baseVertex << "\n"
			<< "\trange start " << indexMin << "\n"
			<< "\trange end " << indexMax << "\n";
	}
	else
		DE_ASSERT(DE_FALSE);

	desc << "\t" << primitiveCount << " ";

	switch (primitive)
	{
		case DrawTestSpec::PRIMITIVE_POINTS:
			desc << "points";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLES:
			desc << "triangles";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
			desc << "triangles (fan)";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
			desc << "triangles (strip)";
			break;
		case DrawTestSpec::PRIMITIVE_LINES:
			desc << "lines";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP:
			desc << "lines (strip)";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_LOOP:
			desc << "lines (loop)";
			break;
		case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
			desc << "lines (adjancency)";
			break;
		case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
			desc << "lines (strip, adjancency)";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
			desc << "triangles (adjancency)";
			break;
		case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
			desc << "triangles (strip, adjancency)";
			break;
		default:
			DE_ASSERT(false);
			break;
	}

	desc << "\n";

	return desc.str();
}

DrawTestSpec::DrawTestSpec (void)
{
	primitive			= PRIMITIVE_LAST;
	primitiveCount		= 0;
	drawMethod			= DRAWMETHOD_LAST;
	indexType			= INDEXTYPE_LAST;
	indexPointerOffset	= 0;
	indexStorage		= STORAGE_LAST;
	first				= 0;
	indexMin			= 0;
	indexMax			= 0;
	instanceCount		= 0;
	indirectOffset		= 0;
	baseVertex			= 0;
}

int DrawTestSpec::hash (void) const
{
	// Use only drawmode-relevant values in "hashing" as the unrelevant values might not be set (causing non-deterministic behavior).
	const MethodInfo	methodInfo		= getMethodInfo(drawMethod);
	const bool			arrayed			= methodInfo.first;
	const bool			instanced		= methodInfo.instanced;
	const bool			ranged			= methodInfo.ranged;
	const bool			indexed			= methodInfo.indexed;
	const bool			indirect		= methodInfo.indirect;
	const bool			hasBaseVtx		= methodInfo.baseVertex;

	const int			indexHash		= (!indexed)	? (0) : (int(indexType) + 10 * indexPointerOffset + 100 * int(indexStorage));
	const int			arrayHash		= (!arrayed)	? (0) : (first);
	const int			indexRangeHash	= (!ranged)		? (0) : (indexMin + 10 * indexMax);
	const int			instanceHash	= (!instanced)	? (0) : (instanceCount);
	const int			indirectHash	= (!indirect)	? (0) : (indirectOffset);
	const int			baseVtxHash		= (!hasBaseVtx)	? (0) : (baseVertex);
	const int			basicHash		= int(primitive) + 10 * primitiveCount + 100 * int(drawMethod);

	return indexHash + 3 * arrayHash + 5 * indexRangeHash + 7 * instanceHash + 13 * basicHash + 17 * (int)attribs.size() + 19 * primitiveCount + 23 * indirectHash + 27 * baseVtxHash;
}

bool DrawTestSpec::valid (void) const
{
	DE_ASSERT(apiType.getProfile() != glu::PROFILE_LAST);
	DE_ASSERT(primitive != PRIMITIVE_LAST);
	DE_ASSERT(drawMethod != DRAWMETHOD_LAST);

	const MethodInfo methodInfo = getMethodInfo(drawMethod);

	for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
		if (!attribs[ndx].valid(apiType))
			return false;

	if (methodInfo.ranged)
	{
		deUint32 maxIndexValue = 0;
		if (indexType == INDEXTYPE_BYTE)
			maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_BYTE).ub.getValue();
		else if (indexType == INDEXTYPE_SHORT)
			maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_SHORT).us.getValue();
		else if (indexType == INDEXTYPE_INT)
			maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_INT).ui.getValue();
		else
			DE_ASSERT(DE_FALSE);

		if (indexMin > indexMax)
			return false;
		if (indexMin < 0 || indexMax < 0)
			return false;
		if ((deUint32)indexMin > maxIndexValue || (deUint32)indexMax > maxIndexValue)
			return false;
	}

	if (methodInfo.first && first < 0)
		return false;

	// GLES2 limits
	if (apiType == glu::ApiType::es(2,0))
	{
		if (drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS && drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS)
			return false;
		if (drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS && (indexType != INDEXTYPE_BYTE && indexType != INDEXTYPE_SHORT))
			return false;
	}

	// Indirect limitations
	if (methodInfo.indirect)
	{
		// Indirect offset alignment
		if (indirectOffset % 4 != 0)
			return false;

		// All attribute arrays must be stored in a buffer
		for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
			if (!attribs[ndx].useDefaultAttribute && attribs[ndx].storage == gls::DrawTestSpec::STORAGE_USER)
				return false;
	}
	if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
	{
		// index offset must be convertable to firstIndex
		if (indexPointerOffset % gls::DrawTestSpec::indexTypeSize(indexType) != 0)
			return false;

		// Indices must be in a buffer
		if (indexStorage != STORAGE_BUFFER)
			return false;
	}

	// Do not allow user pointer in GL core
	if (apiType.getProfile() == glu::PROFILE_CORE)
	{
		if (methodInfo.indexed && indexStorage == DrawTestSpec::STORAGE_USER)
			return false;
	}

	return true;
}

DrawTestSpec::CompatibilityTestType DrawTestSpec::isCompatibilityTest (void) const
{
	const MethodInfo methodInfo = getMethodInfo(drawMethod);

	bool bufferAlignmentBad = false;
	bool strideAlignmentBad = false;

	// Attribute buffer alignment
	for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
		if (!attribs[ndx].isBufferAligned())
			bufferAlignmentBad = true;

	// Attribute stride alignment
	for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
		if (!attribs[ndx].isBufferStrideAligned())
			strideAlignmentBad = true;

	// Index buffer alignment
	if (methodInfo.indexed)
	{
		if (indexStorage == STORAGE_BUFFER)
		{
			int indexSize = 0;
			if (indexType == INDEXTYPE_BYTE)
				indexSize = 1;
			else if (indexType == INDEXTYPE_SHORT)
				indexSize = 2;
			else if (indexType == INDEXTYPE_INT)
				indexSize = 4;
			else
				DE_ASSERT(DE_FALSE);

			if (indexPointerOffset % indexSize != 0)
				bufferAlignmentBad = true;
		}
	}

	// \note combination bad alignment & stride is treated as bad offset
	if (bufferAlignmentBad)
		return COMPATIBILITY_UNALIGNED_OFFSET;
	else if (strideAlignmentBad)
		return COMPATIBILITY_UNALIGNED_STRIDE;
	else
		return COMPATIBILITY_NONE;
}

enum PrimitiveClass
{
	PRIMITIVECLASS_POINT = 0,
	PRIMITIVECLASS_LINE,
	PRIMITIVECLASS_TRIANGLE,

	PRIMITIVECLASS_LAST
};

static PrimitiveClass getDrawPrimitiveClass (gls::DrawTestSpec::Primitive primitiveType)
{
	switch (primitiveType)
	{
		case gls::DrawTestSpec::PRIMITIVE_POINTS:
			return PRIMITIVECLASS_POINT;

		case gls::DrawTestSpec::PRIMITIVE_LINES:
		case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP:
		case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP:
		case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
		case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
			return PRIMITIVECLASS_LINE;

		case gls::DrawTestSpec::PRIMITIVE_TRIANGLES:
		case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
		case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
		case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
		case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
			return PRIMITIVECLASS_TRIANGLE;

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

static bool containsLineCases (const std::vector<DrawTestSpec>& m_specs)
{
	for (int ndx = 0; ndx < (int)m_specs.size(); ++ndx)
	{
		if (getDrawPrimitiveClass(m_specs[ndx].primitive) == PRIMITIVECLASS_LINE)
			return true;
	}
	return false;
}

// DrawTest

DrawTest::DrawTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const DrawTestSpec& spec, const char* name, const char* desc)
	: TestCase			(testCtx, name, desc)
	, m_renderCtx		(renderCtx)
	, m_refBuffers		(DE_NULL)
	, m_refContext		(DE_NULL)
	, m_glesContext		(DE_NULL)
	, m_glArrayPack		(DE_NULL)
	, m_rrArrayPack		(DE_NULL)
	, m_maxDiffRed		(-1)
	, m_maxDiffGreen	(-1)
	, m_maxDiffBlue		(-1)
	, m_iteration		(0)
	, m_result			()	// \note no per-iteration result logging (only one iteration)
{
	addIteration(spec);
}

DrawTest::DrawTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* desc)
	: TestCase			(testCtx, name, desc)
	, m_renderCtx		(renderCtx)
	, m_refBuffers		(DE_NULL)
	, m_refContext		(DE_NULL)
	, m_glesContext		(DE_NULL)
	, m_glArrayPack		(DE_NULL)
	, m_rrArrayPack		(DE_NULL)
	, m_maxDiffRed		(-1)
	, m_maxDiffGreen	(-1)
	, m_maxDiffBlue		(-1)
	, m_iteration		(0)
	, m_result			(testCtx.getLog(), "Iteration result: ")
{
}

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

void DrawTest::addIteration (const DrawTestSpec& spec, const char* description)
{
	// Validate spec
	const bool validSpec = spec.valid();
	DE_ASSERT(validSpec);

	if (!validSpec)
		return;

	// Check the context type is the same with other iterations
	if (!m_specs.empty())
	{
		const bool validContext = m_specs[0].apiType == spec.apiType;
		DE_ASSERT(validContext);

		if (!validContext)
			return;
	}

	m_specs.push_back(spec);

	if (description)
		m_iteration_descriptions.push_back(std::string(description));
	else
		m_iteration_descriptions.push_back(std::string());
}

void DrawTest::init (void)
{
	DE_ASSERT(!m_specs.empty());
	DE_ASSERT(contextSupports(m_renderCtx.getType(), m_specs[0].apiType));

	const int						renderTargetWidth	= de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getWidth());
	const int						renderTargetHeight	= de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getHeight());

	// lines have significantly different rasterization in MSAA mode
	const bool						isLineCase			= containsLineCases(m_specs);
	const bool						isMSAACase			= m_renderCtx.getRenderTarget().getNumSamples() > 1;
	const int						renderTargetSamples	= (isMSAACase && isLineCase) ? (4) : (1);

	sglr::ReferenceContextLimits	limits				(m_renderCtx);
	bool							useVao				= false;

	m_glesContext = new sglr::GLContext(m_renderCtx, m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS, tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight));

	if (m_renderCtx.getType().getAPI() == glu::ApiType::es(2,0) || m_renderCtx.getType().getAPI() == glu::ApiType::es(3,0))
		useVao = false;
	else if (contextSupports(m_renderCtx.getType(), glu::ApiType::es(3,1)) || glu::isContextTypeGLCore(m_renderCtx.getType()))
		useVao = true;
	else
		DE_FATAL("Unknown context type");

	m_refBuffers	= new sglr::ReferenceContextBuffers(m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, renderTargetWidth, renderTargetHeight, renderTargetSamples);
	m_refContext	= new sglr::ReferenceContext(limits, m_refBuffers->getColorbuffer(), m_refBuffers->getDepthbuffer(), m_refBuffers->getStencilbuffer());

	m_glArrayPack	= new AttributePack(m_testCtx, m_renderCtx, *m_glesContext, tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, true);
	m_rrArrayPack	= new AttributePack(m_testCtx, m_renderCtx, *m_refContext,  tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, false);

	m_maxDiffRed	= deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits)));
	m_maxDiffGreen	= deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits)));
	m_maxDiffBlue	= deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().blueBits)));
}

void DrawTest::deinit (void)
{
	delete m_glArrayPack;
	delete m_rrArrayPack;
	delete m_refBuffers;
	delete m_refContext;
	delete m_glesContext;

	m_glArrayPack	= DE_NULL;
	m_rrArrayPack	= DE_NULL;
	m_refBuffers	= DE_NULL;
	m_refContext	= DE_NULL;
	m_glesContext	= DE_NULL;
}

DrawTest::IterateResult DrawTest::iterate (void)
{
	const int					specNdx			= (m_iteration / 2);
	const bool					drawStep		= (m_iteration % 2) == 0;
	const bool					compareStep		= (m_iteration % 2) == 1;
	const IterateResult			iterateResult	= ((size_t)m_iteration + 1 == m_specs.size()*2) ? (STOP) : (CONTINUE);
	const DrawTestSpec&			spec			= m_specs[specNdx];
	const bool					updateProgram	= (m_iteration == 0) || (drawStep && !checkSpecsShaderCompatible(m_specs[specNdx], m_specs[specNdx-1])); // try to use the same shader in all iterations
	IterationLogSectionEmitter	sectionEmitter	(m_testCtx.getLog(), specNdx, m_specs.size(), m_iteration_descriptions[specNdx], drawStep && m_specs.size()!=1);

	if (drawStep)
	{
		const MethodInfo	methodInfo				= getMethodInfo(spec.drawMethod);
		const bool			indexed					= methodInfo.indexed;
		const bool			instanced				= methodInfo.instanced;
		const bool			ranged					= methodInfo.ranged;
		const bool			hasFirst				= methodInfo.first;
		const bool			hasBaseVtx				= methodInfo.baseVertex;

		const size_t		primitiveElementCount	= getElementCount(spec.primitive, spec.primitiveCount);						// !< elements to be drawn
		const int			indexMin				= (ranged) ? (spec.indexMin) : (0);
		const int			firstAddition			= (hasFirst) ? (spec.first) : (0);
		const int			baseVertexAddition		= (hasBaseVtx && spec.baseVertex > 0) ? ( spec.baseVertex) : (0);			// spec.baseVertex > 0 => Create bigger attribute buffer
		const int			indexBase				= (hasBaseVtx && spec.baseVertex < 0) ? (-spec.baseVertex) : (0);			// spec.baseVertex < 0 => Create bigger indices
		const size_t		elementCount			= primitiveElementCount + indexMin + firstAddition + baseVertexAddition;	// !< elements in buffer (buffer should have at least primitiveElementCount ACCESSIBLE (index range, first) elements)
		const int			maxElementIndex			= (int)primitiveElementCount + indexMin + firstAddition - 1;
		const int			indexMax				= de::max(0, (ranged) ? (de::clamp<int>(spec.indexMax, 0, maxElementIndex)) : (maxElementIndex));
		float				coordScale				= getCoordScale(spec);
		float				colorScale				= getColorScale(spec);

		rr::GenericVec4		nullAttribValue;

		// Log info
		m_testCtx.getLog() << TestLog::Message << spec.getMultilineDesc() << TestLog::EndMessage;
		m_testCtx.getLog() << TestLog::Message << TestLog::EndMessage; // extra line for clarity

		// Data

		m_glArrayPack->clearArrays();
		m_rrArrayPack->clearArrays();

		for (int attribNdx = 0; attribNdx < (int)spec.attribs.size(); attribNdx++)
		{
			DrawTestSpec::AttributeSpec attribSpec		= spec.attribs[attribNdx];
			const bool					isPositionAttr	= (attribNdx == 0) || (attribSpec.additionalPositionAttribute);

			if (attribSpec.useDefaultAttribute)
			{
				const int		seed		= 10 * attribSpec.hash() + 100 * spec.hash() + attribNdx;
				rr::GenericVec4 attribValue = RandomArrayGenerator::generateAttributeValue(seed, attribSpec.inputType);

				m_glArrayPack->newArray(DrawTestSpec::STORAGE_USER);
				m_rrArrayPack->newArray(DrawTestSpec::STORAGE_USER);

				m_glArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, false, 0, 0, attribValue, isPositionAttr, false);
				m_rrArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, false, 0, 0, attribValue, isPositionAttr, false);
			}
			else
			{
				const int					seed					= attribSpec.hash() + 100 * spec.hash() + attribNdx;
				const size_t				elementSize				= attribSpec.componentCount * DrawTestSpec::inputTypeSize(attribSpec.inputType);
				const size_t				stride					= (attribSpec.stride == 0) ? (elementSize) : (attribSpec.stride);
				const size_t				evaluatedElementCount	= (instanced && attribSpec.instanceDivisor > 0) ? (spec.instanceCount / attribSpec.instanceDivisor + 1) : (elementCount);
				const size_t				referencedElementCount	= (ranged) ? (de::max<size_t>(evaluatedElementCount, spec.indexMax + 1)) : (evaluatedElementCount);
				const size_t				bufferSize				= attribSpec.offset + stride * (referencedElementCount - 1) + elementSize;
				const char*					data					= RandomArrayGenerator::generateArray(seed, (int)referencedElementCount, attribSpec.componentCount, attribSpec.offset, (int)stride, attribSpec.inputType);

				try
				{
					m_glArrayPack->newArray(attribSpec.storage);
					m_rrArrayPack->newArray(attribSpec.storage);

					m_glArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data, attribSpec.usage);
					m_rrArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data, attribSpec.usage);

					m_glArrayPack->getArray(attribNdx)->setupArray(true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue, isPositionAttr, attribSpec.bgraComponentOrder);
					m_rrArrayPack->getArray(attribNdx)->setupArray(true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType, attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue, isPositionAttr, attribSpec.bgraComponentOrder);

					delete [] data;
					data = NULL;
				}
				catch (...)
				{
					delete [] data;
					throw;
				}
			}
		}

		// Shader program
		if (updateProgram)
		{
			m_glArrayPack->updateProgram();
			m_rrArrayPack->updateProgram();
		}

		// Draw
		try
		{
			// indices
			if (indexed)
			{
				const int		seed				= spec.hash();
				const size_t	indexElementSize	= DrawTestSpec::indexTypeSize(spec.indexType);
				const size_t	indexArraySize		= spec.indexPointerOffset + indexElementSize * elementCount;
				const char*		indexArray			= RandomArrayGenerator::generateIndices(seed, (int)elementCount, spec.indexType, spec.indexPointerOffset, indexMin, indexMax, indexBase);
				const char*		indexPointerBase	= (spec.indexStorage == DrawTestSpec::STORAGE_USER) ? (indexArray) : ((char*)DE_NULL);
				const char*		indexPointer		= indexPointerBase + spec.indexPointerOffset;

				de::UniquePtr<AttributeArray> glArray	(new AttributeArray(spec.indexStorage, *m_glesContext));
				de::UniquePtr<AttributeArray> rrArray	(new AttributeArray(spec.indexStorage, *m_refContext));

				try
				{
					glArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray, DrawTestSpec::USAGE_STATIC_DRAW);
					rrArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray, DrawTestSpec::USAGE_STATIC_DRAW);

					m_glArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount, spec.indexType, indexPointer, spec.indexMin, spec.indexMax, spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale, colorScale, glArray.get());
					m_rrArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount, spec.indexType, indexPointer, spec.indexMin, spec.indexMax, spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale, colorScale, rrArray.get());

					delete [] indexArray;
					indexArray = NULL;
				}
				catch (...)
				{
					delete [] indexArray;
					throw;
				}
			}
			else
			{
				m_glArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount, DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount, spec.indirectOffset, 0, coordScale, colorScale, DE_NULL);
				m_rrArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount, DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount, spec.indirectOffset, 0, coordScale, colorScale, DE_NULL);
			}
		}
		catch (glu::Error& err)
		{
			// GL Errors are ok if the mode is not properly aligned

			const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest();

			m_testCtx.getLog() << TestLog::Message << "Got error: " << err.what() << TestLog::EndMessage;

			if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET)
				m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
			else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
				m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
			else
				throw;
		}
	}
	else if (compareStep)
	{
		if (!compare(spec.primitive))
		{
			const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest();

			if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET)
				m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
			else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
				m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
			else
				m_result.addResult(QP_TEST_RESULT_FAIL, "Image comparison failed.");
		}
	}
	else
	{
		DE_ASSERT(false);
		return STOP;
	}

	m_result.setTestContextResult(m_testCtx);

	m_iteration++;
	return iterateResult;
}

static bool isBlack (const tcu::RGBA& c)
{
	// ignore alpha channel
	return c.getRed() == 0 && c.getGreen() == 0 && c.getBlue() == 0;
}

static bool isEdgeTripletComponent (int c1, int c2, int c3, int renderTargetDifference)
{
	const int	roundingDifference	= 2 * renderTargetDifference; // src and dst pixels rounded to different directions
	const int	d1					= c2 - c1;
	const int	d2					= c3 - c2;
	const int	rampDiff			= de::abs(d2 - d1);

	return rampDiff > roundingDifference;
}

static bool isEdgeTriplet (const tcu::RGBA& c1, const tcu::RGBA& c2, const tcu::RGBA& c3, const tcu::IVec3& renderTargetThreshold)
{
	// black (background color) and non-black is always an edge
	{
		const bool b1 = isBlack(c1);
		const bool b2 = isBlack(c2);
		const bool b3 = isBlack(c3);

		// both pixels with coverage and pixels without coverage
		if ((b1 && b2 && b3) == false && (b1 || b2 || b3) == true)
			return true;
		// all black
		if (b1 && b2 && b3)
			return false;
		// all with coverage
		DE_ASSERT(!b1 && !b2 && !b3);
	}

	// Color is always linearly interpolated => component values change nearly linearly
	// in any constant direction on triangle hull. (df/dx ~= C).

	// Edge detection (this function) is run against the reference image
	// => no dithering to worry about

	return	isEdgeTripletComponent(c1.getRed(),		c2.getRed(),	c3.getRed(),	renderTargetThreshold.x())	||
			isEdgeTripletComponent(c1.getGreen(),	c2.getGreen(),	c3.getGreen(),	renderTargetThreshold.y())	||
			isEdgeTripletComponent(c1.getBlue(),	c2.getBlue(),	c3.getBlue(),	renderTargetThreshold.z());
}

static bool pixelNearEdge (int x, int y, const tcu::Surface& ref, const tcu::IVec3& renderTargetThreshold)
{
	// should not be called for edge pixels
	DE_ASSERT(x >= 1 && x <= ref.getWidth()-2);
	DE_ASSERT(y >= 1 && y <= ref.getHeight()-2);

	// horizontal

	for (int dy = -1; dy < 2; ++dy)
	{
		const tcu::RGBA c1 = ref.getPixel(x-1, y+dy);
		const tcu::RGBA c2 = ref.getPixel(x,   y+dy);
		const tcu::RGBA c3 = ref.getPixel(x+1, y+dy);
		if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold))
			return true;
	}

	// vertical

	for (int dx = -1; dx < 2; ++dx)
	{
		const tcu::RGBA c1 = ref.getPixel(x+dx, y-1);
		const tcu::RGBA c2 = ref.getPixel(x+dx, y);
		const tcu::RGBA c3 = ref.getPixel(x+dx, y+1);
		if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold))
			return true;
	}

	return false;
}

static deUint32 getVisualizationGrayscaleColor (const tcu::RGBA& c)
{
	// make triangle coverage and error pixels obvious by converting coverage to grayscale
	if (isBlack(c))
		return 0;
	else
		return 50u + (deUint32)(c.getRed() + c.getBlue() + c.getGreen()) / 8u;
}

static bool pixelNearLineIntersection (int x, int y, const tcu::Surface& target)
{
	// should not be called for edge pixels
	DE_ASSERT(x >= 1 && x <= target.getWidth()-2);
	DE_ASSERT(y >= 1 && y <= target.getHeight()-2);

	int coveredPixels = 0;

	for (int dy = -1; dy < 2; dy++)
	for (int dx = -1; dx < 2; dx++)
	{
		const bool targetCoverage = !isBlack(target.getPixel(x+dx, y+dy));
		if (targetCoverage)
		{
			++coveredPixels;

			// A single thin line cannot have more than 3 covered pixels in a 3x3 area
			if (coveredPixels >= 4)
				return true;
		}
	}

	return false;
}

static inline bool colorsEqual (const tcu::RGBA& colorA, const tcu::RGBA& colorB, const tcu::IVec3& compareThreshold)
{
	enum
	{
		TCU_RGBA_RGB_MASK = tcu::RGBA::RED_MASK | tcu::RGBA::GREEN_MASK | tcu::RGBA::BLUE_MASK
	};

	return tcu::compareThresholdMasked(colorA, colorB, tcu::RGBA(compareThreshold.x(), compareThreshold.y(), compareThreshold.z(), 0), TCU_RGBA_RGB_MASK);
}

// search 3x3 are for matching color
static bool pixelNeighborhoodContainsColor (const tcu::Surface& target, int x, int y, const tcu::RGBA& color, const tcu::IVec3& compareThreshold)
{
	// should not be called for edge pixels
	DE_ASSERT(x >= 1 && x <= target.getWidth()-2);
	DE_ASSERT(y >= 1 && y <= target.getHeight()-2);

	for (int dy = -1; dy < 2; dy++)
	for (int dx = -1; dx < 2; dx++)
	{
		const tcu::RGBA	targetCmpPixel = target.getPixel(x+dx, y+dy);
		if (colorsEqual(color, targetCmpPixel, compareThreshold))
			return true;
	}

	return false;
}

// search 3x3 are for matching coverage (coverage == (color != background color))
static bool pixelNeighborhoodContainsCoverage (const tcu::Surface& target, int x, int y, bool coverage)
{
	// should not be called for edge pixels
	DE_ASSERT(x >= 1 && x <= target.getWidth()-2);
	DE_ASSERT(y >= 1 && y <= target.getHeight()-2);

	for (int dy = -1; dy < 2; dy++)
	for (int dx = -1; dx < 2; dx++)
	{
		const bool targetCmpCoverage = !isBlack(target.getPixel(x+dx, y+dy));
		if (targetCmpCoverage == coverage)
			return true;
	}

	return false;
}

static bool edgeRelaxedImageCompare (tcu::TestLog& log, const char* imageSetName, const char* imageSetDesc, const tcu::Surface& reference, const tcu::Surface& result, const tcu::IVec3& compareThreshold, const tcu::IVec3& renderTargetThreshold, int maxAllowedInvalidPixels)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());

	const tcu::IVec4				green						(0, 255, 0, 255);
	const tcu::IVec4				red							(255, 0, 0, 255);
	const int						width						= reference.getWidth();
	const int						height						= reference.getHeight();
	tcu::TextureLevel				errorMask					(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height);
	const tcu::PixelBufferAccess	errorAccess					= errorMask.getAccess();
	int								numFailingPixels			= 0;

	// clear errormask edges which would otherwise be transparent

	tcu::clear(tcu::getSubregion(errorAccess, 0,			0,			width,	1),			green);
	tcu::clear(tcu::getSubregion(errorAccess, 0,			height-1,	width,	1),			green);
	tcu::clear(tcu::getSubregion(errorAccess, 0,			0,			1,		height),	green);
	tcu::clear(tcu::getSubregion(errorAccess, width-1,		0,			1,		height),	green);

	// skip edge pixels since coverage on edge cannot be verified

	for (int y = 1; y < height - 1; ++y)
	for (int x = 1; x < width - 1; ++x)
	{
		const tcu::RGBA	refPixel			= reference.getPixel(x, y);
		const tcu::RGBA	screenPixel			= result.getPixel(x, y);
		const bool		directMatch			= colorsEqual(refPixel, screenPixel, compareThreshold);
		const bool		isOkReferencePixel	= directMatch || pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold);			// screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)
		const bool		isOkScreenPixel		= directMatch || pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold);	// reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)

		if (isOkScreenPixel && isOkReferencePixel)
		{
			// pixel valid, write greenish pixels to make the result image easier to read
			const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
			errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
		}
		else if (!pixelNearEdge(x, y, reference, renderTargetThreshold))
		{
			// non-edge pixel values must be within threshold of the reference values
			errorAccess.setPixel(red, x, y);
			++numFailingPixels;
		}
		else
		{
			// we are on/near an edge, verify only coverage (coverage == not background colored)
			const bool	referenceCoverage		= !isBlack(refPixel);
			const bool	screenCoverage			= !isBlack(screenPixel);
			const bool	isOkReferenceCoverage	= pixelNeighborhoodContainsCoverage(result, x, y, referenceCoverage);	// Check reference pixel against screen pixel
			const bool	isOkScreenCoverage		= pixelNeighborhoodContainsCoverage(reference, x, y, screenCoverage);	// Check screen pixels against reference pixel

			if (isOkScreenCoverage && isOkReferenceCoverage)
			{
				// pixel valid, write greenish pixels to make the result image easier to read
				const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
				errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
			}
			else
			{
				// coverage does not match
				errorAccess.setPixel(red, x, y);
				++numFailingPixels;
			}
		}
	}

	log	<< TestLog::Message
		<< "Comparing images:\n"
		<< "\tallowed deviation in pixel positions = 1\n"
		<< "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n"
		<< "\tnumber of invalid pixels = " << numFailingPixels
		<< TestLog::EndMessage;

	if (numFailingPixels > maxAllowedInvalidPixels)
	{
		log << TestLog::Message
			<< "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", " << compareThreshold.y() << ", " << compareThreshold.z() << ")"
			<< TestLog::EndMessage
			<< TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result)
			<< TestLog::Image("Reference",	"Reference",	reference)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;

		return false;
	}
	else
	{
		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result", "Result", result)
			<< TestLog::EndImageSet;

		return true;
	}
}

static bool intersectionRelaxedLineImageCompare (tcu::TestLog& log, const char* imageSetName, const char* imageSetDesc, const tcu::Surface& reference, const tcu::Surface& result, const tcu::IVec3& compareThreshold, int maxAllowedInvalidPixels)
{
	DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());

	const tcu::IVec4				green						(0, 255, 0, 255);
	const tcu::IVec4				red							(255, 0, 0, 255);
	const int						width						= reference.getWidth();
	const int						height						= reference.getHeight();
	tcu::TextureLevel				errorMask					(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height);
	const tcu::PixelBufferAccess	errorAccess					= errorMask.getAccess();
	int								numFailingPixels			= 0;

	// clear errormask edges which would otherwise be transparent

	tcu::clear(tcu::getSubregion(errorAccess, 0,			0,			width,	1),			green);
	tcu::clear(tcu::getSubregion(errorAccess, 0,			height-1,	width,	1),			green);
	tcu::clear(tcu::getSubregion(errorAccess, 0,			0,			1,		height),	green);
	tcu::clear(tcu::getSubregion(errorAccess, width-1,		0,			1,		height),	green);

	// skip edge pixels since coverage on edge cannot be verified

	for (int y = 1; y < height - 1; ++y)
	for (int x = 1; x < width - 1; ++x)
	{
		const tcu::RGBA	refPixel			= reference.getPixel(x, y);
		const tcu::RGBA	screenPixel			= result.getPixel(x, y);
		const bool		directMatch			= colorsEqual(refPixel, screenPixel, compareThreshold);
		const bool		isOkScreenPixel		= directMatch || pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold);	// reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)
		const bool		isOkReferencePixel	= directMatch || pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold);			// screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)

		if (isOkScreenPixel && isOkReferencePixel)
		{
			// pixel valid, write greenish pixels to make the result image easier to read
			const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
			errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
		}
		else if (!pixelNearLineIntersection(x, y, reference) &&
				 !pixelNearLineIntersection(x, y, result))
		{
			// non-intersection pixel values must be within threshold of the reference values
			errorAccess.setPixel(red, x, y);
			++numFailingPixels;
		}
		else
		{
			// pixel is near a line intersection
			// we are on/near an edge, verify only coverage (coverage == not background colored)
			const bool	referenceCoverage		= !isBlack(refPixel);
			const bool	screenCoverage			= !isBlack(screenPixel);
			const bool	isOkScreenCoverage		= pixelNeighborhoodContainsCoverage(reference, x, y, screenCoverage);	// Check screen pixels against reference pixel
			const bool	isOkReferenceCoverage	= pixelNeighborhoodContainsCoverage(result, x, y, referenceCoverage);	// Check reference pixel against screen pixel

			if (isOkScreenCoverage && isOkReferenceCoverage)
			{
				// pixel valid, write greenish pixels to make the result image easier to read
				const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
				errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
			}
			else
			{
				// coverage does not match
				errorAccess.setPixel(red, x, y);
				++numFailingPixels;
			}
		}
	}

	log	<< TestLog::Message
		<< "Comparing images:\n"
		<< "\tallowed deviation in pixel positions = 1\n"
		<< "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n"
		<< "\tnumber of invalid pixels = " << numFailingPixels
		<< TestLog::EndMessage;

	if (numFailingPixels > maxAllowedInvalidPixels)
	{
		log << TestLog::Message
			<< "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", " << compareThreshold.y() << ", " << compareThreshold.z() << ")"
			<< TestLog::EndMessage
			<< TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result)
			<< TestLog::Image("Reference",	"Reference",	reference)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;

		return false;
	}
	else
	{
		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result", "Result", result)
			<< TestLog::EndImageSet;

		return true;
	}
}

bool DrawTest::compare (gls::DrawTestSpec::Primitive primitiveType)
{
	const tcu::Surface&	ref		= m_rrArrayPack->getSurface();
	const tcu::Surface&	screen	= m_glArrayPack->getSurface();

	if (m_renderCtx.getRenderTarget().getNumSamples() > 1)
	{
		// \todo [mika] Improve compare when using multisampling
		m_testCtx.getLog() << tcu::TestLog::Message << "Warning: Comparision of result from multisample render targets are not as stricts as without multisampling. Might produce false positives!" << tcu::TestLog::EndMessage;
		return tcu::fuzzyCompare(m_testCtx.getLog(), "Compare Results", "Compare Results", ref.getAccess(), screen.getAccess(), 0.3f, tcu::COMPARE_LOG_RESULT);
	}
	else
	{
		const PrimitiveClass	primitiveClass							= getDrawPrimitiveClass(primitiveType);
		const int				maxAllowedInvalidPixelsWithPoints		= 0;	//!< points are unlikely to have overlapping fragments
		const int				maxAllowedInvalidPixelsWithLines		= 5;	//!< line are allowed to have a few bad pixels
		const int				maxAllowedInvalidPixelsWithTriangles	= 10;

		switch (primitiveClass)
		{
			case PRIMITIVECLASS_POINT:
			{
				// Point are extremely unlikely to have overlapping regions, don't allow any no extra / missing pixels
				return tcu::intThresholdPositionDeviationErrorThresholdCompare(m_testCtx.getLog(),
																			   "CompareResult",
																			   "Result of rendering",
																			   ref.getAccess(),
																			   screen.getAccess(),
																			   tcu::UVec4(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue, 256),
																			   tcu::IVec3(1, 1, 0),					//!< 3x3 search kernel
																			   true,								//!< relax comparison on the image boundary
																			   maxAllowedInvalidPixelsWithPoints,	//!< error threshold
																			   tcu::COMPARE_LOG_RESULT);
			}

			case PRIMITIVECLASS_LINE:
			{
				// Lines can potentially have a large number of overlapping pixels. Pixel comparison may potentially produce
				// false negatives in such pixels if for example the pixel in question is overdrawn by another line in the
				// reference image but not in the resultin image. Relax comparison near line intersection points (areas) and
				// compare only coverage, not color, in such pixels
				return intersectionRelaxedLineImageCompare(m_testCtx.getLog(),
														   "CompareResult",
														   "Result of rendering",
														   ref,
														   screen,
														   tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue),
														   maxAllowedInvalidPixelsWithLines);
			}

			case PRIMITIVECLASS_TRIANGLE:
			{
				// Triangles are likely to partially or fully overlap. Pixel difference comparison is fragile in pixels
				// where there could be potential overlapping since the  pixels might be covered by one triangle in the
				// reference image and by the other in the result image. Relax comparsion near primitive edges and
				// compare only coverage, not color, in such pixels.
				const tcu::IVec3	renderTargetThreshold					= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold().toIVec().xyz();

				return edgeRelaxedImageCompare(m_testCtx.getLog(),
											   "CompareResult",
											   "Result of rendering",
											   ref,
											   screen,
											   tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue),
											   renderTargetThreshold,
											   maxAllowedInvalidPixelsWithTriangles);
			}

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

float DrawTest::getCoordScale (const DrawTestSpec& spec) const
{
	float maxValue = 1.0f;

	for (int arrayNdx = 0; arrayNdx < (int)spec.attribs.size(); arrayNdx++)
	{
		DrawTestSpec::AttributeSpec attribSpec		= spec.attribs[arrayNdx];
		const bool					isPositionAttr	= (arrayNdx == 0) || (attribSpec.additionalPositionAttribute);
		float						attrMaxValue	= 0;

		if (!isPositionAttr)
			continue;

		if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
		{
			if (attribSpec.normalize)
				attrMaxValue += 1.0f;
			else
				attrMaxValue += 1024.0f;
		}
		else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
		{
			if (attribSpec.normalize)
				attrMaxValue += 1.0f;
			else
				attrMaxValue += 512.0f;
		}
		else
		{
			const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat();

			attrMaxValue += (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType)) ? (1.0f) : (max * 1.1f);
		}

		if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC3 || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4
			|| attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4
			|| attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 || attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4)
				attrMaxValue *= 2;

		maxValue += attrMaxValue;
	}

	return 1.0f / maxValue;
}

float DrawTest::getColorScale (const DrawTestSpec& spec) const
{
	float colorScale = 1.0f;

	for (int arrayNdx = 1; arrayNdx < (int)spec.attribs.size(); arrayNdx++)
	{
		DrawTestSpec::AttributeSpec attribSpec		= spec.attribs[arrayNdx];
		const bool					isPositionAttr	= (arrayNdx == 0) || (attribSpec.additionalPositionAttribute);

		if (isPositionAttr)
			continue;

		if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
		{
			if (!attribSpec.normalize)
				colorScale *= 1.0f / 1024.0f;
		}
		else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
		{
			if (!attribSpec.normalize)
				colorScale *= 1.0f / 512.0f;
		}
		else
		{
			const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat();

			colorScale *= (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f : float(1.0 / double(max)));
			if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4 ||
				attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4 ||
				attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4)
				colorScale *= (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f : float(1.0 / double(max)));
		}
	}

	return colorScale;
}

} // gls
} // deqp
