/*-------------------------------------------------------------------------
 * 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 Vertex array and buffer tests
 *//*--------------------------------------------------------------------*/

#include "glsVertexArrayTests.hpp"

#include "deRandom.h"

#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 "gluPixelTransfer.hpp"
#include "gluCallLogWrapper.hpp"

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

#include "deMath.h"
#include "deStringUtil.hpp"
#include "deArrayUtil.hpp"

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

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

namespace deqp
{
namespace gls
{

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

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

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

std::string Array::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,
		"usigned_int2_10_10_10",	// INPUTTYPE_UNSIGNED_INT_2_10_10_10,
		"int2_10_10_10"				// INPUTTYPE_INT_2_10_10_10,
	};

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

std::string Array::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<Array::OUTPUTTYPE_LAST>(types, (int)type);
}

std::string Array::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<Array::USAGE_LAST>(usages, (int)usage);
}

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

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

std::string Array::primitiveToString (Primitive primitive)
{
	static const char* primitives[] =
	{
		"points",			// PRIMITIVE_POINTS ,
		"triangles",		// PRIMITIVE_TRIANGLES,
		"triangle_fan",		// PRIMITIVE_TRIANGLE_FAN,
		"triangle_strip"	// PRIMITIVE_TRIANGLE_STRIP,
	};

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

int Array::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<Array::INPUTTYPE_LAST>(size, (int)type);
}

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

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

	return false;
}

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

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

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

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<>
inline GLValue::Double minValue (void)
{
	return GLValue::Double::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::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>()));
}

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

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

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

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

