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, deUint32 features);
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, deUint32 seed); // \note Randomizes caseType, uniformCollection and features.
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~UniformCase	(void);
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				init			(void);
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				deinit			(void);
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate			(void);
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniform
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue		finalValue;	//!< The value we ultimately want to set for this uniform.
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko 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.
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				elemNdx;	//!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				rootSize;	//!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniform (const char* const		name_,
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const glu::DataType	type_,
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const bool			isUsedInShader_,
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const VarValue&		finalValue_,
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char* const		rootName_	= DE_NULL,
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				elemNdx_	= -1,
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				rootSize_	= 1)
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  : name			(name_)
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , type			(type_)
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , isUsedInShader	(isUsedInShader_)
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , finalValue		(finalValue_)
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootName		(rootName_ == DE_NULL ? name_ : rootName_)
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , elemNdx			(elemNdx_)
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootSize		(rootSize_)
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 {
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 }
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static vector<BasicUniform>::const_iterator findWithName (const vector<BasicUniform>& vec, const char* const name)
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<BasicUniform>::const_iterator it = vec.begin(); it != vec.end(); it++)
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (it->name == name)
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return it;
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vec.end();
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reference values for info that is expected to be reported by glGetActiveUniform().
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniformReportRef
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
8303c827367444ee418f129b2c238299f49d3264554Jarkko 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.
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				minSize;
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				maxSize;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const int minS, const int maxS, const glu::DataType type_, const bool used)
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(minS), maxSize(maxS), type(type_), isUsedInShader(used) { DE_ASSERT(minSize <= maxSize); }
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const glu::DataType type_, const bool used)
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(1), maxSize(1), type(type_), isUsedInShader(used) {}
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Info that is actually reported by glGetActiveUniform().
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniformReportGL
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				nameLength;
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				size;
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				index;
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportGL (const char* const name_, const int nameLength_, const int size_, const glu::DataType type_, const int index_)
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), nameLength(nameLength_), size(size_), type(type_), index(index_) {}
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static vector<BasicUniformReportGL>::const_iterator findWithName (const vector<BasicUniformReportGL>& vec, const char* const name)
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<BasicUniformReportGL>::const_iterator it = vec.begin(); it != vec.end(); it++)
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (it->name == name)
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return it;
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vec.end();
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Query info with glGetActiveUniform() and check validity.
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getActiveUniforms						(vector<BasicUniformReportGL>& dst, const vector<BasicUniformReportRef>& ref, deUint32 programGL);
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get uniform values with glGetUniform*() and put to valuesDst. Uniforms that get -1 from glGetUniformLocation() get glu::TYPE_INVALID.
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getUniforms								(vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, deUint32 programGL);
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check that every uniform has the default (zero) value.
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						checkUniformDefaultValues				(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assign the basicUniforms[].finalValue values for uniforms. \note rnd parameter is for booleans (true can be any nonzero value).
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						assignUniforms							(const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd);
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare the uniform values given in values (obtained with glGetUniform*()) with the basicUniform.finalValue values.
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						compareUniformValues					(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render and check that all pixels are white (i.e. all uniform comparisons passed).
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						renderTest								(const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd);
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool				test									(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd) = 0;
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32								m_features;
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const SharedPtr<const UniformCollection>	m_uniformCollection;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static deUint32				randomFeatures							(deUint32 seed);
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generates the basic uniforms, based on the uniform with name varName and type varType, in the same manner as are expected
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// to be returned by glGetActiveUniform(), e.g. generates a name like var[0] for arrays, and recursively generates struct member names.
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						generateBasicUniforms					(vector<BasicUniform>&				basicUniformsDst,
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 vector<BasicUniformReportRef>&		basicUniformReportsDst,
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const glu::VarType&				varType,
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*						varName,
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 bool								isParentActive,
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 int&								samplerUnitCounter,
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 Random&							rnd) const;
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformDefinitions					(std::ostringstream& dst) const;
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformCompareExpr					(std::ostringstream& dst, const BasicUniform& uniform) const;
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformComparisons					(std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* variableName) const;
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateVertexSource					(const vector<BasicUniform>& basicUniforms) const;
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateFragmentSource					(const vector<BasicUniform>& basicUniforms) const;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupTexture							(const VarValue& value);
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseShaderType						m_caseShaderType;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::Texture2D*>						m_textures2d;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::TextureCube*>					m_texturesCube;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>							m_filledTextureUnits;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9133c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 UniformCase::randomFeatures (const deUint32 seed)
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 arrayUsageChoices[]		= { 0, FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX										};
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformFuncChoices[]		= { 0, FEATURE_UNIFORMFUNC_VALUE												};
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 arrayAssignChoices[]		= { 0, FEATURE_ARRAYASSIGN_FULL,			FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	};
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformUsageChoices[]		= { 0, FEATURE_UNIFORMUSAGE_EVERY_OTHER											};
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 booleanApiTypeChoices[]	= { 0, FEATURE_BOOLEANAPITYPE_INT												};
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformValueChoices[]		= { 0, FEATURE_UNIFORMVALUE_ZERO												};
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random rnd(seed);
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 result = 0;
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
926dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh#define ARRAY_CHOICE(ARR) ((ARR)[rnd.getInt(0, DE_LENGTH_OF_ARRAY(ARR)-1)])
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(arrayUsageChoices);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformFuncChoices);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(arrayAssignChoices);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformUsageChoices);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(booleanApiTypeChoices);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformValueChoices);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef ARRAY_CHOICE
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 features)
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(features)
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(uniformCollection)
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(caseShaderType)
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* name, const char* description, const deUint32 seed)
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(randomFeatures(seed))
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(UniformCollection::random(seed))
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(randomCaseShaderType(seed))
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::init (void)
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	funcs						= m_context.getRenderContext().getFunctions();
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numSamplerUniforms			= m_uniformCollection->getNumSamplers();
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsRequired		= m_caseShaderType != CASESHADERTYPE_FRAGMENT ? numSamplerUniforms : 0;
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsRequired	= m_caseShaderType != CASESHADERTYPE_VERTEX ? numSamplerUniforms : 0;
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsRequired	= vertexTexUnitsRequired + fragmentTexUnitsRequired;
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsSupported		= getGLInt(funcs, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsSupported	= getGLInt(funcs, GL_MAX_TEXTURE_IMAGE_UNITS);
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsSupported	= getGLInt(funcs, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numSamplerUniforms <= MAX_NUM_SAMPLER_UNIFORMS);
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexTexUnitsRequired > vertexTexUnitsSupported)
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(vertexTexUnitsRequired) + " vertex texture units required, " + de::toString(vertexTexUnitsSupported) + " supported");
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(fragmentTexUnitsRequired) + " fragment texture units required, " + de::toString(fragmentTexUnitsSupported) + " supported");
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (combinedTexUnitsRequired > combinedTexUnitsSupported)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(combinedTexUnitsRequired) + " combined texture units required, " + de::toString(combinedTexUnitsSupported) + " supported");
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::deinit (void)
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_textures2d.size(); i++)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures2d[i];
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures2d.clear();
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_texturesCube.size(); i++)
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_texturesCube[i];
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texturesCube.clear();
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_filledTextureUnits.clear();
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::~UniformCase (void)
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCase::deinit();
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10013c827367444ee418f129b2c238299f49d3264554Jarkko 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
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType())
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isActive	= isParentActive && (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true);
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= varType.getBasicType();
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue			value		= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(type)
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: glu::isDataTypeSampler(type)				? generateRandomVarValue(type, rnd, samplerUnitCounter++)
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: generateRandomVarValue(varType.getBasicType(), rnd);
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformsDst.push_back(BasicUniform(varName, varType.getBasicType(), isActive, value));
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformReportsDst.push_back(BasicUniformReportRef(varName, varType.getBasicType(), isActive));
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isArrayType())
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		size			= varType.getArraySize();
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	arrayRootName	= string("") + varName + "[0]";
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<bool>	isElemActive;
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++)
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	indexedName		= string("") + varName + "[" + de::toString(elemNdx) + "]";
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		isCurElemActive	= isParentActive																						&&
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER			? basicUniformsDst.size() % 2 == 0	: true)	&&
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX		? elemNdx == size/2					: true);
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isElemActive.push_back(isCurElemActive);
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (varType.getElementType().isBasicType())
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::DataType	elemBasicType	= varType.getElementType().getBasicType();
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const VarValue		value			= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(elemBasicType)
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: glu::isDataTypeSampler(elemBasicType)		? generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++)
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: generateRandomVarValue(elemBasicType, rnd);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformsDst.push_back(BasicUniform(indexedName.c_str(), elemBasicType, isCurElemActive, value, arrayRootName.c_str(), elemNdx, size));
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName.c_str(), isCurElemActive, samplerUnitCounter, rnd);
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (varType.getElementType().isBasicType())
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int minSize;
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize-1]; minSize--);
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicUniformReportsDst.push_back(BasicUniformReportRef(arrayRootName.c_str(), minSize, size, varType.getElementType().getBasicType(), isParentActive && minSize > 0));
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(varType.isStructType());
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *varType.getStructPtr();
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::StructMember&	member			= structType.getMember(i);
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string				memberFullName	= string("") + varName + "." + member.getName();
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName.c_str(), isParentActive, samplerUnitCounter, rnd);
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformDefinitions (std::ostringstream& dst) const
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumStructTypes(); i++)
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << glu::declare(m_uniformCollection->getStructType(i)) << ";\n";
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "uniform " << glu::declare(m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str()) << ";\n";
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << "\n";
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const struct
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataTypePredicate	requiringTypes[2];
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*			definition;
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} compareFuncs[] =
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10843c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																		},
10853c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"														},
10863c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"								},
10873c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"		},
10883c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"													},
10893c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"							},
10903c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"	},
10913c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10923c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10933c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10943c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_BOOL>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bool     (bool a, bool b)                    { return a == b ? 1.0 : 0.0; }"																					},
10963c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10973c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10983c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					}
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool containsSamplers = !m_uniformCollection->getSamplerTypes().empty();
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compFuncNdx = 0; compFuncNdx < DE_LENGTH_OF_ARRAY(compareFuncs); compFuncNdx++)
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const dataTypePredicate		(&typeReq)[2]			= compareFuncs[compFuncNdx].requiringTypes;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool					containsTypeSampler		= containsSamplers && (typeReq[0](glu::TYPE_FLOAT_VEC4) || typeReq[1](glu::TYPE_FLOAT_VEC4));
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (containsTypeSampler || m_uniformCollection->containsMatchingBasicType(typeReq[0]) || m_uniformCollection->containsMatchingBasicType(typeReq[1]))
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst << compareFuncs[compFuncNdx].definition << "\n";
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformCompareExpr (std::ostringstream& dst, const BasicUniform& uniform) const
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeSampler(uniform.type))
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_vec4("
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< (uniform.type == glu::TYPE_SAMPLER_2D ? "texture2D" : "textureCube")
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "(" << uniform.name << ", vec" << getSamplerNumLookupDimensions(uniform.type) << "(0.0))";
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_" << glu::getDataTypeName(uniform.type) << "(" << uniform.name;
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << ", " << shaderVarValueStr(uniform.finalValue) << ")";
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformComparisons (std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* const variableName) const
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform& unif = basicUniforms[i];
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unif.isUsedInShader)
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t" << variableName << " *= ";
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeUniformCompareExpr(dst, basicUniforms[i]);
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << ";\n";
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t// UNUSED: " << basicUniforms[i].name << "\n";
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateVertexSource (const vector<BasicUniform>& basicUniforms) const
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX || m_caseShaderType == CASESHADERTYPE_BOTH;
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "attribute highp vec4 a_position;\n"
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "varying mediump float v_vtxOut;\n"
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	gl_Position = a_position;\n"
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	v_vtxOut = 1.0;\n";
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "v_vtxOut");
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "}\n";
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateFragmentSource (const vector<BasicUniform>& basicUniforms) const
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isFragmentCase = m_caseShaderType == CASESHADERTYPE_FRAGMENT || m_caseShaderType == CASESHADERTYPE_BOTH;
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "varying mediump float v_vtxOut;\n"
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	mediump float result = v_vtxOut;\n";
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "result");
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "	gl_FragColor = vec4(result, result, result, 1.0);\n"
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "}\n";
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::setupTexture (const VarValue& value)
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(false);
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						width			= 32;
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						height			= 32;
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4					color			= vec4FromPtr(&value.val.samplerV.fillColor[0]);
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (value.type == glu::TYPE_SAMPLER_2D)
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Texture2D* texture		= new glu::Texture2D(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width, height);
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Texture2D& refTexture	= texture->getRefTexture();
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures2d.push_back(texture);
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		refTexture.allocLevel(0);
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fillWithColor(refTexture.getLevel(0), color);
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (value.type == glu::TYPE_SAMPLER_CUBE)
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(width == height);
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::TextureCube* texture		= new glu::TextureCube(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width);
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureCube& refTexture	= texture->getRefTexture();
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texturesCube.push_back(texture);
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refTexture.allocLevel((tcu::CubeFace)face, 0);
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fillWithColor(refTexture.getLevelFace(0, (tcu::CubeFace)face), color);
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getActiveUniforms (vector<BasicUniformReportGL>& basicUniformReportsDst, const vector<BasicUniformReportRef>& basicUniformReportsRef, const deUint32 programGL)
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log						= m_testCtx.getLog();
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint				numActiveUniforms		= 0;
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint				uniformMaxNameLength	= 0;
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<char>		nameBuffer;
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				success					= true;
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORMS, &numActiveUniforms));
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "// Number of active uniforms reported: " << numActiveUniforms << TestLog::EndMessage;
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxNameLength));
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "// Maximum uniform name length reported: " << uniformMaxNameLength << TestLog::EndMessage;
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	nameBuffer.resize(uniformMaxNameLength);
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < numActiveUniforms; unifNdx++)
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLsizei					reportedNameLength	= 0;
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint					reportedSize		= -1;
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum					reportedTypeGL		= GL_NONE;
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGetActiveUniform(programGL, (GLuint)unifNdx, (GLsizei)uniformMaxNameLength, &reportedNameLength, &reportedSize, &reportedTypeGL, &nameBuffer[0]));
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		reportedType		= glu::getDataTypeFromGLType(reportedTypeGL);
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			reportedNameStr		(&nameBuffer[0]);
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Got name = " << reportedNameStr << ", name length = " << reportedNameLength << ", size = " << reportedSize << ", type = " << glu::getDataTypeName(reportedType) << TestLog::EndMessage;
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((GLsizei)reportedNameStr.length() != reportedNameLength)
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: wrong name length reported, should be " << reportedNameStr.length() << TestLog::EndMessage;
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!deStringBeginsWith(reportedNameStr.c_str(), "gl_")) // Ignore built-in uniforms.
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int referenceNdx;
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (referenceNdx = 0; referenceNdx < (int)basicUniformReportsRef.size(); referenceNdx++)
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (basicUniformReportsRef[referenceNdx].name == reportedNameStr)
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (referenceNdx >= (int)basicUniformReportsRef.size())
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: invalid non-built-in uniform name reported" << TestLog::EndMessage;
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const BasicUniformReportRef& reference = basicUniformReportsRef[referenceNdx];
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.type != glu::TYPE_LAST);
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize <= reference.maxSize);
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (BasicUniformReportGL::findWithName(basicUniformReportsDst, reportedNameStr.c_str()) != basicUniformReportsDst.end())
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: same uniform name reported twice" << TestLog::EndMessage;
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformReportsDst.push_back(BasicUniformReportGL(reportedNameStr.c_str(), reportedNameLength, reportedSize, reportedType, unifNdx));
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedType != reference.type)
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: wrong type reported, should be " << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "// FAILURE: wrong size reported, should be "
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< (reference.minSize == reference.maxSize ? de::toString(reference.minSize) : "in the range [" + de::toString(reference.minSize) + ", " + de::toString(reference.maxSize) + "]")
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniformReportRef& expected = basicUniformReportsRef[i];
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (expected.isUsedInShader && BasicUniformReportGL::findWithName(basicUniformReportsDst, expected.name.c_str()) == basicUniformReportsDst.end())
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: uniform with name " << expected.name << " was not reported by GL" << TestLog::EndMessage;
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getUniforms (vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, const deUint32 programGL)
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName	= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				location	= glGetUniformLocation(programGL, queryName.c_str());
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				size		= glu::getDataTypeScalarSize(uniform.type);
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue				value;
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemset(&value, 0xcd, sizeof(value)); // Initialize to known garbage.
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location == -1)
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.type = glu::TYPE_INVALID;
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesDst.push_back(value);
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniform.isUsedInShader)
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: " << uniform.name << " was used in shader, but has location -1" << TestLog::EndMessage;
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		value.type = uniform.type;
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLint) == sizeof(value.val.intV[0]));
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(value.val.floatV[0]));
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(uniform.type))
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec(uniform.type))
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_features & FEATURE_BOOLEANAPITYPE_INT)
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.intV[i] != 0;
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // Default: use float.
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.floatV[i] != 0.0f;
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(uniform.type))
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLint unit = -1;
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &unit));
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.val.samplerV.unit = unit;
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		valuesDst.push_back(value);
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Got " << uniform.name << " value " << apiVarValueStr(value) << TestLog::EndMessage;
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::checkUniformDefaultValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(values.size() == basicUniforms.size());
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue&			unifValue	= values[unifNdx];
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				valSize		= glu::getDataTypeScalarSize(uniform.type);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define CHECK_UNIFORM(VAR_VALUE_MEMBER, ZERO)																								\
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	do																																		\
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																																		\
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < valSize; i++)																									\
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{																																	\
1438dc795cd4f3d064cbbe2bf9899bf2088d206b7434Chih-Hung Hsieh			if (unifValue.val.VAR_VALUE_MEMBER[i] != (ZERO))																				\
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{																																\
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;	\
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;																											\
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}																																\
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}																																	\
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} while (false)
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(floatV, 0.0f);
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(uniform.type))
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(intV, 0);
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec(uniform.type))
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(boolV, false);
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(uniform.type))
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (unifValue.val.samplerV.unit != 0)
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef CHECK_UNIFORM
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::assignUniforms (const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd)
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		boolApiType		= m_features & FEATURE_BOOLEANAPITYPE_INT	? glu::TYPE_INT
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											:											  glu::TYPE_FLOAT;
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform				= basicUniforms[unifNdx];
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isArrayMember		= uniform.elemNdx >= 0;
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName			= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numValuesToAssign	= !isArrayMember									? 1
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_FULL				? (uniform.elemNdx == 0			? uniform.rootSize	: 0)
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	? (uniform.elemNdx % 2 == 0		? 2					: 0)
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: /* Default: assign array elements separately */	  1;
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign >= 0);
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign == 1 || isArrayMember);
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numValuesToAssign == 0)
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Uniform " << uniform.name << " is covered by another glUniform*v() call to the same array" << TestLog::EndMessage;
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			location			= glGetUniformLocation(programGL, queryName.c_str());
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			typeSize			= glu::getDataTypeScalarSize(uniform.type);
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			assignByValue		= m_features & FEATURE_UNIFORMFUNC_VALUE && !glu::isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue>	valuesToAssign;
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numValuesToAssign; i++)
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	curName = isArrayMember ? beforeLast(uniform.rootName, '[') + "[" + de::toString(uniform.elemNdx+i) + "]" : uniform.name;
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VarValue		unifValue;
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isArrayMember)
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const vector<BasicUniform>::const_iterator elemUnif = BasicUniform::findWithName(basicUniforms, curName.c_str());
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (elemUnif == basicUniforms.end())
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = elemUnif->finalValue;
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = uniform.finalValue;
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const VarValue apiValue = glu::isDataTypeBoolOrBVec(unifValue.type)	? getRandomBoolRepresentation(unifValue, boolApiType, rnd)
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: glu::isDataTypeSampler(unifValue.type)	? getSamplerUnitValue(unifValue)
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: unifValue;
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesToAssign.push_back(apiValue);
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isDataTypeBoolOrBVec(uniform.type))
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Using type " << glu::getDataTypeName(boolApiType) << " to set boolean value " << apiVarValueStr(unifValue) << " for " << curName << TestLog::EndMessage;
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (glu::isDataTypeSampler(uniform.type))
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Texture for the sampler uniform " << curName << " will be filled with color " << apiVarValueStr(getSamplerFillValue(uniform.finalValue)) << TestLog::EndMessage;
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!valuesToAssign.empty());
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(valuesToAssign[0].type))
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float* const ptr = &valuesToAssign[0].val.floatV[0];
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1f(location, ptr[0]));							break;
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2f(location, ptr[0], ptr[1]));					break;
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3f(location, ptr[0], ptr[1], ptr[2]));			break;
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4f(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<float> buffer(valuesToAssign.size() * typeSize);
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeMatrix(valuesToAssign[0].type))
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!assignByValue);
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<float> buffer(valuesToAssign.size() * typeSize);
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)buffer.size(); i++)
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (uniform.type)
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2: GLU_CHECK_CALL(glUniformMatrix2fv(location, (GLsizei)valuesToAssign.size(), GL_FALSE, &buffer[0])); break;
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3: GLU_CHECK_CALL(glUniformMatrix3fv(location, (GLsizei)valuesToAssign.size(), GL_FALSE, &buffer[0])); break;
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4: GLU_CHECK_CALL(glUniformMatrix4fv(location, (GLsizei)valuesToAssign.size(), GL_FALSE, &buffer[0])); break;
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(valuesToAssign[0].type))
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deInt32* const ptr = &valuesToAssign[0].val.intV[0];
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1i(location, ptr[0]));							break;
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2i(location, ptr[0], ptr[1]));					break;
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3i(location, ptr[0], ptr[1], ptr[2]));			break;
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4i(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<deInt32> buffer(valuesToAssign.size() * typeSize);
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLint) == sizeof(buffer[0]));
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(valuesToAssign[0].type))
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glUniform1i(location, uniform.finalValue.val.samplerV.unit));
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLint unit = uniform.finalValue.val.samplerV.unit;
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &unit));
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::compareUniformValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue&			unifValue	= values[unifNdx];
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!apiVarValueEquals(unifValue, uniform.finalValue))
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: value obtained with glGetUniform*() for uniform " << uniform.name << " differs from value set with glUniform*()" << TestLog::EndMessage;
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::renderTest (const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd)
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log				= m_testCtx.getLog();
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportW		= de::min(renderTarget.getWidth(),	MAX_RENDER_WIDTH);
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportH		= de::min(renderTarget.getHeight(),	MAX_RENDER_HEIGHT);
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportX		= rnd.getInt(0, renderTarget.getWidth()		- viewportW);
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportY		= rnd.getInt(0, renderTarget.getHeight()	- viewportH);
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedImg		(viewportW, viewportH);
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assert that no two samplers of different types have the same texture unit - this is an error in GL.
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type))
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int j = 0; j < i; j++)
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (glu::isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit);
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type) && std::find(m_filledTextureUnits.begin(), m_filledTextureUnits.end(), basicUniforms[i].finalValue.val.samplerV.unit) == m_filledTextureUnits.end())
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Filling texture at unit " << apiVarValueStr(basicUniforms[i].finalValue) << " with color " << shaderVarValueStr(basicUniforms[i].finalValue) << TestLog::EndMessage;
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setupTexture(basicUniforms[i].finalValue);
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportW, viewportH));
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const float position[] =
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, -1.0f, 0.0f, 1.0f,
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, +1.0f, 0.0f, 1.0f,
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, -1.0f, 0.0f, 1.0f,
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, +1.0f, 0.0f, 1.0f
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int posLoc = glGetAttribLocation(program.getProgram(), "a_position");
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glEnableVertexAttribArray(posLoc);
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_SHORT, &indices[0]));
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numFailedPixels = 0;
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < renderedImg.getWidth(); x++)
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1712c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			if (renderedImg.getPixel(x, y) != tcu::RGBA::white())
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += 1;
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels > 0)
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-white pixels" << TestLog::EndMessage;
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: got all-white pixels (all uniforms have correct values)" << TestLog::EndMessage;
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::IterateResult UniformCase::iterate (void)
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random							rnd				(deStringHash(getName()) ^ (deUint32)m_context.getTestContext().getCommandLine().getBaseSeed());
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log				= m_testCtx.getLog();
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniform>			basicUniforms;
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportRef>	basicUniformReportsRef;
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int samplerUnitCounter = 0;
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniforms, basicUniformReportsRef, m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str(), true, samplerUnitCounter, rnd);
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					vertexSource	= generateVertexSource(basicUniforms);
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					fragmentSource	= generateFragmentSource(basicUniforms);
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderProgram				program			(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource));
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << program;
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program.isOk())
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glUseProgram(program.getProgram()));
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool success = test(basicUniforms, basicUniformReportsRef, program, rnd);
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							success ? "Passed"				: "Failed");
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformInfoQueryCase : public UniformCase
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				UniformInfoQueryCase	(Context& context, const char* name, const char* description, CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 additionalFeatures = 0);
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformInfoQueryCase::UniformInfoQueryCase (Context& context, const char* const name, const char* const description, const CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 additionalFeatures)
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase	(context, name, description, shaderType, uniformCollection, additionalFeatures)
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformInfoQueryCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(basicUniforms);
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(rnd);
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					programGL	= program.getProgram();
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log			= m_testCtx.getLog();
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportGL>	basicUniformReportsUniform;
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ScopedLogSection section(log, "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool success = getActiveUniforms(basicUniformReportsUniform, basicUniformReportsRef, programGL);
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!success)
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformValueCase : public UniformCase
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ValueToCheck
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_INITIAL = 0,		//!< Verify the initial values of the uniforms (i.e. check that they're zero).
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_ASSIGNED,			//!< Assign values to uniforms with glUniform*(), and check those.
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_LAST
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CheckMethod
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_GET_UNIFORM = 0,	//!< Check values with glGetUniform*().
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_RENDER,				//!< Check values by rendering with the value-checking shader.
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_LAST
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum AssignMethod
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_POINTER = 0,
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_VALUE,
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_LAST
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						UniformValueCase			(Context&									context,
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								name,
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								description,
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CaseShaderType								shaderType,
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const SharedPtr<const UniformCollection>&	uniformCollection,
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ValueToCheck								valueToCheck,
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CheckMethod								checkMethod,
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 AssignMethod								assignMethod,
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 deUint32									additionalFeatures = 0);
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test						(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getValueToCheckName			(ValueToCheck valueToCheck);
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getValueToCheckDescription	(ValueToCheck valueToCheck);
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodName			(CheckMethod checkMethod);
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodDescription	(CheckMethod checkMethod);
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodName			(AssignMethod checkMethod);
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodDescription	(AssignMethod checkMethod);
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ValueToCheck	m_valueToCheck;
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CheckMethod	m_checkMethod;
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getValueToCheckName (const ValueToCheck valueToCheck)
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (valueToCheck)
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_INITIAL:	return "initial";
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_ASSIGNED:	return "assigned";
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);	return DE_NULL;
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getValueToCheckDescription (const ValueToCheck valueToCheck)
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (valueToCheck)
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_INITIAL:	return "Check initial uniform values (zeros)";
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_ASSIGNED:	return "Check assigned uniform values";
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);	return DE_NULL;
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getCheckMethodName (const CheckMethod checkMethod)
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "get_uniform";
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "render";
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getCheckMethodDescription (const CheckMethod checkMethod)
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "Verify values with glGetUniform*()";
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "Verify values by rendering";
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getAssignMethodName (const AssignMethod assignMethod)
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "by_pointer";
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "by_value";
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getAssignMethodDescription (const AssignMethod assignMethod)
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "Assign values by-pointer";
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "Assign values by-value";
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformValueCase::UniformValueCase (Context&									context,
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const							name,
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const							description,
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const CaseShaderType						shaderType,
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const SharedPtr<const UniformCollection>&	uniformCollection,
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const ValueToCheck							valueToCheck,
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const CheckMethod							checkMethod,
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const AssignMethod							assignMethod,
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const deUint32								additionalFeatures)
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase		(context, name, description, shaderType, uniformCollection,
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 (valueToCheck == VALUETOCHECK_INITIAL ? FEATURE_UNIFORMVALUE_ZERO : 0) | (assignMethod == ASSIGNMETHOD_VALUE ? FEATURE_UNIFORMFUNC_VALUE : 0) | additionalFeatures)
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_valueToCheck	(valueToCheck)
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_checkMethod		(checkMethod)
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!(assignMethod == ASSIGNMETHOD_LAST && valueToCheck == VALUETOCHECK_ASSIGNED));
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformValueCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(basicUniformReportsRef);
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	programGL	= program.getProgram();
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log			= m_testCtx.getLog();
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		assignUniforms(basicUniforms, programGL, rnd);
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_checkMethod == CHECKMETHOD_GET_UNIFORM)
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> values;
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "GetUniforms", "Uniform value query");
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = getUniforms(values, basicUniforms, program.getProgram());
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values");
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = compareUniformValues(values, basicUniforms);
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "ValueCheck", "Verify that the uniforms have correct initial values (zeros)");
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = checkUniformDefaultValues(values, basicUniforms);
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_checkMethod == CHECKMETHOD_RENDER);
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "RenderTest", "Render test");
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = renderTest(basicUniforms, program, rnd);
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RandomUniformCase : public UniformCase
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						RandomUniformCase		(Context& m_context, const char* name, const char* description, deUint32 seed);
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomUniformCase::RandomUniformCase (Context& context, const char* const name, const char* const description, const deUint32 seed)
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase (context, name, description, seed ^ (deUint32)context.getTestContext().getCommandLine().getBaseSeed())
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool RandomUniformCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Different sampler types may not be bound to same unit when rendering.
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		renderingPossible						= (m_features & FEATURE_UNIFORMVALUE_ZERO) == 0 || !m_uniformCollection->containsSeveralSamplerTypes();
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			performGetActiveUniforms			= rnd.getBool();
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performGetUniforms					= rnd.getBool();
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performCheckUniformDefaultValues	= performGetUniforms && rnd.getBool();
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performAssignUniforms				= rnd.getBool();
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performCompareUniformValues			= performGetUniforms && performAssignUniforms && rnd.getBool();
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performRenderTest					= renderingPossible && performAssignUniforms && rnd.getBool();
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	programGL							= program.getProgram();
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log									= m_testCtx.getLog();
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!(performGetActiveUniforms || performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms || performCompareUniformValues || performRenderTest))
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		performGetActiveUniforms = true; // Do something at least.
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PERFORM_AND_CHECK(CALL, SECTION_NAME, SECTION_DESCRIPTION)						\
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	do																					\
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																					\
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, (SECTION_NAME), (SECTION_DESCRIPTION));		\
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = (CALL);													\
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)																	\
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;																\
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} while (false)
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (performGetActiveUniforms)
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<BasicUniformReportGL> reportsUniform;
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PERFORM_AND_CHECK(getActiveUniforms(reportsUniform, basicUniformReportsRef, programGL), "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> uniformDefaultValues;
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performGetUniforms)
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getUniforms(uniformDefaultValues, basicUniforms, programGL), "GetUniformDefaults", "Uniform default value query");
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performCheckUniformDefaultValues)
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(checkUniformDefaultValues(uniformDefaultValues, basicUniforms), "DefaultValueCheck", "Verify that the uniforms have correct initial values (zeros)");
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> uniformValues;
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performAssignUniforms)
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			assignUniforms(basicUniforms, programGL, rnd);
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performCompareUniformValues)
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getUniforms(uniformValues, basicUniforms, programGL), "GetUniforms", "Uniform value query");
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(compareUniformValues(uniformValues, basicUniforms), "ValueCheck", "Verify that the reported values match the assigned values");
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (performRenderTest)
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PERFORM_AND_CHECK(renderTest(basicUniforms, program, rnd), "RenderTest", "Render test");
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PERFORM_AND_CHECK
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformApiTests::UniformApiTests (Context& context)
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "uniform_api", "Uniform API Tests")
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformApiTests::~UniformApiTests (void)
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note Although this is only used in UniformApiTest::init, it needs to be defined here as it's used as a template argument.
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct UniformCollectionCase
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string								namePrefix;
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SharedPtr<const UniformCollection>	uniformCollection;
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollectionCase (const char* const name, const UniformCollection* uniformCollection_)
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: namePrefix			(name ? name + string("_") : "")
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, uniformCollection		(uniformCollection_)
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformApiTests::init (void)
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate sets of UniformCollections that are used by several cases.
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC = 0,
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_ARRAY,
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_STRUCT,
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY,
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT,
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS,
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC,
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY,
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS,
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_LAST
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct UniformCollectionGroup
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string							name;
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<UniformCollectionCase>	cases;
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} defaultUniformCollections[UNIFORMCOLLECTIONS_LAST];
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].name							= "basic";
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].name						= "basic_array";
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].name						= "basic_struct";
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].name					= "struct_in_array";
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].name					= "array_in_struct";
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].name			= "nested_structs_arrays";
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].name					= "multiple_basic";
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].name				= "multiple_basic_array";
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].name	= "multiple_nested_structs_arrays";
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_testDataTypes); dataTypeNdx++)
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		dataType	= s_testDataTypes[dataTypeNdx];
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const		typeName	= glu::getDataTypeName(dataType);
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basic(dataType)));
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)													||
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(glu::isDataTypeVector(dataType) && glu::getDataTypeScalarSize(dataType) == 4)	||
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4												||
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basicArray(dataType)));
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)		||
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4	||
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::DataType		secondDataType	= glu::isDataTypeScalar(dataType)	? glu::getDataTypeVector(dataType, 4)
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_FLOAT_MAT4	? glu::TYPE_FLOAT_MAT2
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_SAMPLER_2D	? glu::TYPE_SAMPLER_CUBE
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: glu::TYPE_LAST;
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(secondDataType != glu::TYPE_LAST);
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		secondTypeName	= glu::getDataTypeName(secondDataType);
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string			name			= string("") + typeName + "_" + secondTypeName;
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].cases.push_back			(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, false)));
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, true)));
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::structInArray(dataType, secondDataType, false)));
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(name.c_str(), UniformCollection::nestedArraysStructs(dataType, secondDataType)));
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].cases.push_back					(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasic()));
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].cases.push_back				(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasicArray()));
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(DE_NULL, UniformCollection::multipleNestedArraysStructs()));
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Info-query cases (check info returned by e.g. glGetActiveUniforms()).
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const infoQueryGroup = new TestCaseGroup(m_context, "info_query", "Test glGetActiveUniform()");
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(infoQueryGroup);
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[collectionGroupNdx];
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			infoQueryGroup->addChild(collectionTestGroup);
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionCase& collectionCase = collectionGroup.cases[collectionNdx];
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string								name				= collectionCase.namePrefix + getCaseShaderTypeName((CaseShaderType)shaderType);
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					collectionTestGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection));
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Info-querying cases when unused uniforms are present.
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			infoQueryGroup->addChild(unusedUniformsGroup);
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string								collName			= collectionCase.namePrefix;
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					unusedUniformsGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER | UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX));
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cases testing uniform values.
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const valueGroup = new TestCaseGroup(m_context, "value", "Uniform value tests");
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(valueGroup);
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering.
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const initialValuesGroup = new TestCaseGroup(m_context,
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_INITIAL),
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_INITIAL));
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueGroup->addChild(initialValuesGroup);
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				initialValuesGroup->addChild(checkMethodGroup);
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[collectionGroupNdx];
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					checkMethodGroup->addChild(collectionTestGroup);
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string								collName			= collectionCase.namePrefix;
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																						  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int									numBoolVariations	= varyBoolApiType ? 2 : 1;
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (checkMethod == UniformValueCase::CHECKMETHOD_RENDER && uniformCollection->containsSeveralSamplerTypes())
22403c827367444ee418f129b2c238299f49d3264554Jarkko 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.
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const deUint32		booleanTypeFeat	= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: 0;
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char* const	booleanTypeName	= booleanTypeI == 1 ? "int"
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: "float";
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string		nameWithApiType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string name = nameWithApiType + getCaseShaderTypeName((CaseShaderType)shaderType);
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   UniformValueCase::VALUETOCHECK_INITIAL, checkMethod, UniformValueCase::ASSIGNMETHOD_LAST, booleanTypeFeat));
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering.
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const assignedValuesGroup = new TestCaseGroup(m_context,
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_ASSIGNED),
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_ASSIGNED));
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueGroup->addChild(assignedValuesGroup);
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int assignMethodI = 0; assignMethodI < (int)UniformValueCase::ASSIGNMETHOD_LAST; assignMethodI++)
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformValueCase::AssignMethod	assignMethod		= (UniformValueCase::AssignMethod)assignMethodI;
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const					assignMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getAssignMethodName(assignMethod), UniformValueCase::getAssignMethodDescription(assignMethod));
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				assignedValuesGroup->addChild(assignMethodGroup);
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					assignMethodGroup->addChild(checkMethodGroup);
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int numArrayFirstElemNameCases = checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1;
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++)
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const UniformCollectionGroup&	collectionGroup			= defaultUniformCollections[collectionGroupNdx];
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string					collectionGroupName		= collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
2290ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry							TestCaseGroup*					collectionTestGroup		= DE_NULL;
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string								collName			= collectionCase.namePrefix;
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																								  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int									numBoolVariations	= varyBoolApiType ? 2 : 1;
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									containsMatrices	= uniformCollection->containsMatchingBasicType(glu::isDataTypeMatrix);
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								if (containsMatrices && assignMethod != UniformValueCase::ASSIGNMETHOD_POINTER)
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									continue;
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								{
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const deUint32		booleanTypeFeat		= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: 0;
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const	booleanTypeName		= booleanTypeI == 1 ? "int"
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: "float";
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const string		nameWithBoolType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const string		nameWithMatrixType	= nameWithBoolType;
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									{
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										const string	name							= nameWithMatrixType + getCaseShaderTypeName((CaseShaderType)shaderType);
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										const deUint32	arrayFirstElemNameNoIndexFeat	= referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX;
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2320ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										// skip empty groups by creating groups on demand
2321ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										if (!collectionTestGroup)
2322ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										{
2323ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry											collectionTestGroup = new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
2324ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry											checkMethodGroup->addChild(collectionTestGroup);
2325ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										}
2326ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							UniformValueCase::VALUETOCHECK_ASSIGNED, checkMethod, assignMethod,
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							booleanTypeFeat | arrayFirstElemNameNoIndexFeat));
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									}
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								}
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1).
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				static const struct
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					UniformCase::Feature	arrayAssignMode;
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*				name;
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*				description;
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				} arrayAssignGroups[] =
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{ UniformCase::FEATURE_ARRAYASSIGN_FULL,			"basic_array_assign_full",		"Assign entire basic-type arrays per glUniform*v() call"			},
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{ UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO,	"basic_array_assign_partial",	"Assign two elements of a basic-type array per glUniform*v() call"	}
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				};
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int arrayAssignGroupNdx = 0; arrayAssignGroupNdx < DE_LENGTH_OF_ARRAY(arrayAssignGroups); arrayAssignGroupNdx++)
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					UniformCase::Feature	arrayAssignMode		= arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* const		groupName			= arrayAssignGroups[arrayAssignGroupNdx].name;
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* const		groupDesc			= arrayAssignGroups[arrayAssignGroupNdx].description;
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const curArrayAssignGroup = new TestCaseGroup(m_context, groupName, groupDesc);
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					assignedValuesGroup->addChild(curArrayAssignGroup);
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					static const int basicArrayCollectionGroups[] = { UNIFORMCOLLECTIONS_BASIC_ARRAY, UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT, UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY };
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionGroupNdx = 0; collectionGroupNdx < DE_LENGTH_OF_ARRAY(basicArrayCollectionGroups); collectionGroupNdx++)
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						curArrayAssignGroup->addChild(collectionTestGroup);
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string								collName			= collectionCase.namePrefix;
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   arrayAssignMode));
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Value checking cases when unused uniforms are present.
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				assignedValuesGroup->addChild(unusedUniformsGroup);
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string								collName			= collectionCase.namePrefix;
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						unusedUniformsGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX | UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER));
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Random cases.
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numRandomCases		= 100;
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup*	const randomGroup	= new TestCaseGroup(m_context, "random", "Random cases");
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(randomGroup);
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < numRandomCases; ndx++)
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			randomGroup->addChild(new RandomUniformCase(m_context, de::toString(ndx).c_str(), "", (deUint32)ndx));
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2428