/*-------------------------------------------------------------------------
 * 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 <cstdint>

#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();

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

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

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

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

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

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

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

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

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

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

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
			const auto offsetAsInteger = reinterpret_cast<uintptr_t>(indexOffset);
			DE_ASSERT(offsetAsInteger % gls::DrawTestSpec::indexTypeSize(indexType) == 0); // \note This is checked in spec validation

			command.count				= vertexCount;
			command.primCount			= instanceCount;
			command.firstIndex			= (glw::GLuint)(offsetAsInteger / 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 supportsES32orGL45 = contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 2)) ||
										contextSupports(m_renderCtx.getType(), glu::ApiType::core(4, 5));
		TCU_CHECK_AND_THROW(NotSupportedError, supportsES32orGL45 || 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