Array* ContextArrayPack::getArray (int i)
{
	return m_arrays.at(i);
}

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

	if (m_storage == 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 == STORAGE_USER)
	{
		if (m_data)
			delete[] m_data;

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

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

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

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

void ContextArray::bind (int attribNdx, int offset, int size, InputType inputType, OutputType outType, bool normalized, int stride)
{
	m_attribNdx			= attribNdx;
	m_bound				= true;
	m_componentCount	= size;
	m_inputType			= inputType;
	m_outputType		= outType;
	m_normalize			= normalized;
	m_stride			= stride;
	m_offset			= offset;
}

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

void ContextArray::glBind (deUint32 loc)
{
	if (m_storage == STORAGE_BUFFER)
	{
		m_ctx.bindBuffer(targetToGL(m_target), m_glBuffer);
		GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");

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

			if (outputTypeIsFloatType(m_outputType))
			{
				// Output type is float type
				m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, (GLvoid*)((GLintptr)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, (GLvoid*)((GLintptr)m_offset));
				GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()");
			}
		}
		else
		{
			// Input type is float type

			// Output type must be float type
			DE_ASSERT(m_outputType == OUTPUTTYPE_FLOAT || m_outputType == OUTPUTTYPE_VEC2 || m_outputType == OUTPUTTYPE_VEC3 || m_outputType == OUTPUTTYPE_VEC4);

			m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, (GLvoid*)((GLintptr)m_offset));
			GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()");
		}

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

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

			if (outputTypeIsFloatType(m_outputType))
			{
				// Output type is float type
				m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride, m_data + 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, m_data + m_offset);
				GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()");
			}
		}
		else
		{
			// Input type is float type

			// Output type must be float type
			DE_ASSERT(m_outputType == OUTPUTTYPE_FLOAT || m_outputType == OUTPUTTYPE_VEC2 || m_outputType == OUTPUTTYPE_VEC3 || m_outputType == OUTPUTTYPE_VEC4);

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

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

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

GLenum ContextArray::usageToGL (Array::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<Array::USAGE_LAST>(usages, (int)usage);
}

GLenum ContextArray::inputTypeToGL (Array::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<Array::INPUTTYPE_LAST>(types, (int)type);
}

std::string ContextArray::outputTypeToGLType (Array::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<Array::OUTPUTTYPE_LAST>(types, (int)type);
}

GLenum ContextArray::primitiveToGL (Array::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,
	};

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

ContextArrayPack::ContextArrayPack (glu::RenderContext& renderCtx, sglr::Context& drawContext)
	: m_renderCtx	(renderCtx)
	, m_ctx			(drawContext)
	, m_program		(DE_NULL)
	, m_screen		(std::min(512, renderCtx.getRenderTarget().getWidth()), std::min(512, renderCtx.getRenderTarget().getHeight()))
{
}

ContextArrayPack::~ContextArrayPack (void)
{
	for (std::vector<ContextArray*>::iterator itr = m_arrays.begin(); itr != m_arrays.end(); itr++)
		delete *itr;

	delete m_program;
}

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

void ContextArrayPack::newArray (Array::Storage storage)
{
	m_arrays.push_back(new ContextArray(storage, m_ctx));
}

class ContextShaderProgram : public sglr::ShaderProgram
{
public:
												ContextShaderProgram		(const glu::RenderContext& ctx, const std::vector<ContextArray*>& 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<ContextArray*>& arrays);
	static std::string							genFragmentSource			(const glu::RenderContext& ctx);
	static rr::GenericVecType					mapOutputType				(const Array::OutputType& type);
	static int									getComponentCount			(const Array::OutputType& type);

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

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

ContextShaderProgram::ContextShaderProgram (const glu::RenderContext& ctx, const std::vector<ContextArray*>& arrays)
	: sglr::ShaderProgram	(createProgramDeclaration(ctx, arrays))
	, m_componentCount		(arrays.size())
	, m_attrType			(arrays.size())
{
	for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
	{
		m_componentCount[arrayNdx]	= getComponentCount(arrays[arrayNdx]->getOutputType());
		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 ContextShaderProgram::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(1.0, 1.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];

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

		// Transform position
		{
			packet.position = tcu::Vec4(u_coordScale * coord.x(), u_coordScale * coord.y(), 1.0f, 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);
		}
	}
}

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

	// Triangles are flashaded
	tcu::Vec4 color = rr::readTriangleVarying<float>(packets[0], context, varyingLocColor, 0);

	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
}

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

	if (glu::isGLSLVersionSupported(ctx.getType(), 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";
	}
	else if (glu::isGLSLVersionSupported(ctx.getType(), 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"]		= "";
	}
	else if (glu::isGLSLVersionSupported(ctx.getType(), 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";
	}
	else
		DE_ASSERT(DE_FALSE);

	vertexShaderTmpl << "${VTX_HDR}";

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

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

	for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
	{
		if (arrays[arrayNdx]->getAttribNdx() == 0)
		{
			switch (arrays[arrayNdx]->getOutputType())
			{
				case (Array::OUTPUTTYPE_FLOAT):
					vertexShaderTmpl <<
						"\tcoord = vec2(a_0);\n";
					break;

				case (Array::OUTPUTTYPE_VEC2):
					vertexShaderTmpl <<
						"\tcoord = a_0.xy;\n";
					break;

				case (Array::OUTPUTTYPE_VEC3):
					vertexShaderTmpl <<
						"\tcoord = a_0.xy;\n"
						"\tcoord.x = coord.x + a_0.z;\n";
					break;

				case (Array::OUTPUTTYPE_VEC4):
					vertexShaderTmpl <<
						"\tcoord = a_0.xy;\n"
						"\tcoord += a_0.zw;\n";
					break;

				case (Array::OUTPUTTYPE_IVEC2):
				case (Array::OUTPUTTYPE_UVEC2):
					vertexShaderTmpl <<
						"\tcoord = vec2(a_0.xy);\n";
					break;

				case (Array::OUTPUTTYPE_IVEC3):
				case (Array::OUTPUTTYPE_UVEC3):
					vertexShaderTmpl <<
						"\tcoord = vec2(a_0.xy);\n"
						"\tcoord.x = coord.x + float(a_0.z);\n";
					break;

				case (Array::OUTPUTTYPE_IVEC4):
				case (Array::OUTPUTTYPE_UVEC4):
					vertexShaderTmpl <<
						"\tcoord = vec2(a_0.xy);\n"
						"\tcoord += vec2(a_0.zw);\n";
					break;

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

		switch (arrays[arrayNdx]->getOutputType())
		{
			case (Array::OUTPUTTYPE_FLOAT):
				vertexShaderTmpl <<
					"\tcolor = color * a_" << arrays[arrayNdx]->getAttribNdx() << ";\n";
				break;

			case (Array::OUTPUTTYPE_VEC2):
				vertexShaderTmpl <<
					"\tcolor.rg = color.rg * a_" << arrays[arrayNdx]->getAttribNdx() << ".xy;\n";
				break;

			case (Array::OUTPUTTYPE_VEC3):
				vertexShaderTmpl <<
					"\tcolor = color.rgb * a_" << arrays[arrayNdx]->getAttribNdx() << ".xyz;\n";
				break;

			case (Array::OUTPUTTYPE_VEC4):
				vertexShaderTmpl <<
					"\tcolor = color.rgb * a_" << arrays[arrayNdx]->getAttribNdx() << ".xyz * a_" << arrays[arrayNdx]->getAttribNdx() << ".w;\n";
				break;

			default:
				DE_ASSERT(false);
				break;
		}
	}

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

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

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

	if (glu::isGLSLVersionSupported(ctx.getType(), 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";
	}
	else if (glu::isGLSLVersionSupported(ctx.getType(), 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"]		= "";
	}
	else if (glu::isGLSLVersionSupported(ctx.getType(), 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";
	}
	else
		DE_ASSERT(DE_FALSE);

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

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

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

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

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

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

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

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

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

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

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

sglr::pdec::ShaderProgramDeclaration ContextShaderProgram::createProgramDeclaration (const glu::RenderContext& ctx, const std::vector<ContextArray*>& 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;
}

void ContextArrayPack::updateProgram (void)
{
	delete m_program;
	m_program = new ContextShaderProgram(m_renderCtx, m_arrays);
}

void ContextArrayPack::render (Array::Primitive primitive, int firstVertex, int vertexCount, bool useVao, float coordScale, float colorScale)
{
	deUint32 program = 0;
	deUint32 vaoId = 0;

	updateProgram();

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

	program = m_ctx.createProgram(m_program);

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

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

	if (useVao)
	{
		m_ctx.genVertexArrays(1, &vaoId);
		m_ctx.bindVertexArray(vaoId);
	}

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

			deUint32 loc = m_ctx.getAttribLocation(program, attribName.str().c_str());
			m_ctx.enableVertexAttribArray(loc);
			GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glEnableVertexAttribArray()");

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

	DE_ASSERT((firstVertex % 6) == 0);
	m_ctx.drawArrays(ContextArray::primitiveToGL(primitive), firstVertex, vertexCount - firstVertex);
	GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArrays()");

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

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

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

	if (useVao)
		m_ctx.deleteVertexArrays(1, &vaoId);

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

// GLValue

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

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

	return rangesHi[(int)type];
}

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

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

	return rangesLo[(int)type];
}

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

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

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

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

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

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

			break;
		}

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

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

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

		case Array::INPUTTYPE_DOUBLE:
			return (float)d.getValue();
			break;

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

class RandomArrayGenerator
{
public:
	static char*	generateArray			(int seed, GLValue min, GLValue max, int count, int componentCount, int stride, Array::InputType type);
	static char*	generateQuads			(int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize);
	static char*	generatePerQuad			(int seed, int count, int componentCount, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max);

private:
	template<typename T>
	static char*	createQuads		(int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize);
	template<typename T>
	static char*	createPerQuads	(int seed, int count, int componentCount, int stride, Array::Primitive primitive, T min, T max);
	static char*	createQuadsPacked (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive);
	static void		setData			(char* data, Array::InputType type, deRandom& rnd, GLValue min, GLValue max);
};

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

		case Array::INPUTTYPE_DOUBLE:
		{
			alignmentSafeAssignment<double>(data, getRandom<GLValue::Float>(rnd, min.fl, max.fl));
			break;
		}

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

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

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

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

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

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

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

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

		default:
			DE_ASSERT(false);
			break;
	}
}

char* RandomArrayGenerator::generateArray (int seed, GLValue min, GLValue max, int count, int componentCount, int stride, Array::InputType type)
{
	char* data = NULL;

	deRandom rnd;
	deRandom_init(&rnd, seed);

	if (stride == 0)
		stride = componentCount * Array::inputTypeSize(type);

	data = new char[stride * count];

	for (int vertexNdx = 0; vertexNdx < count; vertexNdx++)
	{
		for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
		{
			setData(&(data[vertexNdx * stride + Array::inputTypeSize(type) * componentNdx]), type, rnd, min, max);
		}
	}

	return data;
}

char* RandomArrayGenerator::generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize)
{
	char* data = DE_NULL;

	switch (type)
	{
		case Array::INPUTTYPE_FLOAT:
			data = createQuads<GLValue::Float>(seed, count, componentCount, offset, stride, primitive, min.fl, max.fl, gridSize);
			break;

		case Array::INPUTTYPE_FIXED:
			data = createQuads<GLValue::Fixed>(seed, count, componentCount, offset, stride, primitive, min.fi, max.fi, gridSize);
			break;

		case Array::INPUTTYPE_DOUBLE:
			data = createQuads<GLValue::Double>(seed, count, componentCount, offset, stride, primitive, min.d, max.d, gridSize);
			break;

		case Array::INPUTTYPE_BYTE:
			data = createQuads<GLValue::Byte>(seed, count, componentCount, offset, stride, primitive, min.b, max.b, gridSize);
			break;

		case Array::INPUTTYPE_SHORT:
			data = createQuads<GLValue::Short>(seed, count, componentCount, offset, stride, primitive, min.s, max.s, gridSize);
			break;

		case Array::INPUTTYPE_UNSIGNED_BYTE:
			data = createQuads<GLValue::Ubyte>(seed, count, componentCount, offset, stride, primitive, min.ub, max.ub, gridSize);
			break;

		case Array::INPUTTYPE_UNSIGNED_SHORT:
			data = createQuads<GLValue::Ushort>(seed, count, componentCount, offset, stride, primitive, min.us, max.us, gridSize);
			break;

		case Array::INPUTTYPE_UNSIGNED_INT:
			data = createQuads<GLValue::Uint>(seed, count, componentCount, offset, stride, primitive, min.ui, max.ui, gridSize);
			break;

		case Array::INPUTTYPE_INT:
			data = createQuads<GLValue::Int>(seed, count, componentCount, offset, stride, primitive, min.i, max.i, gridSize);
			break;

		case Array::INPUTTYPE_HALF:
			data = createQuads<GLValue::Half>(seed, count, componentCount, offset, stride, primitive, min.h, max.h, gridSize);
			break;

		case Array::INPUTTYPE_INT_2_10_10_10:
		case Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10:
			data = createQuadsPacked(seed, count, componentCount, offset, stride, primitive);
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	return data;
}

char* RandomArrayGenerator::createQuadsPacked (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive)
{
	DE_ASSERT(componentCount == 4);
	DE_UNREF(componentCount);
	int quadStride = 0;

	if (stride == 0)
		stride = sizeof(deUint32);

	switch (primitive)
	{
		case Array::PRIMITIVE_TRIANGLES:
			quadStride = stride * 6;
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	char* const _data		= new char[offset + quadStride * (count - 1) + stride * 5 + componentCount * Array::inputTypeSize(Array::INPUTTYPE_INT_2_10_10_10)]; // last element must be fully in the array
	char* const resultData	= _data + offset;

	const deUint32 max		= 1024;
	const deUint32 min		= 10;
	const deUint32 max2		= 4;

	deRandom rnd;
	deRandom_init(&rnd,  seed);

	switch (primitive)
	{
		case Array::PRIMITIVE_TRIANGLES:
		{
			for (int quadNdx = 0; quadNdx < count; quadNdx++)
			{
				deUint32 x1	= min + deRandom_getUint32(&rnd) % (max - min);
				deUint32 x2	= min + deRandom_getUint32(&rnd) % (max - x1);

				deUint32 y1	= min + deRandom_getUint32(&rnd) % (max - min);
				deUint32 y2	= min + deRandom_getUint32(&rnd) % (max - y1);

				deUint32 z	= min + deRandom_getUint32(&rnd) % (max - min);
				deUint32 w	= deRandom_getUint32(&rnd) % max2;

				deUint32 val1 = (w << 30) | (z << 20) | (y1 << 10) | x1;
				deUint32 val2 = (w << 30) | (z << 20) | (y1 << 10) | x2;
				deUint32 val3 = (w << 30) | (z << 20) | (y2 << 10) | x1;

				deUint32 val4 = (w << 30) | (z << 20) | (y2 << 10) | x1;
				deUint32 val5 = (w << 30) | (z << 20) | (y1 << 10) | x2;
				deUint32 val6 = (w << 30) | (z << 20) | (y2 << 10) | x2;

				alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 0]), val1);
				alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 1]), val2);
				alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 2]), val3);
				alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 3]), val4);
				alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 4]), val5);
				alignmentSafeAssignment<deUint32>(&(resultData[quadNdx * quadStride + stride * 5]), val6);
			}

			break;
		}

		default:
			DE_ASSERT(false);
			break;
	}

	return _data;
}

