/*-------------------------------------------------------------------------
 * 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 "gluContextInfo.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>()));
}

// AttributeArray

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						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::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 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);
};

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), glu::BufferOffsetAsPointer(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), glu::BufferOffsetAsPointer(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_contextInfo		(DE_NULL)
	, 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_contextInfo		(DE_NULL)
	, 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)));
	m_contextInfo	= glu::ContextInfo::create(m_renderCtx);
}

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

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

DrawTest::IterateResult DrawTest::iterate (void)
{
	const int					specNdx			= (m_iteration / 2);
	const DrawTestSpec&			spec			= m_specs[specNdx];

	if (spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX ||
		spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX ||
		spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
	{
		const bool supportsES32 = contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 2));
		TCU_CHECK_AND_THROW(NotSupportedError, supportsES32 || m_contextInfo->isExtensionSupported("GL_EXT_draw_elements_base_vertex"), "GL_EXT_draw_elements_base_vertex is not supported.");
	}

	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 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_testCtx.touchWatchdog();
				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
