/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 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 glProgramUniform*() tests.
 *
 * \todo [2013-02-26 nuutti] Much duplication between ES2&3 uniform api
 *							 tests and this. Utilities to glshared?
 *//*--------------------------------------------------------------------*/

#include "es31fProgramUniformTests.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluShaderProgram.hpp"
#include "gluVarType.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "gluTexture.hpp"
#include "gluDrawUtil.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 gles31
{
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);

enum
{
	MAX_RENDER_WIDTH			= 32,
	MAX_RENDER_HEIGHT			= 32,
	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;
	}
}

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

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

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. glProgramUniform1f(), 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 glProgramUniform*(). If none given, assign each element of an array separately.
		FEATURE_ARRAYASSIGN_FULL				= 1<<3, //!< Assign all elements of an array with one glProgramUniform*().
		FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO		= 1<<4, //!< Assign two elements per one glProgramUniform*().

		// 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,

		// 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<<8
	};

								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection);
								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 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) {}
	};

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

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* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection)
	: TestCase				(context, name, description)
	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
	, m_features			(0)
	, m_uniformCollection	(uniformCollection)
	, m_caseShaderType		(caseShaderType)
{
}

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		= 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			= 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 310 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 310 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(1.0-result, result, 0.0, 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_STATIC_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::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;
}

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 glProgramUniform*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(glProgramUniform1f(programGL, location, ptr[0]));							break;
					case 2: GLU_CHECK_CALL(glProgramUniform2f(programGL, location, ptr[0], ptr[1]));					break;
					case 3: GLU_CHECK_CALL(glProgramUniform3f(programGL, location, ptr[0], ptr[1], ptr[2]));			break;
					case 4: GLU_CHECK_CALL(glProgramUniform4f(programGL, 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(glProgramUniform1fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 2: GLU_CHECK_CALL(glProgramUniform2fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 3: GLU_CHECK_CALL(glProgramUniform3fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 4: GLU_CHECK_CALL(glProgramUniform4fv(programGL, 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(glProgramUniformMatrix2fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT3:		GLU_CHECK_CALL(glProgramUniformMatrix3fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT4:		GLU_CHECK_CALL(glProgramUniformMatrix4fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT2X3:	GLU_CHECK_CALL(glProgramUniformMatrix2x3fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT2X4:	GLU_CHECK_CALL(glProgramUniformMatrix2x4fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT3X2:	GLU_CHECK_CALL(glProgramUniformMatrix3x2fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT3X4:	GLU_CHECK_CALL(glProgramUniformMatrix3x4fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT4X2:	GLU_CHECK_CALL(glProgramUniformMatrix4x2fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
				case glu::TYPE_FLOAT_MAT4X3:	GLU_CHECK_CALL(glProgramUniformMatrix4x3fv	(programGL, 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(glProgramUniform1i(programGL, location, ptr[0]));							break;
					case 2: GLU_CHECK_CALL(glProgramUniform2i(programGL, location, ptr[0], ptr[1]));					break;
					case 3: GLU_CHECK_CALL(glProgramUniform3i(programGL, location, ptr[0], ptr[1], ptr[2]));			break;
					case 4: GLU_CHECK_CALL(glProgramUniform4i(programGL, 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(glProgramUniform1iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 2: GLU_CHECK_CALL(glProgramUniform2iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 3: GLU_CHECK_CALL(glProgramUniform3iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 4: GLU_CHECK_CALL(glProgramUniform4iv(programGL, 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(glProgramUniform1ui(programGL, location, ptr[0]));							break;
					case 2: GLU_CHECK_CALL(glProgramUniform2ui(programGL, location, ptr[0], ptr[1]));					break;
					case 3: GLU_CHECK_CALL(glProgramUniform3ui(programGL, location, ptr[0], ptr[1], ptr[2]));			break;
					case 4: GLU_CHECK_CALL(glProgramUniform4ui(programGL, 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(glProgramUniform1uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 2: GLU_CHECK_CALL(glProgramUniform2uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 3: GLU_CHECK_CALL(glProgramUniform3uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					case 4: GLU_CHECK_CALL(glProgramUniform4uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
					default:
						DE_ASSERT(false);
				}
			}
		}
		else if (glu::isDataTypeSampler(valuesToAssign[0].type))
		{
			if (assignByValue)
				GLU_CHECK_CALL(glProgramUniform1i(programGL, location, uniform.finalValue.val.samplerV.unit));
			else
			{
				const GLint unit = uniform.finalValue.val.samplerV.unit;
				GLU_CHECK_CALL(glProgramUniform1iv(programGL, 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 glProgramUniform*()" << 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<int>(renderTarget.getWidth(),		MAX_RENDER_WIDTH);
	const int					viewportH		= de::min<int>(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));
	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
	GLU_CHECK_CALL(glUseProgram(program.getProgram()));

	{
		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 glu::VertexArrayBinding	binding		= glu::va::Float("a_position", 4, 4, 0, &position[0]);

		glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &binding, glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &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::green())
				numFailedPixels += 1;
		}
	}

	if (numFailedPixels > 0)
	{
		log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
		log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-green pixels" << TestLog::EndMessage;
		return false;
	}
	else
	{
		log << TestLog::Message << "Success: got all-green 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));

	// A dummy program that we'll give to glUseProgram before we actually need
	// the real program above, to see if an implementation tries to use the
	// currently active program for something inappropriate (instead of the
	// program given as argument to, say, glProgramUniform*).
	const ShaderProgram				dummyProgram	(m_context.getRenderContext(), glu::makeVtxFragSources("#version 310 es\n"
																										   "void main (void) { gl_Position = vec4(1.0); }\n",

																										   "#version 310 es\n"
																										   "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
																										   "void main (void) { dEQP_FragColor = vec4(0.0, 0.0, 1.0, 1.0); }\n"));

	log << program;

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

	if (!dummyProgram.isOk())
	{
		log << dummyProgram;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of dummy program failed");
		return STOP;
	}

	log << TestLog::Message << "// Note: calling glUseProgram with a dummy program (will only use the real program once it's needed for rendering)" << TestLog::EndMessage;
	glUseProgram(dummyProgram.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 UniformAssignCase : public UniformCase
{
public:
	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
	};

						UniformAssignCase			(Context&									context,
													 const char*								name,
													 const char*								description,
													 CaseShaderType								shaderType,
													 const SharedPtr<const UniformCollection>&	uniformCollection,
													 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*	getCheckMethodName			(CheckMethod checkMethod);
	static const char*	getCheckMethodDescription	(CheckMethod checkMethod);
	static const char*	getAssignMethodName			(AssignMethod checkMethod);
	static const char*	getAssignMethodDescription	(AssignMethod checkMethod);

private:
	const CheckMethod m_checkMethod;
};

const char* UniformAssignCase::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* UniformAssignCase::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* UniformAssignCase::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* UniformAssignCase::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;
	}
}

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

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

	{
		const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
		assignUniforms(basicUniforms, programGL, rnd);
	}

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

		{
			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_checkMethod == CHECKMETHOD_RENDER);

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

		if (!success)
			return false;
	}

	return true;
}

ProgramUniformTests::ProgramUniformTests (Context& context)
	: TestCaseGroup(context, "program_uniform", "glProgramUniform*() tests")
{
}

ProgramUniformTests::~ProgramUniformTests (void)
{
}

namespace
{

// \note Although this is only used in ProgramUniformTests::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 ProgramUniformTests::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()));

	// Basic by-pointer or by-value uniform assignment cases.

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

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

			for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
			{
				const int numArrayFirstElemNameCases = checkMethod == UniformAssignCase::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 == UniformAssignCase::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 != UniformAssignCase::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 UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
																						checkMethod, assignMethod,
																						booleanTypeFeat | arrayFirstElemNameNoIndexFeat | (matrixTypeI == 1 ? UniformCase::FEATURE_MATRIXMODE_ROWMAJOR : 0)));
								}
							}
						}
					}
				}
			}
		}
	}

	// Cases that assign multiple basic-array elements with one glProgramUniform*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 glProgramUniform*v() call"				},
			{ UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO,	"basic_array_assign_partial",	"Assign two elements of a basic-type array per glProgramUniform*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);
			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 UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
																			UniformAssignCase::CHECKMETHOD_GET_UNIFORM, UniformAssignCase::ASSIGNMETHOD_POINTER,
																			arrayAssignMode));
					}
				}
			}
		}
	}

	// Cases with unused uniforms.

	{
		TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
		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 UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
																	UniformAssignCase::CHECKMETHOD_GET_UNIFORM, UniformAssignCase::ASSIGNMETHOD_POINTER,
																	UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX | UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER));
			}
		}
	}
}

} // Functional
} // gles31
} // deqp