template<typename T>
T roundTo (const T& step, const T& value)
{
	return value - (value % step);
}

template<typename T>
char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize)
{
	int componentStride = sizeof(T);
	int quadStride = 0;

	if (stride == 0)
		stride = componentCount * componentStride;

	DE_ASSERT(stride >= componentCount * componentStride);

	switch (primitive)
	{
		case Array::PRIMITIVE_TRIANGLES:
			quadStride = stride * 6;
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	char* resultData = new char[offset + quadStride * count];
	char* _data = resultData;
	resultData = resultData + offset;

	deRandom rnd;
	deRandom_init(&rnd,  seed);

	switch (primitive)
	{
		case Array::PRIMITIVE_TRIANGLES:
		{
			const T	minQuadSize	= T::fromFloat(deFloatAbs(max.template to<float>() - min.template to<float>()) * gridSize);
			const T	minDiff		= minValue<T>() > minQuadSize
								? minValue<T>()
								: minQuadSize;

			for (int quadNdx = 0; quadNdx < count; ++quadNdx)
			{
				T x1, x2;
				T y1, y2;
				T z, w;

				// attempt to find a good (i.e not extremely small) quad
				for (int attemptNdx = 0; attemptNdx < 4; ++attemptNdx)
				{
					x1 = roundTo(minDiff, getRandom<T>(rnd, min, max));
					x2 = roundTo(minDiff, getRandom<T>(rnd, minDiff, abs<T>(max - x1)));

					y1 = roundTo(minDiff, getRandom<T>(rnd, min, max));
					y2 = roundTo(minDiff, getRandom<T>(rnd, minDiff, abs<T>(max - y1)));

					z = (componentCount > 2) ? roundTo(minDiff, (getRandom<T>(rnd, min, max))) : (T::create(0));
					w = (componentCount > 3) ? roundTo(minDiff, (getRandom<T>(rnd, min, max))) : (T::create(1));

					// no additional components, all is good
					if (componentCount <= 2)
						break;

					// The result quad is too thin?
					if ((deFloatAbs(x2.template to<float>() + z.template to<float>()) < minDiff.template to<float>()) ||
						(deFloatAbs(y2.template to<float>() + w.template to<float>()) < minDiff.template to<float>()))
						continue;

					// all ok
					break;
				}

				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride]), x1);
				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + componentStride]), y1);

				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride]), x1 + x2);
				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride + componentStride]), y1);

				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 2]), x1);
				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 2 + componentStride]), y1 + y2);

				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 3]), x1);
				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 3 + componentStride]), y1 + y2);

				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 4]), x1 + x2);
				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 4 + componentStride]), y1);

				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 5]), x1 + x2);
				alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * 5 + componentStride]), y1 + y2);

				if (componentCount > 2)
				{
					for (int i = 0; i < 6; i++)
						alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * i + componentStride * 2]), z);
				}

				if (componentCount > 3)
				{
					for (int i = 0; i < 6; i++)
						alignmentSafeAssignment<T>(&(resultData[quadNdx * quadStride + stride * i + componentStride * 3]), w);
				}
			}

			break;
		}

		default:
			DE_ASSERT(false);
			break;
	}

	return _data;
}

