/*-------------------------------------------------------------------------
 * 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[] =
	{
		sizeof(float),		// INPUTTYPE_FLOAT = 0,
		sizeof(deInt32),	// INPUTTYPE_FIXED,
		sizeof(double),		// INPUTTYPE_DOUBLE

		sizeof(deInt8),		// INPUTTYPE_BYTE,
		sizeof(deInt16),	// INPUTTYPE_SHORT,

		sizeof(deUint8),	// INPUTTYPE_UNSIGNED_BYTE,
		sizeof(deUint16),	// INPUTTYPE_UNSIGNED_SHORT,

		sizeof(deInt32),		// INPUTTYPE_INT,
		sizeof(deUint32),		// INPUTTYPE_UNSIGNED_INT,
		sizeof(deFloat16),		// INPUTTYPE_HALF,
		sizeof(deUint32) / 4,		// INPUTTYPE_UNSIGNED_INT_2_10_10_10,
		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 : 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 : 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 : 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 : 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() + attribValue.z(),	(float)attribValue.y());					break;
			case 4:	coord = tcu::Vec2((float)attribValue.x() + attribValue.z(),	(float)attribValue.y() + attribValue.w());	break;

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

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

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

			case 4:
				color.x() = color.x() * attribValue.x() * attribValue.w();
				color.y() = color.y() * attribValue.y() * attribValue.w();
				color.z() = color.z() * attribValue.z() * 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 / (1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits))))
	, m_maxDiffGreen	(deCeilFloatToInt32(256.0f * (2.0f / (1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits))))
	, m_maxDiffBlue		(deCeilFloatToInt32(256.0f * (2.0f / (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 = 1; y < ref.getHeight()-1; y++)
		{
			for (int x = 1; x < ref.getWidth()-1; x++)
			{
				tcu::RGBA	refPixel		= ref.getPixel(x, y);
				tcu::RGBA	screenPixel		= screen.getPixel(x, y);
				bool		isOkPixel		= false;

				// 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				= deAbs32(refPixel.getRed()		- screenCmpPixel.getRed());
								deUint8		g				= deAbs32(refPixel.getGreen()	- screenCmpPixel.getGreen());
								deUint8		b				= 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				= deAbs32(refCmpPixel.getRed()		- screenPixel.getRed());
								deUint8		g				= deAbs32(refCmpPixel.getGreen()	- screenPixel.getGreen());
								deUint8		b				= 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
