13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 2.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Uniform API tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2013-02-26 nuutti] Much duplication between this and ES3.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *							 Utilities to glshared?
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2fUniformApiTests.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluCallLogWrapper.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarType.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstring>
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::ScopedLogSection;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ShaderProgram;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::StructType;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::SharedPtr;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef bool (* dataTypePredicate)(glu::DataType);
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_RENDER_WIDTH			= 32;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_RENDER_HEIGHT			= 32;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_NUM_SAMPLER_UNIFORMS	= 16;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const glu::DataType s_testDataTypes[] =
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT,
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_VEC2,
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_VEC3,
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_VEC4,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT2,
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT3,
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT4,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT,
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC2,
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC3,
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC4,
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL,
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC2,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC3,
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC4,
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_SAMPLER_2D,
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_SAMPLER_CUBE
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getGLInt (const glw::Functions& funcs, const deUint32 name)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int val = -1;
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	funcs.getIntegerv(name, &val);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return val;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Vec4 vec4FromPtr (const float* const ptr)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4 result;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = ptr[i];
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string beforeLast (const string& str, const char c)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str.substr(0, str.find_last_of(c));
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void fillWithColor (const tcu::PixelBufferAccess& access, const tcu::Vec4& color)
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int z = 0; z < access.getDepth(); z++)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < access.getHeight(); y++)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < access.getWidth(); x++)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		access.setPixel(color, x, y, z);
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getSamplerNumLookupDimensions (const glu::DataType type)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D:
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 2;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE:
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 3;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: // \note All others than 2d and cube are gles3-only types.
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<glu::DataType T>
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool dataTypeEquals (const glu::DataType t)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return t == T;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int N>
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool dataTypeIsMatrixWithNRows (const glu::DataType t)
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::isDataTypeMatrix(t) && glu::getDataTypeMatrixNumRows(t) == N;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool typeContainsMatchingBasicType (const glu::VarType& type, const dataTypePredicate predicate)
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return predicate(type.getBasicType());
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return typeContainsMatchingBasicType(type.getElementType(), predicate);
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate))
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getDistinctSamplerTypes (vector<glu::DataType>& dst, const glu::VarType& type)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType basicType = type.getBasicType();
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicType) && std::find(dst.begin(), dst.end(), basicType) == dst.end())
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.push_back(basicType);
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getDistinctSamplerTypes(dst, type.getElementType());
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getDistinctSamplerTypes(dst, structType.getMember(i).getType());
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumSamplersInType (const glu::VarType& type)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return glu::isDataTypeSampler(type.getBasicType()) ? 1 : 0;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return getNumSamplersInType(type.getElementType()) * type.getArraySize();
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int sum = 0;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sum += getNumSamplersInType(structType.getMember(i).getType());
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sum;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::VarType generateRandomType (const int maxDepth, int& curStructIdx, vector<const StructType*>& structTypesDst, Random& rnd)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isStruct		= maxDepth > 0 && rnd.getFloat() < 0.2f;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isArray		= rnd.getFloat() < 0.3f;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isStruct)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			numMembers = rnd.getInt(1, 5);
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const	structType = new StructType(("structType" + de::toString(curStructIdx++)).c_str());
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numMembers; i++)
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember(("m" + de::toString(i)).c_str(), generateRandomType(maxDepth-1, curStructIdx, structTypesDst, rnd));
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structTypesDst.push_back(structType);
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return isArray ? glu::VarType(glu::VarType(structType), rnd.getInt(1, 5)) : glu::VarType(structType);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		basicType = (glu::DataType)s_testDataTypes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testDataTypes)-1)];
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision = glu::isDataTypeBoolOrBVec(basicType) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return isArray ? glu::VarType(glu::VarType(basicType, precision), rnd.getInt(1, 5)) : glu::VarType(basicType, precision);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VarValue
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType type;
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	union
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float		floatV[4*4]; // At most mat4. \note Matrices here are column-major.
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt32		intV[4];
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool		boolV[4];
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		struct
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		unit;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float	fillColor[4];
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} samplerV;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} val;
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum CaseShaderType
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_VERTEX = 0,
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_FRAGMENT,
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_BOTH,
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_LAST
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Uniform
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			name;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::VarType	type;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Uniform (const char* const name_, const glu::VarType& type_) : name(name_), type(type_) {}
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// A set of uniforms, along with related struct types.
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformCollection
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getNumUniforms		(void) const					{ return (int)m_uniforms.size();	}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getNumStructTypes	(void) const					{ return (int)m_structTypes.size();	}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Uniform&			getUniform			(const int ndx)					{ return m_uniforms[ndx];			}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Uniform&		getUniform			(const int ndx) const			{ return m_uniforms[ndx];			}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const StructType*	getStructType		(const int ndx) const			{ return m_structTypes[ndx];		}
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				addUniform			(const Uniform& uniform)		{ m_uniforms.push_back(uniform);	}
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				addStructType		(const StructType* const type)	{ m_structTypes.push_back(type);	}
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollection	(void) {}
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	~UniformCollection	(void)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_structTypes.size(); i++)
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete m_structTypes[i];
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one.
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note receiver takes ownership of the struct types.
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void moveContents (UniformCollection& receiver)
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			receiver.addUniform(m_uniforms[i]);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_uniforms.clear();
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_structTypes.size(); i++)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			receiver.addStructType(m_structTypes[i]);
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_structTypes.clear();
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool containsMatchingBasicType (const dataTypePredicate predicate) const
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (typeContainsMatchingBasicType(m_uniforms[i].type, predicate))
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::DataType> getSamplerTypes (void) const
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<glu::DataType> samplerTypes;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getDistinctSamplerTypes(samplerTypes, m_uniforms[i].type);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return samplerTypes;
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool containsSeveralSamplerTypes (void) const
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return getSamplerTypes().size() > 1;
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getNumSamplers (void) const
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int sum = 0;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sum += getNumSamplersInType(m_uniforms[i].type);
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sum;
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basic (const glu::DataType type, const char* const nameSuffix = "")
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(type, prec)));
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basicArray (const glu::DataType type, const char* const nameSuffix = "")
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(glu::VarType(type, prec), 3)));
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basicStruct (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec0	= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec1	= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const structType = new StructType((string("structType") + nameSuffix).c_str());
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m0", glu::VarType(type0, prec0));
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m1", glu::VarType(type1, prec1));
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (containsArrays)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember("m2", glu::VarType(glu::VarType(type0, prec0), 3));
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember("m3", glu::VarType(glu::VarType(type1, prec1), 3));
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(structType);
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* structInArray (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const res = basicStruct(type0, type1, containsArrays, nameSuffix);
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->getUniform(0).type = glu::VarType(res->getUniform(0).type, 3);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* nestedArraysStructs (const glu::DataType type0, const glu::DataType type1, const char* const nameSuffix = "")
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const res		= new UniformCollection;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision prec0			= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision prec1			= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const structType		= new StructType((string("structType") + nameSuffix).c_str());
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const subStructType		= new StructType((string("subStructType") + nameSuffix).c_str());
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const subSubStructType	= new StructType((string("subSubStructType") + nameSuffix).c_str());
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subSubStructType->addMember("mss0", glu::VarType(type0, prec0));
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subSubStructType->addMember("mss1", glu::VarType(type1, prec1));
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms0", glu::VarType(type1, prec1));
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms1", glu::VarType(glu::VarType(type0, prec0), 2));
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms2", glu::VarType(glu::VarType(subSubStructType), 2));
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m0", glu::VarType(type0, prec0));
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m1", glu::VarType(subStructType));
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m2", glu::VarType(type1, prec1));
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(subSubStructType);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(subStructType);
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(structType);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleBasic (const char* const nameSuffix = "")
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types[]	= { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_FLOAT_MAT3, glu::TYPE_BOOL_VEC2 };
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = basic(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleBasicArray (const char* const nameSuffix = "")
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types[]	= { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_BOOL_VEC2 };
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = basicArray(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleNestedArraysStructs (const char* const nameSuffix = "")
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types0[]	= { glu::TYPE_FLOAT,		glu::TYPE_INT,		glu::TYPE_BOOL_VEC4 };
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types1[]	= { glu::TYPE_FLOAT_VEC4,	glu::TYPE_INT_VEC4,	glu::TYPE_BOOL };
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res			= new UniformCollection;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types0) == DE_LENGTH_OF_ARRAY(types1));
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types0); i++)
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = nestedArraysStructs(types0[i], types1[i], ("_" + de::toString(i) + nameSuffix).c_str());
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* random (const deUint32 seed)
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Random						rnd			(seed);
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					numUniforms	= rnd.getInt(1, 5);
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int							structIdx	= 0;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res			= new UniformCollection;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numUniforms; i++)
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<const StructType*>	structTypes;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Uniform						uniform(("u_var" + de::toString(i)).c_str(), glu::VarType());
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Discard uniforms that would cause number of samplers to exceed MAX_NUM_SAMPLER_UNIFORMS.
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			do
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int j = 0; j < (int)structTypes.size(); j++)
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					delete structTypes[j];
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				structTypes.clear();
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				uniform.type = (("u_var" + de::toString(i)).c_str(), generateRandomType(3, structIdx, structTypes, rnd));
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			} while (res->getNumSamplers() + getNumSamplersInType(uniform.type) > MAX_NUM_SAMPLER_UNIFORMS);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res->addUniform(uniform);
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int j = 0; j < (int)structTypes.size(); j++)
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				res->addStructType(structTypes[j]);
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Copying these would be cumbersome, since deep-copying both m_uniforms and m_structTypes
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// would mean that we'd need to update pointers from uniforms to point to the new structTypes.
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// When the same UniformCollection is needed in several places, a SharedPtr is used instead.
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCollection	(const UniformCollection&); // Not allowed.
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollection&			operator=			(const UniformCollection&); // Not allowed.
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Uniform>				m_uniforms;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<const StructType*>	m_structTypes;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; // anonymous
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getSamplerFillValue (const VarValue& sampler)
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeSampler(sampler.type));
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue result;
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = glu::TYPE_FLOAT_VEC4;
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.floatV[i] = sampler.val.samplerV.fillColor[i];
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getSamplerUnitValue (const VarValue& sampler)
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeSampler(sampler.type));
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue result;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = glu::TYPE_INT;
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.val.intV[0] = sampler.val.samplerV.unit;
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string shaderVarValueStr (const VarValue& value)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numElems = glu::getDataTypeScalarSize(value.type);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << glu::getDataTypeName(value.type) << "(";
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numElems; i++)
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i > 0)
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << ", ";
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::floatToString(value.val.floatV[i], 2);
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec((value.type)))
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.intV[i]);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec((value.type)))
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << (value.val.boolV[i] ? "true" : "false");
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler((value.type)))
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << shaderVarValueStr(getSamplerFillValue(value));
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << ")";
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string apiVarValueStr (const VarValue& value)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numElems = glu::getDataTypeScalarSize(value.type);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << "(";
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numElems; i++)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i > 0)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << ", ";
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::floatToString(value.val.floatV[i], 2);
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec((value.type)))
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.intV[i]);
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec((value.type)))
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << (value.val.boolV[i] ? "true" : "false");
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler((value.type)))
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << value.val.samplerV.unit;
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << ")";
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic 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. */)
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numElems = glu::getDataTypeScalarSize(type);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue	result;
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = type;
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((samplerUnit >= 0) == (glu::isDataTypeSampler(type)));
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(type))
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.intV[i] = rnd.getInt(-10, 10);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(type))
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.boolV[i] = rnd.getBool();
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(type))
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.samplerV.unit = samplerUnit;
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.samplerV.fillColor[i] = rnd.getFloat(0.0f, 1.0f);
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue generateZeroVarValue (const glu::DataType type)
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numElems = glu::getDataTypeScalarSize(type);
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue	result;
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = type;
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.floatV[i] = 0.0f;
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(type))
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.intV[i] = 0;
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(type))
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.boolV[i] = false;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(type))
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.samplerV.unit = 0;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.samplerV.fillColor[i] = 0.12f * (float)i;
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool apiVarValueEquals (const VarValue& a, const VarValue& b)
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		size			= glu::getDataTypeScalarSize(a.type);
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		floatThreshold	= 0.05f;
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(a.type == b.type);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(a.type) || glu::isDataTypeMatrix(a.type))
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (de::abs(a.val.floatV[i] - b.val.floatV[i]) >= floatThreshold)
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(a.type))
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.intV[i] != b.val.intV[i])
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(a.type))
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.boolV[i] != b.val.boolV[i])
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(a.type))
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (a.val.samplerV.unit != b.val.samplerV.unit)
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getRandomBoolRepresentation (const VarValue& boolValue, const glu::DataType targetScalarType, Random& rnd)
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeBoolOrBVec(boolValue.type));
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				size		= glu::getDataTypeScalarSize(boolValue.type);
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		targetType	= size == 1 ? targetScalarType : glu::getDataTypeVector(targetScalarType, size);
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue				result;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = targetType;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (targetScalarType)
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT:
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.intV[i] = rnd.getInt(-10, 10);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (result.val.intV[i] == 0)
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						result.val.intV[i] = 1;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.intV[i] = 0;
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT:
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (result.val.floatV[i] == 0.0f)
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						result.val.floatV[i] = 1.0f;
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.floatV[i] = 0;
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getCaseShaderTypeName (const CaseShaderType type)
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_VERTEX:		return "vertex";
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_FRAGMENT:	return "fragment";
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_BOTH:		return "both";
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic CaseShaderType randomCaseShaderType (const deUint32 seed)
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (CaseShaderType)Random(seed).getInt(0, CASESHADERTYPE_LAST-1);
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformCase : public TestCase, protected glu::CallLogWrapper
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Feature
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices.
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX	= 1<<0,
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// UNIFORMFUNC_VALUE: use pass-by-value versions of uniform assignment funcs, e.g. glUniform1f(), where possible. If not given, use pass-by-pointer versions.
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMFUNC_VALUE				= 1<<1,
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ARRAYASSIGN: how basic-type arrays are assigned with glUniform*(). If none given, assign each element of an array separately.
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYASSIGN_FULL				= 1<<2, //!< Assign all elements of an array with one glUniform*().
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO		= 1<<3, //!< Assign two elements per one glUniform*().
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// 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).
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMUSAGE_EVERY_OTHER		= 1<<4,
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float.
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_BOOLEANAPITYPE_INT				= 1<<5,
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// UNIFORMVALUE_ZERO: use zero-valued uniforms. If not given, use random uniform values.
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMVALUE_ZERO				= 1<<6,
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// 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.
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX	= 1<<7
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection);
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 features);
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, deUint32 seed); // \note Randomizes caseType, uniformCollection and features.
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~UniformCase	(void);
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				init			(void);
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				deinit			(void);
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate			(void);
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniform
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue		finalValue;	//!< The value we ultimately want to set for this uniform.
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		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.
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				elemNdx;	//!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				rootSize;	//!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniform (const char* const		name_,
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const glu::DataType	type_,
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const bool			isUsedInShader_,
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const VarValue&		finalValue_,
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char* const		rootName_	= DE_NULL,
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				elemNdx_	= -1,
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				rootSize_	= 1)
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  : name			(name_)
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , type			(type_)
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , isUsedInShader	(isUsedInShader_)
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , finalValue		(finalValue_)
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootName		(rootName_ == DE_NULL ? name_ : rootName_)
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , elemNdx			(elemNdx_)
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootSize		(rootSize_)
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 {
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 }
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static vector<BasicUniform>::const_iterator findWithName (const vector<BasicUniform>& vec, const char* const name)
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<BasicUniform>::const_iterator it = vec.begin(); it != vec.end(); it++)
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (it->name == name)
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return it;
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vec.end();
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reference values for info that is expected to be reported by glGetActiveUniform().
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniformReportRef
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \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.
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				minSize;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				maxSize;
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const int minS, const int maxS, const glu::DataType type_, const bool used)
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(minS), maxSize(maxS), type(type_), isUsedInShader(used) { DE_ASSERT(minSize <= maxSize); }
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const glu::DataType type_, const bool used)
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(1), maxSize(1), type(type_), isUsedInShader(used) {}
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Info that is actually reported by glGetActiveUniform().
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniformReportGL
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				nameLength;
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				size;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				index;
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportGL (const char* const name_, const int nameLength_, const int size_, const glu::DataType type_, const int index_)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), nameLength(nameLength_), size(size_), type(type_), index(index_) {}
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static vector<BasicUniformReportGL>::const_iterator findWithName (const vector<BasicUniformReportGL>& vec, const char* const name)
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<BasicUniformReportGL>::const_iterator it = vec.begin(); it != vec.end(); it++)
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (it->name == name)
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return it;
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vec.end();
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Query info with glGetActiveUniform() and check validity.
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getActiveUniforms						(vector<BasicUniformReportGL>& dst, const vector<BasicUniformReportRef>& ref, deUint32 programGL);
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get uniform values with glGetUniform*() and put to valuesDst. Uniforms that get -1 from glGetUniformLocation() get glu::TYPE_INVALID.
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getUniforms								(vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, deUint32 programGL);
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check that every uniform has the default (zero) value.
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						checkUniformDefaultValues				(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assign the basicUniforms[].finalValue values for uniforms. \note rnd parameter is for booleans (true can be any nonzero value).
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						assignUniforms							(const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd);
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare the uniform values given in values (obtained with glGetUniform*()) with the basicUniform.finalValue values.
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						compareUniformValues					(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render and check that all pixels are white (i.e. all uniform comparisons passed).
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						renderTest								(const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd);
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool				test									(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd) = 0;
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32								m_features;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const SharedPtr<const UniformCollection>	m_uniformCollection;
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static deUint32				randomFeatures							(deUint32 seed);
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generates the basic uniforms, based on the uniform with name varName and type varType, in the same manner as are expected
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// to be returned by glGetActiveUniform(), e.g. generates a name like var[0] for arrays, and recursively generates struct member names.
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						generateBasicUniforms					(vector<BasicUniform>&				basicUniformsDst,
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 vector<BasicUniformReportRef>&		basicUniformReportsDst,
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const glu::VarType&				varType,
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*						varName,
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 bool								isParentActive,
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 int&								samplerUnitCounter,
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 Random&							rnd) const;
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformDefinitions					(std::ostringstream& dst) const;
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformCompareExpr					(std::ostringstream& dst, const BasicUniform& uniform) const;
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformComparisons					(std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* variableName) const;
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateVertexSource					(const vector<BasicUniform>& basicUniforms) const;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateFragmentSource					(const vector<BasicUniform>& basicUniforms) const;
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupTexture							(const VarValue& value);
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseShaderType						m_caseShaderType;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::Texture2D*>						m_textures2d;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::TextureCube*>					m_texturesCube;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>							m_filledTextureUnits;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 UniformCase::randomFeatures (const deUint32 seed)
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 arrayUsageChoices[]		= { 0, FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX										};
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformFuncChoices[]		= { 0, FEATURE_UNIFORMFUNC_VALUE												};
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 arrayAssignChoices[]		= { 0, FEATURE_ARRAYASSIGN_FULL,			FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	};
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformUsageChoices[]		= { 0, FEATURE_UNIFORMUSAGE_EVERY_OTHER											};
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 booleanApiTypeChoices[]	= { 0, FEATURE_BOOLEANAPITYPE_INT												};
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformValueChoices[]		= { 0, FEATURE_UNIFORMVALUE_ZERO												};
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random rnd(seed);
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 result = 0;
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define ARRAY_CHOICE(ARR) (ARR[rnd.getInt(0, DE_LENGTH_OF_ARRAY(ARR)-1)])
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(arrayUsageChoices);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformFuncChoices);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(arrayAssignChoices);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformUsageChoices);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(booleanApiTypeChoices);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformValueChoices);
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef ARRAY_CHOICE
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 features)
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(features)
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(uniformCollection)
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(caseShaderType)
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection)
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(0)
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(uniformCollection)
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(caseShaderType)
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* name, const char* description, const deUint32 seed)
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(randomFeatures(seed))
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(UniformCollection::random(seed))
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(randomCaseShaderType(seed))
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::init (void)
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	funcs						= m_context.getRenderContext().getFunctions();
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numSamplerUniforms			= m_uniformCollection->getNumSamplers();
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsRequired		= m_caseShaderType != CASESHADERTYPE_FRAGMENT ? numSamplerUniforms : 0;
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsRequired	= m_caseShaderType != CASESHADERTYPE_VERTEX ? numSamplerUniforms : 0;
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsRequired	= vertexTexUnitsRequired + fragmentTexUnitsRequired;
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsSupported		= getGLInt(funcs, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsSupported	= getGLInt(funcs, GL_MAX_TEXTURE_IMAGE_UNITS);
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsSupported	= getGLInt(funcs, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numSamplerUniforms <= MAX_NUM_SAMPLER_UNIFORMS);
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexTexUnitsRequired > vertexTexUnitsSupported)
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(vertexTexUnitsRequired) + " vertex texture units required, " + de::toString(vertexTexUnitsSupported) + " supported");
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(fragmentTexUnitsRequired) + " fragment texture units required, " + de::toString(fragmentTexUnitsSupported) + " supported");
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (combinedTexUnitsRequired > combinedTexUnitsSupported)
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(combinedTexUnitsRequired) + " combined texture units required, " + de::toString(combinedTexUnitsSupported) + " supported");
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::deinit (void)
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_textures2d.size(); i++)
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures2d[i];
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures2d.clear();
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_texturesCube.size(); i++)
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_texturesCube[i];
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texturesCube.clear();
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_filledTextureUnits.clear();
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::~UniformCase (void)
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCase::deinit();
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::generateBasicUniforms (vector<BasicUniform>& basicUniformsDst, vector<BasicUniformReportRef>& basicUniformReportsDst, const glu::VarType& varType, const char* const varName, const bool isParentActive, int& samplerUnitCounter, Random& rnd) const
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType())
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isActive	= isParentActive && (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true);
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= varType.getBasicType();
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue			value		= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(type)
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: glu::isDataTypeSampler(type)				? generateRandomVarValue(type, rnd, samplerUnitCounter++)
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: generateRandomVarValue(varType.getBasicType(), rnd);
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformsDst.push_back(BasicUniform(varName, varType.getBasicType(), isActive, value));
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformReportsDst.push_back(BasicUniformReportRef(varName, varType.getBasicType(), isActive));
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isArrayType())
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		size			= varType.getArraySize();
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	arrayRootName	= string("") + varName + "[0]";
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<bool>	isElemActive;
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++)
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	indexedName		= string("") + varName + "[" + de::toString(elemNdx) + "]";
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		isCurElemActive	= isParentActive																						&&
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER			? basicUniformsDst.size() % 2 == 0	: true)	&&
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX		? elemNdx == size/2					: true);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isElemActive.push_back(isCurElemActive);
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (varType.getElementType().isBasicType())
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::DataType	elemBasicType	= varType.getElementType().getBasicType();
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const VarValue		value			= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(elemBasicType)
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: glu::isDataTypeSampler(elemBasicType)		? generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++)
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: generateRandomVarValue(elemBasicType, rnd);
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformsDst.push_back(BasicUniform(indexedName.c_str(), elemBasicType, isCurElemActive, value, arrayRootName.c_str(), elemNdx, size));
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName.c_str(), isCurElemActive, samplerUnitCounter, rnd);
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (varType.getElementType().isBasicType())
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int minSize;
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize-1]; minSize--);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicUniformReportsDst.push_back(BasicUniformReportRef(arrayRootName.c_str(), minSize, size, varType.getElementType().getBasicType(), isParentActive && minSize > 0));
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(varType.isStructType());
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *varType.getStructPtr();
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::StructMember&	member			= structType.getMember(i);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string				memberFullName	= string("") + varName + "." + member.getName();
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName.c_str(), isParentActive, samplerUnitCounter, rnd);
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformDefinitions (std::ostringstream& dst) const
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumStructTypes(); i++)
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << glu::declare(m_uniformCollection->getStructType(i)) << ";\n";
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "uniform " << glu::declare(m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str()) << ";\n";
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << "\n";
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const struct
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataTypePredicate	requiringTypes[2];
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*			definition;
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} compareFuncs[] =
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { glu::isDataTypeFloatOrVec,				glu::isDataTypeMatrix				}, "mediump float compare_float    (mediump float a, mediump float b)  { return abs(a - b) < 0.05 ? 1.0 : 0.0; }"																		},
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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); }"														},
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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); }"								},
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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); }"		},
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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]); }"													},
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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]); }"							},
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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]); }"	},
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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; }"																					},
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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; }"																					},
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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; }"																					},
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { 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; }"																					},
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_BOOL>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bool     (bool a, bool b)                    { return a == b ? 1.0 : 0.0; }"																					},
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_BOOL_VEC2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bvec2    (bvec2 a, bvec2 b)                  { return a == b ? 1.0 : 0.0; }"																					},
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_BOOL_VEC3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bvec3    (bvec3 a, bvec3 b)                  { return a == b ? 1.0 : 0.0; }"																					},
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_BOOL_VEC4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bvec4    (bvec4 a, bvec4 b)                  { return a == b ? 1.0 : 0.0; }"																					}
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool containsSamplers = !m_uniformCollection->getSamplerTypes().empty();
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compFuncNdx = 0; compFuncNdx < DE_LENGTH_OF_ARRAY(compareFuncs); compFuncNdx++)
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const dataTypePredicate		(&typeReq)[2]			= compareFuncs[compFuncNdx].requiringTypes;
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool					containsTypeSampler		= containsSamplers && (typeReq[0](glu::TYPE_FLOAT_VEC4) || typeReq[1](glu::TYPE_FLOAT_VEC4));
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (containsTypeSampler || m_uniformCollection->containsMatchingBasicType(typeReq[0]) || m_uniformCollection->containsMatchingBasicType(typeReq[1]))
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst << compareFuncs[compFuncNdx].definition << "\n";
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformCompareExpr (std::ostringstream& dst, const BasicUniform& uniform) const
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeSampler(uniform.type))
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_vec4("
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< (uniform.type == glu::TYPE_SAMPLER_2D ? "texture2D" : "textureCube")
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "(" << uniform.name << ", vec" << getSamplerNumLookupDimensions(uniform.type) << "(0.0))";
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_" << glu::getDataTypeName(uniform.type) << "(" << uniform.name;
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << ", " << shaderVarValueStr(uniform.finalValue) << ")";
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformComparisons (std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* const variableName) const
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform& unif = basicUniforms[i];
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unif.isUsedInShader)
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t" << variableName << " *= ";
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeUniformCompareExpr(dst, basicUniforms[i]);
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << ";\n";
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t// UNUSED: " << basicUniforms[i].name << "\n";
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateVertexSource (const vector<BasicUniform>& basicUniforms) const
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX || m_caseShaderType == CASESHADERTYPE_BOTH;
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "attribute highp vec4 a_position;\n"
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "varying mediump float v_vtxOut;\n"
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	gl_Position = a_position;\n"
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	v_vtxOut = 1.0;\n";
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "v_vtxOut");
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "}\n";
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateFragmentSource (const vector<BasicUniform>& basicUniforms) const
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isFragmentCase = m_caseShaderType == CASESHADERTYPE_FRAGMENT || m_caseShaderType == CASESHADERTYPE_BOTH;
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "varying mediump float v_vtxOut;\n"
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	mediump float result = v_vtxOut;\n";
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "result");
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "	gl_FragColor = vec4(result, result, result, 1.0);\n"
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "}\n";
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::setupTexture (const VarValue& value)
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(false);
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						width			= 32;
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						height			= 32;
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4					color			= vec4FromPtr(&value.val.samplerV.fillColor[0]);
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (value.type == glu::TYPE_SAMPLER_2D)
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Texture2D* texture		= new glu::Texture2D(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width, height);
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Texture2D& refTexture	= texture->getRefTexture();
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures2d.push_back(texture);
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		refTexture.allocLevel(0);
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fillWithColor(refTexture.getLevel(0), color);
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (value.type == glu::TYPE_SAMPLER_CUBE)
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(width == height);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::TextureCube* texture		= new glu::TextureCube(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width);
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureCube& refTexture	= texture->getRefTexture();
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texturesCube.push_back(texture);
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refTexture.allocLevel((tcu::CubeFace)face, 0);
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fillWithColor(refTexture.getLevelFace(0, (tcu::CubeFace)face), color);
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getActiveUniforms (vector<BasicUniformReportGL>& basicUniformReportsDst, const vector<BasicUniformReportRef>& basicUniformReportsRef, const deUint32 programGL)
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log						= m_testCtx.getLog();
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint				numActiveUniforms		= 0;
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint				uniformMaxNameLength	= 0;
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<char>		nameBuffer;
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				success					= true;
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORMS, &numActiveUniforms));
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "// Number of active uniforms reported: " << numActiveUniforms << TestLog::EndMessage;
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxNameLength));
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "// Maximum uniform name length reported: " << uniformMaxNameLength << TestLog::EndMessage;
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	nameBuffer.resize(uniformMaxNameLength);
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < numActiveUniforms; unifNdx++)
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLsizei					reportedNameLength	= 0;
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint					reportedSize		= -1;
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum					reportedTypeGL		= GL_NONE;
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGetActiveUniform(programGL, (GLuint)unifNdx, (GLsizei)uniformMaxNameLength, &reportedNameLength, &reportedSize, &reportedTypeGL, &nameBuffer[0]));
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		reportedType		= glu::getDataTypeFromGLType(reportedTypeGL);
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			reportedNameStr		(&nameBuffer[0]);
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Got name = " << reportedNameStr << ", name length = " << reportedNameLength << ", size = " << reportedSize << ", type = " << glu::getDataTypeName(reportedType) << TestLog::EndMessage;
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((GLsizei)reportedNameStr.length() != reportedNameLength)
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: wrong name length reported, should be " << reportedNameStr.length() << TestLog::EndMessage;
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!deStringBeginsWith(reportedNameStr.c_str(), "gl_")) // Ignore built-in uniforms.
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int referenceNdx;
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (referenceNdx = 0; referenceNdx < (int)basicUniformReportsRef.size(); referenceNdx++)
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (basicUniformReportsRef[referenceNdx].name == reportedNameStr)
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (referenceNdx >= (int)basicUniformReportsRef.size())
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: invalid non-built-in uniform name reported" << TestLog::EndMessage;
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const BasicUniformReportRef& reference = basicUniformReportsRef[referenceNdx];
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.type != glu::TYPE_LAST);
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize <= reference.maxSize);
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (BasicUniformReportGL::findWithName(basicUniformReportsDst, reportedNameStr.c_str()) != basicUniformReportsDst.end())
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: same uniform name reported twice" << TestLog::EndMessage;
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformReportsDst.push_back(BasicUniformReportGL(reportedNameStr.c_str(), reportedNameLength, reportedSize, reportedType, unifNdx));
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedType != reference.type)
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: wrong type reported, should be " << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "// FAILURE: wrong size reported, should be "
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< (reference.minSize == reference.maxSize ? de::toString(reference.minSize) : "in the range [" + de::toString(reference.minSize) + ", " + de::toString(reference.maxSize) + "]")
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniformReportRef& expected = basicUniformReportsRef[i];
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (expected.isUsedInShader && BasicUniformReportGL::findWithName(basicUniformReportsDst, expected.name.c_str()) == basicUniformReportsDst.end())
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: uniform with name " << expected.name << " was not reported by GL" << TestLog::EndMessage;
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getUniforms (vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, const deUint32 programGL)
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName	= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				location	= glGetUniformLocation(programGL, queryName.c_str());
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				size		= glu::getDataTypeScalarSize(uniform.type);
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue				value;
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemset(&value, 0xcd, sizeof(value)); // Initialize to known garbage.
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location == -1)
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.type = glu::TYPE_INVALID;
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesDst.push_back(value);
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniform.isUsedInShader)
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: " << uniform.name << " was used in shader, but has location -1" << TestLog::EndMessage;
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		value.type = uniform.type;
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLint) == sizeof(value.val.intV[0]));
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(value.val.floatV[0]));
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(uniform.type))
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec(uniform.type))
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_features & FEATURE_BOOLEANAPITYPE_INT)
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.intV[i] != 0;
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // Default: use float.
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.floatV[i] != 0.0f;
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(uniform.type))
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLint unit = -1;
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &unit));
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.val.samplerV.unit = unit;
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		valuesDst.push_back(value);
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Got " << uniform.name << " value " << apiVarValueStr(value) << TestLog::EndMessage;
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::checkUniformDefaultValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(values.size() == basicUniforms.size());
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue&			unifValue	= values[unifNdx];
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				valSize		= glu::getDataTypeScalarSize(uniform.type);
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define CHECK_UNIFORM(VAR_VALUE_MEMBER, ZERO)																								\
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	do																																		\
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																																		\
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < valSize; i++)																									\
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{																																	\
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (unifValue.val.VAR_VALUE_MEMBER[i] != ZERO)																					\
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{																																\
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;	\
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;																											\
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}																																\
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}																																	\
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} while (false)
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(floatV, 0.0f);
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(uniform.type))
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(intV, 0);
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec(uniform.type))
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(boolV, false);
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(uniform.type))
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (unifValue.val.samplerV.unit != 0)
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef CHECK_UNIFORM
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::assignUniforms (const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd)
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		boolApiType		= m_features & FEATURE_BOOLEANAPITYPE_INT	? glu::TYPE_INT
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											:											  glu::TYPE_FLOAT;
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform				= basicUniforms[unifNdx];
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isArrayMember		= uniform.elemNdx >= 0;
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName			= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numValuesToAssign	= !isArrayMember									? 1
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_FULL				? (uniform.elemNdx == 0			? uniform.rootSize	: 0)
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	? (uniform.elemNdx % 2 == 0		? 2					: 0)
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: /* Default: assign array elements separately */	  1;
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign >= 0);
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign == 1 || isArrayMember);
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numValuesToAssign == 0)
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Uniform " << uniform.name << " is covered by another glUniform*v() call to the same array" << TestLog::EndMessage;
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			location			= glGetUniformLocation(programGL, queryName.c_str());
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			typeSize			= glu::getDataTypeScalarSize(uniform.type);
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			assignByValue		= m_features & FEATURE_UNIFORMFUNC_VALUE && !glu::isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue>	valuesToAssign;
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numValuesToAssign; i++)
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	curName = isArrayMember ? beforeLast(uniform.rootName, '[') + "[" + de::toString(uniform.elemNdx+i) + "]" : uniform.name;
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VarValue		unifValue;
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isArrayMember)
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const vector<BasicUniform>::const_iterator elemUnif = BasicUniform::findWithName(basicUniforms, curName.c_str());
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (elemUnif == basicUniforms.end())
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = elemUnif->finalValue;
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = uniform.finalValue;
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const VarValue apiValue = glu::isDataTypeBoolOrBVec(unifValue.type)	? getRandomBoolRepresentation(unifValue, boolApiType, rnd)
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: glu::isDataTypeSampler(unifValue.type)	? getSamplerUnitValue(unifValue)
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: unifValue;
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesToAssign.push_back(apiValue);
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isDataTypeBoolOrBVec(uniform.type))
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Using type " << glu::getDataTypeName(boolApiType) << " to set boolean value " << apiVarValueStr(unifValue) << " for " << curName << TestLog::EndMessage;
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (glu::isDataTypeSampler(uniform.type))
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Texture for the sampler uniform " << curName << " will be filled with color " << apiVarValueStr(getSamplerFillValue(uniform.finalValue)) << TestLog::EndMessage;
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!valuesToAssign.empty());
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(valuesToAssign[0].type))
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float* const ptr = &valuesToAssign[0].val.floatV[0];
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1f(location, ptr[0]));							break;
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2f(location, ptr[0], ptr[1]));					break;
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3f(location, ptr[0], ptr[1], ptr[2]));			break;
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4f(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<float> buffer(valuesToAssign.size() * typeSize);
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeMatrix(valuesToAssign[0].type))
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!assignByValue);
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<float> buffer(valuesToAssign.size() * typeSize);
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)buffer.size(); i++)
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (uniform.type)
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2: GLU_CHECK_CALL(glUniformMatrix2fv(location, (GLsizei)valuesToAssign.size(), GL_FALSE, &buffer[0])); break;
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3: GLU_CHECK_CALL(glUniformMatrix3fv(location, (GLsizei)valuesToAssign.size(), GL_FALSE, &buffer[0])); break;
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4: GLU_CHECK_CALL(glUniformMatrix4fv(location, (GLsizei)valuesToAssign.size(), GL_FALSE, &buffer[0])); break;
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(valuesToAssign[0].type))
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deInt32* const ptr = &valuesToAssign[0].val.intV[0];
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1i(location, ptr[0]));							break;
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2i(location, ptr[0], ptr[1]));					break;
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3i(location, ptr[0], ptr[1], ptr[2]));			break;
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4i(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<deInt32> buffer(valuesToAssign.size() * typeSize);
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLint) == sizeof(buffer[0]));
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(valuesToAssign[0].type))
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glUniform1i(location, uniform.finalValue.val.samplerV.unit));
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLint unit = uniform.finalValue.val.samplerV.unit;
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &unit));
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::compareUniformValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue&			unifValue	= values[unifNdx];
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!apiVarValueEquals(unifValue, uniform.finalValue))
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: value obtained with glGetUniform*() for uniform " << uniform.name << " differs from value set with glUniform*()" << TestLog::EndMessage;
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::renderTest (const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd)
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log				= m_testCtx.getLog();
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportW		= de::min(renderTarget.getWidth(),	MAX_RENDER_WIDTH);
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportH		= de::min(renderTarget.getHeight(),	MAX_RENDER_HEIGHT);
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportX		= rnd.getInt(0, renderTarget.getWidth()		- viewportW);
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportY		= rnd.getInt(0, renderTarget.getHeight()	- viewportH);
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedImg		(viewportW, viewportH);
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assert that no two samplers of different types have the same texture unit - this is an error in GL.
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type))
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int j = 0; j < i; j++)
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (glu::isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit);
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type) && std::find(m_filledTextureUnits.begin(), m_filledTextureUnits.end(), basicUniforms[i].finalValue.val.samplerV.unit) == m_filledTextureUnits.end())
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Filling texture at unit " << apiVarValueStr(basicUniforms[i].finalValue) << " with color " << shaderVarValueStr(basicUniforms[i].finalValue) << TestLog::EndMessage;
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setupTexture(basicUniforms[i].finalValue);
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportW, viewportH));
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const float position[] =
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, -1.0f, 0.0f, 1.0f,
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, +1.0f, 0.0f, 1.0f,
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, -1.0f, 0.0f, 1.0f,
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, +1.0f, 0.0f, 1.0f
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int posLoc = glGetAttribLocation(program.getProgram(), "a_position");
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glEnableVertexAttribArray(posLoc);
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_SHORT, &indices[0]));
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numFailedPixels = 0;
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < renderedImg.getWidth(); x++)
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (renderedImg.getPixel(x, y) != tcu::RGBA::white)
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += 1;
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels > 0)
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-white pixels" << TestLog::EndMessage;
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: got all-white pixels (all uniforms have correct values)" << TestLog::EndMessage;
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::IterateResult UniformCase::iterate (void)
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random							rnd				(deStringHash(getName()) ^ (deUint32)m_context.getTestContext().getCommandLine().getBaseSeed());
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log				= m_testCtx.getLog();
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniform>			basicUniforms;
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportRef>	basicUniformReportsRef;
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int samplerUnitCounter = 0;
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniforms, basicUniformReportsRef, m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str(), true, samplerUnitCounter, rnd);
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					vertexSource	= generateVertexSource(basicUniforms);
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					fragmentSource	= generateFragmentSource(basicUniforms);
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderProgram				program			(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource));
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << program;
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program.isOk())
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glUseProgram(program.getProgram()));
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool success = test(basicUniforms, basicUniformReportsRef, program, rnd);
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							success ? "Passed"				: "Failed");
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformInfoQueryCase : public UniformCase
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				UniformInfoQueryCase	(Context& context, const char* name, const char* description, CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 additionalFeatures = 0);
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformInfoQueryCase::UniformInfoQueryCase (Context& context, const char* const name, const char* const description, const CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 additionalFeatures)
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase	(context, name, description, shaderType, uniformCollection, additionalFeatures)
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformInfoQueryCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(basicUniforms);
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(rnd);
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					programGL	= program.getProgram();
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log			= m_testCtx.getLog();
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportGL>	basicUniformReportsUniform;
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ScopedLogSection section(log, "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool success = getActiveUniforms(basicUniformReportsUniform, basicUniformReportsRef, programGL);
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!success)
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformValueCase : public UniformCase
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ValueToCheck
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_INITIAL = 0,		//!< Verify the initial values of the uniforms (i.e. check that they're zero).
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_ASSIGNED,			//!< Assign values to uniforms with glUniform*(), and check those.
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_LAST
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CheckMethod
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_GET_UNIFORM = 0,	//!< Check values with glGetUniform*().
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_RENDER,				//!< Check values by rendering with the value-checking shader.
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_LAST
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum AssignMethod
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_POINTER = 0,
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_VALUE,
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_LAST
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						UniformValueCase			(Context&									context,
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								name,
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								description,
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CaseShaderType								shaderType,
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const SharedPtr<const UniformCollection>&	uniformCollection,
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ValueToCheck								valueToCheck,
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CheckMethod								checkMethod,
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 AssignMethod								assignMethod,
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 deUint32									additionalFeatures = 0);
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test						(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getValueToCheckName			(ValueToCheck valueToCheck);
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getValueToCheckDescription	(ValueToCheck valueToCheck);
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodName			(CheckMethod checkMethod);
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodDescription	(CheckMethod checkMethod);
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodName			(AssignMethod checkMethod);
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodDescription	(AssignMethod checkMethod);
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ValueToCheck	m_valueToCheck;
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CheckMethod	m_checkMethod;
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getValueToCheckName (const ValueToCheck valueToCheck)
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (valueToCheck)
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_INITIAL:	return "initial";
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_ASSIGNED:	return "assigned";
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);	return DE_NULL;
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getValueToCheckDescription (const ValueToCheck valueToCheck)
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (valueToCheck)
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_INITIAL:	return "Check initial uniform values (zeros)";
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_ASSIGNED:	return "Check assigned uniform values";
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);	return DE_NULL;
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getCheckMethodName (const CheckMethod checkMethod)
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "get_uniform";
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "render";
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getCheckMethodDescription (const CheckMethod checkMethod)
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "Verify values with glGetUniform*()";
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "Verify values by rendering";
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getAssignMethodName (const AssignMethod assignMethod)
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "by_pointer";
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "by_value";
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getAssignMethodDescription (const AssignMethod assignMethod)
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "Assign values by-pointer";
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "Assign values by-value";
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformValueCase::UniformValueCase (Context&									context,
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const							name,
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const							description,
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const CaseShaderType						shaderType,
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const SharedPtr<const UniformCollection>&	uniformCollection,
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const ValueToCheck							valueToCheck,
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const CheckMethod							checkMethod,
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const AssignMethod							assignMethod,
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const deUint32								additionalFeatures)
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase		(context, name, description, shaderType, uniformCollection,
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 (valueToCheck == VALUETOCHECK_INITIAL ? FEATURE_UNIFORMVALUE_ZERO : 0) | (assignMethod == ASSIGNMETHOD_VALUE ? FEATURE_UNIFORMFUNC_VALUE : 0) | additionalFeatures)
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_valueToCheck	(valueToCheck)
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_checkMethod		(checkMethod)
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!(assignMethod == ASSIGNMETHOD_LAST && valueToCheck == VALUETOCHECK_ASSIGNED));
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformValueCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(basicUniformReportsRef);
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	programGL	= program.getProgram();
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log			= m_testCtx.getLog();
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		assignUniforms(basicUniforms, programGL, rnd);
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_checkMethod == CHECKMETHOD_GET_UNIFORM)
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> values;
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "GetUniforms", "Uniform value query");
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = getUniforms(values, basicUniforms, program.getProgram());
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values");
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = compareUniformValues(values, basicUniforms);
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "ValueCheck", "Verify that the uniforms have correct initial values (zeros)");
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = checkUniformDefaultValues(values, basicUniforms);
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_checkMethod == CHECKMETHOD_RENDER);
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "RenderTest", "Render test");
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = renderTest(basicUniforms, program, rnd);
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RandomUniformCase : public UniformCase
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						RandomUniformCase		(Context& m_context, const char* name, const char* description, deUint32 seed);
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomUniformCase::RandomUniformCase (Context& context, const char* const name, const char* const description, const deUint32 seed)
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase (context, name, description, seed ^ (deUint32)context.getTestContext().getCommandLine().getBaseSeed())
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool RandomUniformCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Different sampler types may not be bound to same unit when rendering.
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		renderingPossible						= (m_features & FEATURE_UNIFORMVALUE_ZERO) == 0 || !m_uniformCollection->containsSeveralSamplerTypes();
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			performGetActiveUniforms			= rnd.getBool();
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performGetUniforms					= rnd.getBool();
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performCheckUniformDefaultValues	= performGetUniforms && rnd.getBool();
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performAssignUniforms				= rnd.getBool();
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performCompareUniformValues			= performGetUniforms && performAssignUniforms && rnd.getBool();
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performRenderTest					= renderingPossible && performAssignUniforms && rnd.getBool();
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	programGL							= program.getProgram();
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log									= m_testCtx.getLog();
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!(performGetActiveUniforms || performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms || performCompareUniformValues || performRenderTest))
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		performGetActiveUniforms = true; // Do something at least.
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PERFORM_AND_CHECK(CALL, SECTION_NAME, SECTION_DESCRIPTION)						\
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	do																					\
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																					\
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, (SECTION_NAME), (SECTION_DESCRIPTION));		\
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = (CALL);													\
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)																	\
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;																\
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} while (false)
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (performGetActiveUniforms)
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<BasicUniformReportGL> reportsUniform;
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PERFORM_AND_CHECK(getActiveUniforms(reportsUniform, basicUniformReportsRef, programGL), "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> uniformDefaultValues;
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performGetUniforms)
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getUniforms(uniformDefaultValues, basicUniforms, programGL), "GetUniformDefaults", "Uniform default value query");
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performCheckUniformDefaultValues)
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(checkUniformDefaultValues(uniformDefaultValues, basicUniforms), "DefaultValueCheck", "Verify that the uniforms have correct initial values (zeros)");
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> uniformValues;
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performAssignUniforms)
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			assignUniforms(basicUniforms, programGL, rnd);
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performCompareUniformValues)
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getUniforms(uniformValues, basicUniforms, programGL), "GetUniforms", "Uniform value query");
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(compareUniformValues(uniformValues, basicUniforms), "ValueCheck", "Verify that the reported values match the assigned values");
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (performRenderTest)
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PERFORM_AND_CHECK(renderTest(basicUniforms, program, rnd), "RenderTest", "Render test");
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PERFORM_AND_CHECK
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformApiTests::UniformApiTests (Context& context)
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "uniform_api", "Uniform API Tests")
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformApiTests::~UniformApiTests (void)
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note Although this is only used in UniformApiTest::init, it needs to be defined here as it's used as a template argument.
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct UniformCollectionCase
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string								namePrefix;
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SharedPtr<const UniformCollection>	uniformCollection;
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollectionCase (const char* const name, const UniformCollection* uniformCollection_)
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: namePrefix			(name ? name + string("_") : "")
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, uniformCollection		(uniformCollection_)
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformApiTests::init (void)
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate sets of UniformCollections that are used by several cases.
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC = 0,
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_ARRAY,
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_STRUCT,
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY,
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT,
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS,
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC,
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY,
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS,
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_LAST
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct UniformCollectionGroup
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string							name;
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<UniformCollectionCase>	cases;
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} defaultUniformCollections[UNIFORMCOLLECTIONS_LAST];
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].name							= "basic";
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].name						= "basic_array";
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].name						= "basic_struct";
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].name					= "struct_in_array";
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].name					= "array_in_struct";
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].name			= "nested_structs_arrays";
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].name					= "multiple_basic";
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].name				= "multiple_basic_array";
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].name	= "multiple_nested_structs_arrays";
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_testDataTypes); dataTypeNdx++)
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		dataType	= s_testDataTypes[dataTypeNdx];
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const		typeName	= glu::getDataTypeName(dataType);
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basic(dataType)));
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)													||
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(glu::isDataTypeVector(dataType) && glu::getDataTypeScalarSize(dataType) == 4)	||
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4												||
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basicArray(dataType)));
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)		||
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4	||
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::DataType		secondDataType	= glu::isDataTypeScalar(dataType)	? glu::getDataTypeVector(dataType, 4)
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_FLOAT_MAT4	? glu::TYPE_FLOAT_MAT2
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_SAMPLER_2D	? glu::TYPE_SAMPLER_CUBE
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: glu::TYPE_LAST;
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(secondDataType != glu::TYPE_LAST);
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		secondTypeName	= glu::getDataTypeName(secondDataType);
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string			name			= string("") + typeName + "_" + secondTypeName;
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].cases.push_back			(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, false)));
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, true)));
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::structInArray(dataType, secondDataType, false)));
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(name.c_str(), UniformCollection::nestedArraysStructs(dataType, secondDataType)));
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].cases.push_back					(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasic()));
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].cases.push_back				(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasicArray()));
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(DE_NULL, UniformCollection::multipleNestedArraysStructs()));
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Info-query cases (check info returned by e.g. glGetActiveUniforms()).
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const infoQueryGroup = new TestCaseGroup(m_context, "info_query", "Test glGetActiveUniform()");
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(infoQueryGroup);
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[collectionGroupNdx];
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			infoQueryGroup->addChild(collectionTestGroup);
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionCase& collectionCase = collectionGroup.cases[collectionNdx];
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string								name				= collectionCase.namePrefix + getCaseShaderTypeName((CaseShaderType)shaderType);
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					collectionTestGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection));
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Info-querying cases when unused uniforms are present.
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			infoQueryGroup->addChild(unusedUniformsGroup);
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string								collName			= collectionCase.namePrefix;
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					unusedUniformsGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER | UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX));
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cases testing uniform values.
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const valueGroup = new TestCaseGroup(m_context, "value", "Uniform value tests");
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(valueGroup);
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering.
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const initialValuesGroup = new TestCaseGroup(m_context,
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_INITIAL),
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_INITIAL));
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueGroup->addChild(initialValuesGroup);
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				initialValuesGroup->addChild(checkMethodGroup);
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[collectionGroupNdx];
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					checkMethodGroup->addChild(collectionTestGroup);
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string								collName			= collectionCase.namePrefix;
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																						  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int									numBoolVariations	= varyBoolApiType ? 2 : 1;
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (checkMethod == UniformValueCase::CHECKMETHOD_RENDER && uniformCollection->containsSeveralSamplerTypes())
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							continue; // \note Samplers' initial API values (i.e. their texture units) are 0, and no two samplers of different types shall have same unit when rendering.
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const deUint32		booleanTypeFeat	= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: 0;
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char* const	booleanTypeName	= booleanTypeI == 1 ? "int"
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: "float";
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string		nameWithApiType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string name = nameWithApiType + getCaseShaderTypeName((CaseShaderType)shaderType);
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   UniformValueCase::VALUETOCHECK_INITIAL, checkMethod, UniformValueCase::ASSIGNMETHOD_LAST, booleanTypeFeat));
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering.
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const assignedValuesGroup = new TestCaseGroup(m_context,
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_ASSIGNED),
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_ASSIGNED));
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueGroup->addChild(assignedValuesGroup);
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int assignMethodI = 0; assignMethodI < (int)UniformValueCase::ASSIGNMETHOD_LAST; assignMethodI++)
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformValueCase::AssignMethod	assignMethod		= (UniformValueCase::AssignMethod)assignMethodI;
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const					assignMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getAssignMethodName(assignMethod), UniformValueCase::getAssignMethodDescription(assignMethod));
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				assignedValuesGroup->addChild(assignMethodGroup);
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					assignMethodGroup->addChild(checkMethodGroup);
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int numArrayFirstElemNameCases = checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1;
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++)
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const UniformCollectionGroup&	collectionGroup			= defaultUniformCollections[collectionGroupNdx];
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string					collectionGroupName		= collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
2300ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry							TestCaseGroup*					collectionTestGroup		= DE_NULL;
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string								collName			= collectionCase.namePrefix;
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																								  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int									numBoolVariations	= varyBoolApiType ? 2 : 1;
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									containsMatrices	= uniformCollection->containsMatchingBasicType(glu::isDataTypeMatrix);
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								if (containsMatrices && assignMethod != UniformValueCase::ASSIGNMETHOD_POINTER)
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									continue;
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								{
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const deUint32		booleanTypeFeat		= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: 0;
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const	booleanTypeName		= booleanTypeI == 1 ? "int"
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: "float";
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const string		nameWithBoolType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const string		nameWithMatrixType	= nameWithBoolType;
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									{
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										const string	name							= nameWithMatrixType + getCaseShaderTypeName((CaseShaderType)shaderType);
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										const deUint32	arrayFirstElemNameNoIndexFeat	= referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX;
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2330ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										// skip empty groups by creating groups on demand
2331ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										if (!collectionTestGroup)
2332ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										{
2333ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry											collectionTestGroup = new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
2334ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry											checkMethodGroup->addChild(collectionTestGroup);
2335ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										}
2336ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							UniformValueCase::VALUETOCHECK_ASSIGNED, checkMethod, assignMethod,
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							booleanTypeFeat | arrayFirstElemNameNoIndexFeat));
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									}
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								}
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1).
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				static const struct
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					UniformCase::Feature	arrayAssignMode;
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*				name;
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*				description;
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				} arrayAssignGroups[] =
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{ UniformCase::FEATURE_ARRAYASSIGN_FULL,			"basic_array_assign_full",		"Assign entire basic-type arrays per glUniform*v() call"			},
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{ UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO,	"basic_array_assign_partial",	"Assign two elements of a basic-type array per glUniform*v() call"	}
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				};
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int arrayAssignGroupNdx = 0; arrayAssignGroupNdx < DE_LENGTH_OF_ARRAY(arrayAssignGroups); arrayAssignGroupNdx++)
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					UniformCase::Feature	arrayAssignMode		= arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* const		groupName			= arrayAssignGroups[arrayAssignGroupNdx].name;
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* const		groupDesc			= arrayAssignGroups[arrayAssignGroupNdx].description;
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const curArrayAssignGroup = new TestCaseGroup(m_context, groupName, groupDesc);
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					assignedValuesGroup->addChild(curArrayAssignGroup);
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					static const int basicArrayCollectionGroups[] = { UNIFORMCOLLECTIONS_BASIC_ARRAY, UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT, UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY };
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionGroupNdx = 0; collectionGroupNdx < DE_LENGTH_OF_ARRAY(basicArrayCollectionGroups); collectionGroupNdx++)
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						curArrayAssignGroup->addChild(collectionTestGroup);
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string								collName			= collectionCase.namePrefix;
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   arrayAssignMode));
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Value checking cases when unused uniforms are present.
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				assignedValuesGroup->addChild(unusedUniformsGroup);
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string								collName			= collectionCase.namePrefix;
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						unusedUniformsGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX | UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER));
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Random cases.
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numRandomCases		= 100;
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup*	const randomGroup	= new TestCaseGroup(m_context, "random", "Random cases");
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(randomGroup);
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < numRandomCases; ndx++)
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			randomGroup->addChild(new RandomUniformCase(m_context, de::toString(ndx).c_str(), "", (deUint32)ndx));
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2438