/*-------------------------------------------------------------------------
 * 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* const			collectionTestGroup		= new TestCaseGroup(m_context, collectionGroupName.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 == 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;

									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