char* RandomArrayGenerator::generatePerQuad (int seed, int count, int componentCount, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max)
{
	char* data = DE_NULL;

	switch (type)
	{
		case Array::INPUTTYPE_FLOAT:
			data = createPerQuads<GLValue::Float>(seed, count, componentCount, stride, primitive, min.fl, max.fl);
			break;

		case Array::INPUTTYPE_FIXED:
			data = createPerQuads<GLValue::Fixed>(seed, count, componentCount, stride, primitive, min.fi, max.fi);
			break;

		case Array::INPUTTYPE_DOUBLE:
			data = createPerQuads<GLValue::Double>(seed, count, componentCount, stride, primitive, min.d, max.d);
			break;

		case Array::INPUTTYPE_BYTE:
			data = createPerQuads<GLValue::Byte>(seed, count, componentCount, stride, primitive, min.b, max.b);
			break;

		case Array::INPUTTYPE_SHORT:
			data = createPerQuads<GLValue::Short>(seed, count, componentCount, stride, primitive, min.s, max.s);
			break;

		case Array::INPUTTYPE_UNSIGNED_BYTE:
			data = createPerQuads<GLValue::Ubyte>(seed, count, componentCount, stride, primitive, min.ub, max.ub);
			break;

		case Array::INPUTTYPE_UNSIGNED_SHORT:
			data = createPerQuads<GLValue::Ushort>(seed, count, componentCount, stride, primitive, min.us, max.us);
			break;

		case Array::INPUTTYPE_UNSIGNED_INT:
			data = createPerQuads<GLValue::Uint>(seed, count, componentCount, stride, primitive, min.ui, max.ui);
			break;

		case Array::INPUTTYPE_INT:
			data = createPerQuads<GLValue::Int>(seed, count, componentCount, stride, primitive, min.i, max.i);
			break;

		case Array::INPUTTYPE_HALF:
			data = createPerQuads<GLValue::Half>(seed, count, componentCount, stride, primitive, min.h, max.h);
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	return data;
}

template<typename T>
char* RandomArrayGenerator::createPerQuads (int seed, int count, int componentCount, int stride, Array::Primitive primitive, T min, T max)
{
	deRandom rnd;
	deRandom_init(&rnd, seed);

	int componentStride = sizeof(T);

	if (stride == 0)
		stride = componentStride * componentCount;

	int quadStride = 0;

	switch (primitive)
	{
		case Array::PRIMITIVE_TRIANGLES:
			quadStride = stride * 6;
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	char* data = new char[count * quadStride];

	for (int quadNdx = 0; quadNdx < count; quadNdx++)
	{
		for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
		{
			T val = getRandom<T>(rnd, min, max);

			alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 0 + componentStride * componentNdx, val);
			alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 1 + componentStride * componentNdx, val);
			alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 2 + componentStride * componentNdx, val);
			alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 3 + componentStride * componentNdx, val);
			alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 4 + componentStride * componentNdx, val);
			alignmentSafeAssignment<T>(data + quadNdx * quadStride + stride * 5 + componentStride * componentNdx, val);
		}
	}

	return data;
}

