/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 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 Uniform API tests.
 *
 * \todo [2013-02-26 nuutti] Much duplication between this and ES2.
 *							 Utilities to glshared?
 *//*--------------------------------------------------------------------*/

#include "es3fUniformApiTests.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluShaderProgram.hpp"
#include "gluVarType.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "gluTexture.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"
#include "tcuCommandLine.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deString.h"
#include "deSharedPtr.hpp"
#include "deMemory.h"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include <set>
#include <cstring>

using namespace glw;

namespace deqp
{
namespace gles3
{
namespace Functional
{

using std::vector;
using std::string;
using tcu::TestLog;
using tcu::ScopedLogSection;
using glu::ShaderProgram;
using glu::StructType;
using de::Random;
using de::SharedPtr;

typedef bool (* dataTypePredicate)(glu::DataType);

static const int MAX_RENDER_WIDTH			= 32;
static const int MAX_RENDER_HEIGHT			= 32;
static const int MAX_NUM_SAMPLER_UNIFORMS	= 16;

static const glu::DataType s_testDataTypes[] =
{
	glu::TYPE_FLOAT,
	glu::TYPE_FLOAT_VEC2,
	glu::TYPE_FLOAT_VEC3,
	glu::TYPE_FLOAT_VEC4,
	glu::TYPE_FLOAT_MAT2,
	glu::TYPE_FLOAT_MAT2X3,
	glu::TYPE_FLOAT_MAT2X4,
	glu::TYPE_FLOAT_MAT3X2,
	glu::TYPE_FLOAT_MAT3,
	glu::TYPE_FLOAT_MAT3X4,
	glu::TYPE_FLOAT_MAT4X2,
	glu::TYPE_FLOAT_MAT4X3,
	glu::TYPE_FLOAT_MAT4,

	glu::TYPE_INT,
	glu::TYPE_INT_VEC2,
	glu::TYPE_INT_VEC3,
	glu::TYPE_INT_VEC4,

	glu::TYPE_UINT,
	glu::TYPE_UINT_VEC2,
	glu::TYPE_UINT_VEC3,
	glu::TYPE_UINT_VEC4,

	glu::TYPE_BOOL,
	glu::TYPE_BOOL_VEC2,
	glu::TYPE_BOOL_VEC3,
	glu::TYPE_BOOL_VEC4,

	glu::TYPE_SAMPLER_2D,
	glu::TYPE_SAMPLER_CUBE
	// \note We don't test all sampler types here.
};

static inline int getGLInt (const glw::Functions& funcs, const deUint32 name)
{
	int val = -1;
	funcs.getIntegerv(name, &val);
	return val;
}

static inline tcu::Vec4 vec4FromPtr (const float* const ptr)
{
	tcu::Vec4 result;
	for (int i = 0; i < 4; i++)
		result[i] = ptr[i];
	return result;
}

static inline string beforeLast (const string& str, const char c)
{
	return str.substr(0, str.find_last_of(c));
}

static inline void fillWithColor (const tcu::PixelBufferAccess& access, const tcu::Vec4& color)
{
	for (int z = 0; z < access.getDepth(); z++)
	for (int y = 0; y < access.getHeight(); y++)
	for (int x = 0; x < access.getWidth(); x++)
		access.setPixel(color, x, y, z);
}

static inline int getSamplerNumLookupDimensions (const glu::DataType type)
{
	switch (type)
	{
		case glu::TYPE_SAMPLER_2D:
		case glu::TYPE_INT_SAMPLER_2D:
		case glu::TYPE_UINT_SAMPLER_2D:
			return 2;

		case glu::TYPE_SAMPLER_3D:
		case glu::TYPE_INT_SAMPLER_3D:
		case glu::TYPE_UINT_SAMPLER_3D:
		case glu::TYPE_SAMPLER_2D_SHADOW:
		case glu::TYPE_SAMPLER_2D_ARRAY:
		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
		case glu::TYPE_SAMPLER_CUBE:
		case glu::TYPE_INT_SAMPLER_CUBE:
		case glu::TYPE_UINT_SAMPLER_CUBE:
			return 3;

		case glu::TYPE_SAMPLER_CUBE_SHADOW:
		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
			return 4;

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

static inline glu::DataType getSamplerLookupReturnType (const glu::DataType type)
{
	switch (type)
	{
		case glu::TYPE_SAMPLER_2D:
		case glu::TYPE_SAMPLER_CUBE:
		case glu::TYPE_SAMPLER_2D_ARRAY:
		case glu::TYPE_SAMPLER_3D:
			return glu::TYPE_FLOAT_VEC4;

		case glu::TYPE_UINT_SAMPLER_2D:
		case glu::TYPE_UINT_SAMPLER_CUBE:
		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
		case glu::TYPE_UINT_SAMPLER_3D:
			return glu::TYPE_UINT_VEC4;

		case glu::TYPE_INT_SAMPLER_2D:
		case glu::TYPE_INT_SAMPLER_CUBE:
		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
		case glu::TYPE_INT_SAMPLER_3D:
			return glu::TYPE_INT_VEC4;

		case glu::TYPE_SAMPLER_2D_SHADOW:
		case glu::TYPE_SAMPLER_CUBE_SHADOW:
		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
			return glu::TYPE_FLOAT;

		default:
			DE_ASSERT(false);
			return glu::TYPE_LAST;
	}
}

template<glu::DataType T>
static bool dataTypeEquals (const glu::DataType t)
{
	return t == T;
}

template<int N>
static bool dataTypeIsMatrixWithNRows (const glu::DataType t)
{
	return glu::isDataTypeMatrix(t) && glu::getDataTypeMatrixNumRows(t) == N;
}

static bool typeContainsMatchingBasicType (const glu::VarType& type, const dataTypePredicate predicate)
{
	if (type.isBasicType())
		return predicate(type.getBasicType());
	else if (type.isArrayType())
		return typeContainsMatchingBasicType(type.getElementType(), predicate);
	else
	{
		DE_ASSERT(type.isStructType());
		const StructType& structType = *type.getStructPtr();
		for (int i = 0; i < structType.getNumMembers(); i++)
			if (typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate))
				return true;
		return false;
	}
}

static void getDistinctSamplerTypes (vector<glu::DataType>& dst, const glu::VarType& type)
{
	if (type.isBasicType())
	{
		const glu::DataType basicType = type.getBasicType();
		if (glu::isDataTypeSampler(basicType) && std::find(dst.begin(), dst.end(), basicType) == dst.end())
			dst.push_back(basicType);
	}
	else if (type.isArrayType())
		getDistinctSamplerTypes(dst, type.getElementType());
	else
	{
		DE_ASSERT(type.isStructType());
		const StructType& structType = *type.getStructPtr();
		for (int i = 0; i < structType.getNumMembers(); i++)
			getDistinctSamplerTypes(dst, structType.getMember(i).getType());
	}
}

static int getNumSamplersInType (const glu::VarType& type)
{
	if (type.isBasicType())
		return glu::isDataTypeSampler(type.getBasicType()) ? 1 : 0;
	else if (type.isArrayType())
		return getNumSamplersInType(type.getElementType()) * type.getArraySize();
	else
	{
		DE_ASSERT(type.isStructType());
		const StructType& structType = *type.getStructPtr();
		int sum = 0;
		for (int i = 0; i < structType.getNumMembers(); i++)
			sum += getNumSamplersInType(structType.getMember(i).getType());
		return sum;
	}
}

static glu::VarType generateRandomType (const int maxDepth, int& curStructIdx, vector<const StructType*>& structTypesDst, Random& rnd)
{
	const bool isStruct		= maxDepth > 0 && rnd.getFloat() < 0.2f;
	const bool isArray		= rnd.getFloat() < 0.3f;

	if (isStruct)
	{
		const int			numMembers = rnd.getInt(1, 5);
		StructType* const	structType = new StructType(("structType" + de::toString(curStructIdx++)).c_str());

		for (int i = 0; i < numMembers; i++)
			structType->addMember(("m" + de::toString(i)).c_str(), generateRandomType(maxDepth-1, curStructIdx, structTypesDst, rnd));

		structTypesDst.push_back(structType);
		return isArray ? glu::VarType(glu::VarType(structType), rnd.getInt(1, 5)) : glu::VarType(structType);
	}
	else
	{
		const glu::DataType		basicType = (glu::DataType)s_testDataTypes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testDataTypes)-1)];
		const glu::Precision	precision = glu::isDataTypeBoolOrBVec(basicType) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
		return isArray ? glu::VarType(glu::VarType(basicType, precision), rnd.getInt(1, 5)) : glu::VarType(basicType, precision);
	}
}

namespace
{

struct VarValue
{
	glu::DataType type;

	union
	{
		float		floatV[4*4]; // At most mat4. \note Matrices here are column-major.
		deInt32		intV[4];
		deUint32	uintV[4];
		bool		boolV[4];
		struct
		{
			int		unit;
			union
			{
				float		floatV[4];
				deInt32		intV[4];
				deUint32	uintV[4];
			} fillColor;
		} samplerV;
	} val;
};

enum CaseShaderType
{
	CASESHADERTYPE_VERTEX = 0,
	CASESHADERTYPE_FRAGMENT,
	CASESHADERTYPE_BOTH,

	CASESHADERTYPE_LAST
};

struct Uniform
{
	string			name;
	glu::VarType	type;

	Uniform (const char* const name_, const glu::VarType& type_) : name(name_), type(type_) {}
};

// A set of uniforms, along with related struct types.
class UniformCollection
{
public:
	int					getNumUniforms		(void) const					{ return (int)m_uniforms.size();	}
	int					getNumStructTypes	(void) const					{ return (int)m_structTypes.size();	}
	Uniform&			getUniform			(const int ndx)					{ return m_uniforms[ndx];			}
	const Uniform&		getUniform			(const int ndx) const			{ return m_uniforms[ndx];			}
	const StructType*	getStructType		(const int ndx) const			{ return m_structTypes[ndx];		}
	void				addUniform			(const Uniform& uniform)		{ m_uniforms.push_back(uniform);	}
	void				addStructType		(const StructType* const type)	{ m_structTypes.push_back(type);	}

	UniformCollection	(void) {}
	~UniformCollection	(void)
	{
		for (int i = 0; i < (int)m_structTypes.size(); i++)
			delete m_structTypes[i];
	}

	// Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one.
	// \note receiver takes ownership of the struct types.
	void moveContents (UniformCollection& receiver)
	{
		for (int i = 0; i < (int)m_uniforms.size(); i++)
			receiver.addUniform(m_uniforms[i]);
		m_uniforms.clear();

		for (int i = 0; i < (int)m_structTypes.size(); i++)
			receiver.addStructType(m_structTypes[i]);
		m_structTypes.clear();
	}

	bool containsMatchingBasicType (const dataTypePredicate predicate) const
	{
		for (int i = 0; i < (int)m_uniforms.size(); i++)
			if (typeContainsMatchingBasicType(m_uniforms[i].type, predicate))
				return true;
		return false;
	}

	vector<glu::DataType> getSamplerTypes (void) const
	{
		vector<glu::DataType> samplerTypes;
		for (int i = 0; i < (int)m_uniforms.size(); i++)
			getDistinctSamplerTypes(samplerTypes, m_uniforms[i].type);
		return samplerTypes;
	}

	bool containsSeveralSamplerTypes (void) const
	{
		return getSamplerTypes().size() > 1;
	}

	int getNumSamplers (void) const
	{
		int sum = 0;
		for (int i = 0; i < (int)m_uniforms.size(); i++)
			sum += getNumSamplersInType(m_uniforms[i].type);
		return sum;
	}

	static UniformCollection* basic (const glu::DataType type, const char* const nameSuffix = "")
	{
		UniformCollection* const	res		= new UniformCollection;
		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(type, prec)));
		return res;
	}

