/*-------------------------------------------------------------------------
 * 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();
			break;

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

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

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

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

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

			break;
		}

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

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

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

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

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

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

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

	return rangesHi[(int)type];
}

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

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

	return rangesLo[(int)type];
}

template<typename T>
struct GLValueTypeTraits;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// AttributeArray

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// DrawTestShaderProgram

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

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

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

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

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

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

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

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

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

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

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

			default:
				DE_ASSERT(false);
		}
	}
}

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

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

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

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

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

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

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

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

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

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

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

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

	generateShaderParams(params, ctx.getType());

	vertexShaderTmpl << "${VTX_HDR}";

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	generateShaderParams(params, ctx.getType());

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return decl;
}

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

private:
	template<typename T>
	static char*			createIndices			(int seed, int elementCount, int offset, int min, int max, int indexBase);

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

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

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

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

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

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

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

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

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

	GLType previousComponents[4];

	deRandom rnd;
	deRandom_init(&rnd, seed);

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

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

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

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

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

		writePtr += stride;
	}

	return data;
}

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

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

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

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

	deRandom rnd;
	deRandom_init(&rnd, seed);

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

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

	return data;
}

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

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

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

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

		default:
			DE_ASSERT(false);
			break;
	}

	return data;
}

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

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

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

	deRandom rnd;
	deRandom_init(&rnd, seed);

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

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

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

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

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

		oldNdx2 = oldNdx1;
		oldNdx1 = ndx;

		ndx += indexBase;

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

	return data;
}

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

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

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

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

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

} // anonymous

// AttributePack

class AttributePack
{
public:

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

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

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

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

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

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

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

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

	if (m_programID)
		m_ctx.deleteProgram(m_programID);

	if (m_program)
		delete m_program;

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

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

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

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

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

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

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

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

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

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

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

	if (m_useVao)
		m_ctx.bindVertexArray(m_vaoID);

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

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

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

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

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

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

		{
			DrawCommand command;

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

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

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

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

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

		m_ctx.drawArraysIndirect(primitiveToGL(primitive), glu::BufferOffsetAsPointer(indirectOffset));
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()");

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

		{
			DrawCommand command;

			// index offset must be converted to firstIndex by dividing with the index element size
			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