// VertexArrayTest

VertexArrayTest::VertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name ,const char* desc)
	: TestCase			(testCtx, name, desc)
	, m_renderCtx		(renderCtx)
	, m_refBuffers		(DE_NULL)
	, m_refContext		(DE_NULL)
	, m_glesContext		(DE_NULL)
	, m_glArrayPack		(DE_NULL)
	, m_rrArrayPack		(DE_NULL)
	, m_isOk			(false)
	, m_maxDiffRed		(deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits))))
	, m_maxDiffGreen	(deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits))))
	, m_maxDiffBlue		(deCeilFloatToInt32(256.0f * (2.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().blueBits))))
{
}

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

void VertexArrayTest::init (void)
{
	const int						renderTargetWidth	= de::min(512, m_renderCtx.getRenderTarget().getWidth());
	const int						renderTargetHeight	= de::min(512, m_renderCtx.getRenderTarget().getHeight());
	sglr::ReferenceContextLimits	limits				(m_renderCtx);

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

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

	m_glArrayPack		= new ContextArrayPack(m_renderCtx, *m_glesContext);
	m_rrArrayPack		= new ContextArrayPack(m_renderCtx, *m_refContext);
}

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

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

void VertexArrayTest::compare (void)
{
	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;
		m_isOk = tcu::fuzzyCompare(m_testCtx.getLog(), "Compare Results", "Compare Results", ref.getAccess(), screen.getAccess(), 1.5f, tcu::COMPARE_LOG_RESULT);
	}
	else
	{
		tcu::RGBA		threshold	(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue, 255);
		tcu::Surface	error		(ref.getWidth(), ref.getHeight());

		m_isOk = true;

		for (int y = 0; y < ref.getHeight(); y++)
		{
			for (int x = 0; x < ref.getWidth(); x++)
			{
				tcu::RGBA	refPixel		= ref.getPixel(x, y);
				tcu::RGBA	screenPixel		= screen.getPixel(x, y);
				bool		isOkPixel		= false;

				if (y == 0 || y + 1 == ref.getHeight() || x == 0 || x + 1 == ref.getWidth())
				{
					// Don't check borders since the pixel neighborhood is undefined
					error.setPixel(x, y, tcu::RGBA(screenPixel.getRed(), (screenPixel.getGreen() + 255) / 2, screenPixel.getBlue(), 255));
					continue;
				}

				// Don't do comparisons for this pixel if it belongs to a one-pixel-thin part (i.e. it doesn't have similar-color neighbors in both x and y directions) in both result and reference.
				// This fixes some false negatives.
				bool		refThin			= (!tcu::compareThreshold(refPixel, ref.getPixel(x-1, y  ), threshold) && !tcu::compareThreshold(refPixel, ref.getPixel(x+1, y  ), threshold)) ||
											  (!tcu::compareThreshold(refPixel, ref.getPixel(x  , y-1), threshold) && !tcu::compareThreshold(refPixel, ref.getPixel(x  , y+1), threshold));
				bool		screenThin		= (!tcu::compareThreshold(screenPixel, screen.getPixel(x-1, y  ), threshold) && !tcu::compareThreshold(screenPixel, screen.getPixel(x+1, y  ), threshold)) ||
											  (!tcu::compareThreshold(screenPixel, screen.getPixel(x  , y-1), threshold) && !tcu::compareThreshold(screenPixel, screen.getPixel(x  , y+1), threshold));

				if (refThin && screenThin)
					isOkPixel = true;
				else
				{
					for (int dy = -1; dy < 2 && !isOkPixel; dy++)
					{
						for (int dx = -1; dx < 2 && !isOkPixel; dx++)
						{
							// Check reference pixel against screen pixel
							{
								tcu::RGBA	screenCmpPixel	= screen.getPixel(x+dx, y+dy);
								deUint8		r				= (deUint8)deAbs32(refPixel.getRed()	- screenCmpPixel.getRed());
								deUint8		g				= (deUint8)deAbs32(refPixel.getGreen()	- screenCmpPixel.getGreen());
								deUint8		b				= (deUint8)deAbs32(refPixel.getBlue()	- screenCmpPixel.getBlue());

								if (r <= m_maxDiffRed && g <= m_maxDiffGreen && b <= m_maxDiffBlue)
									isOkPixel = true;
							}

							// Check screen pixels against reference pixel
							{
								tcu::RGBA	refCmpPixel		= ref.getPixel(x+dx, y+dy);
								deUint8		r				= (deUint8)deAbs32(refCmpPixel.getRed()		- screenPixel.getRed());
								deUint8		g				= (deUint8)deAbs32(refCmpPixel.getGreen()	- screenPixel.getGreen());
								deUint8		b				= (deUint8)deAbs32(refCmpPixel.getBlue()	- screenPixel.getBlue());

								if (r <= m_maxDiffRed && g <= m_maxDiffGreen && b <= m_maxDiffBlue)
									isOkPixel = true;
							}
						}
					}
				}

				if (isOkPixel)
					error.setPixel(x, y, tcu::RGBA(screen.getPixel(x, y).getRed(), (screen.getPixel(x, y).getGreen() + 255) / 2, screen.getPixel(x, y).getBlue(), 255));
				else
				{
					error.setPixel(x, y, tcu::RGBA(255, 0, 0, 255));
					m_isOk = false;
				}
			}
		}

		tcu::TestLog& log = m_testCtx.getLog();
		if (!m_isOk)
		{
			log << TestLog::Message << "Image comparison failed, threshold = (" << m_maxDiffRed << ", " << m_maxDiffGreen << ", " << m_maxDiffBlue << ")" << TestLog::EndMessage;
			log << TestLog::ImageSet("Compare result", "Result of rendering")
				<< TestLog::Image("Result",		"Result",		screen)
				<< TestLog::Image("Reference",	"Reference",	ref)
				<< TestLog::Image("ErrorMask",	"Error mask",	error)
				<< TestLog::EndImageSet;
		}
		else
		{
			log << TestLog::ImageSet("Compare result", "Result of rendering")
				<< TestLog::Image("Result", "Result", screen)
				<< TestLog::EndImageSet;
		}
	}
}