	static UniformCollection* basicArray (const glu::DataType type, const char* const nameSuffix = "")
	{
		UniformCollection* const	res		= new UniformCollection;
		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(glu::VarType(type, prec), 3)));
		return res;
	}

	static UniformCollection* basicStruct (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
	{
		UniformCollection* const	res		= new UniformCollection;
		const glu::Precision		prec0	= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
		const glu::Precision		prec1	= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;

		StructType* const structType = new StructType((string("structType") + nameSuffix).c_str());
		structType->addMember("m0", glu::VarType(type0, prec0));
		structType->addMember("m1", glu::VarType(type1, prec1));
		if (containsArrays)
		{
			structType->addMember("m2", glu::VarType(glu::VarType(type0, prec0), 3));
			structType->addMember("m3", glu::VarType(glu::VarType(type1, prec1), 3));
		}

		res->addStructType(structType);
		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));

		return res;
	}

	static UniformCollection* structInArray (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
	{
		UniformCollection* const res = basicStruct(type0, type1, containsArrays, nameSuffix);
		res->getUniform(0).type = glu::VarType(res->getUniform(0).type, 3);
		return res;
	}

	static UniformCollection* nestedArraysStructs (const glu::DataType type0, const glu::DataType type1, const char* const nameSuffix = "")
	{
		UniformCollection* const res		= new UniformCollection;
		const glu::Precision prec0			= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
		const glu::Precision prec1			= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
		StructType* const structType		= new StructType((string("structType") + nameSuffix).c_str());
		StructType* const subStructType		= new StructType((string("subStructType") + nameSuffix).c_str());
		StructType* const subSubStructType	= new StructType((string("subSubStructType") + nameSuffix).c_str());

		subSubStructType->addMember("mss0", glu::VarType(type0, prec0));
		subSubStructType->addMember("mss1", glu::VarType(type1, prec1));

		subStructType->addMember("ms0", glu::VarType(type1, prec1));
		subStructType->addMember("ms1", glu::VarType(glu::VarType(type0, prec0), 2));
		subStructType->addMember("ms2", glu::VarType(glu::VarType(subSubStructType), 2));

		structType->addMember("m0", glu::VarType(type0, prec0));
		structType->addMember("m1", glu::VarType(subStructType));
		structType->addMember("m2", glu::VarType(type1, prec1));

		res->addStructType(subSubStructType);
		res->addStructType(subStructType);
		res->addStructType(structType);

		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));

		return res;
	}

	static UniformCollection* multipleBasic (const char* const nameSuffix = "")
	{
		static const glu::DataType	types[]	= { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_UINT_VEC4, glu::TYPE_FLOAT_MAT3, glu::TYPE_BOOL_VEC2 };
		UniformCollection* const	res		= new UniformCollection;

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
		{
			UniformCollection* const sub = basic(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
			sub->moveContents(*res);
			delete sub;
		}

		return res;
	}

	static UniformCollection* multipleBasicArray (const char* const nameSuffix = "")
	{
		static const glu::DataType	types[]	= { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_BOOL_VEC2 };
		UniformCollection* const	res		= new UniformCollection;

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
		{
			UniformCollection* const sub = basicArray(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
			sub->moveContents(*res);
			delete sub;
		}

		return res;
	}

	static UniformCollection* multipleNestedArraysStructs (const char* const nameSuffix = "")
	{
		static const glu::DataType	types0[]	= { glu::TYPE_FLOAT,		glu::TYPE_INT,		glu::TYPE_BOOL_VEC4 };
		static const glu::DataType	types1[]	= { glu::TYPE_FLOAT_VEC4,	glu::TYPE_INT_VEC4,	glu::TYPE_BOOL };
		UniformCollection* const	res			= new UniformCollection;

		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types0) == DE_LENGTH_OF_ARRAY(types1));

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types0); i++)
		{
			UniformCollection* const sub = nestedArraysStructs(types0[i], types1[i], ("_" + de::toString(i) + nameSuffix).c_str());
			sub->moveContents(*res);
			delete sub;
		}

		return res;
	}

	static UniformCollection* random (const deUint32 seed)
	{
		Random						rnd			(seed);
		const int					numUniforms	= rnd.getInt(1, 5);
		int							structIdx	= 0;
		UniformCollection* const	res			= new UniformCollection;

		for (int i = 0; i < numUniforms; i++)
		{
			vector<const StructType*>	structTypes;
			Uniform						uniform(("u_var" + de::toString(i)).c_str(), glu::VarType());

			// \note Discard uniforms that would cause number of samplers to exceed MAX_NUM_SAMPLER_UNIFORMS.
			do
			{
				for (int j = 0; j < (int)structTypes.size(); j++)
					delete structTypes[j];
				structTypes.clear();
				uniform.type = generateRandomType(3, structIdx, structTypes, rnd);
			} while (res->getNumSamplers() + getNumSamplersInType(uniform.type) > MAX_NUM_SAMPLER_UNIFORMS);

			res->addUniform(uniform);
			for (int j = 0; j < (int)structTypes.size(); j++)
				res->addStructType(structTypes[j]);
		}

		return res;
	}

private:
	// \note Copying these would be cumbersome, since deep-copying both m_uniforms and m_structTypes
	// would mean that we'd need to update pointers from uniforms to point to the new structTypes.
	// When the same UniformCollection is needed in several places, a SharedPtr is used instead.
								UniformCollection	(const UniformCollection&); // Not allowed.
	UniformCollection&			operator=			(const UniformCollection&); // Not allowed.

	vector<Uniform>				m_uniforms;
	vector<const StructType*>	m_structTypes;
};

} // anonymous

static VarValue getSamplerFillValue (const VarValue& sampler)
{
	DE_ASSERT(glu::isDataTypeSampler(sampler.type));

	VarValue result;
	result.type = getSamplerLookupReturnType(sampler.type);

	switch (result.type)
	{
		case glu::TYPE_FLOAT_VEC4:
			for (int i = 0; i < 4; i++)
				result.val.floatV[i] = sampler.val.samplerV.fillColor.floatV[i];
			break;
		case glu::TYPE_UINT_VEC4:
			for (int i = 0; i < 4; i++)
				result.val.uintV[i] = sampler.val.samplerV.fillColor.uintV[i];
			break;
		case glu::TYPE_INT_VEC4:
			for (int i = 0; i < 4; i++)
				result.val.intV[i] = sampler.val.samplerV.fillColor.intV[i];
			break;
		case glu::TYPE_FLOAT:
			result.val.floatV[0] = sampler.val.samplerV.fillColor.floatV[0];
			break;
		default:
			DE_ASSERT(false);
	}

	return result;
}

static VarValue getSamplerUnitValue (const VarValue& sampler)
{
	DE_ASSERT(glu::isDataTypeSampler(sampler.type));

	VarValue result;
	result.type = glu::TYPE_INT;
	result.val.intV[0] = sampler.val.samplerV.unit;

	return result;
}

static glu::DataType getDataTypeTransposedMatrix (const glu::DataType original)
{
	return glu::getDataTypeMatrix(glu::getDataTypeMatrixNumRows(original), glu::getDataTypeMatrixNumColumns(original));
}

static VarValue getTransposeMatrix (const VarValue& original)
{
	DE_ASSERT(glu::isDataTypeMatrix(original.type));

	const int	rows = glu::getDataTypeMatrixNumRows(original.type);
	const int	cols = glu::getDataTypeMatrixNumColumns(original.type);
	VarValue	result;
	result.type = getDataTypeTransposedMatrix(original.type);

	for (int i = 0; i < rows; i++)
	for (int j = 0; j < cols; j++)
		result.val.floatV[i*cols + j] = original.val.floatV[j*rows + i];

	return result;
}

static string shaderVarValueStr (const VarValue& value)
{
	const int			numElems = glu::getDataTypeScalarSize(value.type);
	std::ostringstream	result;

	if (numElems > 1)
		result << glu::getDataTypeName(value.type) << "(";

	for (int i = 0; i < numElems; i++)
	{
		if (i > 0)
			result << ", ";

		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
			result << de::floatToString(value.val.floatV[i], 2);
		else if (glu::isDataTypeIntOrIVec((value.type)))
			result << de::toString(value.val.intV[i]);
		else if (glu::isDataTypeUintOrUVec((value.type)))
			result << de::toString(value.val.uintV[i]) << "u";
		else if (glu::isDataTypeBoolOrBVec((value.type)))
			result << (value.val.boolV[i] ? "true" : "false");
		else if (glu::isDataTypeSampler((value.type)))
			result << shaderVarValueStr(getSamplerFillValue(value));
		else
			DE_ASSERT(false);
	}

	if (numElems > 1)
		result << ")";

	return result.str();
}

static string apiVarValueStr (const VarValue& value)
{
	const int			numElems = glu::getDataTypeScalarSize(value.type);
	std::ostringstream	result;

	if (numElems > 1)
		result << "(";

	for (int i = 0; i < numElems; i++)
	{
		if (i > 0)
			result << ", ";

		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
			result << de::floatToString(value.val.floatV[i], 2);
		else if (glu::isDataTypeIntOrIVec((value.type)))
			result << de::toString(value.val.intV[i]);
		else if (glu::isDataTypeUintOrUVec((value.type)))
			result << de::toString(value.val.uintV[i]);
		else if (glu::isDataTypeBoolOrBVec((value.type)))
			result << (value.val.boolV[i] ? "true" : "false");
		else if (glu::isDataTypeSampler((value.type)))
			result << value.val.samplerV.unit;
		else
			DE_ASSERT(false);
	}

	if (numElems > 1)
		result << ")";

	return result.str();
}

