/*-------------------------------------------------------------------------
 * 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);
	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);
	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)
{
	char* data = DE_NULL;

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

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

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

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

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

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

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

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

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

		case Array::INPUTTYPE_HALF:
			data = createQuads<GLValue::Half>(seed, count, componentCount, offset, stride, primitive, min.h, max.h);
			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>
char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max)
{
	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:
		{
			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 = getRandom<T>(rnd, min, max);
					x2 = getRandom<T>(rnd, minValue<T>(), abs<T>(max - x1));

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

					z = (componentCount > 2) ? (getRandom<T>(rnd, min, max)) : (T::create(0));
					w = (componentCount > 3) ? (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>()) < minValue<T>().template to<float>()) ||
						(deFloatAbs(y2.template to<float>() + w.template to<float>()) < minValue<T>().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);

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