// MultiVertexArrayTest

MultiVertexArrayTest::Spec::ArraySpec::ArraySpec(Array::InputType inputType_, Array::OutputType outputType_, Array::Storage storage_, Array::Usage usage_, int componentCount_, int offset_, int stride_, bool normalize_, GLValue min_, GLValue max_)
	: inputType		(inputType_)
	, outputType	(outputType_)
	, storage		(storage_)
	, usage			(usage_)
	, componentCount(componentCount_)
	, offset		(offset_)
	, stride		(stride_)
	, normalize		(normalize_)
	, min			(min_)
	, max			(max_)
{
}

std::string MultiVertexArrayTest::Spec::getName (void) const
{
	std::stringstream name;

	for (size_t ndx = 0; ndx < arrays.size(); ++ndx)
	{
		const ArraySpec& array = arrays[ndx];

		if (arrays.size() > 1)
			name << "array" << ndx << "_";

		name
			<< Array::storageToString(array.storage) << "_"
			<< array.offset << "_"
			<< array.stride << "_"
			<< Array::inputTypeToString((Array::InputType)array.inputType);
		if (array.inputType != Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 && array.inputType != Array::INPUTTYPE_INT_2_10_10_10)
			name << array.componentCount;
		name
			<< "_"
			<< (array.normalize ? "normalized_" : "")
			<< Array::outputTypeToString(array.outputType) << "_"
			<< Array::usageTypeToString(array.usage) << "_";
	}

	if (first)
		name << "first" << first << "_";

	switch (primitive)
	{
		case Array::PRIMITIVE_TRIANGLES:
			name << "quads_";
			break;
		case Array::PRIMITIVE_POINTS:
			name << "points_";
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	name << drawCount;

	return name.str();
}

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

	for (size_t ndx = 0; ndx < arrays.size(); ++ndx)
	{
		const ArraySpec& array = arrays[ndx];

		desc
			<< "Array " << ndx << ": "
			<< "Storage in " << Array::storageToString(array.storage) << ", "
			<< "stride " << array.stride << ", "
			<< "input datatype " << Array::inputTypeToString((Array::InputType)array.inputType) << ", "
			<< "input component count " << array.componentCount << ", "
			<< (array.normalize ? "normalized, " : "")
			<< "used as " << Array::outputTypeToString(array.outputType) << ", ";
	}

	desc
		<< "drawArrays(), "
		<< "first " << first << ", "
		<< drawCount;

	switch (primitive)
	{
		case Array::PRIMITIVE_TRIANGLES:
			desc << "quads ";
			break;
		case Array::PRIMITIVE_POINTS:
			desc << "points";
			break;

		default:
			DE_ASSERT(false);
			break;
	}


	return desc.str();
}