static VarValue generateRandomVarValue (const glu::DataType type, Random& rnd, int samplerUnit = -1 /* Used if type is a sampler type. \note Samplers' unit numbers are not randomized. */)
{
	const int	numElems = glu::getDataTypeScalarSize(type);
	VarValue	result;
	result.type = type;

	DE_ASSERT((samplerUnit >= 0) == (glu::isDataTypeSampler(type)));

	if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
	}
	else if (glu::isDataTypeIntOrIVec(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.intV[i] = rnd.getInt(-10, 10);
	}
	else if (glu::isDataTypeUintOrUVec(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.uintV[i] = (deUint32)rnd.getInt(0, 10);
	}
	else if (glu::isDataTypeBoolOrBVec(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.boolV[i] = rnd.getBool();
	}
	else if (glu::isDataTypeSampler(type))
	{
		const glu::DataType		texResultType		= getSamplerLookupReturnType(type);
		const glu::DataType		texResultScalarType	= glu::getDataTypeScalarType(texResultType);
		const int				texResultNumDims	= glu::getDataTypeScalarSize(texResultType);

		result.val.samplerV.unit = samplerUnit;

		for (int i = 0; i < texResultNumDims; i++)
		{
			switch (texResultScalarType)
			{
				case glu::TYPE_FLOAT:	result.val.samplerV.fillColor.floatV[i]		= rnd.getFloat(0.0f, 1.0f);		break;
				case glu::TYPE_INT:		result.val.samplerV.fillColor.intV[i]		= rnd.getInt(-10, 10);			break;
				case glu::TYPE_UINT:	result.val.samplerV.fillColor.uintV[i]		= (deUint32)rnd.getInt(0, 10);	break;
				default:
					DE_ASSERT(false);
			}
		}
	}
	else
		DE_ASSERT(false);

	return result;
}

static VarValue generateZeroVarValue (const glu::DataType type)
{
	const int	numElems = glu::getDataTypeScalarSize(type);
	VarValue	result;
	result.type = type;

	if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.floatV[i] = 0.0f;
	}
	else if (glu::isDataTypeIntOrIVec(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.intV[i] = 0;
	}
	else if (glu::isDataTypeUintOrUVec(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.uintV[i] = 0u;
	}
	else if (glu::isDataTypeBoolOrBVec(type))
	{
		for (int i = 0; i < numElems; i++)
			result.val.boolV[i] = false;
	}
	else if (glu::isDataTypeSampler(type))
	{
		const glu::DataType		texResultType		= getSamplerLookupReturnType(type);
		const glu::DataType		texResultScalarType	= glu::getDataTypeScalarType(texResultType);
		const int				texResultNumDims	= glu::getDataTypeScalarSize(texResultType);

		result.val.samplerV.unit = 0;

		for (int i = 0; i < texResultNumDims; i++)
		{
			switch (texResultScalarType)
			{
				case glu::TYPE_FLOAT:	result.val.samplerV.fillColor.floatV[i]		= 0.12f * (float)i;	break;
				case glu::TYPE_INT:		result.val.samplerV.fillColor.intV[i]		= -2 + i;			break;
				case glu::TYPE_UINT:	result.val.samplerV.fillColor.uintV[i]		= 4 + i;			break;
				default:
					DE_ASSERT(false);
			}
		}
	}
	else
		DE_ASSERT(false);

	return result;
}

static bool apiVarValueEquals (const VarValue& a, const VarValue& b)
{
	const int		size			= glu::getDataTypeScalarSize(a.type);
	const float		floatThreshold	= 0.05f;

	DE_ASSERT(a.type == b.type);

	if (glu::isDataTypeFloatOrVec(a.type) || glu::isDataTypeMatrix(a.type))
	{
		for (int i = 0; i < size; i++)
			if (de::abs(a.val.floatV[i] - b.val.floatV[i]) >= floatThreshold)
				return false;
	}
	else if (glu::isDataTypeIntOrIVec(a.type))
	{
		for (int i = 0; i < size; i++)
			if (a.val.intV[i] != b.val.intV[i])
				return false;
	}
	else if (glu::isDataTypeUintOrUVec(a.type))
	{
		for (int i = 0; i < size; i++)
			if (a.val.uintV[i] != b.val.uintV[i])
				return false;
	}
	else if (glu::isDataTypeBoolOrBVec(a.type))
	{
		for (int i = 0; i < size; i++)
			if (a.val.boolV[i] != b.val.boolV[i])
				return false;
	}
	else if (glu::isDataTypeSampler(a.type))
	{
		if (a.val.samplerV.unit != b.val.samplerV.unit)
			return false;
	}
	else
		DE_ASSERT(false);

	return true;
}

static VarValue getRandomBoolRepresentation (const VarValue& boolValue, const glu::DataType targetScalarType, Random& rnd)
{
	DE_ASSERT(glu::isDataTypeBoolOrBVec(boolValue.type));

	const int				size		= glu::getDataTypeScalarSize(boolValue.type);
	const glu::DataType		targetType	= size == 1 ? targetScalarType : glu::getDataTypeVector(targetScalarType, size);
	VarValue				result;
	result.type = targetType;

	switch (targetScalarType)
	{
		case glu::TYPE_INT:
			for (int i = 0; i < size; i++)
			{
				if (boolValue.val.boolV[i])
				{
					result.val.intV[i] = rnd.getInt(-10, 10);
					if (result.val.intV[i] == 0)
						result.val.intV[i] = 1;
				}
				else
					result.val.intV[i] = 0;
			}
			break;

		case glu::TYPE_UINT:
			for (int i = 0; i < size; i++)
			{
				if (boolValue.val.boolV[i])
					result.val.uintV[i] = rnd.getInt(1, 10);
				else
					result.val.uintV[i] = 0;
			}
			break;

		case glu::TYPE_FLOAT:
			for (int i = 0; i < size; i++)
			{
				if (boolValue.val.boolV[i])
				{
					result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
					if (result.val.floatV[i] == 0.0f)
						result.val.floatV[i] = 1.0f;
				}
				else
					result.val.floatV[i] = 0;
			}
			break;

		default:
			DE_ASSERT(false);
	}

	return result;
}

static const char* getCaseShaderTypeName (const CaseShaderType type)
{
	switch (type)
	{
		case CASESHADERTYPE_VERTEX:		return "vertex";
		case CASESHADERTYPE_FRAGMENT:	return "fragment";
		case CASESHADERTYPE_BOTH:		return "both";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static CaseShaderType randomCaseShaderType (const deUint32 seed)
{
	return (CaseShaderType)Random(seed).getInt(0, CASESHADERTYPE_LAST-1);
}

class UniformCase : public TestCase, protected glu::CallLogWrapper
{
public:
	enum Feature
	{
		// ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices.
		FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX	= 1<<0,

		// UNIFORMFUNC_VALUE: use pass-by-value versions of uniform assignment funcs, e.g. glUniform1f(), where possible. If not given, use pass-by-pointer versions.
		FEATURE_UNIFORMFUNC_VALUE				= 1<<1,

		// MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major.
		FEATURE_MATRIXMODE_ROWMAJOR				= 1<<2,

		// ARRAYASSIGN: how basic-type arrays are assigned with glUniform*(). If none given, assign each element of an array separately.
		FEATURE_ARRAYASSIGN_FULL				= 1<<3, //!< Assign all elements of an array with one glUniform*().
		FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO		= 1<<4, //!< Assign two elements per one glUniform*().

		// UNIFORMUSAGE_EVERY_OTHER: use about half of the uniforms. If not given, use all uniforms (except that some array indices may be omitted according to ARRAYUSAGE).
		FEATURE_UNIFORMUSAGE_EVERY_OTHER		= 1<<5,

		// BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float.
		FEATURE_BOOLEANAPITYPE_INT				= 1<<6,
		FEATURE_BOOLEANAPITYPE_UINT				= 1<<7,

		// UNIFORMVALUE_ZERO: use zero-valued uniforms. If not given, use random uniform values.
		FEATURE_UNIFORMVALUE_ZERO				= 1<<8,

		// ARRAY_FIRST_ELEM_NAME_NO_INDEX: in certain API functions, when referring to the first element of an array, use just the array name without [0] at the end.
		FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX	= 1<<9
	};

								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 features);
								UniformCase		(Context& context, const char* name, const char* description, deUint32 seed); // \note Randomizes caseType, uniformCollection and features.
	virtual						~UniformCase	(void);

	virtual void				init			(void);
	virtual void				deinit			(void);

	IterateResult				iterate			(void);

protected:
	// A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
	struct BasicUniform
	{
		string			name;
		glu::DataType	type;
		bool			isUsedInShader;
		VarValue		finalValue;	//!< The value we ultimately want to set for this uniform.

		string			rootName;	//!< If this is a member of a basic-typed array, rootName is the name of that array with "[0]" appended. Otherwise it equals name.
		int				elemNdx;	//!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
		int				rootSize;	//!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.

		BasicUniform (const char* const		name_,
					  const glu::DataType	type_,
					  const bool			isUsedInShader_,
					  const VarValue&		finalValue_,
					  const char* const		rootName_	= DE_NULL,
					  const int				elemNdx_	= -1,
					  const int				rootSize_	= 1)
					  : name			(name_)
					  , type			(type_)
					  , isUsedInShader	(isUsedInShader_)
					  , finalValue		(finalValue_)
					  , rootName		(rootName_ == DE_NULL ? name_ : rootName_)
					  , elemNdx			(elemNdx_)
					  , rootSize		(rootSize_)
					 {
					 }

		static vector<BasicUniform>::const_iterator findWithName (const vector<BasicUniform>& vec, const char* const name)
		{
			for (vector<BasicUniform>::const_iterator it = vec.begin(); it != vec.end(); it++)
			{
				if (it->name == name)
					return it;
			}
			return vec.end();
		}
	};

	// Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniformsiv().
	struct BasicUniformReportRef
	{
		string			name;
		// \note minSize and maxSize are for arrays and can be distinct since implementations are allowed, but not required, to trim the inactive end indices of arrays.
		int				minSize;
		int				maxSize;
		glu::DataType	type;
		bool			isUsedInShader;

		BasicUniformReportRef (const char* const name_, const int minS, const int maxS, const glu::DataType type_, const bool used)
			: name(name_), minSize(minS), maxSize(maxS), type(type_), isUsedInShader(used) { DE_ASSERT(minSize <= maxSize); }
		BasicUniformReportRef (const char* const name_, const glu::DataType type_, const bool used)
			: name(name_), minSize(1), maxSize(1), type(type_), isUsedInShader(used) {}
	};

	// Info that is actually reported by glGetActiveUniform() or glGetActiveUniformsiv().
	struct BasicUniformReportGL
	{
		string			name;
		int				nameLength; // \note Whether this includes the null byte depends on whether it was queried with glGetActiveUniform() or glGetActiveUniformsiv().
		int				size;
		glu::DataType	type;

		int				index;

		BasicUniformReportGL (const char* const name_, const int nameLength_, const int size_, const glu::DataType type_, const int index_)
			: name(name_), nameLength(nameLength_), size(size_), type(type_), index(index_) {}

		static vector<BasicUniformReportGL>::const_iterator findWithName (const vector<BasicUniformReportGL>& vec, const char* const name)
		{
			for (vector<BasicUniformReportGL>::const_iterator it = vec.begin(); it != vec.end(); it++)
			{
				if (it->name == name)
					return it;
			}
			return vec.end();
		}
	};

	// Query info with glGetActiveUniform() and check validity.
	bool						getActiveUniforms						(vector<BasicUniformReportGL>& dst, const vector<BasicUniformReportRef>& ref, deUint32 programGL);
	// Query info with glGetUniformIndices() + glGetActiveUniformsiv() and check validity.
	bool						getActiveUniformsiv						(vector<BasicUniformReportGL>& dst, const vector<BasicUniformReportRef>& ref, deUint32 programGL);
	// Compare infos returned by glGetActiveUniform() and glGetUniformIndices() + glGetActiveUniformsiv().
	bool						uniformVsUniformsivComparison			(const vector<BasicUniformReportGL>& uniformsResult, const vector<BasicUniformReportGL>& uniformsivResult);
	// Get uniform values with glGetUniform*() and put to valuesDst. Uniforms that get -1 from glGetUniformLocation() get glu::TYPE_INVALID.
	bool						getUniforms								(vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, deUint32 programGL);
	// Check that every uniform has the default (zero) value.
	bool						checkUniformDefaultValues				(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
	// Assign the basicUniforms[].finalValue values for uniforms. \note rnd parameter is for booleans (true can be any nonzero value).
	void						assignUniforms							(const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd);
	// Compare the uniform values given in values (obtained with glGetUniform*()) with the basicUniform.finalValue values.
	bool						compareUniformValues					(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
	// Render and check that all pixels are white (i.e. all uniform comparisons passed).
	bool						renderTest								(const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd);

	virtual bool				test									(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd) = 0;

	const deUint32								m_features;
	const SharedPtr<const UniformCollection>	m_uniformCollection;

private:
	static deUint32				randomFeatures							(deUint32 seed);

	// Generates the basic uniforms, based on the uniform with name varName and type varType, in the same manner as are expected
	// to be returned by glGetActiveUniform(), e.g. generates a name like var[0] for arrays, and recursively generates struct member names.
	void						generateBasicUniforms					(vector<BasicUniform>&				basicUniformsDst,
																		 vector<BasicUniformReportRef>&		basicUniformReportsDst,
																		 const glu::VarType&				varType,
																		 const char*						varName,
																		 bool								isParentActive,
																		 int&								samplerUnitCounter,
																		 Random&							rnd) const;

	void						writeUniformDefinitions					(std::ostringstream& dst) const;
	void						writeUniformCompareExpr					(std::ostringstream& dst, const BasicUniform& uniform) const;
	void						writeUniformComparisons					(std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* variableName) const;

	string						generateVertexSource					(const vector<BasicUniform>& basicUniforms) const;
	string						generateFragmentSource					(const vector<BasicUniform>& basicUniforms) const;

	void						setupTexture							(const VarValue& value);

	const CaseShaderType						m_caseShaderType;

	vector<glu::Texture2D*>						m_textures2d;
	vector<glu::TextureCube*>					m_texturesCube;
	vector<deUint32>							m_filledTextureUnits;
};

deUint32 UniformCase::randomFeatures (const deUint32 seed)
{
	static const deUint32 arrayUsageChoices[]		= { 0, FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX										};
	static const deUint32 uniformFuncChoices[]		= { 0, FEATURE_UNIFORMFUNC_VALUE												};
	static const deUint32 matrixModeChoices[]		= { 0, FEATURE_MATRIXMODE_ROWMAJOR												};
	static const deUint32 arrayAssignChoices[]		= { 0, FEATURE_ARRAYASSIGN_FULL,			FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	};
	static const deUint32 uniformUsageChoices[]		= { 0, FEATURE_UNIFORMUSAGE_EVERY_OTHER											};
	static const deUint32 booleanApiTypeChoices[]	= { 0, FEATURE_BOOLEANAPITYPE_INT,			FEATURE_BOOLEANAPITYPE_UINT			};
	static const deUint32 uniformValueChoices[]		= { 0, FEATURE_UNIFORMVALUE_ZERO												};

	Random rnd(seed);

	deUint32 result = 0;

#define ARRAY_CHOICE(ARR) ((ARR)[rnd.getInt(0, DE_LENGTH_OF_ARRAY(ARR)-1)])

	result |= ARRAY_CHOICE(arrayUsageChoices);
	result |= ARRAY_CHOICE(uniformFuncChoices);
	result |= ARRAY_CHOICE(matrixModeChoices);
	result |= ARRAY_CHOICE(arrayAssignChoices);
	result |= ARRAY_CHOICE(uniformUsageChoices);
	result |= ARRAY_CHOICE(booleanApiTypeChoices);
	result |= ARRAY_CHOICE(uniformValueChoices);

#undef ARRAY_CHOICE

	return result;
}

UniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 features)
	: TestCase				(context, name, description)
	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
	, m_features			(features)
	, m_uniformCollection	(uniformCollection)
	, m_caseShaderType		(caseShaderType)
{
}

UniformCase::UniformCase (Context& context, const char* name, const char* description, const deUint32 seed)
	: TestCase				(context, name, description)
	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
	, m_features			(randomFeatures(seed))
	, m_uniformCollection	(UniformCollection::random(seed))
	, m_caseShaderType		(randomCaseShaderType(seed))
{
}

void UniformCase::init (void)
{
	{
		const glw::Functions&	funcs						= m_context.getRenderContext().getFunctions();
		const int				numSamplerUniforms			= m_uniformCollection->getNumSamplers();
		const int				vertexTexUnitsRequired		= m_caseShaderType != CASESHADERTYPE_FRAGMENT ? numSamplerUniforms : 0;
		const int				fragmentTexUnitsRequired	= m_caseShaderType != CASESHADERTYPE_VERTEX ? numSamplerUniforms : 0;
		const int				combinedTexUnitsRequired	= vertexTexUnitsRequired + fragmentTexUnitsRequired;
		const int				vertexTexUnitsSupported		= getGLInt(funcs, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
		const int				fragmentTexUnitsSupported	= getGLInt(funcs, GL_MAX_TEXTURE_IMAGE_UNITS);
		const int				combinedTexUnitsSupported	= getGLInt(funcs, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);

		DE_ASSERT(numSamplerUniforms <= MAX_NUM_SAMPLER_UNIFORMS);

		if (vertexTexUnitsRequired > vertexTexUnitsSupported)
			throw tcu::NotSupportedError(de::toString(vertexTexUnitsRequired) + " vertex texture units required, " + de::toString(vertexTexUnitsSupported) + " supported");
		if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
			throw tcu::NotSupportedError(de::toString(fragmentTexUnitsRequired) + " fragment texture units required, " + de::toString(fragmentTexUnitsSupported) + " supported");
		if (combinedTexUnitsRequired > combinedTexUnitsSupported)
			throw tcu::NotSupportedError(de::toString(combinedTexUnitsRequired) + " combined texture units required, " + de::toString(combinedTexUnitsSupported) + " supported");
	}

	enableLogging(true);
}

void UniformCase::deinit (void)
{
	for (int i = 0; i < (int)m_textures2d.size(); i++)
		delete m_textures2d[i];
	m_textures2d.clear();

	for (int i = 0; i < (int)m_texturesCube.size(); i++)
		delete m_texturesCube[i];
	m_texturesCube.clear();

	m_filledTextureUnits.clear();
}

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

void UniformCase::generateBasicUniforms (vector<BasicUniform>& basicUniformsDst, vector<BasicUniformReportRef>& basicUniformReportsDst, const glu::VarType& varType, const char* const varName, const bool isParentActive, int& samplerUnitCounter, Random& rnd) const
{
	if (varType.isBasicType())
	{
		const bool				isActive	= isParentActive && (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true);
		const glu::DataType		type		= varType.getBasicType();
		const VarValue			value		= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(type)
											: glu::isDataTypeSampler(type)				? generateRandomVarValue(type, rnd, samplerUnitCounter++)
											: generateRandomVarValue(varType.getBasicType(), rnd);

		basicUniformsDst.push_back(BasicUniform(varName, varType.getBasicType(), isActive, value));
		basicUniformReportsDst.push_back(BasicUniformReportRef(varName, varType.getBasicType(), isActive));
	}
	else if (varType.isArrayType())
	{
		const int		size			= varType.getArraySize();
		const string	arrayRootName	= string("") + varName + "[0]";
		vector<bool>	isElemActive;

		for (int elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++)
		{
			const string	indexedName		= string("") + varName + "[" + de::toString(elemNdx) + "]";
			const bool		isCurElemActive	= isParentActive																						&&
											  (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER			? basicUniformsDst.size() % 2 == 0	: true)	&&
											  (m_features & FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX		? elemNdx == size/2					: true);

			isElemActive.push_back(isCurElemActive);

			if (varType.getElementType().isBasicType())
			{
				// \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
				const glu::DataType	elemBasicType	= varType.getElementType().getBasicType();
				const VarValue		value			= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(elemBasicType)
													: glu::isDataTypeSampler(elemBasicType)		? generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++)
													: generateRandomVarValue(elemBasicType, rnd);

				basicUniformsDst.push_back(BasicUniform(indexedName.c_str(), elemBasicType, isCurElemActive, value, arrayRootName.c_str(), elemNdx, size));
			}
			else
				generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName.c_str(), isCurElemActive, samplerUnitCounter, rnd);
		}

		if (varType.getElementType().isBasicType())
		{
			int minSize;
			for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize-1]; minSize--);

			basicUniformReportsDst.push_back(BasicUniformReportRef(arrayRootName.c_str(), minSize, size, varType.getElementType().getBasicType(), isParentActive && minSize > 0));
		}
	}
	else
	{
		DE_ASSERT(varType.isStructType());

		const StructType& structType = *varType.getStructPtr();

		for (int i = 0; i < structType.getNumMembers(); i++)
		{
			const glu::StructMember&	member			= structType.getMember(i);
			const string				memberFullName	= string("") + varName + "." + member.getName();

			generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName.c_str(), isParentActive, samplerUnitCounter, rnd);
		}
	}
}

void UniformCase::writeUniformDefinitions (std::ostringstream& dst) const
{
	for (int i = 0; i < (int)m_uniformCollection->getNumStructTypes(); i++)
		dst << glu::declare(m_uniformCollection->getStructType(i)) << ";\n";

	for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
		dst << "uniform " << glu::declare(m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str()) << ";\n";

	dst << "\n";

	{
		static const struct
		{
			dataTypePredicate	requiringTypes[2];
			const char*			definition;
		} compareFuncs[] =
		{
			{ { glu::isDataTypeFloatOrVec,				glu::isDataTypeMatrix				}, "mediump float compare_float    (mediump float a, mediump float b)  { return abs(a - b) < 0.05 ? 1.0 : 0.0; }"																		},
			{ { dataTypeEquals<glu::TYPE_FLOAT_VEC2>,	dataTypeIsMatrixWithNRows<2>		}, "mediump float compare_vec2     (mediump vec2 a, mediump vec2 b)    { return compare_float(a.x, b.x)*compare_float(a.y, b.y); }"														},
			{ { dataTypeEquals<glu::TYPE_FLOAT_VEC3>,	dataTypeIsMatrixWithNRows<3>		}, "mediump float compare_vec3     (mediump vec3 a, mediump vec3 b)    { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z); }"								},
			{ { dataTypeEquals<glu::TYPE_FLOAT_VEC4>,	dataTypeIsMatrixWithNRows<4>		}, "mediump float compare_vec4     (mediump vec4 a, mediump vec4 b)    { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z)*compare_float(a.w, b.w); }"		},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat2     (mediump mat2 a, mediump mat2 b)    { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1]); }"													},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT2X3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat2x3   (mediump mat2x3 a, mediump mat2x3 b){ return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1]); }"													},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT2X4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat2x4   (mediump mat2x4 a, mediump mat2x4 b){ return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1]); }"													},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT3X2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat3x2   (mediump mat3x2 a, mediump mat3x2 b){ return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2]); }"							},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat3     (mediump mat3 a, mediump mat3 b)    { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2]); }"							},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT3X4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat3x4   (mediump mat3x4 a, mediump mat3x4 b){ return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2]); }"							},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT4X2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat4x2   (mediump mat4x2 a, mediump mat4x2 b){ return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2])*compare_vec2(a[3], b[3]); }"	},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT4X3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat4x3   (mediump mat4x3 a, mediump mat4x3 b){ return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2])*compare_vec3(a[3], b[3]); }"	},
			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat4     (mediump mat4 a, mediump mat4 b)    { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2])*compare_vec4(a[3], b[3]); }"	},
			{ { dataTypeEquals<glu::TYPE_INT>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_int      (mediump int a, mediump int b)      { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_INT_VEC2>,		dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_ivec2    (mediump ivec2 a, mediump ivec2 b)  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_INT_VEC3>,		dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_ivec3    (mediump ivec3 a, mediump ivec3 b)  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_INT_VEC4>,		dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_ivec4    (mediump ivec4 a, mediump ivec4 b)  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_UINT>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uint     (mediump uint a, mediump uint b)    { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_UINT_VEC2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uvec2    (mediump uvec2 a, mediump uvec2 b)  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_UINT_VEC3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uvec3    (mediump uvec3 a, mediump uvec3 b)  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_UINT_VEC4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uvec4    (mediump uvec4 a, mediump uvec4 b)  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_BOOL>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bool     (bool a, bool b)                    { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_BOOL_VEC2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bvec2    (bvec2 a, bvec2 b)                  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_BOOL_VEC3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bvec3    (bvec3 a, bvec3 b)                  { return a == b ? 1.0 : 0.0; }"																					},
			{ { dataTypeEquals<glu::TYPE_BOOL_VEC4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bvec4    (bvec4 a, bvec4 b)                  { return a == b ? 1.0 : 0.0; }"																					}
		};

		const vector<glu::DataType> samplerTypes = m_uniformCollection->getSamplerTypes();

		for (int compFuncNdx = 0; compFuncNdx < DE_LENGTH_OF_ARRAY(compareFuncs); compFuncNdx++)
		{
			const dataTypePredicate		(&typeReq)[2]			= compareFuncs[compFuncNdx].requiringTypes;
			bool						containsTypeSampler		= false;

			for (int i = 0; i < (int)samplerTypes.size(); i++)
			{
				if (glu::isDataTypeSampler(samplerTypes[i]))
				{
					const glu::DataType retType = getSamplerLookupReturnType(samplerTypes[i]);
					if (typeReq[0](retType) || typeReq[1](retType))
					{
						containsTypeSampler = true;
						break;
					}
				}
			}

			if (containsTypeSampler || m_uniformCollection->containsMatchingBasicType(typeReq[0]) || m_uniformCollection->containsMatchingBasicType(typeReq[1]))
				dst << compareFuncs[compFuncNdx].definition << "\n";
		}
	}
}

void UniformCase::writeUniformCompareExpr (std::ostringstream& dst, const BasicUniform& uniform) const
{
	if (glu::isDataTypeSampler(uniform.type))
		dst << "compare_" << glu::getDataTypeName(getSamplerLookupReturnType(uniform.type)) << "(texture(" << uniform.name << ", vec" << getSamplerNumLookupDimensions(uniform.type) << "(0.0))";
	else
		dst << "compare_" << glu::getDataTypeName(uniform.type) << "(" << uniform.name;

	dst << ", " << shaderVarValueStr(uniform.finalValue) << ")";
}

void UniformCase::writeUniformComparisons (std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* const variableName) const
{
	for (int i = 0; i < (int)basicUniforms.size(); i++)
	{
		const BasicUniform& unif = basicUniforms[i];

		if (unif.isUsedInShader)
		{
			dst << "\t" << variableName << " *= ";
			writeUniformCompareExpr(dst, basicUniforms[i]);
			dst << ";\n";
		}
		else
			dst << "\t// UNUSED: " << basicUniforms[i].name << "\n";
	}
}

string UniformCase::generateVertexSource (const vector<BasicUniform>& basicUniforms) const
{
	const bool			isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX || m_caseShaderType == CASESHADERTYPE_BOTH;
	std::ostringstream	result;

	result << "#version 300 es\n"
			  "in highp vec4 a_position;\n"
			  "out mediump float v_vtxOut;\n"
			  "\n";

	if (isVertexCase)
		writeUniformDefinitions(result);

	result << "\n"
			  "void main (void)\n"
			  "{\n"
			  "	gl_Position = a_position;\n"
			  "	v_vtxOut = 1.0;\n";

	if (isVertexCase)
		writeUniformComparisons(result, basicUniforms, "v_vtxOut");

	result << "}\n";

	return result.str();
}

string UniformCase::generateFragmentSource (const vector<BasicUniform>& basicUniforms) const
{
	const bool			isFragmentCase = m_caseShaderType == CASESHADERTYPE_FRAGMENT || m_caseShaderType == CASESHADERTYPE_BOTH;
	std::ostringstream	result;

	result << "#version 300 es\n"
			  "in mediump float v_vtxOut;\n"
			  "\n";

	if (isFragmentCase)
		writeUniformDefinitions(result);

	result << "\n"
			  "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
			  "\n"
			  "void main (void)\n"
			  "{\n"
			  "	mediump float result = v_vtxOut;\n";

	if (isFragmentCase)
		writeUniformComparisons(result, basicUniforms, "result");

	result << "	dEQP_FragColor = vec4(result, result, result, 1.0);\n"
			  "}\n";

	return result.str();
}

void UniformCase::setupTexture (const VarValue& value)
{
	// \note No handling for samplers other than 2D or cube.

	enableLogging(false);

	DE_ASSERT(getSamplerLookupReturnType(value.type) == glu::TYPE_FLOAT_VEC4);

	const int						width			= 32;
	const int						height			= 32;
	const tcu::Vec4					color			= vec4FromPtr(&value.val.samplerV.fillColor.floatV[0]);

	if (value.type == glu::TYPE_SAMPLER_2D)
	{
		glu::Texture2D* texture		= new glu::Texture2D(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width, height);
		tcu::Texture2D& refTexture	= texture->getRefTexture();
		m_textures2d.push_back(texture);

		refTexture.allocLevel(0);
		fillWithColor(refTexture.getLevel(0), color);

		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
		m_filledTextureUnits.push_back(value.val.samplerV.unit);
		texture->upload();
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
	}
	else if (value.type == glu::TYPE_SAMPLER_CUBE)
	{
		DE_ASSERT(width == height);

		glu::TextureCube* texture		= new glu::TextureCube(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width);
		tcu::TextureCube& refTexture	= texture->getRefTexture();
		m_texturesCube.push_back(texture);

		for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
		{
			refTexture.allocLevel((tcu::CubeFace)face, 0);
			fillWithColor(refTexture.getLevelFace(0, (tcu::CubeFace)face), color);
		}

		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
		m_filledTextureUnits.push_back(value.val.samplerV.unit);
		texture->upload();
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST));

	}
	else
		DE_ASSERT(false);

	enableLogging(true);
}

bool UniformCase::getActiveUniforms (vector<BasicUniformReportGL>& basicUniformReportsDst, const vector<BasicUniformReportRef>& basicUniformReportsRef, const deUint32 programGL)
{
	TestLog&			log						= m_testCtx.getLog();
	GLint				numActiveUniforms		= 0;
	GLint				uniformMaxNameLength	= 0;
	vector<char>		nameBuffer;
	bool				success					= true;

	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORMS, &numActiveUniforms));
	log << TestLog::Message << "// Number of active uniforms reported: " << numActiveUniforms << TestLog::EndMessage;
	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxNameLength));
	log << TestLog::Message << "// Maximum uniform name length reported: " << uniformMaxNameLength << TestLog::EndMessage;
	nameBuffer.resize(uniformMaxNameLength);

	for (int unifNdx = 0; unifNdx < numActiveUniforms; unifNdx++)
	{
		GLsizei					reportedNameLength	= 0;
		GLint					reportedSize		= -1;
		GLenum					reportedTypeGL		= GL_NONE;

		GLU_CHECK_CALL(glGetActiveUniform(programGL, (GLuint)unifNdx, (GLsizei)uniformMaxNameLength, &reportedNameLength, &reportedSize, &reportedTypeGL, &nameBuffer[0]));

		const glu::DataType		reportedType		= glu::getDataTypeFromGLType(reportedTypeGL);
		const string			reportedNameStr		(&nameBuffer[0]);

		TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");

		log << TestLog::Message << "// Got name = " << reportedNameStr << ", name length = " << reportedNameLength << ", size = " << reportedSize << ", type = " << glu::getDataTypeName(reportedType) << TestLog::EndMessage;

		if ((GLsizei)reportedNameStr.length() != reportedNameLength)
		{
			log << TestLog::Message << "// FAILURE: wrong name length reported, should be " << reportedNameStr.length() << TestLog::EndMessage;
			success = false;
		}

		if (!deStringBeginsWith(reportedNameStr.c_str(), "gl_")) // Ignore built-in uniforms.
		{
			int referenceNdx;
			for (referenceNdx = 0; referenceNdx < (int)basicUniformReportsRef.size(); referenceNdx++)
			{
				if (basicUniformReportsRef[referenceNdx].name == reportedNameStr)
					break;
			}

			if (referenceNdx >= (int)basicUniformReportsRef.size())
			{
				log << TestLog::Message << "// FAILURE: invalid non-built-in uniform name reported" << TestLog::EndMessage;
				success = false;
			}
			else
			{
				const BasicUniformReportRef& reference = basicUniformReportsRef[referenceNdx];

				DE_ASSERT(reference.type != glu::TYPE_LAST);
				DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
				DE_ASSERT(reference.minSize <= reference.maxSize);

				if (BasicUniformReportGL::findWithName(basicUniformReportsDst, reportedNameStr.c_str()) != basicUniformReportsDst.end())
				{
					log << TestLog::Message << "// FAILURE: same uniform name reported twice" << TestLog::EndMessage;
					success = false;
				}

				basicUniformReportsDst.push_back(BasicUniformReportGL(reportedNameStr.c_str(), reportedNameLength, reportedSize, reportedType, unifNdx));

				if (reportedType != reference.type)
				{
					log << TestLog::Message << "// FAILURE: wrong type reported, should be " << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
					success = false;
				}
				if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
				{
					log << TestLog::Message
						<< "// FAILURE: wrong size reported, should be "
						<< (reference.minSize == reference.maxSize ? de::toString(reference.minSize) : "in the range [" + de::toString(reference.minSize) + ", " + de::toString(reference.maxSize) + "]")
						<< TestLog::EndMessage;

					success = false;
				}
			}
		}
	}

	for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
	{
		const BasicUniformReportRef& expected = basicUniformReportsRef[i];
		if (expected.isUsedInShader && BasicUniformReportGL::findWithName(basicUniformReportsDst, expected.name.c_str()) == basicUniformReportsDst.end())
		{
			log << TestLog::Message << "// FAILURE: uniform with name " << expected.name << " was not reported by GL" << TestLog::EndMessage;
			success = false;
		}
	}

	return success;
}

