/*-------------------------------------------------------------------------
 * 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, 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)
{
}

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

	// An unused 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				unusedProgram	(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 (!unusedProgram.isOk())
	{
		log << unusedProgram;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of unused program failed");
		return STOP;
	}

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