MultiVertexArrayTest::MultiVertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const Spec& spec, const char* name, const char* desc)
	: VertexArrayTest	(testCtx, renderCtx, name, desc)
	, m_spec			(spec)
	, m_iteration		(0)
{
}

MultiVertexArrayTest::~MultiVertexArrayTest	(void)
{
}

MultiVertexArrayTest::IterateResult MultiVertexArrayTest::iterate (void)
{
	if (m_iteration == 0)
	{
		const size_t	primitiveSize		= (m_spec.primitive == Array::PRIMITIVE_TRIANGLES) ? (6) : (1); // in non-indexed draw Triangles means rectangles
		float			coordScale			= 1.0f;
		float			colorScale			= 1.0f;
		const bool		useVao				= m_renderCtx.getType().getProfile() == glu::PROFILE_CORE;

		// Log info
		m_testCtx.getLog() << TestLog::Message << m_spec.getDesc() << TestLog::EndMessage;

		// Color and Coord scale
		{
			// First array is always position
			{
				Spec::ArraySpec arraySpec = m_spec.arrays[0];
				if (arraySpec.inputType == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
				{
					if (arraySpec.normalize)
						coordScale = 1.0f;
					else
						coordScale = 1.0 / 1024.0;
				}
				else if (arraySpec.inputType == Array::INPUTTYPE_INT_2_10_10_10)
				{
					if (arraySpec.normalize)
						coordScale = 1.0f;
					else
						coordScale = 1.0 / 512.0;
				}
				else
					coordScale = (arraySpec.normalize && !inputTypeIsFloatType(arraySpec.inputType) ? 1.0f : float(0.9 / double(arraySpec.max.toFloat())));

				if (arraySpec.outputType == Array::OUTPUTTYPE_VEC3 || arraySpec.outputType == Array::OUTPUTTYPE_VEC4
					|| arraySpec.outputType == Array::OUTPUTTYPE_IVEC3 || arraySpec.outputType == Array::OUTPUTTYPE_IVEC4
					|| arraySpec.outputType == Array::OUTPUTTYPE_UVEC3 || arraySpec.outputType == Array::OUTPUTTYPE_UVEC4)
						coordScale = coordScale * 0.5f;
			}

			// And other arrays are color-like
			for (int arrayNdx = 1; arrayNdx < (int)m_spec.arrays.size(); arrayNdx++)
			{
				Spec::ArraySpec arraySpec	= m_spec.arrays[arrayNdx];

				colorScale *= (arraySpec.normalize && !inputTypeIsFloatType(arraySpec.inputType) ? 1.0f : float(1.0 / double(arraySpec.max.toFloat())));
				if (arraySpec.outputType == Array::OUTPUTTYPE_VEC4)
					colorScale *= (arraySpec.normalize && !inputTypeIsFloatType(arraySpec.inputType) ? 1.0f : float(1.0 / double(arraySpec.max.toFloat())));
			}
		}

		// Data
		for (int arrayNdx = 0; arrayNdx < (int)m_spec.arrays.size(); arrayNdx++)
		{
			Spec::ArraySpec arraySpec		= m_spec.arrays[arrayNdx];
			const int		seed			= int(arraySpec.inputType) + 10 * int(arraySpec.outputType) + 100 * int(arraySpec.storage) + 1000 * int(m_spec.primitive) + 10000 * int(arraySpec.usage) + int(m_spec.drawCount) + 12 * int(arraySpec.componentCount) + int(arraySpec.stride) + int(arraySpec.normalize);
			const char*		data			= DE_NULL;
			const size_t	stride			= (arraySpec.stride == 0) ? (arraySpec.componentCount * Array::inputTypeSize(arraySpec.inputType)) : (arraySpec.stride);
			const size_t	bufferSize		= arraySpec.offset + stride * (m_spec.drawCount * primitiveSize - 1) + arraySpec.componentCount  * Array::inputTypeSize(arraySpec.inputType);
			// Snap values to at least 3x3 grid
			const float		gridSize		= 3.0f / (float)(de::min(m_renderCtx.getRenderTarget().getWidth(), m_renderCtx.getRenderTarget().getHeight()) - 1);

			switch (m_spec.primitive)
			{
	//			case Array::PRIMITIVE_POINTS:
	//				data = RandomArrayGenerator::generateArray(seed, arraySpec.min, arraySpec.max, arraySpec.count, arraySpec.componentCount, arraySpec.stride, arraySpec.inputType);
	//				break;
				case Array::PRIMITIVE_TRIANGLES:
					if (arrayNdx == 0)
					{
						data = RandomArrayGenerator::generateQuads(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.offset, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max, gridSize);
					}
					else
					{
						DE_ASSERT(arraySpec.offset == 0); // \note [jarkko] it just hasn't been implemented
						data = RandomArrayGenerator::generatePerQuad(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max);
					}
					break;

				default:
					DE_ASSERT(false);
					break;
			}

			m_glArrayPack->newArray(arraySpec.storage);
			m_rrArrayPack->newArray(arraySpec.storage);

			m_glArrayPack->getArray(arrayNdx)->data(Array::TARGET_ARRAY, (int)bufferSize, data, arraySpec.usage);
			m_rrArrayPack->getArray(arrayNdx)->data(Array::TARGET_ARRAY, (int)bufferSize, data, arraySpec.usage);

			m_glArrayPack->getArray(arrayNdx)->bind(arrayNdx, arraySpec.offset, arraySpec.componentCount, arraySpec.inputType, arraySpec.outputType, arraySpec.normalize, arraySpec.stride);
			m_rrArrayPack->getArray(arrayNdx)->bind(arrayNdx, arraySpec.offset, arraySpec.componentCount, arraySpec.inputType, arraySpec.outputType, arraySpec.normalize, arraySpec.stride);

			delete [] data;
		}

		try
		{
			m_glArrayPack->render(m_spec.primitive, m_spec.first, m_spec.drawCount * (int)primitiveSize, useVao, coordScale, colorScale);
			m_testCtx.touchWatchdog();
			m_rrArrayPack->render(m_spec.primitive, m_spec.first, m_spec.drawCount * (int)primitiveSize, useVao, coordScale, colorScale);
		}
		catch (glu::Error& err)
		{
			// GL Errors are ok if the mode is not properly aligned

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

			if (isUnalignedBufferOffsetTest())
				m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
			else if (isUnalignedBufferStrideTest())
				m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
			else
				throw;

			return STOP;
		}

		m_iteration++;
		return CONTINUE;
	}
	else if (m_iteration == 1)
	{
		compare();

		if (m_isOk)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		}
		else
		{
			if (isUnalignedBufferOffsetTest())
				m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
			else if (isUnalignedBufferStrideTest())
				m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
			else
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed.");
		}

		m_iteration++;
		return STOP;
	}
	else
	{
		DE_ASSERT(false);
		return STOP;
	}
}