bool UniformCase::getActiveUniformsiv (vector<BasicUniformReportGL>& basicUniformReportsDst, const vector<BasicUniformReportRef>& basicUniformReportsRef, const deUint32 programGL)
{
	TestLog&				log				= m_testCtx.getLog();
	vector<string>			queryNames		(basicUniformReportsRef.size());
	vector<const char*>		queryNamesC		(basicUniformReportsRef.size());
	vector<GLuint>			uniformIndices	(basicUniformReportsRef.size());
	vector<deUint32>		validUniformIndices; // This shall have the same contents, and in same order, as uniformIndices, but with GL_INVALID_INDEX entries removed.
	bool					success			= true;

	for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
	{
		const string& name = basicUniformReportsRef[i].name;
		queryNames[i]	= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && name[name.size()-1] == ']' ? beforeLast(name, '[') : name;
		queryNamesC[i]	= queryNames[i].c_str();
	}

	GLU_CHECK_CALL(glGetUniformIndices(programGL, (GLsizei)basicUniformReportsRef.size(), &queryNamesC[0], &uniformIndices[0]));

	for (int i = 0; i < (int)uniformIndices.size(); i++)
	{
		if (uniformIndices[i] != GL_INVALID_INDEX)
			validUniformIndices.push_back(uniformIndices[i]);
		else
		{
			if (basicUniformReportsRef[i].isUsedInShader)
			{
				log << TestLog::Message << "// FAILURE: uniform with name " << basicUniformReportsRef[i].name << " received GL_INVALID_INDEX" << TestLog::EndMessage;
				success = false;
			}
		}
	}

	if (!validUniformIndices.empty())
	{
		vector<GLint> uniformNameLengthBuf	(validUniformIndices.size());
		vector<GLint> uniformSizeBuf		(validUniformIndices.size());
		vector<GLint> uniformTypeBuf		(validUniformIndices.size());

		GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0], GL_UNIFORM_NAME_LENGTH,	&uniformNameLengthBuf[0]));
		GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0], GL_UNIFORM_SIZE,			&uniformSizeBuf[0]));
		GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0], GL_UNIFORM_TYPE,			&uniformTypeBuf[0]));

		{
			int validNdx = -1; // Keeps the corresponding index to validUniformIndices while unifNdx is the index to uniformIndices.
			for (int unifNdx = 0; unifNdx < (int)uniformIndices.size(); unifNdx++)
			{
				if (uniformIndices[unifNdx] == GL_INVALID_INDEX)
					continue;

				validNdx++;

				const BasicUniformReportRef&	reference			= basicUniformReportsRef[unifNdx];
				const int						reportedIndex		= validUniformIndices[validNdx];
				const int						reportedNameLength	= (int)uniformNameLengthBuf[validNdx];
				const int						reportedSize		= (int)uniformSizeBuf[validNdx];
				const glu::DataType				reportedType		= glu::getDataTypeFromGLType((deUint32)uniformTypeBuf[validNdx]);

				TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");

				log << TestLog::Message
					<< "// Got name length = " << reportedNameLength
					<< ", size = " << reportedSize
					<< ", type = " << glu::getDataTypeName(reportedType)
					<< " for the uniform at index " << reportedIndex << " (" << reference.name << ")"
					<< TestLog::EndMessage;

				DE_ASSERT(reference.type != glu::TYPE_LAST);
				DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
				DE_ASSERT(reference.minSize <= reference.maxSize);
				basicUniformReportsDst.push_back(BasicUniformReportGL(reference.name.c_str(), reportedNameLength, reportedSize, reportedType, reportedIndex));

				if (reportedNameLength != (int)reference.name.length() + 1)
				{
					log << TestLog::Message << "// FAILURE: wrong name length reported, should be " << reference.name.length() + 1 << TestLog::EndMessage;
					success = false;
				}

				if (reportedType != reference.type)
				{
					log << TestLog::Message << "// FAILURE: wrong type reported, should be " << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
					success = false;
				}

				if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
				{
					log << TestLog::Message
						<< "// FAILURE: wrong size reported, should be "
						<< (reference.minSize == reference.maxSize ? de::toString(reference.minSize) : "in the range [" + de::toString(reference.minSize) + ", " + de::toString(reference.maxSize) + "]")
						<< TestLog::EndMessage;

					success = false;
				}
			}
		}
	}

	return success;
}

bool UniformCase::uniformVsUniformsivComparison (const vector<BasicUniformReportGL>& uniformResults, const vector<BasicUniformReportGL>& uniformsivResults)
{
	TestLog&	log			= m_testCtx.getLog();
	bool		success		= true;

	for (int uniformResultNdx = 0; uniformResultNdx < (int)uniformResults.size(); uniformResultNdx++)
	{
		const BasicUniformReportGL&							uniformResult		= uniformResults[uniformResultNdx];
		const string&										uniformName			= uniformResult.name;
		const vector<BasicUniformReportGL>::const_iterator	uniformsivResultIt	= BasicUniformReportGL::findWithName(uniformsivResults, uniformName.c_str());

		if (uniformsivResultIt != uniformsivResults.end())
		{
			const BasicUniformReportGL& uniformsivResult = *uniformsivResultIt;

			log << TestLog::Message << "// Checking uniform " << uniformName << TestLog::EndMessage;

			if (uniformResult.index != uniformsivResult.index)
			{
				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetUniformIndices() gave different indices for uniform " << uniformName << TestLog::EndMessage;
				success = false;
			}
			if (uniformResult.nameLength + 1 != uniformsivResult.nameLength)
			{
				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave incompatible name lengths for uniform " << uniformName << TestLog::EndMessage;
				success = false;
			}
			if (uniformResult.size != uniformsivResult.size)
			{
				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave different sizes for uniform " << uniformName << TestLog::EndMessage;
				success = false;
			}
			if (uniformResult.type != uniformsivResult.type)
			{
				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave different types for uniform " << uniformName << TestLog::EndMessage;
				success = false;
			}
		}
		else
		{
			log << TestLog::Message << "// FAILURE: uniform " << uniformName << " was reported active by glGetActiveUniform() but not by glGetUniformIndices()" << TestLog::EndMessage;
			success = false;
		}
	}

	for (int uniformsivResultNdx = 0; uniformsivResultNdx < (int)uniformsivResults.size(); uniformsivResultNdx++)
	{
		const BasicUniformReportGL&							uniformsivResult	= uniformsivResults[uniformsivResultNdx];
		const string&										uniformsivName		= uniformsivResult.name;
		const vector<BasicUniformReportGL>::const_iterator	uniformsResultIt	= BasicUniformReportGL::findWithName(uniformsivResults, uniformsivName.c_str());

		if (uniformsResultIt == uniformsivResults.end())
		{
			log << TestLog::Message << "// FAILURE: uniform " << uniformsivName << " was reported active by glGetUniformIndices() but not by glGetActiveUniform()" << TestLog::EndMessage;
			success = false;
		}
	}

	return success;
}

bool UniformCase::getUniforms (vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, const deUint32 programGL)
{
	TestLog&	log			= m_testCtx.getLog();
	bool		success		= true;

	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
	{
		const BasicUniform&		uniform		= basicUniforms[unifNdx];
		const string			queryName	= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
		const int				location	= glGetUniformLocation(programGL, queryName.c_str());
		const int				size		= glu::getDataTypeScalarSize(uniform.type);
		VarValue				value;

		deMemset(&value, 0xcd, sizeof(value)); // Initialize to known garbage.

		if (location == -1)
		{
			value.type = glu::TYPE_INVALID;
			valuesDst.push_back(value);
			if (uniform.isUsedInShader)
			{
				log << TestLog::Message << "// FAILURE: " << uniform.name << " was used in shader, but has location -1" << TestLog::EndMessage;
				success = false;
			}
			continue;
		}

		value.type = uniform.type;

		DE_STATIC_ASSERT(sizeof(GLint) == sizeof(value.val.intV[0]));
		DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(value.val.uintV[0]));
		DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(value.val.floatV[0]));

		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
			GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
		else if (glu::isDataTypeIntOrIVec(uniform.type))
			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
		else if (glu::isDataTypeUintOrUVec(uniform.type))
			GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
		else if (glu::isDataTypeBoolOrBVec(uniform.type))
		{
			if (m_features & FEATURE_BOOLEANAPITYPE_INT)
			{
				GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
				for (int i = 0; i < size; i++)
					value.val.boolV[i] = value.val.intV[i] != 0;
			}
			else if (m_features & FEATURE_BOOLEANAPITYPE_UINT)
			{
				GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
				for (int i = 0; i < size; i++)
					value.val.boolV[i] = value.val.uintV[i] != 0;
			}
			else // Default: use float.
			{
				GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
				for (int i = 0; i < size; i++)
					value.val.boolV[i] = value.val.floatV[i] != 0.0f;
			}
		}
		else if (glu::isDataTypeSampler(uniform.type))
		{
			GLint unit = -1;
			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &unit));
			value.val.samplerV.unit = unit;
		}
		else
			DE_ASSERT(false);

		valuesDst.push_back(value);

		log << TestLog::Message << "// Got " << uniform.name << " value " << apiVarValueStr(value) << TestLog::EndMessage;
	}

	return success;
}

bool UniformCase::checkUniformDefaultValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
{
	TestLog&	log			= m_testCtx.getLog();
	bool		success		= true;

	DE_ASSERT(values.size() == basicUniforms.size());

	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
	{
		const BasicUniform&		uniform		= basicUniforms[unifNdx];
		const VarValue&			unifValue	= values[unifNdx];
		const int				valSize		= glu::getDataTypeScalarSize(uniform.type);

		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;

		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
			continue;

#define CHECK_UNIFORM(VAR_VALUE_MEMBER, ZERO)																								\
	do																																		\
	{																																		\
		for (int i = 0; i < valSize; i++)																									\
		{																																	\
			if (unifValue.val.VAR_VALUE_MEMBER[i] != (ZERO))																				\
			{																																\
				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;	\
				success = false;																											\
			}																																\
		}																																	\
	} while (false)

		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
			CHECK_UNIFORM(floatV, 0.0f);
		else if (glu::isDataTypeIntOrIVec(uniform.type))
			CHECK_UNIFORM(intV, 0);
		else if (glu::isDataTypeUintOrUVec(uniform.type))
			CHECK_UNIFORM(uintV, 0);
		else if (glu::isDataTypeBoolOrBVec(uniform.type))
			CHECK_UNIFORM(boolV, false);
		else if (glu::isDataTypeSampler(uniform.type))
		{
			if (unifValue.val.samplerV.unit != 0)
			{
				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;
				success = false;
			}
		}
		else
			DE_ASSERT(false);

#undef CHECK_UNIFORM
	}

	return success;
}