bool MultiVertexArrayTest::isUnalignedBufferOffsetTest (void) const
{
	// Buffer offsets should be data type size aligned
	for (size_t i = 0; i < m_spec.arrays.size(); ++i)
	{
		if (m_spec.arrays[i].storage == Array::STORAGE_BUFFER)
		{
			const bool inputTypePacked = m_spec.arrays[i].inputType == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_spec.arrays[i].inputType == Array::INPUTTYPE_INT_2_10_10_10;

			int dataTypeSize = Array::inputTypeSize(m_spec.arrays[i].inputType);
			if (inputTypePacked)
				dataTypeSize = 4;

			if (m_spec.arrays[i].offset % dataTypeSize != 0)
				return true;
		}
	}

	return false;
}

bool MultiVertexArrayTest::isUnalignedBufferStrideTest (void) const
{
	// Buffer strides should be data type size aligned
	for (size_t i = 0; i < m_spec.arrays.size(); ++i)
	{
		if (m_spec.arrays[i].storage == Array::STORAGE_BUFFER)
		{
			const bool inputTypePacked = m_spec.arrays[i].inputType == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_spec.arrays[i].inputType == Array::INPUTTYPE_INT_2_10_10_10;

			int dataTypeSize = Array::inputTypeSize(m_spec.arrays[i].inputType);
			if (inputTypePacked)
				dataTypeSize = 4;

			if (m_spec.arrays[i].stride % dataTypeSize != 0)
				return true;
		}
	}

	return false;
}

} // gls
} // deqp