void UniformCase::assignUniforms (const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd)
{
	TestLog&				log				= m_testCtx.getLog();
	const bool				transpose		= (m_features & FEATURE_MATRIXMODE_ROWMAJOR) != 0;
	const GLboolean			transposeGL		= transpose ? GL_TRUE : GL_FALSE;
	const glu::DataType		boolApiType		= m_features & FEATURE_BOOLEANAPITYPE_INT	? glu::TYPE_INT
											: m_features & FEATURE_BOOLEANAPITYPE_UINT	? glu::TYPE_UINT
											:											  glu::TYPE_FLOAT;

	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
	{
		const BasicUniform&		uniform				= basicUniforms[unifNdx];
		const bool				isArrayMember		= uniform.elemNdx >= 0;
		const string			queryName			= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
		const int				numValuesToAssign	= !isArrayMember									? 1
													: m_features & FEATURE_ARRAYASSIGN_FULL				? (uniform.elemNdx == 0			? uniform.rootSize	: 0)
													: m_features & FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	? (uniform.elemNdx % 2 == 0		? 2					: 0)
													: /* Default: assign array elements separately */	  1;

		DE_ASSERT(numValuesToAssign >= 0);
		DE_ASSERT(numValuesToAssign == 1 || isArrayMember);

		if (numValuesToAssign == 0)
		{
			log << TestLog::Message << "// Uniform " << uniform.name << " is covered by another glUniform*v() call to the same array" << TestLog::EndMessage;
			continue;
		}

		const int			location			= glGetUniformLocation(programGL, queryName.c_str());
		const int			typeSize			= glu::getDataTypeScalarSize(uniform.type);
		const bool			assignByValue		= m_features & FEATURE_UNIFORMFUNC_VALUE && !glu::isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
		vector<VarValue>	valuesToAssign;

		for (int i = 0; i < numValuesToAssign; i++)
		{
			const string	curName = isArrayMember ? beforeLast(uniform.rootName, '[') + "[" + de::toString(uniform.elemNdx+i) + "]" : uniform.name;
			VarValue		unifValue;

			if (isArrayMember)
			{
				const vector<BasicUniform>::const_iterator elemUnif = BasicUniform::findWithName(basicUniforms, curName.c_str());
				if (elemUnif == basicUniforms.end())
					continue;
				unifValue = elemUnif->finalValue;
			}
			else
				unifValue = uniform.finalValue;

			const VarValue apiValue = glu::isDataTypeBoolOrBVec(unifValue.type)	? getRandomBoolRepresentation(unifValue, boolApiType, rnd)
									: glu::isDataTypeSampler(unifValue.type)	? getSamplerUnitValue(unifValue)
									: unifValue;

			valuesToAssign.push_back(glu::isDataTypeMatrix(apiValue.type) && transpose ? getTransposeMatrix(apiValue) : apiValue);

			if (glu::isDataTypeBoolOrBVec(uniform.type))
				log << TestLog::Message << "// Using type " << glu::getDataTypeName(boolApiType) << " to set boolean value " << apiVarValueStr(unifValue) << " for " << curName << TestLog::EndMessage;
			else if (glu::isDataTypeSampler(uniform.type))
				log << TestLog::Message << "// Texture for the sampler uniform " << curName << " will be filled with color " << apiVarValueStr(getSamplerFillValue(uniform.finalValue)) << TestLog::EndMessage;
		}

		DE_ASSERT(!valuesToAssign.empty());

		if (glu::isDataTypeFloatOrVec(valuesToAssign[0].type))
		{
			if (assignByValue)
			{
				const float* const ptr = &valuesToAssign[0].val.floatV[0];

				switch (typeSize)
				{
					case 1: GLU_CHECK_CALL(glUniform1f(location, ptr[0]));							break;
					case 2: GLU_CHECK_CALL(glUniform2f(location, ptr[0], ptr[1]));					break;
					case 3: GLU_CHECK_CALL(glUniform3f(location, ptr[0], ptr[1], ptr[2]));			break;
					case 4: GLU_CHECK_CALL(glUniform4f(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
					default:
						DE_ASSERT(false);
				}
			}
			else
			{
				vector<float> buffer(valuesToAssign.size() * typeSize);
				for (int i = 0; i < (int)buffer.size(); i++)
					buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];

				DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
				switch (typeSize)
				{
					case 1: GLU_CHECK_CALL(glUniform1fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 2: GLU_CHECK_CALL(glUniform2fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 3: GLU_CHECK_CALL(glUniform3fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 4: GLU_CHECK_CALL(glUniform4fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					default:
						DE_ASSERT(false);
				}
			}
		}
		else if (glu::isDataTypeMatrix(valuesToAssign[0].type))
		{
			DE_ASSERT(!assignByValue);

			vector<float> buffer(valuesToAssign.size() * typeSize);
			for (int i = 0; i < (int)buffer.size(); i++)
				buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];

			DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
			switch (uniform.type)
			{
				case glu::TYPE_FLOAT_MAT2:		GLU_CHECK_CALL(glUniformMatrix2fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT3:		GLU_CHECK_CALL(glUniformMatrix3fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT4:		GLU_CHECK_CALL(glUniformMatrix4fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT2X3:	GLU_CHECK_CALL(glUniformMatrix2x3fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT2X4:	GLU_CHECK_CALL(glUniformMatrix2x4fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT3X2:	GLU_CHECK_CALL(glUniformMatrix3x2fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT3X4:	GLU_CHECK_CALL(glUniformMatrix3x4fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT4X2:	GLU_CHECK_CALL(glUniformMatrix4x2fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT4X3:	GLU_CHECK_CALL(glUniformMatrix4x3fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				default:
					DE_ASSERT(false);
			}
		}
		else if (glu::isDataTypeIntOrIVec(valuesToAssign[0].type))
		{
			if (assignByValue)
			{
				const deInt32* const ptr = &valuesToAssign[0].val.intV[0];

				switch (typeSize)
				{
					case 1: GLU_CHECK_CALL(glUniform1i(location, ptr[0]));							break;
					case 2: GLU_CHECK_CALL(glUniform2i(location, ptr[0], ptr[1]));					break;
					case 3: GLU_CHECK_CALL(glUniform3i(location, ptr[0], ptr[1], ptr[2]));			break;
					case 4: GLU_CHECK_CALL(glUniform4i(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
					default:
						DE_ASSERT(false);
				}
			}
			else
			{
				vector<deInt32> buffer(valuesToAssign.size() * typeSize);
				for (int i = 0; i < (int)buffer.size(); i++)
					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];

				DE_STATIC_ASSERT(sizeof(GLint) == sizeof(buffer[0]));
				switch (typeSize)
				{
					case 1: GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 2: GLU_CHECK_CALL(glUniform2iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 3: GLU_CHECK_CALL(glUniform3iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 4: GLU_CHECK_CALL(glUniform4iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					default:
						DE_ASSERT(false);
				}
			}
		}
		else if (glu::isDataTypeUintOrUVec(valuesToAssign[0].type))
		{
			if (assignByValue)
			{
				const deUint32* const ptr = &valuesToAssign[0].val.uintV[0];

				switch (typeSize)
				{
					case 1: GLU_CHECK_CALL(glUniform1ui(location, ptr[0]));							break;
					case 2: GLU_CHECK_CALL(glUniform2ui(location, ptr[0], ptr[1]));					break;
					case 3: GLU_CHECK_CALL(glUniform3ui(location, ptr[0], ptr[1], ptr[2]));			break;
					case 4: GLU_CHECK_CALL(glUniform4ui(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
					default:
						DE_ASSERT(false);
				}
			}
			else
			{
				vector<deUint32> buffer(valuesToAssign.size() * typeSize);
				for (int i = 0; i < (int)buffer.size(); i++)
					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];

				DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(buffer[0]));
				switch (typeSize)
				{
					case 1: GLU_CHECK_CALL(glUniform1uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 2: GLU_CHECK_CALL(glUniform2uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 3: GLU_CHECK_CALL(glUniform3uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 4: GLU_CHECK_CALL(glUniform4uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					default:
						DE_ASSERT(false);
				}
			}
		}
		else if (glu::isDataTypeSampler(valuesToAssign[0].type))
		{
			if (assignByValue)
				GLU_CHECK_CALL(glUniform1i(location, uniform.finalValue.val.samplerV.unit));
			else
			{
				const GLint unit = uniform.finalValue.val.samplerV.unit;
				GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &unit));
			}
		}
		else
			DE_ASSERT(false);
	}
}

bool UniformCase::compareUniformValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
{
	TestLog&	log			= m_testCtx.getLog();
	bool		success		= true;

	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
	{
		const BasicUniform&		uniform		= basicUniforms[unifNdx];
		const VarValue&			unifValue	= values[unifNdx];

		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;

		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
			continue;

		if (!apiVarValueEquals(unifValue, uniform.finalValue))
		{
			log << TestLog::Message << "// FAILURE: value obtained with glGetUniform*() for uniform " << uniform.name << " differs from value set with glUniform*()" << TestLog::EndMessage;
			success = false;
		}
	}

	return success;
}

bool UniformCase::renderTest (const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd)
{
	TestLog&					log				= m_testCtx.getLog();
	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
	const int					viewportW		= de::min(renderTarget.getWidth(),	MAX_RENDER_WIDTH);
	const int					viewportH		= de::min(renderTarget.getHeight(),	MAX_RENDER_HEIGHT);
	const int					viewportX		= rnd.getInt(0, renderTarget.getWidth()		- viewportW);
	const int					viewportY		= rnd.getInt(0, renderTarget.getHeight()	- viewportH);
	tcu::Surface				renderedImg		(viewportW, viewportH);

	// Assert that no two samplers of different types have the same texture unit - this is an error in GL.
	for (int i = 0; i < (int)basicUniforms.size(); i++)
	{
		if (glu::isDataTypeSampler(basicUniforms[i].type))
		{
			for (int j = 0; j < i; j++)
			{
				if (glu::isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
					DE_ASSERT(basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit);
			}
		}
	}

	for (int i = 0; i < (int)basicUniforms.size(); i++)
	{
		if (glu::isDataTypeSampler(basicUniforms[i].type) && std::find(m_filledTextureUnits.begin(), m_filledTextureUnits.end(), basicUniforms[i].finalValue.val.samplerV.unit) == m_filledTextureUnits.end())
		{
			log << TestLog::Message << "// Filling texture at unit " << apiVarValueStr(basicUniforms[i].finalValue) << " with color " << shaderVarValueStr(basicUniforms[i].finalValue) << TestLog::EndMessage;
			setupTexture(basicUniforms[i].finalValue);
		}
	}

	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportW, viewportH));

	{
		static const float position[] =
		{
			-1.0f, -1.0f, 0.0f, 1.0f,
			-1.0f, +1.0f, 0.0f, 1.0f,
			+1.0f, -1.0f, 0.0f, 1.0f,
			+1.0f, +1.0f, 0.0f, 1.0f
		};
		static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };

		const int posLoc = glGetAttribLocation(program.getProgram(), "a_position");
		glEnableVertexAttribArray(posLoc);
		glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
		GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_SHORT, &indices[0]));
	}

	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());

	int numFailedPixels = 0;
	for (int y = 0; y < renderedImg.getHeight(); y++)
	{
		for (int x = 0; x < renderedImg.getWidth(); x++)
		{
			if (renderedImg.getPixel(x, y) != tcu::RGBA::white())
				numFailedPixels += 1;
		}
	}

	if (numFailedPixels > 0)
	{
		log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
		log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-white pixels" << TestLog::EndMessage;
		return false;
	}
	else
	{
		log << TestLog::Message << "Success: got all-white pixels (all uniforms have correct values)" << TestLog::EndMessage;
		return true;
	}
}

UniformCase::IterateResult UniformCase::iterate (void)
{
	Random							rnd				(deStringHash(getName()) ^ (deUint32)m_context.getTestContext().getCommandLine().getBaseSeed());
	TestLog&						log				= m_testCtx.getLog();
	vector<BasicUniform>			basicUniforms;
	vector<BasicUniformReportRef>	basicUniformReportsRef;

	{
		int samplerUnitCounter = 0;
		for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
			generateBasicUniforms(basicUniforms, basicUniformReportsRef, m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str(), true, samplerUnitCounter, rnd);
	}

	const string					vertexSource	= generateVertexSource(basicUniforms);
	const string					fragmentSource	= generateFragmentSource(basicUniforms);
	const ShaderProgram				program			(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource));

	log << program;

	if (!program.isOk())
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
		return STOP;
	}

	GLU_CHECK_CALL(glUseProgram(program.getProgram()));

	const bool success = test(basicUniforms, basicUniformReportsRef, program, rnd);
	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							success ? "Passed"				: "Failed");

	return STOP;
}

class UniformInfoQueryCase : public UniformCase
{
public:
	enum CaseType
	{
		CASETYPE_UNIFORM = 0,			//!< Check info returned by glGetActiveUniform().
		CASETYPE_INDICES_UNIFORMSIV,	//!< Check info returned by glGetUniformIndices() + glGetActiveUniformsiv().
		CASETYPE_CONSISTENCY,			//!< Query info with both above methods, and check consistency.

		CASETYPE_LAST
	};

						UniformInfoQueryCase	(Context& context, const char* name, const char* description, CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, CaseType caseType, deUint32 additionalFeatures = 0);
	bool				test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);

	static const char*	getCaseTypeName			(CaseType caseType);
	static const char*	getCaseTypeDescription	(CaseType caseType);

private:
	const CaseType		m_caseType;
};

const char* UniformInfoQueryCase::getCaseTypeName (const CaseType caseType)
{
	switch (caseType)
	{
		case CASETYPE_UNIFORM:				return "active_uniform";
		case CASETYPE_INDICES_UNIFORMSIV:	return "indices_active_uniformsiv";
		case CASETYPE_CONSISTENCY:			return "consistency";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

const char* UniformInfoQueryCase::getCaseTypeDescription (const CaseType caseType)
{
	switch (caseType)
	{
		case CASETYPE_UNIFORM:				return "Test glGetActiveUniform()";
		case CASETYPE_INDICES_UNIFORMSIV:	return "Test glGetUniformIndices() along with glGetActiveUniformsiv()";
		case CASETYPE_CONSISTENCY:			return "Check consistency between results from glGetActiveUniform() and glGetUniformIndices() + glGetActiveUniformsiv()";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

UniformInfoQueryCase::UniformInfoQueryCase (Context& context, const char* const name, const char* const description, const CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, const CaseType caseType, const deUint32 additionalFeatures)
	: UniformCase	(context, name, description, shaderType, uniformCollection, additionalFeatures)
	, m_caseType	(caseType)
{
}

bool UniformInfoQueryCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
{
	DE_UNREF(basicUniforms);
	DE_UNREF(rnd);

	const deUint32					programGL	= program.getProgram();
	TestLog&						log			= m_testCtx.getLog();
	vector<BasicUniformReportGL>	basicUniformReportsUniform;
	vector<BasicUniformReportGL>	basicUniformReportsUniformsiv;

	if (m_caseType == CASETYPE_UNIFORM || m_caseType == CASETYPE_CONSISTENCY)
	{
		bool success = false;

		{
			const ScopedLogSection section(log, "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
			success = getActiveUniforms(basicUniformReportsUniform, basicUniformReportsRef, programGL);
		}

		if (!success)
		{
			if (m_caseType == CASETYPE_UNIFORM)
				return false;
			else
			{
				DE_ASSERT(m_caseType == CASETYPE_CONSISTENCY);
				log << TestLog::Message << "// Note: this is a consistency case, so ignoring above failure(s)" << TestLog::EndMessage;
			}
		}
	}

	if (m_caseType == CASETYPE_INDICES_UNIFORMSIV || m_caseType == CASETYPE_CONSISTENCY)
	{
		bool success = false;

		{
			const ScopedLogSection section(log, "InfoGetActiveUniformsiv", "Uniform information queries with glGetUniformIndices() and glGetActiveUniformsiv()");
			success = getActiveUniformsiv(basicUniformReportsUniformsiv, basicUniformReportsRef, programGL);
		}

		if (!success)
		{
			if (m_caseType == CASETYPE_INDICES_UNIFORMSIV)
				return false;
			else
			{
				DE_ASSERT(m_caseType == CASETYPE_CONSISTENCY);
				log << TestLog::Message << "// Note: this is a consistency case, so ignoring above failure(s)" << TestLog::EndMessage;
			}
		}
	}

	if (m_caseType == CASETYPE_CONSISTENCY)
	{
		bool success = false;

		{
			const ScopedLogSection section(log, "CompareUniformVsUniformsiv", "Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()");
			success = uniformVsUniformsivComparison(basicUniformReportsUniform, basicUniformReportsUniformsiv);
		}

		if (!success)
			return false;
	}

	return true;
}

class UniformValueCase : public UniformCase
{
public:
	enum ValueToCheck
	{
		VALUETOCHECK_INITIAL = 0,		//!< Verify the initial values of the uniforms (i.e. check that they're zero).
		VALUETOCHECK_ASSIGNED,			//!< Assign values to uniforms with glUniform*(), and check those.

		VALUETOCHECK_LAST
	};
	enum CheckMethod
	{
		CHECKMETHOD_GET_UNIFORM = 0,	//!< Check values with glGetUniform*().
		CHECKMETHOD_RENDER,				//!< Check values by rendering with the value-checking shader.

		CHECKMETHOD_LAST
	};
	enum AssignMethod
	{
		ASSIGNMETHOD_POINTER = 0,
		ASSIGNMETHOD_VALUE,

		ASSIGNMETHOD_LAST
	};

						UniformValueCase			(Context&									context,
													 const char*								name,
													 const char*								description,
													 CaseShaderType								shaderType,
													 const SharedPtr<const UniformCollection>&	uniformCollection,
													 ValueToCheck								valueToCheck,
													 CheckMethod								checkMethod,
													 AssignMethod								assignMethod,
													 deUint32									additionalFeatures = 0);

	bool				test						(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);

	static const char*	getValueToCheckName			(ValueToCheck valueToCheck);
	static const char*	getValueToCheckDescription	(ValueToCheck valueToCheck);
	static const char*	getCheckMethodName			(CheckMethod checkMethod);
	static const char*	getCheckMethodDescription	(CheckMethod checkMethod);
	static const char*	getAssignMethodName			(AssignMethod checkMethod);
	static const char*	getAssignMethodDescription	(AssignMethod checkMethod);

private:
	const ValueToCheck	m_valueToCheck;
	const CheckMethod	m_checkMethod;
};

const char* UniformValueCase::getValueToCheckName (const ValueToCheck valueToCheck)
{
	switch (valueToCheck)
	{
		case VALUETOCHECK_INITIAL:	return "initial";
		case VALUETOCHECK_ASSIGNED:	return "assigned";
		default: DE_ASSERT(false);	return DE_NULL;
	}
}

const char* UniformValueCase::getValueToCheckDescription (const ValueToCheck valueToCheck)
{
	switch (valueToCheck)
{
		case VALUETOCHECK_INITIAL:	return "Check initial uniform values (zeros)";
		case VALUETOCHECK_ASSIGNED:	return "Check assigned uniform values";
		default: DE_ASSERT(false);	return DE_NULL;
	}
}

const char* UniformValueCase::getCheckMethodName (const CheckMethod checkMethod)
{
	switch (checkMethod)
	{
		case CHECKMETHOD_GET_UNIFORM:	return "get_uniform";
		case CHECKMETHOD_RENDER:		return "render";
		default: DE_ASSERT(false);		return DE_NULL;
	}
}

const char* UniformValueCase::getCheckMethodDescription (const CheckMethod checkMethod)
{
	switch (checkMethod)
	{
		case CHECKMETHOD_GET_UNIFORM:	return "Verify values with glGetUniform*()";
		case CHECKMETHOD_RENDER:		return "Verify values by rendering";
		default: DE_ASSERT(false);		return DE_NULL;
	}
}

const char* UniformValueCase::getAssignMethodName (const AssignMethod assignMethod)
{
	switch (assignMethod)
	{
		case ASSIGNMETHOD_POINTER:		return "by_pointer";
		case ASSIGNMETHOD_VALUE:		return "by_value";
		default: DE_ASSERT(false);		return DE_NULL;
	}
}

const char* UniformValueCase::getAssignMethodDescription (const AssignMethod assignMethod)
{
	switch (assignMethod)
	{
		case ASSIGNMETHOD_POINTER:		return "Assign values by-pointer";
		case ASSIGNMETHOD_VALUE:		return "Assign values by-value";
		default: DE_ASSERT(false);		return DE_NULL;
	}
}

UniformValueCase::UniformValueCase (Context&									context,
									const char* const							name,
									const char* const							description,
									const CaseShaderType						shaderType,
									const SharedPtr<const UniformCollection>&	uniformCollection,
									const ValueToCheck							valueToCheck,
									const CheckMethod							checkMethod,
									const AssignMethod							assignMethod,
									const deUint32								additionalFeatures)
	: UniformCase		(context, name, description, shaderType, uniformCollection,
						 (valueToCheck == VALUETOCHECK_INITIAL ? FEATURE_UNIFORMVALUE_ZERO : 0) | (assignMethod == ASSIGNMETHOD_VALUE ? FEATURE_UNIFORMFUNC_VALUE : 0) | additionalFeatures)
	, m_valueToCheck	(valueToCheck)
	, m_checkMethod		(checkMethod)
{
	DE_ASSERT(!(assignMethod == ASSIGNMETHOD_LAST && valueToCheck == VALUETOCHECK_ASSIGNED));
}

bool UniformValueCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
{
	DE_UNREF(basicUniformReportsRef);

	const deUint32	programGL	= program.getProgram();
	TestLog&		log			= m_testCtx.getLog();

	if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
	{
		const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
		assignUniforms(basicUniforms, programGL, rnd);
	}
	else
		DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);

	if (m_checkMethod == CHECKMETHOD_GET_UNIFORM)
	{
		vector<VarValue> values;

		{
			const ScopedLogSection section(log, "GetUniforms", "Uniform value query");
			const bool success = getUniforms(values, basicUniforms, program.getProgram());

			if (!success)
				return false;
		}

		if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
		{
			const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values");
			const bool success = compareUniformValues(values, basicUniforms);

			if (!success)
				return false;
		}
		else
		{
			DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);

			const ScopedLogSection section(log, "ValueCheck", "Verify that the uniforms have correct initial values (zeros)");
			const bool success = checkUniformDefaultValues(values, basicUniforms);

			if (!success)
				return false;
		}
	}
	else
	{
		DE_ASSERT(m_checkMethod == CHECKMETHOD_RENDER);

		const ScopedLogSection section(log, "RenderTest", "Render test");
		const bool success = renderTest(basicUniforms, program, rnd);

		if (!success)
			return false;
	}

	return true;
}

class RandomUniformCase : public UniformCase
{
public:
						RandomUniformCase		(Context& m_context, const char* name, const char* description, deUint32 seed);

	bool				test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
};

RandomUniformCase::RandomUniformCase (Context& context, const char* const name, const char* const description, const deUint32 seed)
	: UniformCase (context, name, description, seed ^ (deUint32)context.getTestContext().getCommandLine().getBaseSeed())
{
}

bool RandomUniformCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
{
	// \note Different sampler types may not be bound to same unit when rendering.
	const bool		renderingPossible						= (m_features & FEATURE_UNIFORMVALUE_ZERO) == 0 || !m_uniformCollection->containsSeveralSamplerTypes();

	bool			performGetActiveUniforms				= rnd.getBool();
	const bool		performGetActiveUniformsiv				= rnd.getBool();
	const bool		performUniformVsUniformsivComparison	= performGetActiveUniforms && performGetActiveUniformsiv && rnd.getBool();
	const bool		performGetUniforms						= rnd.getBool();
	const bool		performCheckUniformDefaultValues		= performGetUniforms && rnd.getBool();
	const bool		performAssignUniforms					= rnd.getBool();
	const bool		performCompareUniformValues				= performGetUniforms && performAssignUniforms && rnd.getBool();
	const bool		performRenderTest						= renderingPossible && performAssignUniforms && rnd.getBool();
	const deUint32	programGL								= program.getProgram();
	TestLog&		log										= m_testCtx.getLog();

	if (!(performGetActiveUniforms || performGetActiveUniformsiv || performUniformVsUniformsivComparison || performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms || performCompareUniformValues || performRenderTest))
		performGetActiveUniforms = true; // Do something at least.

#define PERFORM_AND_CHECK(CALL, SECTION_NAME, SECTION_DESCRIPTION)						\
	do																					\
	{																					\
		const ScopedLogSection section(log, (SECTION_NAME), (SECTION_DESCRIPTION));		\
		const bool success = (CALL);													\
		if (!success)																	\
			return false;																\
	} while (false)

	{
		vector<BasicUniformReportGL> reportsUniform;
		vector<BasicUniformReportGL> reportsUniformsiv;

		if (performGetActiveUniforms)
			PERFORM_AND_CHECK(getActiveUniforms(reportsUniform, basicUniformReportsRef, programGL), "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
		if (performGetActiveUniformsiv)
			PERFORM_AND_CHECK(getActiveUniformsiv(reportsUniformsiv, basicUniformReportsRef, programGL), "InfoGetActiveUniformsiv", "Uniform information queries with glGetIndices() and glGetActiveUniformsiv()");
		if (performUniformVsUniformsivComparison)
			PERFORM_AND_CHECK(uniformVsUniformsivComparison(reportsUniform, reportsUniformsiv), "CompareUniformVsUniformsiv", "Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()");
	}

	{
		vector<VarValue> uniformDefaultValues;

		if (performGetUniforms)
			PERFORM_AND_CHECK(getUniforms(uniformDefaultValues, basicUniforms, programGL), "GetUniformDefaults", "Uniform default value query");
		if (performCheckUniformDefaultValues)
			PERFORM_AND_CHECK(checkUniformDefaultValues(uniformDefaultValues, basicUniforms), "DefaultValueCheck", "Verify that the uniforms have correct initial values (zeros)");
	}

	{
		vector<VarValue> uniformValues;

		if (performAssignUniforms)
		{
			const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
			assignUniforms(basicUniforms, programGL, rnd);
		}
		if (performCompareUniformValues)
		{
			PERFORM_AND_CHECK(getUniforms(uniformValues, basicUniforms, programGL), "GetUniforms", "Uniform value query");
			PERFORM_AND_CHECK(compareUniformValues(uniformValues, basicUniforms), "ValueCheck", "Verify that the reported values match the assigned values");
		}
	}

	if (performRenderTest)
		PERFORM_AND_CHECK(renderTest(basicUniforms, program, rnd), "RenderTest", "Render test");

#undef PERFORM_AND_CHECK

	return true;
}

UniformApiTests::UniformApiTests (Context& context)
	: TestCaseGroup(context, "uniform_api", "Uniform API Tests")
{
}

UniformApiTests::~UniformApiTests (void)
{
}

namespace
{

// \note Although this is only used in UniformApiTest::init, it needs to be defined here as it's used as a template argument.
struct UniformCollectionCase
{
	string								namePrefix;
	SharedPtr<const UniformCollection>	uniformCollection;

	UniformCollectionCase (const char* const name, const UniformCollection* uniformCollection_)
		: namePrefix			(name ? name + string("_") : "")
		, uniformCollection		(uniformCollection_)
	{
	}
};

} // anonymous

void UniformApiTests::init (void)
{
	// Generate sets of UniformCollections that are used by several cases.

	enum
	{
		UNIFORMCOLLECTIONS_BASIC = 0,
		UNIFORMCOLLECTIONS_BASIC_ARRAY,
		UNIFORMCOLLECTIONS_BASIC_STRUCT,
		UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY,
		UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT,
		UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS,
		UNIFORMCOLLECTIONS_MULTIPLE_BASIC,
		UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY,
		UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS,

		UNIFORMCOLLECTIONS_LAST
	};

	struct UniformCollectionGroup
	{
		string							name;
		vector<UniformCollectionCase>	cases;
	} defaultUniformCollections[UNIFORMCOLLECTIONS_LAST];

	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].name							= "basic";
	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].name						= "basic_array";
	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].name						= "basic_struct";
	defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].name					= "struct_in_array";
	defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].name					= "array_in_struct";
	defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].name			= "nested_structs_arrays";
	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].name					= "multiple_basic";
	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].name				= "multiple_basic_array";
	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].name	= "multiple_nested_structs_arrays";

	for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_testDataTypes); dataTypeNdx++)
	{
		const glu::DataType		dataType	= s_testDataTypes[dataTypeNdx];
		const char* const		typeName	= glu::getDataTypeName(dataType);

		defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basic(dataType)));

		if (glu::isDataTypeScalar(dataType)													||
			(glu::isDataTypeVector(dataType) && glu::getDataTypeScalarSize(dataType) == 4)	||
			dataType == glu::TYPE_FLOAT_MAT4												||
			dataType == glu::TYPE_SAMPLER_2D)
			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basicArray(dataType)));

		if (glu::isDataTypeScalar(dataType)		||
			dataType == glu::TYPE_FLOAT_MAT4	||
			dataType == glu::TYPE_SAMPLER_2D)
		{
			const glu::DataType		secondDataType	= glu::isDataTypeScalar(dataType)	? glu::getDataTypeVector(dataType, 4)
													: dataType == glu::TYPE_FLOAT_MAT4	? glu::TYPE_FLOAT_MAT2
													: dataType == glu::TYPE_SAMPLER_2D	? glu::TYPE_SAMPLER_CUBE
													: glu::TYPE_LAST;
			DE_ASSERT(secondDataType != glu::TYPE_LAST);
			const char* const		secondTypeName	= glu::getDataTypeName(secondDataType);
			const string			name			= string("") + typeName + "_" + secondTypeName;

			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].cases.push_back			(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, false)));
			defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, true)));
			defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::structInArray(dataType, secondDataType, false)));
			defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(name.c_str(), UniformCollection::nestedArraysStructs(dataType, secondDataType)));
		}
	}
	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].cases.push_back					(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasic()));
	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].cases.push_back				(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasicArray()));
	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(DE_NULL, UniformCollection::multipleNestedArraysStructs()));

	// Info-query cases (check info returned by e.g. glGetActiveUniforms()).

	{
		TestCaseGroup* const infoQueryGroup = new TestCaseGroup(m_context, "info_query", "Test uniform info querying functions");
		addChild(infoQueryGroup);
		for (int caseTypeI = 0; caseTypeI < (int)UniformInfoQueryCase::CASETYPE_LAST; caseTypeI++)
		{
			const UniformInfoQueryCase::CaseType	caseType		= (UniformInfoQueryCase::CaseType)caseTypeI;
			TestCaseGroup* const					caseTypeGroup	= new TestCaseGroup(m_context, UniformInfoQueryCase::getCaseTypeName(caseType), UniformInfoQueryCase::getCaseTypeDescription(caseType));
			infoQueryGroup->addChild(caseTypeGroup);

			for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
			{
				const int numArrayFirstElemNameCases = caseType == UniformInfoQueryCase::CASETYPE_INDICES_UNIFORMSIV && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1;

				for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++)
				{
					const UniformCollectionGroup&	collectionGroup			= defaultUniformCollections[collectionGroupNdx];
					const string					collectionGroupName		= collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
					TestCaseGroup* const			collectionTestGroup		= new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
					caseTypeGroup->addChild(collectionTestGroup);

					for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
					{
						const UniformCollectionCase& collectionCase = collectionGroup.cases[collectionNdx];

						for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
						{
							const string								name				= collectionCase.namePrefix + getCaseShaderTypeName((CaseShaderType)shaderType);
							const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;

							collectionTestGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection, (UniformInfoQueryCase::CaseType)caseType,
																				   referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX));
						}
					}
				}
			}

			// Info-querying cases when unused uniforms are present.

			{
				TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
				caseTypeGroup->addChild(unusedUniformsGroup);

				const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];

				for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
				{
					const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
					const string								collName			= collectionCase.namePrefix;
					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;

					for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
					{
						const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
						unusedUniformsGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection, (UniformInfoQueryCase::CaseType)caseType,
																			   UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER | UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX));
					}
				}
			}
		}
	}

	// Cases testing uniform values.

	{
		TestCaseGroup* const valueGroup = new TestCaseGroup(m_context, "value", "Uniform value tests");
		addChild(valueGroup);

		// Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering.

		{
			TestCaseGroup* const initialValuesGroup = new TestCaseGroup(m_context,
																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_INITIAL),
																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_INITIAL));
			valueGroup->addChild(initialValuesGroup);

			for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
			{
				const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
				TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
				initialValuesGroup->addChild(checkMethodGroup);

				for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
				{
					const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[collectionGroupNdx];
					TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
					checkMethodGroup->addChild(collectionTestGroup);

					for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
					{
						const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
						const string								collName			= collectionCase.namePrefix;
						const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
						const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
						const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
																						  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
						const int									numBoolVariations	= varyBoolApiType ? 3 : 1;

						if (checkMethod == UniformValueCase::CHECKMETHOD_RENDER && uniformCollection->containsSeveralSamplerTypes())
							continue; // \note Samplers' initial API values (i.e. their texture units) are 0, and no two samplers of different types shall have same unit when rendering.

						for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
						{
							const deUint32		booleanTypeFeat	= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
																: booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT
																: 0;
							const char* const	booleanTypeName	= booleanTypeI == 1 ? "int"
																: booleanTypeI == 2 ? "uint"
																: "float";
							const string		nameWithApiType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;

							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
							{
								const string name = nameWithApiType + getCaseShaderTypeName((CaseShaderType)shaderType);
								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
																				   UniformValueCase::VALUETOCHECK_INITIAL, checkMethod, UniformValueCase::ASSIGNMETHOD_LAST, booleanTypeFeat));
							}
						}
					}
				}
			}
		}

		// Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering.

		{
			TestCaseGroup* const assignedValuesGroup = new TestCaseGroup(m_context,
																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_ASSIGNED),
																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_ASSIGNED));
			valueGroup->addChild(assignedValuesGroup);

			for (int assignMethodI = 0; assignMethodI < (int)UniformValueCase::ASSIGNMETHOD_LAST; assignMethodI++)
			{
				const UniformValueCase::AssignMethod	assignMethod		= (UniformValueCase::AssignMethod)assignMethodI;
				TestCaseGroup* const					assignMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getAssignMethodName(assignMethod), UniformValueCase::getAssignMethodDescription(assignMethod));
				assignedValuesGroup->addChild(assignMethodGroup);

				for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
				{
					const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
					TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
					assignMethodGroup->addChild(checkMethodGroup);

					for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
					{
						const int numArrayFirstElemNameCases = checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1;

						for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++)
						{
							const UniformCollectionGroup&	collectionGroup			= defaultUniformCollections[collectionGroupNdx];
							const string					collectionGroupName		= collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
							TestCaseGroup*					collectionTestGroup		= DE_NULL;

							for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
							{
								const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
								const string								collName			= collectionCase.namePrefix;
								const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
								const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
								const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
																								  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
								const int									numBoolVariations	= varyBoolApiType ? 3 : 1;
								const bool									containsMatrices	= uniformCollection->containsMatchingBasicType(glu::isDataTypeMatrix);
								const bool									varyMatrixMode		= containsMatrices &&
																								  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
								const int									numMatVariations	= varyMatrixMode ? 2 : 1;

								if (containsMatrices && assignMethod != UniformValueCase::ASSIGNMETHOD_POINTER)
									continue;

								for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
								{
									const deUint32		booleanTypeFeat		= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
																			: booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT
																			: 0;
									const char* const	booleanTypeName		= booleanTypeI == 1 ? "int"
																			: booleanTypeI == 2 ? "uint"
																			: "float";
									const string		nameWithBoolType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;

									for (int matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++)
									{
										const string nameWithMatrixType = nameWithBoolType + (matrixTypeI == 1 ? "row_major_" : "");

										for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
										{
											const string	name							= nameWithMatrixType + getCaseShaderTypeName((CaseShaderType)shaderType);
											const deUint32	arrayFirstElemNameNoIndexFeat	= referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX;

											// skip empty groups by creating groups on demand
											if (!collectionTestGroup)
											{
												collectionTestGroup = new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
												checkMethodGroup->addChild(collectionTestGroup);
											}

											collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
																							   UniformValueCase::VALUETOCHECK_ASSIGNED, checkMethod, assignMethod,
																							   booleanTypeFeat | arrayFirstElemNameNoIndexFeat | (matrixTypeI == 1 ? UniformCase::FEATURE_MATRIXMODE_ROWMAJOR : 0)));
										}
									}
								}
							}
						}
					}
				}
			}

			// Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1).

			{
				static const struct
				{
					UniformCase::Feature	arrayAssignMode;
					const char*				name;
					const char*				description;
				} arrayAssignGroups[] =
				{
					{ UniformCase::FEATURE_ARRAYASSIGN_FULL,			"basic_array_assign_full",		"Assign entire basic-type arrays per glUniform*v() call"			},
					{ UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO,	"basic_array_assign_partial",	"Assign two elements of a basic-type array per glUniform*v() call"	}
				};

				for (int arrayAssignGroupNdx = 0; arrayAssignGroupNdx < DE_LENGTH_OF_ARRAY(arrayAssignGroups); arrayAssignGroupNdx++)
				{
					UniformCase::Feature	arrayAssignMode		= arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
					const char* const		groupName			= arrayAssignGroups[arrayAssignGroupNdx].name;
					const char* const		groupDesc			= arrayAssignGroups[arrayAssignGroupNdx].description;

					TestCaseGroup* const curArrayAssignGroup = new TestCaseGroup(m_context, groupName, groupDesc);
					assignedValuesGroup->addChild(curArrayAssignGroup);

					static const int basicArrayCollectionGroups[] = { UNIFORMCOLLECTIONS_BASIC_ARRAY, UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT, UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY };

					for (int collectionGroupNdx = 0; collectionGroupNdx < DE_LENGTH_OF_ARRAY(basicArrayCollectionGroups); collectionGroupNdx++)
					{
						const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
						TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
						curArrayAssignGroup->addChild(collectionTestGroup);

						for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
						{
							const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
							const string								collName			= collectionCase.namePrefix;
							const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;

							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
							{
								const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
																				   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
																				   arrayAssignMode));
							}
						}
					}
				}
			}

			// Value checking cases when unused uniforms are present.

			{
				TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
				assignedValuesGroup->addChild(unusedUniformsGroup);

				const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];

				for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
				{
					const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
					const string								collName			= collectionCase.namePrefix;
					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;

					for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
					{
						const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
						unusedUniformsGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
																		   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
																		   UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX | UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER));
					}
				}
			}
		}
	}

	// Random cases.

	{
		const int		numRandomCases		= 100;
		TestCaseGroup*	const randomGroup	= new TestCaseGroup(m_context, "random", "Random cases");
		addChild(randomGroup);

		for (int ndx = 0; ndx < numRandomCases; ndx++)
			randomGroup->addChild(new RandomUniformCase(m_context, de::toString(ndx).c_str(), "", (deUint32)ndx));
	}
}

} // Functional
} // gles3
} // deqp
